Dynamic Content Beans
Introduction
Goal
Use dynamic runtime content bean generation for your document types.
Background
For typical document types created using theDocument Type Editor and image sets configured using theGallery Manager,content bean classes are dynamically generated at runtime. Changes are available immediately, for example in Freemarker templates, without the need for a rebuild & restart cycle in the development environment. This greatly increases development velocity compared to manually developing content beans or generating them using theBeanwriter tool.
Dynamically Generate Content Beans
Dynamic bean generation supports all content types which are document types, compound types, and image set types. All standard fields and compound typed fields available in theDocument Type Editor are supported.
The dynamic bean feature generates the content beans at runtime when needed. With the help of code generation (Byte Buddy), a content bean class is generated that contains getters for all the fields described in the node type definition.Byte Buddyis a code generation and manipulation library for creating and modifying Java classes at runtime.
Since the bean classes are only generated once (or after a change of a document type via the document type editor), there is no impact on performance.
Bean generation logic runs for your content types regardless of content bean classes being present for the content types in your project. If there is no existing content bean Java class related to a document type in the result of automatic scanning for content bean annotated classes, the runtime-generated bean will extend from BaseDocument and thus developers can add some general methods to theirBaseDocument class if they want.
The bean class is generated on the fly by reading definitions in the related JCR nodes. A sample generated class is for the document type myproject:mydocumentype as follows
...public BaseDocument$Mydocumenttype$8btLfpVF extends BaseDocument { public String getStringTypeField() { return (String) super.getProperty("myproject:stringTypeField"); } public Calendar getDateTypeField() { return (Calendar) super.getProperty("myproject:dateTypeField"); } public HippoHtml getRichTextEditorCompoundType() { return super.getHippoHtml("myproject:richTextEditorCompoundType"); } public HippoGalleryImageSet getImagelinkCompoundType() { return (HippoGalleryImageSet) super.getLinkedBean("myproject:imagelinkCompoundType",HippoGalleryImageSet.class); } ... ...}If the project doesn’t have anyBaseDocument class, which means that no class has@Node(jcrType="myproject:basedocument") annotation, the generated bean for the document types extends from theHippoDocument class.
The content beans for compound types are generated by extending from theHippoCompound class.
Enhance Existing Content Bean Classes
If an implementation project contains any custom content bean classes, a new class may be generated, extending from the existing content bean class and adding any getter methods that are missing.
The existing bean class:
@Node(jcrType = "myproject:mydocumentype")public class Mydocumenttype extends BaseDocument {}The dynamically generated bean class:
public Mydocumenttype$Mydocumenttype$8btLfpVF extends Mydocumenttype { public String getMissingfield() { return (String) super.getProperty("myproject:missingfield"); }}A new content bean class is generated for the existing bean class on the fly if the existing class doesnot have the annotation @HippoEssentialsGenerated or if present does not have @HippoEssentialsGenerated(allowModifications=false). One exception is that if the existing bean is up-to-date and has getter methods for all of the fields in the content type, a new bean class is not generated and the existing bean is used.
Mark Existing Bean Classes as Not Modifiable
You can exclude your bean classes from any runtime modification by setting the HippoEssentialsGenerated annotation'sallowModifications parameter tofalse.
@HippoEssentialsGenerated(internalName = "myproject:mydocumentype", allowModifications = false)@Node(jcrType = "myproject:mydocumentype")public class Mydocumenttype extends BaseDocument { ... ...}Support for Custom Bean Class Hierarchies
If the existing bean class of either a document type or a compound type has a parent class of another document type or compound type instead ofBaseDocument, then the dynamic bean generates the new classes with the same class hierarchy of the existing HippoBeans.
In the following example, the generated class of theChilddocument type, myproject:childdocument, is extended from the generated class of theParentdocument type, myproject:parentdocument.
public class BaseDocument$Parentdocument$IB2IXnoT extends BaseDocument { ... ...}public class BaseDocument$Parentdocument$IB2IXnoT$Childdocument$2E9PXydT extendsIB2IXnoT { ... ...}Handling of Custom Image Sets
Custom image sets can be created using the Gallery Manager tool in the Essentials setup application. When the developer defines a custom image set with the choice of updating the current images, then the property with namegallerytype on the /content/gallery node is set to the name of the custom image set, locally.
While generating the beans, the value of thegallerytype property is taken into account and the bean is generated with this image set type.
- Be sure that a changed/content/gallery/hippostd:gallerytype property is propagated to standing environments when deploying.
Disable Dynamic Bean Generation At System Level
Dynamic bean generation is active by default. You can disable dynamic bean generation by setting the system property Dynamic.bean.generation tofalse. To disable dynamic bean generation, pass a parameter to the JVM as follows:
-Ddynamic.bean.generation=false
Use Dynamic Content Beans with the Content REST API
Dynamic bean generation is compatible with theContent REST API.
Custom REST resources are not supported at the moment. If your project contains custom REST resources, it is recommended that youmark the related content bean classes as not modifiable.