When starting to use Flex together with a server you will probably always have the problem that you have a server-side model and want to use that model in the Flex client. The naive approach would be to manually create ActionScript counterparts for every server class. This approach really sucks ... I think we all agree here. 

Fortunately Flexmojos comes with a set of code generators that can be used to automatically create and maintain an ActionScript version of our server side model (I don't know if this is possible for non Java backends, but for Java it works nicely).

In order to have Flexmojos generate your model classes, you have to configure an execution of the "generate" goal. This will result in the default Generator being used (The default being the GraniteDS 2.3.2 Generator).

If you don't tell Flexmojos which Classes to generate, it will generate all Clases it finds in the modules classpath. This would generate quite a lot of junk. In order to explicitly tell Flexmojos which classes to generate Code for, the "includeJavaClasses" config option is used.

Here comes an example config:

            <plugin>
                <groupId>net.flexmojos.oss</groupId>
                <artifactId>flexmojos-maven-plugin</artifactId>
                <extensions>true</extensions>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <includeJavaClasses>
                                <class>de.cware.cweb.model.User</class>
                                <class>de.cware.cweb.model.Group</class>
                            </includeJavaClasses>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

The above configuration would make Flexmojos generate two classes "User" and "Group". For every class Flexmojos actually generates up to 2 classes. It will generate a class de.cware.cweb.model.User in the "src/main/flex" directory. This is a dummy class that does nothing else than to extend a class named de.cware.cweb.model.UserBase. The de.cware.cweb.model.UserBase class is generated in target/generated-sources/flexmojos and contains the actual "logic".

The reason for this is simple. The base-class is re-generated with every build and represents the properties of the server-side class. If you want to extend this class with custom logic or properties these would be lost when rebuilding. Therefore you add your custom code to the de.cware.cweb.model.User class and have Flexmojos maintain the de.cware.cweb.model.UserBase class for you.

As long as your backend server uses GraniteDS as a AMF layer you're good to go ... if however you are using a different backend, especially the Apache BlazeDS Server, continue with the next chapter.

Generating classes for Apache BlazeDS or other backends

Ok ... now as soon as you have generated your first classes you will notice that the Generator generates code that is highly dependent on a GraniteDS server. These classes will not work if you use a BlazeDS server on your backend.

In order to be able to generate code for BlazeDS (or other backends) you have to override the templates the generator uses.

Here comes the above configuration which uses custom templates:

<plugin>
                <groupId>net.flexmojos.oss</groupId>
                <artifactId>flexmojos-maven-plugin</artifactId>
                <extensions>true</extensions>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <includeJavaClasses>
                                <include>de.cware.cweb.model.User</include>
                                <include>de.cware.cweb.model.Group</include>
                            </includeJavaClasses>
                            <templates>
                                <enum-template>src/main/templates/enum.gsp</enum-template>
                                <interface-template>src/main/templates/interface.gsp</interface-template>
                                <base-entity-template>src/main/templates/entityBase.gsp</base-entity-template>
                                <entity-template>src/main/templates/entity.gsp</entity-template>
                                <base-bean-template>src/main/templates/beanBase.gsp</base-bean-template>
                                <bean-template>src/main/templates/bean.gsp</bean-template>
                                <base-remote-template>src/main/templates/remoteBase.gsp</base-remote-template>
                                <remote-template>src/main/templates/remote.gsp</remote-template>
                            </templates>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

 
...
 
	<dependencies>
	
	...
 
		<!-- for code generation -->
		<dependency>
		    <groupId>de.cware.cweb</groupId>
		    <artifactId>cweb-mod.forum.service</artifactId>
		    <version>1.0.0-SNAPSHOT</version>
		    <type>jar</type>
		    <scope>provided</scope>
		</dependency>


	...
 

I added all of the templates the GraniteDS generator supports.

  • Java Enum classes will be generated by the enum-template (This doesn't have a base-template)
  • Java Interfaces will be generated by the interface-template (This doesn't have a base-template)
  • Classes annotated with the JPA annotation "@Entity" or "@MappedSuperclass" will be generated by entity-template and base-entity-template.
  • Classes annotated with a custom GraniteDS annotation "@RemoteDestination" will be generated by remote-template and base-remote-template.
  • All remaining classes will be generated by bean-template and base-bean-template

Note that the generator requires to have access to the classes it should generate code for. I usually make sure of that by defining a dependency to the java model artifact and set the scope to provided, so it is not added to the output.

In above configuration example the templates are located in a local directory relative to the modules pom in "src/main/templates". This works fine if you have only one model artifact, but it starts becoming annoying as soon as you have several model artifacts. For this it is also possible to reference templates from the classpath. In order to use this option, you need to prefix the path with "class:" and add the artifact containing the templates to the plugin dependencies:

<plugin>
                <groupId>net.flexmojos.oss</groupId>
                <artifactId>flexmojos-maven-plugin</artifactId>
                <extensions>true</extensions>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <includeJavaClasses>
                                <class>de.cware.cweb.model.User</class>
                                <class>de.cware.cweb.model.Group</class>
                            </includeJavaClasses>
                            <templates>
                                <enum-template>class:de/cware/cweb/utils/granite/templates/enum.gsp</enum-template>
                                <interface-template>class:de/cware/cweb/utils/granite/templates/interface.gsp</interface-template>
                                <base-entity-template>class:de/cware/cweb/utils/granite/templates/entitsBase.gsp</base-entity-template>
                                <entity-template>class:de/cware/cweb/utils/granite/templates/entity.gsp</entity-template>
                                <base-bean-template>class:de/cware/cweb/utils/granite/templates/beanBase.gsp</base-bean-template>
                                <bean-template>class:de/cware/cweb/utils/granite/templates/bean.gsp</bean-template>
                                <base-remote-template>class:de/cware/cweb/utils/granite/templates/remoteBase.gsp</base-remote-template>
                                <remote-template>class:de/cware/cweb/utils/granite/templates/remote.gsp</remote-template>
                            </templates>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>de.cware.cweb.utils</groupId>
                        <artifactId>granite-templates</artifactId>
                        <version>1</version>
                    </dependency>
                </dependencies>
            </plugin>

For a more detailed description, have a look at the documentataion of the GraniteDS Generator Ant-Task documentation: http://www.graniteds.org/confluence/display/DOC/3.+Gas3+Code+Generator

  • No labels