Freemarker Inheritance / Checking Instances

my use case is to provide the user with the ability to create reports using a templating engine. So I extracted the relevant part of my data model and integrated Freemarker as a templating engine. This worked fine so far, but now my data model contains inheritance in some positions, but Freemarker doesn't seem to support instanceof operations? How to deal with this problem? Are there any other templating mechanisms that support model inheritance?

Dummy example:

I have 2 classes "Car" and "Bicycle" which extends "Car". And the model contains a fleet class that contains a list of vehicles. The user wants (using a template) to iterate over the list and write the "countSeats" attribute in the case of a car, and the "frame size" attribute in the case of a bicycle. How can this be achieved with Freemarker? Can this be done in any template?

Thank you very much in advance!

// Edit: Unfortunately, it is not possible to split a list with superclasses in multiple lists with "specific" objects, since the order of the vehicles (in the example above) is required in the list.

+3


source to share


3 answers


There is nothing for this, but it shouldn't be either. You can write your own, TemplateMethodModelEx

or put simple Java helper objects into the data model to do almost anything. Or you can just put the relevant classes in the data model, for example, root.put("Car", Car.class)

etc., and then use the Java API Class

like this:<#if Car.isInstance(someObject)>



+2


source


More complex solution



            <#if yourObject.class.simpleName == "Simple class name like String">
                something
            </#if>                     

           <#if yourObject.class.simpleName == "the other simple class name">
                do something else
            </#if>  `

      

+2


source


Solution with help TemplateMethodModelEx

.

Class:

public class InstanceOfMethod implements TemplateMethodModelEx {

    @Override
    public Object exec(List list) throws TemplateModelException
    {
        if (list.size() != 2) {
            throw new TemplateModelException("Wrong arguments for method 'instanceOf'. Method has two required parameters: object and class");
        } else {
            Object object = ((WrapperTemplateModel) list.get(0)).getWrappedObject();
            Object p2 = ((WrapperTemplateModel) list.get(1)).getWrappedObject();
            if (!(p2 instanceof Class)) {
                throw new TemplateModelException("Wrong type of the second parameter. It should be Class. Found: " + p2.getClass());
            } else {
                Class c = (Class) p2;
                return c.isAssignableFrom(object.getClass());
            }
        }
    }
}

      

Place an instance of this class and all the required classes in the template input parameters:

parameters.put("instanceOf", new InstanceOfMethod());
parameters.put("Car", Car.class);
...

      

Or, you can add a method to shared variables: http://freemarker.org/docs/pgui_config_sharedvariables.html

Thus, you can use the method in FTL like this:

<#if instanceOf(object, Car)>
       ...
</#if>

      

0


source







All Articles