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() {
313            public int compare(Object o1, Object o2) {
314                JClass c1 = (JClass)o1;
315                JClass c2 = (JClass)o2;
316                return c1.getSimpleName().compareTo(c2.getSimpleName());
317            }
318        });
319
320        for (Iterator<JClass> iter = list.iterator(); iter.hasNext();) {
321            JClass jclass = iter.next();
322            out.println("        add(new " + jclass.getSimpleName() + "Marshaller());");
323        }
324
325        out.println("");
326        out.println("    }");
327        out.println("");
328        out.println("    static private void add(DataStreamMarshaller dsm) {");
329        out.println("        marshaller[dsm.getDataStructureType()] = dsm;");
330        out.println("    }");
331        out.println("    ");
332        out.println("    static public DataStreamMarshaller[] createMarshallerMap(OpenWireFormat wireFormat) {");
333        out.println("        return marshaller;");
334        out.println("    }");
335        out.println("}");
336    }
337
338    protected void processClass(JClass jclass) {
339        super.processClass(jclass);
340
341        if (!jclass.isAbstract()) {
342            concreteClasses.add(jclass);
343        }
344    }
345
346    protected String getClassName(JClass jclass) {
347        return super.getClassName(jclass) + "Marshaller";
348    }
349
350    protected String getBaseClassName(JClass jclass) {
351        String answer = "BaseDataStreamMarshaller";
352        JClass superclass = jclass.getSuperclass();
353        if (superclass != null) {
354            String superName = superclass.getSimpleName();
355            if (!superName.equals("Object") && !superName.equals("JNDIBaseStorable") && !superName.equals("DataStructureSupport")) {
356                answer = superName + "Marshaller";
357            }
358        }
359        return answer;
360    }
361
362    protected void initialiseManuallyMaintainedClasses() {
363    }
364
365    protected void generateTightUnmarshalBody(PrintWriter out) {
366        List properties = getProperties();
367        for (Iterator iter = properties.iterator(); iter.hasNext();) {
368            JProperty property = (JProperty)iter.next();
369            JAnnotation annotation = property.getAnnotation("openwire:property");
370            JAnnotationValue size = annotation.getValue("size");
371            JClass propertyType = property.getType();
372            String propertyTypeName = propertyType.getSimpleName();
373
374            if (propertyType.isArrayType() && !propertyTypeName.equals("byte[]")) {
375                generateTightUnmarshalBodyForArrayProperty(out, property, size);
376            } else {
377                generateTightUnmarshalBodyForProperty(out, property, size);
378            }
379        }
380    }
381
382    protected void generateTightUnmarshalBodyForProperty(PrintWriter out, JProperty property, JAnnotationValue size) {
383        String setter = property.getSetter().getSimpleName();
384        String type = property.getType().getSimpleName();
385
386        if (type.equals("boolean")) {
387            out.println("        info." + setter + "(bs.readBoolean());");
388        } else if (type.equals("byte")) {
389            out.println("        info." + setter + "(dataIn.readByte());");
390        } else if (type.equals("char")) {
391            out.println("        info." + setter + "(dataIn.readChar());");
392        } else if (type.equals("short")) {
393            out.println("        info." + setter + "(dataIn.readShort());");
394        } else if (type.equals("int")) {
395            out.println("        info." + setter + "(dataIn.readInt());");
396        } else if (type.equals("long")) {
397            out.println("        info." + setter + "(tightUnmarshalLong(wireFormat, dataIn, bs));");
398        } else if (type.equals("String")) {
399            out.println("        info." + setter + "(tightUnmarshalString(dataIn, bs));");
400        } else if (type.equals("byte[]")) {
401            if (size != null) {
402                out.println("        info." + setter + "(tightUnmarshalConstByteArray(dataIn, bs, " + size.asInt() + "));");
403            } else {
404                out.println("        info." + setter + "(tightUnmarshalByteArray(dataIn, bs));");
405            }
406        } else if (type.equals("ByteSequence")) {
407            out.println("        info." + setter + "(tightUnmarshalByteSequence(dataIn, bs));");
408        } else if (isThrowable(property.getType())) {
409            out.println("        info." + setter + "((" + property.getType().getQualifiedName() + ") tightUnmarsalThrowable(wireFormat, dataIn, bs));");
410        } else if (isCachedProperty(property)) {
411            out.println("        info." + setter + "((" + property.getType().getQualifiedName() + ") tightUnmarsalCachedObject(wireFormat, dataIn, bs));");
412        } else {
413            out.println("        info." + setter + "((" + property.getType().getQualifiedName() + ") tightUnmarsalNestedObject(wireFormat, dataIn, bs));");
414        }
415    }
416
417    protected void generateTightUnmarshalBodyForArrayProperty(PrintWriter out, JProperty property, JAnnotationValue size) {
418        JClass propertyType = property.getType();
419        String arrayType = propertyType.getArrayComponentType().getQualifiedName();
420        String setter = property.getSetter().getSimpleName();
421        out.println();
422        if (size != null) {
423            out.println("        {");
424            out.println("            " + arrayType + " value[] = new " + arrayType + "[" + size.asInt() + "];");
425            out.println("            " + "for( int i=0; i < " + size.asInt() + "; i++ ) {");
426            out.println("                value[i] = (" + arrayType + ") tightUnmarsalNestedObject(wireFormat,dataIn, bs);");
427            out.println("            }");
428            out.println("            info." + setter + "(value);");
429            out.println("        }");
430        } else {
431            out.println("        if (bs.readBoolean()) {");
432            out.println("            short size = dataIn.readShort();");
433            out.println("            " + arrayType + " value[] = new " + arrayType + "[size];");
434            out.println("            for( int i=0; i < size; i++ ) {");
435            out.println("                value[i] = (" + arrayType + ") tightUnmarsalNestedObject(wireFormat,dataIn, bs);");
436            out.println("            }");
437            out.println("            info." + setter + "(value);");
438            out.println("        }");
439            out.println("        else {");
440            out.println("            info." + setter + "(null);");
441            out.println("        }");
442        }
443    }
444
445    protected int generateTightMarshal1Body(PrintWriter out) {
446        List properties = getProperties();
447        int baseSize = 0;
448        for (Iterator iter = properties.iterator(); iter.hasNext();) {
449            JProperty property = (JProperty)iter.next();
450            JAnnotation annotation = property.getAnnotation("openwire:property");
451            JAnnotationValue size = annotation.getValue("size");
452            JClass propertyType = property.getType();
453            String type = propertyType.getSimpleName();
454            String getter = "info." + property.getGetter().getSimpleName() + "()";
455
456            if (type.equals("boolean")) {
457                out.println("        bs.writeBoolean(" + getter + ");");
458            } else if (type.equals("byte")) {
459                baseSize += 1;
460            } else if (type.equals("char")) {
461                baseSize += 2;
462            } else if (type.equals("short")) {
463                baseSize += 2;
464            } else if (type.equals("int")) {
465                baseSize += 4;
466            } else if (type.equals("long")) {
467                out.println("        rc+=tightMarshalLong1(wireFormat, " + getter + ", bs);");
468            } else if (type.equals("String")) {
469                out.println("        rc += tightMarshalString1(" + getter + ", bs);");
470            } else if (type.equals("byte[]")) {
471                if (size == null) {
472                    out.println("        rc += tightMarshalByteArray1(" + getter + ", bs);");
473                } else {
474                    out.println("        rc += tightMarshalConstByteArray1(" + getter + ", bs, " + size.asInt() + ");");
475                }
476            } else if (type.equals("ByteSequence")) {
477                out.println("        rc += tightMarshalByteSequence1(" + getter + ", bs);");
478            } else if (propertyType.isArrayType()) {
479                if (size != null) {
480                    out.println("        rc += tightMarshalObjectArrayConstSize1(wireFormat, " + getter + ", bs, " + size.asInt() + ");");
481                } else {
482                    out.println("        rc += tightMarshalObjectArray1(wireFormat, " + getter + ", bs);");
483                }
484            } else if (isThrowable(propertyType)) {
485                out.println("        rc += tightMarshalThrowable1(wireFormat, " + getter + ", bs);");
486            } else {
487                if (isCachedProperty(property)) {
488                    out.println("        rc += tightMarshalCachedObject1(wireFormat, (DataStructure)" + getter + ", bs);");
489                } else {
490                    out.println("        rc += tightMarshalNestedObject1(wireFormat, (DataStructure)" + getter + ", bs);");
491                }
492            }
493        }
494        return baseSize;
495    }
496
497    protected void generateTightMarshal2Body(PrintWriter out) {
498        List properties = getProperties();
499        for (Iterator iter = properties.iterator(); iter.hasNext();) {
500            JProperty property = (JProperty)iter.next();
501            JAnnotation annotation = property.getAnnotation("openwire:property");
502            JAnnotationValue size = annotation.getValue("size");
503            JClass propertyType = property.getType();
504            String type = propertyType.getSimpleName();
505            String getter = "info." + property.getGetter().getSimpleName() + "()";
506
507            if (type.equals("boolean")) {
508                out.println("        bs.readBoolean();");
509            } else if (type.equals("byte")) {
510                out.println("        dataOut.writeByte(" + getter + ");");
511            } else if (type.equals("char")) {
512                out.println("        dataOut.writeChar(" + getter + ");");
513            } else if (type.equals("short")) {
514                out.println("        dataOut.writeShort(" + getter + ");");
515            } else if (type.equals("int")) {
516                out.println("        dataOut.writeInt(" + getter + ");");
517            } else if (type.equals("long")) {
518                out.println("        tightMarshalLong2(wireFormat, " + getter + ", dataOut, bs);");
519            } else if (type.equals("String")) {
520                out.println("        tightMarshalString2(" + getter + ", dataOut, bs);");
521            } else if (type.equals("byte[]")) {
522                if (size != null) {
523                    out.println("        tightMarshalConstByteArray2(" + getter + ", dataOut, bs, " + size.asInt() + ");");
524                } else {
525                    out.println("        tightMarshalByteArray2(" + getter + ", dataOut, bs);");
526                }
527            } else if (type.equals("ByteSequence")) {
528                out.println("        tightMarshalByteSequence2(" + getter + ", dataOut, bs);");
529            } else if (propertyType.isArrayType()) {
530                if (size != null) {
531                    out.println("        tightMarshalObjectArrayConstSize2(wireFormat, " + getter + ", dataOut, bs, " + size.asInt() + ");");
532                } else {
533                    out.println("        tightMarshalObjectArray2(wireFormat, " + getter + ", dataOut, bs);");
534                }
535            } else if (isThrowable(propertyType)) {
536                out.println("        tightMarshalThrowable2(wireFormat, " + getter + ", dataOut, bs);");
537            } else {
538                if (isCachedProperty(property)) {
539                    out.println("        tightMarshalCachedObject2(wireFormat, (DataStructure)" + getter + ", dataOut, bs);");
540                } else {
541                    out.println("        tightMarshalNestedObject2(wireFormat, (DataStructure)" + getter + ", dataOut, bs);");
542                }
543            }
544        }
545    }
546
547    protected void generateLooseMarshalBody(PrintWriter out) {
548        List properties = getProperties();
549        for (Iterator iter = properties.iterator(); iter.hasNext();) {
550            JProperty property = (JProperty)iter.next();
551            JAnnotation annotation = property.getAnnotation("openwire:property");
552            JAnnotationValue size = annotation.getValue("size");
553            JClass propertyType = property.getType();
554            String type = propertyType.getSimpleName();
555            String getter = "info." + property.getGetter().getSimpleName() + "()";
556
557            if (type.equals("boolean")) {
558                out.println("        dataOut.writeBoolean(" + getter + ");");
559            } else if (type.equals("byte")) {
560                out.println("        dataOut.writeByte(" + getter + ");");
561            } else if (type.equals("char")) {
562                out.println("        dataOut.writeChar(" + getter + ");");
563            } else if (type.equals("short")) {
564                out.println("        dataOut.writeShort(" + getter + ");");
565            } else if (type.equals("int")) {
566                out.println("        dataOut.writeInt(" + getter + ");");
567            } else if (type.equals("long")) {
568                out.println("        looseMarshalLong(wireFormat, " + getter + ", dataOut);");
569            } else if (type.equals("String")) {
570                out.println("        looseMarshalString(" + getter + ", dataOut);");
571            } else if (type.equals("byte[]")) {
572                if (size != null) {
573                    out.println("        looseMarshalConstByteArray(wireFormat, " + getter + ", dataOut, " + size.asInt() + ");");
574                } else {
575                    out.println("        looseMarshalByteArray(wireFormat, " + getter + ", dataOut);");
576                }
577            } else if (type.equals("ByteSequence")) {
578                out.println("        looseMarshalByteSequence(wireFormat, " + getter + ", dataOut);");
579            } else if (propertyType.isArrayType()) {
580                if (size != null) {
581                    out.println("        looseMarshalObjectArrayConstSize(wireFormat, " + getter + ", dataOut, " + size.asInt() + ");");
582                } else {
583                    out.println("        looseMarshalObjectArray(wireFormat, " + getter + ", dataOut);");
584                }
585            } else if (isThrowable(propertyType)) {
586                out.println("        looseMarshalThrowable(wireFormat, " + getter + ", dataOut);");
587            } else {
588                if (isCachedProperty(property)) {
589                    out.println("        looseMarshalCachedObject(wireFormat, (DataStructure)" + getter + ", dataOut);");
590                } else {
591                    out.println("        looseMarshalNestedObject(wireFormat, (DataStructure)" + getter + ", dataOut);");
592                }
593            }
594        }
595    }
596
597    protected void generateLooseUnmarshalBody(PrintWriter out) {
598        List properties = getProperties();
599        for (Iterator iter = properties.iterator(); iter.hasNext();) {
600            JProperty property = (JProperty)iter.next();
601            JAnnotation annotation = property.getAnnotation("openwire:property");
602            JAnnotationValue size = annotation.getValue("size");
603            JClass propertyType = property.getType();
604            String propertyTypeName = propertyType.getSimpleName();
605
606            if (propertyType.isArrayType() && !propertyTypeName.equals("byte[]")) {
607                generateLooseUnmarshalBodyForArrayProperty(out, property, size);
608            } else {
609                generateLooseUnmarshalBodyForProperty(out, property, size);
610            }
611        }
612    }
613
614    protected void generateLooseUnmarshalBodyForProperty(PrintWriter out, JProperty property, JAnnotationValue size) {
615        String setter = property.getSetter().getSimpleName();
616        String type = property.getType().getSimpleName();
617
618        if (type.equals("boolean")) {
619            out.println("        info." + setter + "(dataIn.readBoolean());");
620        } else if (type.equals("byte")) {
621            out.println("        info." + setter + "(dataIn.readByte());");
622        } else if (type.equals("char")) {
623            out.println("        info." + setter + "(dataIn.readChar());");
624        } else if (type.equals("short")) {
625            out.println("        info." + setter + "(dataIn.readShort());");
626        } else if (type.equals("int")) {
627            out.println("        info." + setter + "(dataIn.readInt());");
628        } else if (type.equals("long")) {
629            out.println("        info." + setter + "(looseUnmarshalLong(wireFormat, dataIn));");
630        } else if (type.equals("String")) {
631            out.println("        info." + setter + "(looseUnmarshalString(dataIn));");
632        } else if (type.equals("byte[]")) {
633            if (size != null) {
634                out.println("        info." + setter + "(looseUnmarshalConstByteArray(dataIn, " + size.asInt() + "));");
635            } else {
636                out.println("        info." + setter + "(looseUnmarshalByteArray(dataIn));");
637            }
638        } else if (type.equals("ByteSequence")) {
639            out.println("        info." + setter + "(looseUnmarshalByteSequence(dataIn));");
640        } else if (isThrowable(property.getType())) {
641            out.println("        info." + setter + "((" + property.getType().getQualifiedName() + ") looseUnmarsalThrowable(wireFormat, dataIn));");
642        } else if (isCachedProperty(property)) {
643            out.println("        info." + setter + "((" + property.getType().getQualifiedName() + ") looseUnmarsalCachedObject(wireFormat, dataIn));");
644        } else {
645            out.println("        info." + setter + "((" + property.getType().getQualifiedName() + ") looseUnmarsalNestedObject(wireFormat, dataIn));");
646        }
647    }
648
649    protected void generateLooseUnmarshalBodyForArrayProperty(PrintWriter out, JProperty property, JAnnotationValue size) {
650        JClass propertyType = property.getType();
651        String arrayType = propertyType.getArrayComponentType().getQualifiedName();
652        String setter = property.getSetter().getSimpleName();
653        out.println();
654        if (size != null) {
655            out.println("        {");
656            out.println("            " + arrayType + " value[] = new " + arrayType + "[" + size.asInt() + "];");
657            out.println("            " + "for( int i=0; i < " + size.asInt() + "; i++ ) {");
658            out.println("                value[i] = (" + arrayType + ") looseUnmarsalNestedObject(wireFormat,dataIn);");
659            out.println("            }");
660            out.println("            info." + setter + "(value);");
661            out.println("        }");
662        } else {
663            out.println("        if (dataIn.readBoolean()) {");
664            out.println("            short size = dataIn.readShort();");
665            out.println("            " + arrayType + " value[] = new " + arrayType + "[size];");
666            out.println("            for( int i=0; i < size; i++ ) {");
667            out.println("                value[i] = (" + arrayType + ") looseUnmarsalNestedObject(wireFormat,dataIn);");
668            out.println("            }");
669            out.println("            info." + setter + "(value);");
670            out.println("        }");
671            out.println("        else {");
672            out.println("            info." + setter + "(null);");
673            out.println("        }");
674        }
675    }
676
677    /**
678     * Returns whether or not the given annotation has a mandatory flag on it or
679     * not
680     */
681    protected String getMandatoryFlag(JAnnotation annotation) {
682        JAnnotationValue value = annotation.getValue("mandatory");
683        if (value != null) {
684            String text = value.asString();
685            if (text != null && text.equalsIgnoreCase("true")) {
686                return "true";
687            }
688        }
689        return "false";
690    }
691
692    public List<JClass> getConcreteClasses() {
693        return concreteClasses;
694    }
695
696    public void setConcreteClasses(List<JClass> concreteClasses) {
697        this.concreteClasses = concreteClasses;
698    }
699
700    public File getFactoryFile() {
701        return factoryFile;
702    }
703
704    public void setFactoryFile(File factoryFile) {
705        this.factoryFile = factoryFile;
706    }
707
708    public String getFactoryFileName() {
709        return factoryFileName;
710    }
711
712    public void setFactoryFileName(String factoryFileName) {
713        this.factoryFileName = factoryFileName;
714    }
715
716    public String getIndent() {
717        return indent;
718    }
719
720    public void setIndent(String indent) {
721        this.indent = indent;
722    }
723
724    public String getTargetDir() {
725        return targetDir;
726    }
727
728    public void setTargetDir(String sourceDir) {
729        this.targetDir = sourceDir;
730    }
731}