zkh152 / xdocreport

Automatically exported from code.google.com/p/xdocreport
0 stars 0 forks source link

generation of the fields.xml file is going wrong - Tested only for Velocity #225

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. create 3 classes
 a. public class TemplateDate extends Date{

    /**
     * 
     */
    private static final long serialVersionUID = -1536291628656381845L;

    @MetadataFieldDescription(value="Generation Date in row Format(will be used full format)")
    public Date getRowDate()
    {
        return this;
    }

    @MetadataFieldDescription(value="Document Generation Date In Short format")
    public String getShortFormat()
    {
        return SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT).format(this);
    }
 b. 
@MetadataModelDescription(reportTemplateBaseName="default-template",
        value="Default Tempalte Model.")
public class DefaultTemplateModel{

    protected TemplateDate date;
    protected String customer;

    /**
     * @return the date
     */
    @MetadataFieldDescription(value="Document Generation Date")
    public TemplateDate getDate() {
        return date;
    }
    /**
     * @param date the date to set
     */ 
    public final void setDate(TemplateDate date) {
        this.date = date;
    }
    /**
     * @return the customer
     */
    @MetadataFieldDescription(value="Customer Name")
    public String getCustomer() {
        return customer;
    }
    /**
     * @param customer the customer to set
     */
    public final void setCustomer(String customer) {
        this.customer = customer;
    }

}

c.
@MetadataModelDescription(reportTemplateBaseName="extended-template",
        value="Extended Tempalte Model.")
public class ExtendedProofDodTemplateModel extends DefaultTemplateModel {

}

    P.S. Don't pay atention on annotations. They are used to fill description of the field in my chunk of code(code can be shared, just ask me)

2. public static void generateFieldsXmls(Class<? extends 
DefaultProofDodTemplateModel> clazz)
    {
            FieldsMetadata metadata=new FieldsMetadata(TemplateEngineKind.Velocity.name());
            metadata.load("template", clazz);
            File xmlFieldsFile=new File(clazz.getSimpleName()+".fields.xml");
            metadata.saveXML(new FileOutputStream(xmlFieldsFile),true);         
    }

What is the expected output? What do you see instead?
Is expected to have 2 fields.xml files with fields inside.
the ExtendedTemplateModel.fields.xml contain fields from TemplateDate.
but instead we see no fields(in fact we see only siple fields, it seems that 
complex field date is ignored)

What version of the product are you using? On what operating system?
1.0.0

Original issue reported on code.google.com by ruslancu...@gmail.com on 20 Feb 2013 at 12:10

GoogleCodeExporter commented 9 years ago
After checking sources I made conclusion why it is happen.
The problem is in FieldsMetadataClassSerializerRegistry singleton.
As once it was registered it keep inside the reference to Serizlizer 
instance(Velocity or Freemaker, it doesn't matter). So at first time it works 
well, so Serizlizer register inside it the serialized complex types. When we 
try to serizlyze nex extended class, the Serilizer is loaded from Register 
singleton, but the serilized complex types are not removed from serializer, so 
these complex types are just ignored.

test case:
List<Class<?>> cc=new ArrayList<Class<?>>();
cc.add(DefaultTemplateModel.class);
cc.add(ExtendedProofDodTemplateModel.class);

for(Class<?> clazz:cc)
{
FieldsMetadata metadata=new FieldsMetadata(TemplateEngineKind.Velocity.name());
metadata.load("template", clazz);
File xmlFieldsFile=new File(lazz.getSimpleName()+".fields.xml");
metadata.saveXML(new FileOutputStream(xmlFieldsFile),true);
}

As you see from chunk of code, I will haev 2 different template models, but one 
is extended from another. But due to the implementation problem which I 
described upper, the second class will miss complex types in result xml.

Original comment by ruslancu...@gmail.com on 20 Feb 2013 at 1:14

GoogleCodeExporter commented 9 years ago
a quick solutions to this is:
1. add method reset/clear (or what ever which will reset the state of 
seriazlizer to initial from ) to it's initial state
2. Keep in serialyzer registry singleton not serialyzer objects, but classes, 
and initiate this classs only from FieldsMetadata constructor.

P.S.
Second solutino in my opinion is better

Original comment by ruslancu...@gmail.com on 20 Feb 2013 at 1:23

GoogleCodeExporter commented 9 years ago
Hi,

Is it posisble for you to attach a code with your proble please. It's difficult 
for me to see the problem without debugging. Perhaps you could find the problem 
and attach a patch?

It seems that you have implemented @MetadataFieldDescription which seems that 
you manage fieldsmetadata with annotation. I would like implement too 
http://code.google.com/p/xdocreport/issues/detail?id=180 It should be cool if 
you could share your work.

Thank's!

Regards Angelo

Original comment by angelo.z...@gmail.com on 20 Feb 2013 at 1:26

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I prepared a test case.

P.P.S. Angelo, in the source code is the example with annotations.

Original comment by ruslancu...@gmail.com on 20 Feb 2013 at 1:47

Attachments:

GoogleCodeExporter commented 9 years ago
Find an work around:
FieldsMetadataClassSerializerRegistry.getRegistry().dispose();
FieldsMetadata metadata=new FieldsMetadata(TemplateEngineKind.Velocity.name());

So, it is need to dispose the registry before init new metadata. 
In our case there is nonsense to keep in the registry the instances of the 
Serializers.

P.S.
Don't know in details whole model of the XDocreport, but I'm afraid that this 
bug affect all classes which use the combination Registry - Serializer

Original comment by ruslancu...@gmail.com on 20 Feb 2013 at 2:05

GoogleCodeExporter commented 9 years ago
Here I attach a patch which will add new UnitTest which will test this case.

After checking the source code for I'm afraid that solution of issue 117(cycle 
reference) generated this bug(and I'm afraid other one which use inheritance 
with complex type as field in base class). I have a patch with dirty solution, 
but it will not solve the case when:
FieldsMetadada metadata=new FieldsMetadata("Velocity");
metadata.load("childA",ChildA.class);
metadata.load("childB",ChildB.class);

in this case(get conclusion by examining src, not tested), the childB will miss 
the complexType.

Original comment by ruslancu...@gmail.com on 20 Feb 2013 at 5:04

Attachments:

GoogleCodeExporter commented 9 years ago
Here I attach a patch(which contain the same unit tests for issue 225). As I 
said upper, this bug was generated by solution for issue 117. So in this patch 
was added some improvements to solution 117.
Details:
As hasBeenProcessed variable keep the processed classes first of all it should 
be cleaned after each load. In re recursibe method process was added removing 
current clazz from processed, so the meaning of the variable hasBeenProcessed 
is a little bit changed, not it mean "classes in process", which allow to avoid 
circular processing, and also allow to used complex types in base class in 
inheritance case.
After process method is finished, all "inProcessing" classes are removed, to 
free the algorithm for future processing.

Original comment by ruslancu...@gmail.com on 20 Feb 2013 at 5:40

Attachments:

GoogleCodeExporter commented 9 years ago
Many thank's for your contribution.

We will see your patch asap.

Regards Angelo

Original comment by angelo.z...@gmail.com on 21 Feb 2013 at 8:47

GoogleCodeExporter commented 9 years ago
Integrated in commit 5d6c010cdc47108e9f3aaa3775ea8ce085cf3abd.

Thx for the patch.

Original comment by pascal.leclercq on 21 Feb 2013 at 9:19