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     */
017    package org.apache.activemq.openwire.tool;
018    
019    import java.io.File;
020    import java.io.FileWriter;
021    import java.io.PrintWriter;
022    import java.util.ArrayList;
023    import java.util.Collections;
024    import java.util.Comparator;
025    import java.util.Iterator;
026    import java.util.List;
027    
028    import org.codehaus.jam.JAnnotation;
029    import org.codehaus.jam.JAnnotationValue;
030    import org.codehaus.jam.JClass;
031    import org.codehaus.jam.JPackage;
032    import org.codehaus.jam.JProperty;
033    
034    /**
035     * 
036     */
037    public 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    }