Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 7 Next »

On Flex we have several ways to integrate java-server and flex-client. The most used are RemoteObjects and/or Dataservices.

Using this, we have typed communication, but, it mean we must have the same DTO (Data Transfer Object or ValueObject or Pojo or whatever you wanna call it) on both sides. That mean 2 sources files with same data.

Duplicating information is the first step on getting out-to-date information. A good way to avoid this is write one side DTO and generate other. Is exactly that what Granite GAS3 Generator does.

Gas 3 is a AntTask to generate .as files based on Java .class files. In other to get this behavior, flex-mojos uses Gas3's generator. It works on a similar way. But it doesn't run over a java project, it runs on a flex project.

There is a sample here.

The steps to get code generation are simple:

 

 

Add generator mojo goal to your pom:

 

 

  <build>
    <plugins>
      <plugin>
        <groupId>org.sonatype.flexmojos</groupId>
        <artifactId>flexmojos-maven-plugin</artifactId>
        <version>${flexmojos.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>generate</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

 

 

Add a dependencies to your model classes

In order to function, the Generator needs to find your Java classes in the modules dependencies (Not the plugin-dependencies).

<dependencies>
    <dependency>
      <groupId>com.acme.utils</groupId>
      <artifactId>cool-libs</artifactId>
      <version>1.2.3</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

 

I usually set the scope of these artifacts to "provided" and group all of these java-dependencies together at the bottom of the pom with a comment that these artifacts are needed for code generation.

List the classes

You could omit the declaration of the classes, but in this case the generator would generate Model classes for any java class it finds in the projects dependencies. So if you have some default Java imports in your master pom ... be prepared to have ActionScript classes being generated for every class in those packages (smile)

 

  <build>
    <plugins>
      <plugin>
        <groupId>org.sonatype.flexmojos</groupId>
        <artifactId>flexmojos-maven-plugin</artifactId>
        <version>${flexmojos.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>generate</goal>
            </goals>
            <configuration>
              <includeJavaClasses>
                <class>com.acme.utils.coolLibs.A</class>
                <class>com.acme.utils.coolLibs.B</class>
                <class>com.acme.utils.coolLibs.C</class>
                <class>com.acme.utils.coolLibs.D</class>
                <class>com.acme.utils.coolLibs.E</class>
                <class>com.acme.utils.coolLibs.F</class>
              </includeJavaClasses>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

Using custom generation templates

The Granite generator generates classes that can be used with a GraniteDS Server without modification. If howerver you would be intending to use a BlazeDS Server for communication these classes would not be compatable with BlazeDS. In order to be able to generate code that can be used with a BlazeDS Server, you need to provide some custom templates.

The Granite generator which is used per default supports the following types of classes:

  • Enum types (Enum Java types)
  • Entity types (JPA Pojos)
  • Bean types (Non-JPA Pojos)
  • Interfaces (Java Interfaces)
  • Remote types (Java POJO Services)

For "Enum" and "Interface" the generator generates exactly one ActionScript class matching the package and the Classname of the original Java class into the main source directory.

Keep in mind that these classes are updated upon every build. So if you modify them, the next time the generation goal is executed, the changes will be lost. I am probably going to change this as soon as I find the time.

For the other types two classes are generated. One class matching the package and the Classname of the original Java class is generated into the main source directory (usually "src/main/flex") and a second class in the same package but with the name-suffix "Base" is generated to "target/generated-sources/garanite". This Base-class contains all the properties and methods of the original classes and is generated every time the generator is executed. The class in the main source directory extends this Base-class and can be used to customize the class as this file is only generated if if didn't exist and is left unchanged, if a file with that name allready existed.

  <build>
    <plugins>
      <plugin>
        <groupId>org.sonatype.flexmojos</groupId>
        <artifactId>flexmojos-maven-plugin</artifactId>
        <version>${flexmojos.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>generate</goal>
            </goals>
            <configuration>
              <includeJavaClasses>
                <class>com.acme.utils.coolLibs.A</class>
                <class>com.acme.utils.coolLibs.B</class>
                <class>com.acme.utils.coolLibs.C</class>
                <class>com.acme.utils.coolLibs.D</class>
                <class>com.acme.utils.coolLibs.E</class>
                <class>com.acme.utils.coolLibs.F</class>
              </includeJavaClasses>
            </configuration>
            <templates>
              <enum-template>src/main/templates/enum.gsp</enum-template>
              <base-entity-template>src/main/templates/beanBase.gsp</base-entity-template>
              <entity-template>src/main/templates/bean.gsp</entity-template>
              <base-bean-template>src/main/templates/beanBase.gsp</base-bean-template>
              <bean-template>src/main/templates/bean.gsp</bean-template>
              <interface-template>src/main/templates/interface.gsp</interface-template>
              <remote-template>src/main/templates/remote.gsp</remote-template>
              <base-remote-template>src/main/templates/remoteBase.gsp</base-remote-template>
            </templates>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

The above configuration would make Granite use my custom templates instead.

This approach is great as long as you have only a hand full of module artifacts. If however your application consists of many modules containing generated classes you start having to maintain multiple copies of the same templates or you start having relative paths to your templates. Both solutions are not really nice. I therefore introduced a modification in Flexmojos 4.x which allowss to use templates in the classpath (This time it's the plugin dependencies).

  <build>
    <plugins>
      <plugin>
        <groupId>org.sonatype.flexmojos</groupId>
        <artifactId>flexmojos-maven-plugin</artifactId>
        <version>${flexmojos.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>generate</goal>
            </goals>
            <configuration>
              <includeJavaClasses>
                <class>com.acme.utils.coolLibs.A</class>
                <class>com.acme.utils.coolLibs.B</class>
                <class>com.acme.utils.coolLibs.C</class>
                <class>com.acme.utils.coolLibs.D</class>
                <class>com.acme.utils.coolLibs.E</class>
                <class>com.acme.utils.coolLibs.F</class>
              </includeJavaClasses>
            </configuration>
            <templates>
              <enum-template>class:com/acme/utils/templates/enum.gsp</enum-template>
              <base-entity-template>class:com/acme/utils/templates/beanBase.gsp</base-entity-template>
              <entity-template>class:com/acme/utils/templates/bean.gsp</entity-template>
              <base-bean-template>class:com/acme/utils/templates/beanBase.gsp</base-bean-template>
              <bean-template>class:com/acme/utils/templates/bean.gsp</bean-template>
              <interface-template>class:com/acme/utils/templates/interface.gsp</interface-template>
              <remote-template>class:com/acme/utils/templates/remote.gsp</remote-template>
              <base-remote-template>class:com/acme/utils/templates/remoteBase.gsp</base-remote-template>
            </templates>
          </execution>
        </executions>
        <dependencies>
          <dependencies>
            <groupId>com.acme.utils</groupId>
            <artifactId>templates</artifactId>
            <version>1.3.4</version>
          </dependencies>
        </dependencies>
      </plugin>
    </plugins>
  </build>

This allows you to define the templates in one central artifact and to use these templates throughout your application without having to worry about keeping all templates in sync.

This approach does have one minor drawback though. You have to make sure the artifact is deployed to your local repo before you start the big build. This is due to the fact that Maven varifies the availability of all plugin dependencies before executing the build. This would fail if the templates module has not yet been deployed. For this I usually have a "minimal" profile in my projects, which only builds and deploys artifacts like this. After executing one minimal build I won't have to do this again.

Known Issues

type key summary
Loading...
Refresh

  • No labels