loading table of contents...

4.1.1. Generate Content Beans from the Content Type model

The Content Application Engine comes with a source code generator that reads your content type definition file and generates beans for each content type. The bean interfaces mirror the content properties, and the class hierarchy mirrors the content type hierarchy. After generating the code, you can modify and adapt it to your application’s needs.

Since you need the code generator only once (or even not at all, if you start over with CoreMedia Blueprint), there is no need for a dedicated application. Just add a temporary dependency

  <dependency>
    <groupId>com.coremedia.cms</groupId>
    <artifactId>bean-generator</artifactId>
    <scope>runtime</scope>
  </dependency>

to the POM file of your CoreMedia CAE module and build it. Then the code generator can be invoked as follows from within the WEB-INF directory of the CoreMedia CAE :

java -jar lib/bean-generator-<version>.jar

This gives you all available options of the generator as shown in Table 4.1, “Parameters of the Beangenerator”. You need to pass the location of your content type definition file(s), a package for the generated classes and a target directory for the source code. By default, the generator creates code with generics for link lists as comments in order to be compatible with legacy Java versions. When you have successfully created your content beans, you should delete the temporary dependency on bean-generator again so that your actual web application does not get unnecessarily bloated.

The meaning of the parameters of the Beangenerator is described in the next table.

Parameter Variable Description
-d --document-types Name of the document types file to use The URL of the document types file to use. You need at least one file.
-baseonly   Create only the base classes, but no implementations and no interfaces.
-beanmapping Name of a file The file into which the bean mapping will be written (see Section 4.1.1.2, “Spring Configuration”).
-c Name of a properties file that contains the package information.

Define specific packages for specific document types in order to organize your bean files properly. There a three possible configuration types:

One package for all files of a document type

Example:

doctype.Image.package= com.mycompany.image

doctype.Article.package= com.mycompany.article

Different packages for the different files of a document type

Example:

doctype.Article.package.base= com.mycompany.base

doctype.Article.package.implementation= com.mycompany.impl

doctype.Article.package.interface= com.mycompany

Settings for all document types

Example:

package=com.mycompany

package.base=com.mycompany.base

package.implementation= com.mycompony.impl

package.interface=com.mycompany

-document Document type Generate the code for the defined content type. It must be included in one of the document type files defined with the -d parameter.
-e, --exclude Comma separated list of document types Exclude these types from generation process.
-enc, --encoding One of the defined Java encodings Encode the output files with the defined encoding (default is Cp1252)
-f   Overwrite existing files
-generics   Use Java 1.5 Generics.
-gensetter   Deprecated parameter. Generates code with public setter methods.
-avoidlist   Generate methods with simple (non-list) parameters and return values for linklist types that have a maximum cardinality of '1'.
-i, --include Comma separated list of document types Document types that should be included in the generation process (default is all)
-noimpl   Only create base classes and interfaces but no implementations
-o, -out Directory name The directory where to generate the source code into. If it does not exist, it will be created.
-p, --package Package name The package name used for the generated beans. A setting defined with -c overwrites the package defined with -p. To avoid confusion only use -p or -c.

Table 4.1. Parameters of the Beangenerator


Example

If you use the following call from the lib directory of your content application web application,

java -jar beangenerator.jar
-d /contentserver/config/contentserver/doctypes/menu-doctypes.xml
-o /output/classes
-c /properties/package.properties
-beanmapping /properties/contentbeans.xml
-e Picture
-generics

with the following package.properties file,

doctype.Dish.package=com.menusite.dish
package=com.menusite

this will generate interfaces, base classes and implementation classes for all document types of the menu site example except for the Picture document type. The document types are read from the /contentserver/config/contentserver/doctypes/menu-doctypes.xml file and the generated classes are written to the /output/classes directory.

The Dish document type belongs to the com.menusite.dish package while the other types are in the com.menusite package, this information is taken from the /properties/package.properties file. The bean mapping is written to the /properties/contentbeans.xml file. Generics are used which results in code like the following:

public List<? extends Dish> getContent() {
    List/*<Content>*/ contents = getContent().getLinks("content");
    return (List<? extends Dish>) createBeansFor(contents);
}
Structure of the Generated Code

When you inspect the generated classes, you will find that three files per document type are generated:

  • An interface with the same name as the document type

  • An abstract class ending with “Base” and

  • A concrete class ending with “Impl"

The interface is what you should use in other classes, “*Base” contains the repository access code and “*Impl” is the actual class that is instantiated. This class is the place for you to modify. When a document type inherits from another type, its "*Base" class inherits the "*Impl" class of its parent. This way, it inherits the custom extensions made for the supertype. For content types that do not have a parent, the "*Base" class inherits from a framework class AbstractContentBean that defines the underlying content bean, factory, equality and hash code as well as a few convenience methods.

[Note]Note

The generated code may not compile under some circumstances, due to naming conflicts, for example. A content property named ‘content’ will clash with the method #getContent inherited from ContentBean. In this case you should rename the generated getters in the interface and the *Base class.

The "*Base" class contains property getters for every user-defined property in the corresponding content type. Getters are not generated for metadata such as name or creation date. The property types are mapped to Java as follows:

Property Type Java Type Conversion
IntProperty int Simply the value from the underlying content object
StringProperty String Simply the value from the underlying content object
DateProperty Calendar Simply the value from the underlying content object
XmlProperty (with grammar "coremedia-struct-2008") Struct The parsed Struct value from the underlying content object
XmlProperty Markup The markup is transformed. Every internal xlink to a document or blob is transformed into the corresponding content bean id or blob id.
BlobProperty CapBlobRef This is the result of #getBlobRef of the underlying content object
LinkListProperty List Every content object in the link list is converted to a bean through the content bean factory

Table 4.2. Document property to Java property mappings


You are free to modify the generated code. For example, you can do the following:

  • Add a new method to both the public interface and the "*Impl" class

  • Remove a method from the public interface of a bean. It will still be available for the implementation classes but not for clients.

  • Combine both to implement a derived property based on the now hidden content property, possibly with a different result type

  • Implement additional interfaces that may crosscut the document type hierarchy

When extending, you should not declare any fields in a content bean except for read-only, immutable service references.