001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.activemq.openwire.tool;
018
019import java.io.File;
020import java.io.FileWriter;
021import java.io.PrintWriter;
022import java.util.ArrayList;
023import java.util.Collections;
024import java.util.Comparator;
025import java.util.Iterator;
026import java.util.List;
027
028import org.codehaus.jam.JAnnotation;
029import org.codehaus.jam.JAnnotationValue;
030import org.codehaus.jam.JClass;
031import org.codehaus.jam.JPackage;
032import org.codehaus.jam.JProperty;
033
034/**
035 * 
036 */
037public class JavaMarshallingGenerator extends MultiSourceGenerator {
038
039    protected List<JClass> concreteClasses = new ArrayList<JClass>();
040    protected File factoryFile;
041    protected String factoryFileName = "MarshallerFactory";
042    protected String indent = "    ";
043    protected String targetDir = "src/main/java";
044
045    public Object run() {
046        if (destDir == null) {
047            destDir = new File(targetDir + "/org/apache/activemq/openwire/v" + getOpenwireVersion());
048        }
049        Object answer = super.run();
050        processFactory();
051        return answer;
052    }
053
054    protected void generateFile(PrintWriter out) throws Exception {
055
056        generateLicence(out);
057        out.println("");
058        out.println("package org.apache.activemq.openwire.v" + getOpenwireVersion() + ";");
059        out.println("");
060        out.println("import java.io.DataInput;");
061        out.println("import java.io.DataOutput;");
062        out.println("import java.io.IOException;");
063        out.println("");
064        out.println("import org.apache.activemq.openwire.*;");
065        out.println("import org.apache.activemq.command.*;");
066        out.println("");
067        out.println("");
068        for (int i = 0; i < getJclass().getImportedPackages().length; i++) {
069            JPackage pkg = getJclass().getImportedPackages()[i];
070            for (int j = 0; j < pkg.getClasses().length; j++) {
071                JClass clazz = pkg.getClasses()[j];
072                out.println("import " + clazz.getQualifiedName() + ";");
073            }
074        }
075
076        out.println("");
077        out.println("/**");
078        out.println(" * Marshalling code for Open Wire Format for " + getClassName() + "");
079        out.println(" *");
080        out.println(" *");
081        out.println(" * NOTE!: This file is auto generated - do not modify!");
082        out.println(" *        if you need to make a change, please see the modify the groovy scripts in the");
083        out.println(" *        under src/gram/script and then use maven openwire:generate to regenerate ");
084        out.println(" *        this file.");
085        out.println(" *");
086        out.println(" * ");
087        out.println(" */");
088        out.println("public " + getAbstractClassText() + "class " + getClassName() + " extends " + getBaseClass() + " {");
089        out.println("");
090
091        if (!isAbstractClass()) {
092
093            out.println("    /**");
094            out.println("     * Return the type of Data Structure we marshal");
095            out.println("     * @return short representation of the type data structure");
096            out.println("     */");
097            out.println("    public byte getDataStructureType() {");
098            out.println("        return " + getJclass().getSimpleName() + ".DATA_STRUCTURE_TYPE;");
099            out.println("    }");
100            out.println("    ");
101            out.println("    /**");
102            out.println("     * @return a new object instance");
103            out.println("     */");
104            out.println("    public DataStructure createObject() {");
105            out.println("        return new " + getJclass().getSimpleName() + "();");
106            out.println("    }");
107            out.println("");
108        }
109
110        out.println("    /**");
111        out.println("     * Un-marshal an object instance from the data input stream");
112        out.println("     *");
113        out.println("     * @param o the object to un-marshal");
114        out.println("     * @param dataIn the data input stream to build the object from");
115        out.println("     * @throws IOException");
116        out.println("     */");
117        out.println("    public void tightUnmarshal(OpenWireFormat wireFormat, Object o, DataInput dataIn, BooleanStream bs) throws IOException {");
118        out.println("        super.tightUnmarshal(wireFormat, o, dataIn, bs);");
119
120        if (!getProperties().isEmpty()) {
121            out.println("");
122            out.println("        " + getJclass().getSimpleName() + " info = (" + getJclass().getSimpleName() + ")o;");
123        }
124
125        if (isMarshallerAware()) {
126            out.println("");
127            out.println("        info.beforeUnmarshall(wireFormat);");
128            out.println("        ");
129        }
130
131        generateTightUnmarshalBody(out);
132
133        if (isMarshallerAware()) {
134            out.println("");
135            out.println("        info.afterUnmarshall(wireFormat);");
136        }
137
138        out.println("");
139        out.println("    }");
140        out.println("");
141        out.println("");
142        out.println("    /**");
143        out.println("     * Write the booleans that this object uses to a BooleanStream");
144        out.println("     */");
145        out.println("    public int tightMarshal1(OpenWireFormat wireFormat, Object o, BooleanStream bs) throws IOException {");
146
147        if (!getProperties().isEmpty()) {
148            out.println("");
149            out.println("        " + getJclass().getSimpleName() + " info = (" + getJclass().getSimpleName() + ")o;");
150        }
151
152        if (isMarshallerAware()) {
153            out.println("");
154            out.println("        info.beforeMarshall(wireFormat);");
155        }
156
157        out.println("");
158        out.println("        int rc = super.tightMarshal1(wireFormat, o, bs);");
159        int baseSize = generateTightMarshal1Body(out);
160
161        out.println("");
162        out.println("        return rc + " + baseSize + ";");
163        out.println("    }");
164        out.println("");
165        out.println("    /**");
166        out.println("     * Write a object instance to data output stream");
167        out.println("     *");
168        out.println("     * @param o the instance to be marshaled");
169        out.println("     * @param dataOut the output stream");
170        out.println("     * @throws IOException thrown if an error occurs");
171        out.println("     */");
172        out.println("    public void tightMarshal2(OpenWireFormat wireFormat, Object o, DataOutput dataOut, BooleanStream bs) throws IOException {");
173        out.println("        super.tightMarshal2(wireFormat, o, dataOut, bs);");
174        if (!getProperties().isEmpty()) {
175            out.println("");
176            out.println("        " + getJclass().getSimpleName() + " info = (" + getJclass().getSimpleName() + ")o;");
177        }
178
179        generateTightMarshal2Body(out);
180
181        if (isMarshallerAware()) {
182            out.println("");
183            out.println("        info.afterMarshall(wireFormat);");
184        }
185
186        out.println("");
187        out.println("    }");
188        out.println("");
189        out.println("    /**");
190        out.println("     * Un-marshal an object instance from the data input stream");
191        out.println("     *");
192        out.println("     * @param o the object to un-marshal");
193        out.println("     * @param dataIn the data input stream to build the object from");
194        out.println("     * @throws IOException");
195        out.println("     */");
196        out.println("    public void looseUnmarshal(OpenWireFormat wireFormat, Object o, DataInput dataIn) throws IOException {");
197        out.println("        super.looseUnmarshal(wireFormat, o, dataIn);");
198
199        if (!getProperties().isEmpty()) {
200            out.println("");
201            out.println("        " + getJclass().getSimpleName() + " info = (" + getJclass().getSimpleName() + ")o;");
202        }
203
204        if (isMarshallerAware()) {
205            out.println("");
206            out.println("        info.beforeUnmarshall(wireFormat);");
207            out.println("        ");
208        }
209
210        generateLooseUnmarshalBody(out);
211
212        if (isMarshallerAware()) {
213            out.println("");
214            out.println("        info.afterUnmarshall(wireFormat);");
215        }
216
217        out.println("");
218        out.println("    }");
219        out.println("");
220        out.println("");
221        out.println("    /**");
222        out.println("     * Write the booleans that this object uses to a BooleanStream");
223        out.println("     */");
224        out.println("    public void looseMarshal(OpenWireFormat wireFormat, Object o, DataOutput dataOut) throws IOException {");
225
226        if (!getProperties().isEmpty()) {
227            out.println("");
228            out.println("        " + getJclass().getSimpleName() + " info = (" + getJclass().getSimpleName() + ")o;");
229        }
230
231        if (isMarshallerAware()) {
232            out.println("");
233            out.println("        info.beforeMarshall(wireFormat);");
234        }
235
236        out.println("");
237        out.println("        super.looseMarshal(wireFormat, o, dataOut);");
238
239        generateLooseMarshalBody(out);
240
241        out.println("");
242        out.println("    }");
243        out.println("}");
244    }
245
246    private void generateLicence(PrintWriter out) {
247        out.println("/**");
248        out.println(" *");
249        out.println(" * Licensed to the Apache Software Foundation (ASF) under one or more");
250        out.println(" * contributor license agreements.  See the NOTICE file distributed with");
251        out.println(" * this work for additional information regarding copyright ownership.");
252        out.println(" * The ASF licenses this file to You under the Apache License, Version 2.0");
253        out.println(" * (the \"License\"); you may not use this file except in compliance with");
254        out.println(" * the License.  You may obtain a copy of the License at");
255        out.println(" *");
256        out.println(" * http://www.apache.org/licenses/LICENSE-2.0");
257        out.println(" *");
258        out.println(" * Unless required by applicable law or agreed to in writing, software");
259        out.println(" * distributed under the License is distributed on an \"AS IS\" BASIS,");
260        out.println(" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.");
261        out.println(" * See the License for the specific language governing permissions and");
262        out.println(" * limitations under the License.");
263        out.println(" */");
264    }
265
266    protected void processFactory() {
267        if (factoryFile == null) {
268            factoryFile = new File(destDir, factoryFileName + filePostFix);
269        }
270        PrintWriter out = null;
271        try {
272            out = new PrintWriter(new FileWriter(factoryFile));
273            generateFactory(out);
274        } catch (Exception e) {
275            throw new RuntimeException(e);
276        } finally {
277            if (out != null) {
278                out.close();
279            }
280        }
281    }
282
283    protected void generateFactory(PrintWriter out) {
284        generateLicence(out);
285        out.println("");
286        out.println("package org.apache.activemq.openwire.v" + getOpenwireVersion() + ";");
287        out.println("");
288        out.println("import org.apache.activemq.openwire.DataStreamMarshaller;");
289        out.println("import org.apache.activemq.openwire.OpenWireFormat;");
290        out.println("");
291        out.println("/**");
292        out.println(" * MarshallerFactory for Open Wire Format.");
293        out.println(" *");
294        out.println(" *");
295        out.println(" * NOTE!: This file is auto generated - do not modify!");
296        out.println(" *        if you need to make a change, please see the modify the groovy scripts in the");
297        out.println(" *        under src/gram/script and then use maven openwire:generate to regenerate ");
298        out.println(" *        this file.");
299        out.println(" *");
300        out.println(" * ");
301        out.println(" */");
302        out.println("public class MarshallerFactory {");
303        out.println("");
304        out.println("    /**");
305        out.println("     * Creates a Map of command type -> Marshallers");
306        out.println("     */");
307        out.println("    static final private DataStreamMarshaller marshaller[] = new DataStreamMarshaller[256];");
308        out.println("    static {");
309        out.println("");
310
311        List<JClass> list = new ArrayList<JClass>(getConcreteClasses());
312        Collections.sort(list, new Comparator<JClass>() {
313            public int compare(JClass c1, JClass c2) {
314                return c1.getSimpleName().compareTo(c2.getSimpleName());
315            }
316        });
317
318        for (Iterator<JClass> iter = list.iterator(); iter.hasNext();) {
319            JClass jclass = iter.next();
320            out.println("        add(new " + jclass.getSimpleName() + "Marshaller());");
321        }
322
323        out.println("");
324        out.println("    }");
325        out.println("");
326        out.println("    static private void add(DataStreamMarshaller dsm) {");
327        out.println("        marshaller[dsm.getDataStructureType()] = dsm;");
328        out.println("    }");
329        out.println("    ");
330        out.println("    static public DataStreamMarshaller[] createMarshallerMap(OpenWireFormat wireFormat) {");
331        out.println("        return marshaller;");
332        out.println("    }");
333        out.println("}");
334    }
335
336    protected void processClass(JClass jclass) {
337        super.processClass(jclass);
338
339        if (!jclass.isAbstract()) {
340            concreteClasses.add(jclass);
341        }
342    }
343
344    protected String getClassName(JClass jclass) {
345        return super.getClassName(jclass) + "Marshaller";
346    }
347
348    protected String getBaseClassName(JClass jclass) {
349        String answer = "BaseDataStreamMarshaller";
350        JClass superclass = jclass.getSuperclass();
351        if (superclass != null) {
352            String superName = superclass.getSimpleName();
353            if (!superName.equals("Object") && !superName.equals("JNDIBaseStorable") && !superName.equals("DataStructureSupport")) {
354                answer = superName + "Marshaller";
355            }
356        }
357        return answer;
358    }
359
360    protected void initialiseManuallyMaintainedClasses() {
361    }
362
363    protected void generateTightUnmarshalBody(PrintWriter out) {
364        List properties = getProperties();
365        for (Iterator iter = properties.iterator(); iter.hasNext();) {
366            JProperty property = (JProperty)iter.next();
367            JAnnotation annotation = property.getAnnotation("openwire:property");
368            JAnnotationValue size = annotation.getValue("size");
369            JClass propertyType = property.getType();
370            String propertyTypeName = propertyType.getSimpleName();
371
372            if (propertyType.isArrayType() && !propertyTypeName.equals("byte[]")) {
373                generateTightUnmarshalBodyForArrayProperty(out, property, size);
374            } else {
375                generateTightUnmarshalBodyForProperty(out, property, size);
376            }
377        }
378    }
379
380    protected void generateTightUnmarshalBodyForProperty(PrintWriter out, JProperty property, JAnnotationValue size) {
381        String setter = property.getSetter().getSimpleName();
382        String type = property.getType().getSimpleName();
383
384        if (type.equals("boolean")) {
385            out.println("        info." + setter + "(bs.readBoolean());");
386        } else if (type.equals("byte")) {
387            out.println("        info." + setter + "(dataIn.readByte());");
388        } else if (type.equals("char")) {
389            out.println("        info." + setter + "(dataIn.readChar());");
390        } else if (type.equals("short")) {
391            out.println("        info." + setter + "(dataIn.readShort());");
392        } else if (type.equals("int")) {
393            out.println("        info." + setter + "(dataIn.readInt());");
394        } else if (type.equals("long")) {
395            out.println("        info." + setter + "(tightUnmarshalLong(wireFormat, dataIn, bs));");
396        } else if (type.equals("String")) {
397            out.println("        info." + setter + "(tightUnmarshalString(dataIn, bs));");
398        } else if (type.equals("byte[]")) {
399            if (size != null) {
400                out.println("        info." + setter + "(tightUnmarshalConstByteArray(dataIn, bs, " + size.asInt() + "));");
401            } else {
402                out.println("        info." + setter + "(tightUnmarshalByteArray(dataIn, bs));");
403            }
404        } else if (type.equals("ByteSequence")) {
405            out.println("        info." + setter + "(tightUnmarshalByteSequence(dataIn, bs));");
406        } else if (isThrowable(property.getType())) {
407            out.println("        info." + setter + "((" + property.getType().getQualifiedName() + ") tightUnmarsalThrowable(wireFormat, dataIn, bs));");
408        } else if (isCachedProperty(property)) {
409            out.println("        info." + setter + "((" + property.getType().getQualifiedName() + ") tightUnmarsalCachedObject(wireFormat, dataIn, bs));");
410        } else {
411            out.println("        info." + setter + "((" + property.getType().getQualifiedName() + ") tightUnmarsalNestedObject(wireFormat, dataIn, bs));");
412        }
413    }
414
415    protected void generateTightUnmarshalBodyForArrayProperty(PrintWriter out, JProperty property, JAnnotationValue size) {
416        JClass propertyType = property.getType();
417        String arrayType = propertyType.getArrayComponentType().getQualifiedName();
418        String setter = property.getSetter().getSimpleName();
419        out.println();
420        if (size != null) {
421            out.println("        {");
422            out.println("            " + arrayType + " value[] = new " + arrayType + "[" + size.asInt() + "];");
423            out.println("            " + "for( int i=0; i < " + size.asInt() + "; i++ ) {");
424            out.println("                value[i] = (" + arrayType + ") tightUnmarsalNestedObject(wireFormat,dataIn, bs);");
425            out.println("            }");
426            out.println("            info." + setter + "(value);");
427            out.println("        }");
428        } else {
429            out.println("        if (bs.readBoolean()) {");
430            out.println("            short size = dataIn.readShort();");
431            out.println("            " + arrayType + " value[] = new " + arrayType + "[size];");
432            out.println("            for( int i=0; i < size; i++ ) {");
433            out.println("                value[i] = (" + arrayType + ") tightUnmarsalNestedObject(wireFormat,dataIn, bs);");
434            out.println("            }");
435            out.println("            info." + setter + "(value);");
436            out.println("        }");
437            out.println("        else {");
438            out.println("            info." + setter + "(null);");
439            out.println("        }");
440        }
441    }
442
443    protected int generateTightMarshal1Body(PrintWriter out) {
444        List properties = getProperties();
445        int baseSize = 0;
446        for (Iterator iter = properties.iterator(); iter.hasNext();) {
447            JProperty property = (JProperty)iter.next();
448            JAnnotation annotation = property.getAnnotation("openwire:property");
449            JAnnotationValue size = annotation.getValue("size");
450            JClass propertyType = property.getType();
451            String type = propertyType.getSimpleName();
452            String getter = "info." + property.getGetter().getSimpleName() + "()";
453
454            if (type.equals("boolean")) {
455                out.println("        bs.writeBoolean(" + getter + ");");
456            } else if (type.equals("byte")) {
457                baseSize += 1;
458            } else if (type.equals("char")) {
459                baseSize += 2;
460            } else if (type.equals("short")) {
461                baseSize += 2;
462            } else if (type.equals("int")) {
463                baseSize += 4;
464            } else if (type.equals("long")) {
465                out.println("        rc+=tightMarshalLong1(wireFormat, " + getter + ", bs);");
466            } else if (type.equals("String")) {
467                out.println("        rc += tightMarshalString1(" + getter + ", bs);");
468            } else if (type.equals("byte[]")) {
469                if (size == null) {
470                    out.println("        rc += tightMarshalByteArray1(" + getter + ", bs);");
471                } else {
472                    out.println("        rc += tightMarshalConstByteArray1(" + getter + ", bs, " + size.asInt() + ");");
473                }
474            } else if (type.equals("ByteSequence")) {
475                out.println("        rc += tightMarshalByteSequence1(" + getter + ", bs);");
476            } else if (propertyType.isArrayType()) {
477                if (size != null) {
478                    out.println("        rc += tightMarshalObjectArrayConstSize1(wireFormat, " + getter + ", bs, " + size.asInt() + ");");
479                } else {
480                    out.println("        rc += tightMarshalObjectArray1(wireFormat, " + getter + ", bs);");
481                }
482            } else if (isThrowable(propertyType)) {
483                out.println("        rc += tightMarshalThrowable1(wireFormat, " + getter + ", bs);");
484            } else {
485                if (isCachedProperty(property)) {
486                    out.println("        rc += tightMarshalCachedObject1(wireFormat, (DataStructure)" + getter + ", bs);");
487                } else {
488                    out.println("        rc += tightMarshalNestedObject1(wireFormat, (DataStructure)" + getter + ", bs);");
489                }
490            }
491        }
492        return baseSize;
493    }
494
495    protected void generateTightMarshal2Body(PrintWriter out) {
496        List properties = getProperties();
497        for (Iterator iter = properties.iterator(); iter.hasNext();) {
498            JProperty property = (JProperty)iter.next();
499            JAnnotation annotation = property.getAnnotation("openwire:property");
500            JAnnotationValue size = annotation.getValue("size");
501            JClass propertyType = property.getType();
502            String type = propertyType.getSimpleName();
503            String getter = "info." + property.getGetter().getSimpleName() + "()";
504
505            if (type.equals("boolean")) {
506                out.println("        bs.readBoolean();");
507            } else if (type.equals("byte")) {
508                out.println("        dataOut.writeByte(" + getter + ");");
509            } else if (type.equals("char")) {
510                out.println("        dataOut.writeChar(" + getter + ");");
511            } else if (type.equals("short")) {
512                out.println("        dataOut.writeShort(" + getter + ");");
513            } else if (type.equals("int")) {
514                out.println("        dataOut.writeInt(" + getter + ");");
515            } else if (type.equals("long")) {
516                out.println("        tightMarshalLong2(wireFormat, " + getter + ", dataOut, bs);");
517            } else if (type.equals("String")) {
518                out.println("        tightMarshalString2(" + getter + ", dataOut, bs);");
519            } else if (type.equals("byte[]")) {
520                if (size != null) {
521                    out.println("        tightMarshalConstByteArray2(" + getter + ", dataOut, bs, " + size.asInt() + ");");
522                } else {
523                    out.println("        tightMarshalByteArray2(" + getter + ", dataOut, bs);");
524                }
525            } else if (type.equals("ByteSequence")) {
526                out.println("        tightMarshalByteSequence2(" + getter + ", dataOut, bs);");
527            } else if (propertyType.isArrayType()) {
528                if (size != null) {
529                    out.println("        tightMarshalObjectArrayConstSize2(wireFormat, " + getter + ", dataOut, bs, " + size.asInt() + ");");
530                } else {
531                    out.println("        tightMarshalObjectArray2(wireFormat, " + getter + ", dataOut, bs);");
532                }
533            } else if (isThrowable(propertyType)) {
534                out.println("        tightMarshalThrowable2(wireFormat, " + getter + ", dataOut, bs);");
535            } else {
536                if (isCachedProperty(property)) {
537                    out.println("        tightMarshalCachedObject2(wireFormat, (DataStructure)" + getter + ", dataOut, bs);");
538                } else {
539                    out.println("        tightMarshalNestedObject2(wireFormat, (DataStructure)" + getter + ", dataOut, bs);");
540                }
541            }
542        }
543    }
544
545    protected void generateLooseMarshalBody(PrintWriter out) {
546        List properties = getProperties();
547        for (Iterator iter = properties.iterator(); iter.hasNext();) {
548            JProperty property = (JProperty)iter.next();
549            JAnnotation annotation = property.getAnnotation("openwire:property");
550            JAnnotationValue size = annotation.getValue("size");
551            JClass propertyType = property.getType();
552            String type = propertyType.getSimpleName();
553            String getter = "info." + property.getGetter().getSimpleName() + "()";
554
555            if (type.equals("boolean")) {
556                out.println("        dataOut.writeBoolean(" + getter + ");");
557            } else if (type.equals("byte")) {
558                out.println("        dataOut.writeByte(" + getter + ");");
559            } else if (type.equals("char")) {
560                out.println("        dataOut.writeChar(" + getter + ");");
561            } else if (type.equals("short")) {
562                out.println("        dataOut.writeShort(" + getter + ");");
563            } else if (type.equals("int")) {
564                out.println("        dataOut.writeInt(" + getter + ");");
565            } else if (type.equals("long")) {
566                out.println("        looseMarshalLong(wireFormat, " + getter + ", dataOut);");
567            } else if (type.equals("String")) {
568                out.println("        looseMarshalString(" + getter + ", dataOut);");
569            } else if (type.equals("byte[]")) {
570                if (size != null) {
571                    out.println("        looseMarshalConstByteArray(wireFormat, " + getter + ", dataOut, " + size.asInt() + ");");
572                } else {
573                    out.println("        looseMarshalByteArray(wireFormat, " + getter + ", dataOut);");
574                }
575            } else if (type.equals("ByteSequence")) {
576                out.println("        looseMarshalByteSequence(wireFormat, " + getter + ", dataOut);");
577            } else if (propertyType.isArrayType()) {
578                if (size != null) {
579                    out.println("        looseMarshalObjectArrayConstSize(wireFormat, " + getter + ", dataOut, " + size.asInt() + ");");
580                } else {
581                    out.println("        looseMarshalObjectArray(wireFormat, " + getter + ", dataOut);");
582                }
583            } else if (isThrowable(propertyType)) {
584                out.println("        looseMarshalThrowable(wireFormat, " + getter + ", dataOut);");
585            } else {
586                if (isCachedProperty(property)) {
587                    out.println("        looseMarshalCachedObject(wireFormat, (DataStructure)" + getter + ", dataOut);");
588                } else {
589                    out.println("        looseMarshalNestedObject(wireFormat, (DataStructure)" + getter + ", dataOut);");
590                }
591            }
592        }
593    }
594
595    protected void generateLooseUnmarshalBody(PrintWriter out) {
596        List properties = getProperties();
597        for (Iterator iter = properties.iterator(); iter.hasNext();) {
598            JProperty property = (JProperty)iter.next();
599            JAnnotation annotation = property.getAnnotation("openwire:property");
600            JAnnotationValue size = annotation.getValue("size");
601            JClass propertyType = property.getType();
602            String propertyTypeName = propertyType.getSimpleName();
603
604            if (propertyType.isArrayType() && !propertyTypeName.equals("byte[]")) {
605                generateLooseUnmarshalBodyForArrayProperty(out, property, size);
606            } else {
607                generateLooseUnmarshalBodyForProperty(out, property, size);
608            }
609        }
610    }
611
612    protected void generateLooseUnmarshalBodyForProperty(PrintWriter out, JProperty property, JAnnotationValue size) {
613        String setter = property.getSetter().getSimpleName();
614        String type = property.getType().getSimpleName();
615
616        if (type.equals("boolean")) {
617            out.println("        info." + setter + "(dataIn.readBoolean());");
618        } else if (type.equals("byte")) {
619            out.println("        info." + setter + "(dataIn.readByte());");
620        } else if (type.equals("char")) {
621            out.println("        info." + setter + "(dataIn.readChar());");
622        } else if (type.equals("short")) {
623            out.println("        info." + setter + "(dataIn.readShort());");
624        } else if (type.equals("int")) {
625            out.println("        info." + setter + "(dataIn.readInt());");
626        } else if (type.equals("long")) {
627            out.println("        info." + setter + "(looseUnmarshalLong(wireFormat, dataIn));");
628        } else if (type.equals("String")) {
629            out.println("        info." + setter + "(looseUnmarshalString(dataIn));");
630        } else if (type.equals("byte[]")) {
631            if (size != null) {
632                out.println("        info." + setter + "(looseUnmarshalConstByteArray(dataIn, " + size.asInt() + "));");
633            } else {
634                out.println("        info." + setter + "(looseUnmarshalByteArray(dataIn));");
635            }
636        } else if (type.equals("ByteSequence")) {
637            out.println("        info." + setter + "(looseUnmarshalByteSequence(dataIn));");
638        } else if (isThrowable(property.getType())) {
639            out.println("        info." + setter + "((" + property.getType().getQualifiedName() + ") looseUnmarsalThrowable(wireFormat, dataIn));");
640        } else if (isCachedProperty(property)) {
641            out.println("        info." + setter + "((" + property.getType().getQualifiedName() + ") looseUnmarsalCachedObject(wireFormat, dataIn));");
642        } else {
643            out.println("        info." + setter + "((" + property.getType().getQualifiedName() + ") looseUnmarsalNestedObject(wireFormat, dataIn));");
644        }
645    }
646
647    protected void generateLooseUnmarshalBodyForArrayProperty(PrintWriter out, JProperty property, JAnnotationValue size) {
648        JClass propertyType = property.getType();
649        String arrayType = propertyType.getArrayComponentType().getQualifiedName();
650        String setter = property.getSetter().getSimpleName();
651        out.println();
652        if (size != null) {
653            out.println("        {");
654            out.println("            " + arrayType + " value[] = new " + arrayType + "[" + size.asInt() + "];");
655            out.println("            " + "for( int i=0; i < " + size.asInt() + "; i++ ) {");
656            out.println("                value[i] = (" + arrayType + ") looseUnmarsalNestedObject(wireFormat,dataIn);");
657            out.println("            }");
658            out.println("            info." + setter + "(value);");
659            out.println("        }");
660        } else {
661            out.println("        if (dataIn.readBoolean()) {");
662            out.println("            short size = dataIn.readShort();");
663            out.println("            " + arrayType + " value[] = new " + arrayType + "[size];");
664            out.println("            for( int i=0; i < size; i++ ) {");
665            out.println("                value[i] = (" + arrayType + ") looseUnmarsalNestedObject(wireFormat,dataIn);");
666            out.println("            }");
667            out.println("            info." + setter + "(value);");
668            out.println("        }");
669            out.println("        else {");
670            out.println("            info." + setter + "(null);");
671            out.println("        }");
672        }
673    }
674
675    /**
676     * Returns whether or not the given annotation has a mandatory flag on it or
677     * not
678     */
679    protected String getMandatoryFlag(JAnnotation annotation) {
680        JAnnotationValue value = annotation.getValue("mandatory");
681        if (value != null) {
682            String text = value.asString();
683            if (text != null && text.equalsIgnoreCase("true")) {
684                return "true";
685            }
686        }
687        return "false";
688    }
689
690    public List<JClass> getConcreteClasses() {
691        return concreteClasses;
692    }
693
694    public void setConcreteClasses(List<JClass> concreteClasses) {
695        this.concreteClasses = concreteClasses;
696    }
697
698    public File getFactoryFile() {
699        return factoryFile;
700    }
701
702    public void setFactoryFile(File factoryFile) {
703        this.factoryFile = factoryFile;
704    }
705
706    public String getFactoryFileName() {
707        return factoryFileName;
708    }
709
710    public void setFactoryFileName(String factoryFileName) {
711        this.factoryFileName = factoryFileName;
712    }
713
714    public String getIndent() {
715        return indent;
716    }
717
718    public void setIndent(String indent) {
719        this.indent = indent;
720    }
721
722    public String getTargetDir() {
723        return targetDir;
724    }
725
726    public void setTargetDir(String sourceDir) {
727        this.targetDir = sourceDir;
728    }
729}