jeudi 5 novembre 2009

New in GraniteDS 2.1.0 RC1: new features of the gas3 generator

Typesafe proxies


One of the very nice new features in GraniteDS 2.1 has been contributed by Francesco Faraone and Saverio Trioni.

If you have already used RemoteObject or the Tide Component/Object API to access remote services, you most likely already have noticed that neither of these options are typesafe.
What this means is that you can't have code completion in your Flex IDE, and that you can easily make a mistake in either the remote method name or its arguments.

With GDS 2.1, the gas3 generator is now able to generate typesafe client proxy classes from Java service classes or interfaces. While it can work with service implementations, it's much better to generate the client proxies from service interface when possible. Let's see how this works with the gas3 ant task :

<target name="generate.as3" depends="define.gas3"
description="Generate AS3 beans and proxies for example entities and services">

<gas3 outputdir="flex">
<classpath>
<pathelement location="classes"/>
<path dir="lib"/>
</classpath>
<fileset dir="classes">
<include name="com/myapp/entities/**/*.class"/>
</fileset>
<fileset dir="classes">
<include name="com/myapp/services/**/*Service.class"/>
</fileset>
</gas3>
</target>


As you can see, this is no different from generating as3 entity beans, just include the interface classes in the generator fileset.

It's not the only thing to do, because the generator needs to know that is has to generate a client proxy for our interface and not only an as3 interface. So you have to annotate your service interface with @RemoteDestination(id="myService"). If you use GraniteDS for remoting, that should be generally already the case. Here's an example service interface :

@RemoteDestination(id="personService")
public interface PersonService {

public Person createPerson(Person person);

public Person modifyPerson(Person person);

public void deletePerson(Integer personId);
}


When generating the client for this interface, you will get a PersonService as3 class that extends RemoteObject and can be used exactly as a RemoteObject :

var personService:PersonService = new PersonService();
personService.addOperationListener(personService.modifyPerson, ResultEvent.RESULT, handlerFunction);


This proxy generator can also be used with the Tide remoting API with the option tide="true". You then will be able to use typesafe service proxies either declared manually :

Tide.getInstance().addComponent("personService", PersonService)

PersonService(tideContext.personService).modifyPerson(person, modifyResult)

Or much easier, using implicit declaration and injection :

[In]
public var personService:PersonService;

personService.modifyPerson(person, modifyResult);


Note that since the generator requires the annotation @RemoteDestination to identity service interface, it's better to use it than @TideEnabled if you want to use typesafe proxies, even if it requires an unused id attribute.

The service generation can also be done with the Eclipse builder plugin, in this case just add the service interfaces classes in the 'Java Sources' section of the plugin properties page.




Generation of flex-config.xml



Another very frequent cause of errors with AMF objects serialization/deserialization comes from the Flex compiler not including all classes in the compiled SWF because they are not referenced anywhere in the code.
The fix generally consists in adding dummy variables of the missing type, but this is very tedious and it is very easy to forget one.
It would be a lot easier if the Flex compiler had an option to always include all classes in a source directory (don't hesitate to vote for the following feature request on the Adobe Flex JIRA) but as long as this is not the case, we felt the need to provide something similar ourselves.

So there is a new option in the gas3 Eclipse builder plugin that automatically builds a flex-config.xml in the root folder of the project including all as3 files from the current source path.



Then you just have to add the following compiler option :

-load-config += flex-config.xml

And you can say goodbye to problems with missing classes.


Custom entity factory



If you use the gas3 ant task, you maybe know that it's already possible to define custom templates for all kinds of generated elements and in particular for entity classes with attributes like entitytemplate="blah.gsp" and entitybasetemplate="blahbase.gsp".

However your custom templates are still limited to use what is provided by the gas3 entity reflection factory. For example it's not easily possible to generate custom as3 annotation from existing Java annotations.
To allow this, you can now define a custom implementation of EntityFactory that will build a custom instance of JavaEntityBean where you could parse and store whatever information you need from the Java class.

For example you could build a HVEntityFactory that reads Hibernate Validator 3 annotations to generate custom constraint annotations in the as3 entity class. You could do this with :

<gas3 entityfactory="com.myapp.MyEntityFactory"
entitybasetemplate="file:///C:/myapp/myEntityBase.gsp"/>

3 commentaires:

Saverio a dit…

Thank to Franck to give a code so clean to work on and to accept the contribution.

I'd like to make a little correction in my surname, that is Trioni (with final 'i', not final 'e')

Glad to help.

Saverio Trioni

William Draï a dit…

Really sorry, I changed it the text.

Ryan a dit…

Hey that's a lovely blog. Granite countertops is the for kitchen & bathroom.