I have a problem. But firstly for the archives, here are the bits that work. I hope it well help a few people get up and running a little faster than I did. Oopenamf is not exactly the world's best documented project.
My user bean in AS:
NOTE: The property names (not the getter names) in the AS class must match the getter and setter names in the java class.
ActionScript Code:
import mx.remoting.NetServices;
class BMUser {
public var userName:String;
public var pword:String;
public var uid:Number;
public var lastLogin:Number;
function BMUser() {
trace(userName+" "+pword+" "+uid+" "+lastLogin);
}
function getUserName():String {
return userName;
}
function setUserName(in_s:String) {
userName = in_s;
}
function getPword():String {
return pword;
}
function setPword(in_s:String) {
pword = in_s;
}
function getUid():Number {
return uid;
}
function setUid(in_id:Number) {
uid = in_id;
}
function getLastLogin():Number {
return lastLogin;
}
function setLastLogin(in_l:Number) {
lastLogin = in_l;
}
}
My communication class in AS:
ActionScript Code:
import mx.remoting.NetServices;
class UserDirectory {
private var gatewayPath:String = "";
private var servicePath:String = "";
private var serviceConnection:Object = new Object();
private var serviceObject:Object = new Object();
public static var _instance:UserDirectory
public static function getInstance():UserDirectory
{
if(_instance == undefined)
{
_instance = new UserDirectory()
}
return _instance
}
private function UserDirectory() {
this.gatewayPath = GLOBALS.gatewayPath;
this.servicePath = "";
this.setServicePath("com.jakestone.bm.remoting.UserDirectory");
this.setServiceObject();
}
function getGatewayPath():String {
return gatewayPath;
}
function setGatewayPath(in_s:String) {
gatewayPath = in_s;
}
function getServicePath():String {
return servicePath;
}
function setServicePath(in_s:String) {
servicePath = in_s;
}
function setServiceObject() {
trace("UserDirectory settingserviceObject");
NetServices.setDefaultGatewayUrl(this.gatewayPath);
this.serviceConnection = NetServices.createGatewayConnection();
this.serviceObject = this.serviceConnection.getService(this.servicePath, this);
}
function login(user:BMUser) {
try {
trace("UserDirectory:login username="+user.getUserName());
trace("UserDirectory:login username="+user.getPword());
this.setServiceObject();
this.serviceObject.login(user);
} catch (errorObj:Error) {
trace(errorObj.message);
}
}
function login_Result(loginresult:BMUser) {
try {
trace("UserDirectory:login_result loginresult.getLastLogin()="+loginresult.getLastLogin());
if (undefined == loginresult.getLastLogin()) {
trace(" Login Failed");
} else {
trace(" Login Succeeded");
}
} catch (errorObj:Error) {
trace(errorObj.message);
}
}
}
This works fine as is butdidn't work when I tried to create a superclass for some of the methods such as setServiceObject. This just needs reviewing. I'm sure it can be done.
SERVER SIDE:
openamf.config.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<!--
Configure behavior of outgoing AMF messages:
forceLowerCaseKeys - if true, the hash maps used to return custom classes
will convert all keys to lower case;
set this to:
true if you're using ActionScript 1.0 on the client,
false if you're using ActionScript 2.0 (which is case-sensitive)
-->
<amf-serializer>
<force-lower-case-keys>true</force-lower-case-keys>
</amf-serializer>
<!-- Required for DefaultGateway-->
<invoker>
<name>PageableRecordSet</name>
<class>org.openamf.invoker.PageableResultSetServiceInvoker</class>
</invoker>
<invoker>
<name>SessionControl</name>
<class>org.openamf.invoker.SessionControlInvoker</class>
</invoker>
<invoker>
<name>WebService</name>
<class>org.openamf.invoker.WebServiceInvoker</class>
</invoker>
<invoker>
<name>JMX</name>
<class>org.openamf.invoker.JMXServiceInvoker</class>
</invoker>
<!-- Uncomment this to enable EJB invoker
<invoker>
<name>EJB</name>
<class>org.openamf.invoker.EJBServiceInvoker</class>
</invoker>
-->
<invoker>
<name>Java</name>
<class>org.openamf.invoker.JavaServiceInvoker</class>
</invoker>
<pageable-recordset>
<initial-data-row-count>20</initial-data-row-count>
</pageable-recordset>
<!--
Example Custom Class to Java Class mapping
When a class of type org.openamf.examples.Person is Serialized
it will be registered to Person in flash
When a custom class of Person is Deserialized it
will be translated to an org.openamf.examples.Person
<custom-class-mapping>
<java-class>org.openamf.examples.Person</java-class>
<custom-class>Person</custom-class>
</custom-class-mapping>
-->
<!-- Required for AdvancedGateway -->
<!--
This allows you to declare infomation about your services,
instead of having the DefaultGateway guess
-->
<service>
<name>SessionControlService</name>
<invoker-ref>SessionControl</invoker-ref>
<method>
<name>close</name>
<parameter>
<type>*</type>
</parameter>
</method>
</service>
<service>
<name>OpenAMFPageableRecordSet</name>
<invoker-ref>PageableRecordSet</invoker-ref>
<method>
<name>*</name>
<parameter>
<type>*</type>
</parameter>
</method>
</service>
<service>
<name>Test</name>
<service-location>com.jakestone.bm.Test</service-location>
<invoker-ref>Java</invoker-ref>
<method>
<!-- Operation's are matched by the name and parameters -->
<name>sayHello</name>
<state-bean-ref>
<name>Authentication</name>
</state-bean-ref>
<parameter>
<!--
type can be the the name of the class,
a * for any types,
or a ? any 1 type
-->
<type>*</type>
</parameter>
</method>
</service>
<service>
<name>UserDirectory</name>
<service-location>com.jakestone.bm.remoting.UserDirectory</service-location>
<invoker-ref>Java</invoker-ref>
<method>
<!-- Operation's are matched by the name and parameters -->
<name>login</name>
<state-bean-ref>
<name>Authentication</name>
</state-bean-ref>
<parameter>
<!--
type can be the the name of the class,
a * for any types,
or a ? any 1 type
-->
<type>com.jakestone.bm.datamodel.BMUser</type>
</parameter>
</method>
</service>
<state-bean>
<name>Authentication</name>
<class>org.openamf.examples.Authentication</class>
<scope>session</scope>
</state-bean>
</config>
My web.xml. (Password to db is TOP SECRET so don't read it)
Code:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Copyright 2004 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Brain Map Project</display-name>
<description>
Brain Map Project.
</description>
<servlet>
<servlet-name>InitServlet</servlet-name>
<servlet-class>com.jakestone.bm.servlet.InitServlet</servlet-class>
<init-param id="param1">
<param-name>
DRIVER
</param-name>
<param-value>
com.mckoi.JDBCDriver
</param-value>
</init-param>
<init-param id="param2">
<param-name>
USER
</param-name>
<param-value>
bmdb
</param-value>
</init-param>
<init-param id="param3">
<param-name>
PASSWORD
</param-name>
<param-value>
bmdb
</param-value>
</init-param>
<init-param id="param4">
<param-name>
URL
</param-name>
<param-value>
jdbc:mckoi:local://../webapps/bm/mckoi/db.conf
</param-value>
</init-param>
<init-param id="param5">
<param-name>
logLevel
</param-name>
<param-value>
FINEST
</param-value>
</init-param>
<init-param id="param6">
<param-name>
logFile
</param-name>
<param-value>
../webapps/bm/logs/bmwebapp.log
</param-value>
</init-param>
<init-param id="param7">
<param-name>
mckoiDir
</param-name>
<param-value>
../webapps/bm/mckoi
</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet>
<servlet-name>DefaultGateway</servlet-name>
<display-name>DefaultGateway</display-name>
<description>DefaultGateway</description>
<servlet-class>org.openamf.DefaultGateway</servlet-class>
<init-param>
<param-name>OPENAMF_CONFIG</param-name>
<param-value>/WEB-INF/openamf-config.xml</param-value>
<description>Location of the OpenAMF config file.</description>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DefaultGateway</servlet-name>
<url-pattern>/gateway</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>InitServlet</servlet-name>
<url-pattern>/InitServlet</url-pattern>
</servlet-mapping>
</web-app>
My service class:
Code:
package com.jakestone.bm.remoting;
import com.jakestone.bm.datamodel.BMUser;
import com.jakestone.bm.utils.BMLogManager;
import java.util.logging.Level;
import java.io.Serializable;
/**
* Created by IntelliJ IDEA.
* User: Jacob
* Date: May 8, 2005
* Time: 8:59:05 PM
* To change this template use Options | File Templates.
*/
public class UserDirectory implements Serializable
{
public BMUser login(BMUser user)
{
try
{
BMLogManager.getDefaultLogger().log(Level.INFO,"user is "+user.toString());
user.login();
return user;
}
catch(Exception e)
{
BMLogManager.getDefaultLogger().log(Level.WARNING,"EXCEPTION IN DIRECTORY"+e.toString(),e);
}
return null;
}
}
and my userbean which talks to a DAO:
Code:
package com.jakestone.bm.datamodel;
import com.jakestone.bm.BMException;
import com.jakestone.bm.ExceptionEncoder;
//import com.jakestone.bm.servlet.Constants;
//import com.jakestone.bm.servlet.XMLWrap;
import com.jakestone.bm.utils.BMLogManager;
import java.sql.Date;
import java.util.logging.Level;
import java.io.Serializable;
/**
* Created by IntelliJ IDEA.
* User: jake
* Date: Jun 26, 2004
* Time: 8:09:42 AM
* To change this template use Options | File Templates.
*/
public class BMUser extends BMAbstractDataObject implements Serializable
{
private String userName;
private String pword;
private long lastLogin;
public long getUid()
{
return uid;
}
public void setUid(long in_id)
{
uid = in_id;
}
public BMException getBMException()
{
return exception;
}
public void setBMException(BMException in_exception)
{
exception = in_exception;
}
public String getUserName()
{
return userName;
}
public String getPword()
{
return pword;
}
public long getLastLogin()
{
return lastLogin;
}
public void setUserName(String in_userName)
{
userName = in_userName;
}
public void setPword(String in_password)
{
pword = in_password;
}
public void setLastLogin(long in_lastLogin)
{
lastLogin = in_lastLogin;
}
public Date showLastLogin()
{
return new Date(lastLogin);
}
protected void doInsert() throws BMDataModelException
{
//BMLogManager.getDefaultLogger().log(Level.FINE, "inserting ");
BMUserMgr.getInstance().doInsert(this);
}
protected void doUpdate() throws BMDataModelException
{
BMUserMgr.getInstance().doUpdate(this);
}
public void doPopulate() throws BMDataModelException
{
BMUserMgr.getInstance().populate(this);
}
public void doDelete() throws BMDataModelException
{
BMUserMgr.getInstance().delete(this);
}
public void populate(String un, String pw) throws BMDataModelException
{
this.userName = un;
this.pword = pw;
BMUserMgr.getInstance().populate(this);
}
protected void validate() throws BMException
{
if (null == pword || null == userName)
{
BMLogManager.getDefaultLogger().log(Level.WARNING, "Username or pword is blank");
BMException exc = new BMException("Username or pword is blank");
exc.setHumanMessage("Username or pword is blank");
throw exc;
}
if (userName.length() > 16)
{
BMLogManager.getDefaultLogger().log(Level.WARNING, "User name longer than 16 characters");
BMException exc = new BMException("User name longer than 16 characters");
exc.setHumanMessage("User name longer than 16 characters");
throw exc;
}
else if (userName.length() > 16)
{
BMLogManager.getDefaultLogger().log(Level.WARNING, "Password longer than 16 characters");
BMException exc = new BMException("Password longer than 16 characters");
exc.setHumanMessage("Password longer than 16 characters");
throw exc;
}
}
public void login()
{
try
{
try
{
BMLogManager.getDefaultLogger().log(Level.FINE, "db is local");
BMUserMgr.getInstance().login(this);
}
catch (Exception e)
{
BMLogManager.getDefaultLogger().log(Level.FINE, e.getMessage());
setBMException(ExceptionEncoder.encodeException(e));
}
}
catch (Exception e)
{
this.setBMException(ExceptionEncoder.encodeException(e));
BMLogManager.getDefaultLogger().log(Level.FINE, "standard exception" + e.getMessage());
}
}
public String toString()
{
return super.toString() + "\r\nuser=" + userName + "\r\nlastlogin=" + lastLogin;
}
}
All of this works up to the point where the BMUser instance is received back at the client in the login_Result method of UserDirectory