JodaDateTime2Date
converter/reverter:
Here is a complete implementation of a Joda DateTime
converter/reverter:
package com.myapp.converters;
import java.lang.reflect.Type;
import java.util.Date;
import org.granite.messaging.amf.io.convert.Converter;
import org.granite.messaging.amf.io.convert.Converters;
import org.granite.messaging.amf.io.convert.Reverter;
import org.granite.util.ClassUtil;
import org.joda.time.DateTime;
public class JodaDateTime2Date extends Converter implements Reverter {
public JodaDateTime2Date(Converters converters) {
super(converters);
}
// AMF3Deserialization (Converter)...
@Override
protected boolean internalCanConvert(Object value, Type targetType) {
Class<?> targetClass = ClassUtil.classOfType(targetType);
return (
targetClass.isAssignableFrom(DateTime.class) &&
(value == null || value instanceof Date)
);
}
@Override
protected Object internalConvert(Object value, Type targetType) {
return (value == null ? null : new DateTime(((Date)value).getTime()));
}
// AMF3Serialization (Reverter)...
public boolean canRevert(Object value) {
return value instanceof DateTime;
}
public Object revert(Object value) {
return ((DateTime)value).toDate();
}
}
The converter should be setup in granite-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE granite-config PUBLIC
"-//Granite Data Services//DTD granite-config internal//EN"
"http://www.graniteds.org/public/dtd/2.3.0/granite-config.dtd">
<granite-config>
<converters>
<converter type="com.myapp.converters.JodaDateTime2Date" />
</converters>
</granite-config>
import org.joda.time.DateTime; private var myDate:DateTime = null;
package com.myapp.converters;
import org.granite.generator.as3.As3Type;
import org.granite.generator.as3.DefaultAs3TypeFactory;
import org.joda.time.DateTime;
public class CustomAs3TypeFactory extends DefaultAs3TypeFactory {
@Override
protected As3Type createAs3Type(Class<?> jType) {
if (DataTime.class.isAssignableFrom(jType))
return As3Type.DATE;
return super.createAs3Type(jType);
}
}
Then, declare this new factory in the Gas3 task (here for example in an Ant build file):
<gas3 as3typefactory="com.myapp.converters.CustomAs3TypeFactory" ...>
...
<classpath>
...
<pathelement location="path/to/my/factory"/>
</classpath>
...
</gas3>
package org.granite.messaging.service.security;
import java.util.Map;
public interface SecurityService {
public void configure(Map<String, String> params);
public void login(Object credentials) throws SecurityServiceException;
public void login(Object credentials, String charset) throws SecurityServiceException;
public Object authorize(AbstractSecurityContext context) throws Exception;
public void logout() throws SecurityServiceException;
public void handleSecurityException(SecurityServiceException e);
}
configure
: This method is called at startup time and gives a chance to pass parameters to the security service.
login
: This method is called when you call one of the setCredentials
or setRemoteCredentials
RemoteObject
's method. Note that these method calls do not fire any request by themselves but only pass credentials on
the next destination service method call. The login
method is responsible for creating and exposing a java.security.Principal
or throwing an appropriate org.granite.messaging.service.security.SecurityServiceException
if credentials are invalid.
Note that credentials are a Base64 string with the common "username:password"
format. An additional login
method with an extra charset
parameter is available, so you can use the RemoteObject.setCredentials(user, pass, charset)
method and specify the charset used in the username/password string (default is ISO-8859-1).
authorize
: This method is called upon each and every service method call invocations (RemoteObject
)
or subscribe/publish actions (Consumer
/Producer
). When used with RemoteObject
s,
the authorize
method is responsible for checking security, calling the service method, and returning the corresponding result.
When used with Consumer
s/Producer
s, it is simply responsible for checking security;
no service method invocation, no result.
If authorization fails, either because the user is not logged in or because it doesn't have required rights, it must throw an appropriate
org.granite.messaging.service.security.SecurityServiceException
.
logout
: This method is called when you call the RemoteObject
's logout
method.
Note that the RemoteObject.logout
method fires a remote request by itself.
handleSecurityException
: This method is called whenever a SecurityServiceException
is thrown by
a login or logout operation. The default implementation of this method in AbstractSecurityService
is to do nothing,
but you may add extra care for these security exceptions if you need so.
<?xml version="1.0" encoding="UTF-8"?>
<services-config>
...
<factories>
<factory id="..." class="...">
<properties>
<service-exception-handler>
path.to.my.CustomServiceExceptionHandler
</service-exception-handler>
...
</properties>
</factory>
</factories>
...
</services-config>
public ServiceException handleNoSuchMethodException(
Message request,
Destination destination,
Object invokee,
String method,
Object[] args,
NoSuchMethodException e
);
public ServiceException handleInvocationException(
ServiceInvocationContext context,
Throwable t
);
<?xml version="1.0" encoding="UTF-8"?>
<granite-config>
...
<amf3-message-interceptor type="com.myapp.MyMessageInterceptor"/>
</granite-config>
amf3MessageInterceptor=com.myapp.MyMessageInterceptor
You may write and plugin your own Java or ActionScript3 descriptors, for example:
public class MyJavaClassDescriptor
extends org.granite.messaging.amf.io.util.JavaClassDescriptor {
public MyJavaClassDescriptor(Class type) {
super(type);
}
@Override
protected List<Property> introspectProperties() {
// put your custom code here...
}
}
public class MyAS3ClassDescriptor
extends org.granite.messaging.amf.io.util.ActionScriptClassDescriptor {
public MyAS3ClassDescriptor(String type, byte encoding) {
super(type, encoding);
}
@Override
public void defineProperty(String name) {
// put your custom code here...
}
@Override
public Object newJavaInstance() {
// put your custom code here...
}
}
Then, you have to declare these descriptors in your granite-config.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE granite-config PUBLIC
"-//Granite Data Services//DTD granite-config internal//EN"
"http://www.graniteds.org/public/dtd/2.3.0/granite-config.dtd">
<granite-config>
<descriptors>
<descriptor
type="path.to.MyClass"
java="path.to.MyJavaClassDescriptor"
as3="path.to.MyAS3ClassDescriptor" />
<descriptor
instance-of="path.to.MyBaseClass"
java="path.to.MyJavaClassDescriptor"
as3="path.to.MyAS3ClassDescriptor" />
<!-- other descriptor configuration... -->
</descriptors>
</granite-config>
public class MyAMF3Serializer implements java.io.ObjectOutput {
public MyAMF3Serializer(java.io.OutputStream out) {
// ...
}
// ObjectOutput implemention...
}
Then, you must register this serializer in granite-config.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE granite-config PUBLIC
"-//Granite Data Services//DTD granite-config internal//EN"
"http://www.graniteds.org/public/dtd/2.3.0/granite-config.dtd">
<granite-config>
<amf3-serializer type="path.to.MyAMF3Serializer"/>
</granite-config>
public class MyAMF3Deserializer implements java.io.ObjectInput {
public MyAMF3Deserializer(java.io.InputStream in) {
// ...
}
// ObjectInput implemention...
}
Then, you have to register this deserializer in granite-config.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE granite-config PUBLIC
"-//Granite Data Services//DTD granite-config internal//EN"
"http://www.graniteds.org/public/dtd/2.3.0/granite-config.dtd">
<granite-config>
<amf3-deserializer type="path.to.MyAMF3Deserializer"/>
</granite-config>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE granite-config PUBLIC
"-//Granite Data Services//DTD granite-config internal//EN"
"http://www.graniteds.org/public/dtd/2.3.0/granite-config.dtd">
<granite-config>
<invocation-listener type="path.to.MyServiceInvocationListener"/>
</granite-config>
public Object[] beforeMethodSearch(Object invokee, String methodName, Object[] args);
public void beforeInvocation(ServiceInvocationContext context);
public void afterInvocationError(ServiceInvocationContext context, Throwable t);
public Object afterInvocation(ServiceInvocationContext context, Object result);