Return-Path: Delivered-To: apmail-activemq-commits-archive@www.apache.org Received: (qmail 81801 invoked from network); 6 Feb 2010 21:47:06 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 6 Feb 2010 21:47:06 -0000 Received: (qmail 74967 invoked by uid 500); 6 Feb 2010 21:47:06 -0000 Delivered-To: apmail-activemq-commits-archive@activemq.apache.org Received: (qmail 74903 invoked by uid 500); 6 Feb 2010 21:47:05 -0000 Mailing-List: contact commits-help@activemq.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@activemq.apache.org Delivered-To: mailing list commits@activemq.apache.org Received: (qmail 74893 invoked by uid 99); 6 Feb 2010 21:47:05 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 06 Feb 2010 21:47:05 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 06 Feb 2010 21:47:03 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id DC25523889EB; Sat, 6 Feb 2010 21:46:42 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r907314 [3/4] - in /activemq/sandbox/activemq-apollo-actor/activemq-amqp-generator/src: handcoded/org/apache/activemq/amqp/generator/handcoded/ handcoded/org/apache/activemq/amqp/generator/handcoded/marshaller/ handcoded/org/apache/activemq... Date: Sat, 06 Feb 2010 21:46:42 -0000 To: commits@activemq.apache.org From: cmacnaug@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100206214642.DC25523889EB@eris.apache.org> Modified: activemq/sandbox/activemq-apollo-actor/activemq-amqp-generator/src/main/java/org/apache/activemq/amqp/generator/AmqpClass.java URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo-actor/activemq-amqp-generator/src/main/java/org/apache/activemq/amqp/generator/AmqpClass.java?rev=907314&r1=907313&r2=907314&view=diff ============================================================================== --- activemq/sandbox/activemq-apollo-actor/activemq-amqp-generator/src/main/java/org/apache/activemq/amqp/generator/AmqpClass.java (original) +++ activemq/sandbox/activemq-apollo-actor/activemq-amqp-generator/src/main/java/org/apache/activemq/amqp/generator/AmqpClass.java Sat Feb 6 21:46:41 2010 @@ -5,14 +5,19 @@ import static org.apache.activemq.amqp.generator.Utils.tab; import static org.apache.activemq.amqp.generator.Utils.toJavaConstant; import static org.apache.activemq.amqp.generator.Utils.toJavaName; +import static org.apache.activemq.amqp.generator.Utils.writeJavaComment; import static org.apache.activemq.amqp.generator.Utils.writeJavaCopyWrite; import java.io.BufferedWriter; +import java.io.DataInput; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.rmi.UnexpectedException; import java.util.LinkedHashMap; import java.util.LinkedList; +import java.util.List; +import java.util.Map; import java.util.TreeSet; import org.apache.activemq.amqp.generator.TypeRegistry.JavaTypeMapping; @@ -44,9 +49,13 @@ public boolean handcoded; // Java mapping for this class: - public TypeRegistry.JavaTypeMapping typeMapping; + protected TypeRegistry.JavaTypeMapping typeMapping; // Java mapping of the value that this type holds (if any) - public TypeRegistry.JavaTypeMapping valueMapping; + protected TypeRegistry.JavaTypeMapping valueMapping; + // Java mapping of the value that this type holds (if any) + protected TypeRegistry.JavaTypeMapping beanMapping; + + public TypeRegistry.JavaTypeMapping versionMarshaller; public void parseFromType(Generator generator, Amqp source, Section section, Type type) throws UnknownTypeException { this.name = type.getName(); @@ -96,7 +105,21 @@ this.restricted = true; } - typeMapping = new JavaTypeMapping(name, generator.getPackagePrefix() + "." + source.getName() + "." + "Amqp" + capFirst(toJavaName(name))); + typeMapping = new JavaTypeMapping(name, generator.getPackagePrefix() + ".types." + "Amqp" + capFirst(toJavaName(name))); + + if (needsMarshaller()) { + beanMapping = new JavaTypeMapping(name + "-bean", generator.getPackagePrefix() + ".marshaller." + typeMapping + "Bean"); + } + + // For described types the value is actually the bean mapping which + // describes all of the fields: + if (isDescribed()) { + valueMapping = beanMapping; + } else if (isPrimitive()) { + valueMapping = TypeRegistry.getJavaTypeMapping(name); + } else if (isRestricted()) { + valueMapping = typeMapping; + } } public void generate(Generator generator) throws IOException, UnknownTypeException { @@ -115,108 +138,167 @@ writeJavaCopyWrite(writer); writer.write("package " + typeMapping.getPackageName() + ";\n"); writer.newLine(); - if (writeImports(writer, generator)) { + if (writeImports(writer, generator, false)) { writer.newLine(); } if (doc != null) { doc.writeJavaDoc(writer, 0); } else if (label != null) { - Utils.writeJavaComment(writer, 0, "Represents a " + label); + writeJavaComment(writer, 0, "Represents a " + label); } // We use enums for restricted types with a choice: - if (isRestricted() && choice != null) { + if (isEnumType()) { writer.write("public enum " + className); - } else { - writer.write("public class " + className); - if (isPrimitive() || descriptor != null) { - writer.write(" extends AmqpType"); - } else if (isRestricted()) { - writer.write(" extends " + resolveRestrictedType().getTypeMapping().getShortName()); + } else if (isMarshallable()) { + + if (isRestricted()) { + writer.write("public class " + className + " extends " + resolveRestrictedType().getTypeMapping()); + } else { + writer.write("public class " + className + " extends AmqpType<" + getValueMapping() + "> implements " + beanMapping); } if (isCommand()) { - writer.write(" implements AmqpCommand"); + writer.write(", AmqpCommand"); } } writer.write(" {"); writer.newLine(); - writeConstants(writer); - - writeFields(writer); - - writeConstructors(writer); - - writeFieldAccesors(writer); - - writeSerializers(writer); + if (isMarshallable()) { + writer.newLine(); + writeBeanImpl(writer, 1); + } else { + writeEnumType(writer); + } writer.write("}"); writer.flush(); writer.close(); + // We don't generate beans or marshallers for restricted types: + if (!isRestricted()) { + generateBeanInterface(generator); + generateMarshaller(generator); + } + } - private boolean writeImports(BufferedWriter writer, Generator generator) throws IOException, UnknownTypeException { + private boolean writeImports(BufferedWriter writer, Generator generator, boolean marshaller) throws IOException, UnknownTypeException { TreeSet imports = new TreeSet(); for (AmqpField field : fields.values()) { AmqpClass fieldType = field.resolveAmqpFieldType(); - filterOrAddImport(imports, fieldType.getTypeMapping()); - filterOrAddImport(imports, fieldType.resolveValueMapping()); + filterOrAddImport(imports, fieldType.getTypeMapping(), marshaller); + filterOrAddImport(imports, fieldType.getValueMapping(), marshaller); + if (fieldType.choice != null) { - filterOrAddImport(imports, fieldType.resolveBaseTypeMapping()); + filterOrAddImport(imports, fieldType.resolveBaseTypeMapping(), marshaller); } - if (fieldType.getName().equals("*")) { - imports.add(generator.getPackagePrefix() + ".AmqpMarshaller"); + if (marshaller) { + JavaTypeMapping mapping = fieldType.getTypeMapping(); + if (fieldType.isRestricted()) { + mapping = fieldType.resolveBaseTypeMapping(); + } + if (!mapping.getAmqpType().equals("*")) { + imports.add(mapping.getFullVersionMarshallerName(generator)); + + } + } } - if (isCommand()) { + if (!marshaller && isCommand()) { imports.add(generator.getPackagePrefix() + ".AmqpCommandHandler"); imports.add(generator.getPackagePrefix() + ".AmqpCommand"); } - if (isPrimitive() || descriptor != null) { + if (marshaller) { + // Add the marshalled type: + filterOrAddImport(imports, typeMapping, marshaller); + if (hasCompoundEncoding()) { + filterOrAddImport(imports, TypeRegistry.resolveAmqpClass("*").getTypeMapping(), marshaller); + } + imports.add("java.io.DataInput"); + TypeRegistry.resolveAmqpClass("null").getTypeMapping().getFullVersionMarshallerName(generator); + imports.add(generator.getMarshallerPackage() + ".Encoder"); + imports.add(generator.getMarshallerPackage() + ".Encoder.*"); + imports.add("org.apache.activemq.util.buffer.Buffer"); + + imports.add(generator.getPackagePrefix() + ".marshaller.UnexpectedTypeException"); + imports.add(generator.getPackagePrefix() + ".marshaller.AmqpEncodingError"); + + if (descriptor != null || hasMultipleEncodings()) { + imports.add(generator.getPackagePrefix() + ".marshaller.Encoded"); + } + + if (descriptor != null) { + + imports.add(generator.getPackagePrefix() + ".marshaller.AmqpEncodingError"); + + AmqpClass describedType = descriptor.resolveDescribedType(); + if (describedType.getName().equals("list")) { + imports.add(TypeRegistry.resolveAmqpClass("list").getTypeMapping().getFullVersionMarshallerName(generator) + ".*"); + imports.add(TypeRegistry.resolveAmqpClass("list").getValueMapping().getImport()); + } else if (describedType.getName().equals("map")) { + imports.add(TypeRegistry.resolveAmqpClass("map").getTypeMapping().getFullVersionMarshallerName(generator) + ".*"); + imports.add(TypeRegistry.resolveAmqpClass("map").getValueMapping().getImport()); + imports.add(TypeRegistry.resolveAmqpClass("symbol").getTypeMapping().getFullVersionMarshallerName(generator)); + // Import symbol which is used for the keys: + imports.add(TypeRegistry.resolveAmqpClass("symbol").getTypeMapping().getImport()); + imports.add("java.util.Map"); + } + + filterOrAddImport(imports, describedType.getTypeMapping(), marshaller); + + imports.add(generator.getPackagePrefix() + ".types.AmqpLong"); + imports.add(generator.getPackagePrefix() + ".types.AmqpSymbol"); + // filterOrAddImport(imports, + // describedType.resolveValueMapping()); + } + + imports.add(generator.getPackagePrefix() + ".marshaller.Encoded"); + imports.add(generator.getPackagePrefix() + ".marshaller.Encoding"); + imports.add(generator.getPackagePrefix() + ".marshaller.AmqpVersion"); imports.add(generator.getPackagePrefix() + ".types.AmqpType"); + + imports.add(beanMapping.getImport()); imports.add("java.io.DataOutput"); - imports.add("java.io.DataInput"); imports.add("java.io.IOException"); - } - if (isPrimitive()) { - filterOrAddImport(imports, resolveValueMapping()); - // Need the AmqpMarshaller to help with encodings: - if (hasNonZeroEncoding() || encodings.size() > 1) { - imports.add(generator.getPackagePrefix() + ".AmqpMarshaller"); + } else if (isMarshallable()) { + imports.add(generator.getPackagePrefix() + ".marshaller.Encoded"); + if (isRestricted()) { + imports.add(resolveRestrictedType().getBeanMapping().getImport()); + imports.add(resolveRestrictedType().valueMapping.getImport()); + } else { + imports.add(generator.getPackagePrefix() + ".marshaller.AmqpEncodingError"); + imports.add(generator.getPackagePrefix() + ".marshaller.AmqpMarshaller"); + imports.add(beanMapping.getImport()); + imports.add("java.io.IOException"); } - imports.add("java.io.UnsupportedEncodingException"); + } + + if (isDescribed()) { + filterOrAddImport(imports, getValueMapping(), marshaller); } if (isRestricted()) { if (choice != null) { - imports.add("java.io.UnsupportedEncodingException"); + imports.add(generator.getPackagePrefix() + ".marshaller.AmqpEncodingError"); + imports.add("java.util.HashMap"); } imports.add(TypeRegistry.resolveAmqpClass(restrictedType).getTypeMapping().getImport()); - } - if (descriptor != null) { - AmqpClass describedType = descriptor.resolveDescribedType(); - if (describedType.getName().equals("list")) { - imports.add("java.util.ArrayList"); - } else if (describedType.getName().equals("map")) { - // Import symbol which is used for the keys: - imports.add(TypeRegistry.resolveAmqpClass("symbol").getTypeMapping().getImport()); - } + } - filterOrAddImport(imports, describedType.getTypeMapping()); - // filterOrAddImport(imports, describedType.resolveValueMapping()); + if (isPrimitive()) { + filterOrAddImport(imports, getValueMapping(), marshaller); } boolean ret = false; @@ -229,98 +311,38 @@ return ret; } - private void filterOrAddImport(TreeSet imports, JavaTypeMapping mapping) { + private void filterOrAddImport(TreeSet imports, JavaTypeMapping mapping, boolean marshaller) { if (mapping == null) { return; } if (mapping.getImport() == null) { return; } - if (mapping.getPackageName().equals(typeMapping.getPackageName())) { - return; - } - imports.add(mapping.getImport()); - } - - private boolean writeConstants(BufferedWriter writer) throws IOException, UnknownTypeException { - boolean ret = false; - - // Write out the descriptor (for compound types): - if (descriptor != null) { - ret = true; - writer.newLine(); - writer.write(tab(1) + "public static final String SYMBOLIC_NAME = \"" + descriptor.getSymbolicName() + "\";"); - writer.newLine(); - writer.write(tab(1) + "//Format code: " + descriptor.getFormatCode() + ":"); - writer.newLine(); - writer.write(tab(1) + "public static final long CATEGORY = " + descriptor.getCategory() + ";"); - writer.newLine(); - writer.write(tab(1) + "public static final long DESCRIPTOR_ID = " + descriptor.getDescriptorId() + ";"); - writer.newLine(); - writer.write(tab(1) + "public static final long FORMAT_CODE = CATEGORY << 32 | DESCRIPTOR_ID; //(" + (descriptor.getCategory() << 32 | descriptor.getDescriptorId()) + "L)"); - writer.newLine(); - writer.write(tab(1) + "//Hard coded constructor (minus the trailing primitive format code whose encoding may vary):"); - writer.newLine(); - writer.write(tab(1) + "public static final byte [] CONSTRUCTOR = new byte [] {"); - writer.newLine(); - writer.write(tab(2) + "(byte) 0x00, // COMPOUND_TYPE);"); - writer.newLine(); - // TODO retrieve ulong encoding from the ulong itself: - writer.write(tab(2) + "(byte) 0x80, // ulong descriptor encoding)"); - writer.newLine(); - // Add the category code: - writer.write(tab(2)); - String categoryHex = padHex(descriptor.getFormatCode().substring(2, descriptor.getFormatCode().indexOf(":")), 8); - for (int i = 0; i < 8; i += 2) { - writer.write("(byte) 0x" + categoryHex.substring(i, i + 2) + ", "); - } - writer.write(" // CATEGORY CODE"); - writer.newLine(); - writer.write(tab(2)); - // Add the descriptor id code: - String descriptorIdHex = padHex(descriptor.getFormatCode().substring(descriptor.getFormatCode().indexOf(":") + 3), 8); - - for (int i = 0; i < 8; i += 2) { - writer.write("(byte) 0x" + descriptorIdHex.substring(i, i + 2)); - if (i < 6) { - writer.write(", "); - } - } - writer.write(" // DESCRIPTOR ID CODE"); - writer.newLine(); - writer.write(tab(1) + "};"); - writer.newLine(); - - if (descriptor.getDescribedType().equals("map")) { - writer.newLine(); - writer.write(tab(1) + "//Accessor keys for field mapped fields:"); - writer.newLine(); - for (AmqpField field : fields.values()) { - writer.write(tab(1) + "private static final AmqpSymbol " + toJavaConstant(field.getName()) + "_KEY = " + " new AmqpSymbol(\"" + field.getName() + "\");"); - writer.newLine(); - } - writer.newLine(); + if (!marshaller) { + if (mapping.getPackageName().equals(typeMapping.getPackageName())) { + return; } } + imports.add(mapping.getImport()); + } - // Write out encodings: - if (encodings != null) { - writeEncodings(writer); - } + private void writeEnumType(BufferedWriter writer) throws IOException, UnknownTypeException { - if (choice != null) { - ret = true; + if (isEnumType()) { writer.newLine(); int i = 0; - AmqpClass amqpType = TypeRegistry.resolveAmqpClass(restrictedType); + AmqpClass amqpClass = TypeRegistry.resolveAmqpClass(restrictedType); + JavaTypeMapping amqpType = amqpClass.getTypeMapping(); + JavaTypeMapping valueType = amqpClass.getValueMapping(); + for (Choice constant : choice.choices) { i++; if (constant.getDoc() != null) { new AmqpDoc(constant.getDoc()).writeJavaDoc(writer, 1); } - writer.write(tab(1) + toJavaConstant(constant.getName()) + "((" + amqpType.resolveValueMapping().getJavaType() + ") " + constant.getValue() + ")"); + writer.write(tab(1) + toJavaConstant(constant.getName()) + "(new " + valueType + "(\"" + constant.getValue() + "\"))"); if (i < choice.choices.size()) { writer.write(","); } else { @@ -330,72 +352,54 @@ } writer.newLine(); - writer.write(tab(1) + "private final " + amqpType.getTypeMapping().getJavaType() + " value = new " + amqpType.getTypeMapping().getJavaType() + "();"); + writer.write(tab(1) + "private static final HashMap<" + valueType + ", " + getJavaType() + "> LOOKUP = new HashMap<" + valueType + ", " + getJavaType() + ">(2);"); writer.newLine(); - + writer.write(tab(1) + "static {"); writer.newLine(); - writer.write(tab(1) + "private " + typeMapping.getShortName() + "(" + amqpType.resolveValueMapping().getJavaType() + " value) {"); + writer.write(tab(2) + "for (" + getJavaType() + " " + toJavaName(getName()) + " : " + getJavaType() + ".values()) {"); writer.newLine(); - writer.write(tab(2) + "this.value.setValue(value);"); + writer.write(tab(3) + "LOOKUP.put(" + toJavaName(getName()) + ".value.getValue(), " + toJavaName(getName()) + ");"); + writer.newLine(); + writer.write(tab(2) + "}"); writer.newLine(); writer.write(tab(1) + "}"); writer.newLine(); writer.newLine(); - writer.write(tab(1) + "//TODO: Remove?"); + writer.write(tab(1) + "private final " + amqpType + " value;"); writer.newLine(); - writer.write(tab(1) + "public " + amqpType.getTypeMapping().getJavaType() + " getValue() {"); + writer.newLine(); - writer.write(tab(2) + "return value;"); + writer.write(tab(1) + "private " + typeMapping + "(" + valueType + " value) {"); + writer.newLine(); + writer.write(tab(2) + "this.value = new " + amqpType + "(value);"); + writer.newLine(); writer.write(tab(1) + "}"); writer.newLine(); writer.newLine(); - writer.write(tab(1) + "public static final " + getTypeMapping().getJavaType() + " get(" + amqpType.resolveValueMapping().getJavaType() + " value) throws UnsupportedEncodingException{"); - if (amqpType.resolveValueMapping().getJavaType().equals("int")) { - writer.newLine(); - writer.write(tab(2) + "switch (value) {"); - writer.newLine(); - for (Choice constant : choice.choices) { - writer.write(tab(2) + "case " + constant.getValue() + ": {"); - writer.newLine(); - writer.write(tab(3) + "return " + toJavaConstant(constant.getName()) + ";"); - writer.newLine(); - writer.write(tab(2) + "}"); - writer.newLine(); - } - - writer.write(tab(2) + "default: {"); - writer.newLine(); - writer.write(tab(3) + "throw new UnsupportedEncodingException();"); - writer.newLine(); - writer.write(tab(2) + "}"); - writer.newLine(); - writer.write(tab(2) + "}"); - } else { - writer.newLine(); - i = 0; - for (Choice constant : choice.choices) { - writer.write(tab(2)); - if (i > 0) { - writer.write("else "); - } - writer.write("if (value == " + constant.getValue() + ") {"); - writer.newLine(); - writer.write(tab(3) + "return " + toJavaConstant(constant.getName()) + ";"); - writer.newLine(); - writer.write(tab(2) + "}"); - writer.newLine(); - i++; - } + writer.write(tab(1) + "public final " + amqpType + " getValue() {"); + writer.newLine(); + writer.write(tab(2) + "return value;"); + writer.newLine(); + writer.write(tab(1) + "}"); + writer.newLine(); - writer.write(tab(2) + "else {"); - writer.newLine(); - writer.write(tab(3) + "throw new UnsupportedEncodingException();"); - writer.newLine(); - writer.write(tab(2) + "}"); - } + writer.newLine(); + writer.write(tab(1) + "public static final " + getJavaType() + " get(" + amqpType + " value) throws AmqpEncodingError{"); + writer.newLine(); + writer.write(tab(2) + getJavaType() + " " + toJavaName(getName()) + "= LOOKUP.get(value.getValue());"); + writer.newLine(); + writer.write(tab(2) + "if (" + toJavaName(getName()) + " == null) {"); + writer.newLine(); + writer.write(tab(3) + "//TODO perhaps this should be an IllegalArgumentException?"); + writer.newLine(); + writer.write(tab(3) + "throw new AmqpEncodingError(\"Unknown " + toJavaName(getName()) + ": \" + value + \" expected one of \" + LOOKUP.keySet());"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + writer.write(tab(2) + "return " + toJavaName(getName()) + ";"); writer.newLine(); writer.write(tab(1) + "}"); writer.newLine(); @@ -413,566 +417,1319 @@ // writer.newLine(); } - return ret; } private void writeEncodings(BufferedWriter writer) throws IOException, UnknownTypeException { - if (encodings != null && encodings.size() == 1 && "fixed".equals(encodings.getFirst().getCategory())) { - writer.newLine(); - writer.write(tab(1) + "public static final byte FORMAT_CODE = (byte) " + encodings.getFirst().getCode() + ";"); - writer.newLine(); - writer.write(tab(1) + "public static final FormatSubCategory FORMAT_CATEGORY = FormatSubCategory.getCategory(FORMAT_CODE);"); - writer.newLine(); - } else { - String encodingName = getEncodingName(false); - writer.newLine(); - writer.write(tab(1) + "public static enum " + encodingName + " {"); - writer.newLine(); + if (isDescribed()) { - int i = 0; - for (AmqpEncoding encoding : encodings) { - i++; - String eName = encoding.getName(); - if (eName == null) { - eName = name; + JavaTypeMapping describedType = descriptor.resolveDescribedType().getTypeMapping(); + + if (descriptor.getDescribedType().equals("list")) { + writer.newLine(); + writer.write(tab(1) + "private static final ListDecoder DECODER = new ListDecoder() {"); + writer.newLine(); + writer.write(tab(2) + "public final AmqpType unmarshalType(int pos, DataInput in) throws IOException {"); + writer.newLine(); + writer.write(tab(3) + "switch(pos) {"); + writer.newLine(); + int f = 0; + for (AmqpField field : fields.values()) { + AmqpClass fieldType = field.resolveAmqpFieldType(); + + writer.write(tab(3) + "case " + f++ + ": {"); + writer.newLine(); + if (fieldType.isEnumType() || fieldType.isAny()) { + writer.write(tab(4) + "return " + fieldType.getMarshaller() + ".unmarshalType(in);"); + } else { + writer.write(tab(4) + "return " + fieldType.getMarshaller() + ".unmarshalType(new " + fieldType.getTypeMapping() + "(), in);"); + } + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); } - eName = toJavaConstant(eName); + writer.write(tab(3) + "default: {"); + writer.newLine(); + writer.write(tab(4) + "return AmqpMarshaller.SINGLETON.unmarshalType(in);"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); - writer.write(tab(2) + eName + " ((byte) " + encoding.getCode() + ")"); - if (i < encodings.size()) { - writer.write(","); - } else { - writer.write(";"); + writer.newLine(); + writer.write(tab(2) + "public final AmqpType decodeType(int pos, EncodedBuffer buffer) throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(3) + "switch(pos) {"); + writer.newLine(); + + f = 0; + for (AmqpField field : fields.values()) { + AmqpClass fieldType = field.resolveAmqpFieldType(); + + writer.write(tab(3) + "case " + f++ + ": {"); + writer.newLine(); + if (fieldType.isEnumType() || fieldType.isAny() || isPrimitive()) { + writer.write(tab(4) + "return " + fieldType.getMarshaller() + ".decodeType(buffer);"); + } else { + writer.write(tab(4) + "return " + fieldType.getMarshaller() + ".decodeType(new " + fieldType.getTypeMapping() + "(), buffer);"); + } + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); } + writer.write(tab(3) + "default: {"); + writer.newLine(); + writer.write(tab(4) + "return AmqpMarshaller.SINGLETON.decodeType(buffer);"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); - if (encoding.getLabel() != null) { - writer.write(" // " + encoding.getLabel()); + writer.write(tab(1) + "};"); + } else if (descriptor.getDescribedType().equals("map")) { + + writer.newLine(); + writer.write(tab(1) + "private static final MapDecoder DECODER = new MapDecoder() {"); + writer.newLine(); + writer.write(tab(2) + "public void decodeToMap(EncodedBuffer encodedKey, EncodedBuffer encodedValue, Map, AmqpType> map) throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(3) + "AmqpSymbol key = AmqpSymbolMarshaller.decodeType(encodedKey);"); + writer.newLine(); + writer.write(tab(3) + "if (key == null) {"); + writer.newLine(); + writer.write(tab(4) + "throw new AmqpEncodingError(\"Null Key for \" + SYMBOLIC_ID);"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + writer.newLine(); + int f = 0; + for (AmqpField field : fields.values()) { + AmqpClass fieldType = field.resolveAmqpFieldType(); + writer.write(tab(3) + (f > 0 ? "else " : "") + "if (key.getValue().equals(" + toJavaConstant(field.getName()) + "_KEY.getValue())){"); + writer.newLine(); + if (fieldType.isEnumType() || fieldType.isAny() || fieldType.isPrimitive()) { + writer.write(tab(4) + "map.put(" + toJavaConstant(field.getName()) + "_KEY, " + fieldType.getMarshaller() + ".decodeType(encodedValue));"); + } else { + writer.write(tab(4) + "map.put(" + toJavaConstant(field.getName()) + "_KEY, " + fieldType.getMarshaller() + ".decodeType(new " + fieldType.getTypeMapping() + + "(), encodedValue));"); + } + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + } + writer.write(tab(3) + "else {"); + writer.newLine(); + writer.write(tab(4) + "throw new UnexpectedTypeException(\"Invalid Key for \" + SYMBOLIC_ID + \" : \" + key);"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.write(tab(2) + "public void unmarshalToMap(DataInput in, Map, AmqpType> map) throws AmqpEncodingError, IOException {"); + writer.newLine(); + writer.write(tab(3) + "AmqpSymbol key = AmqpSymbolMarshaller.unmarshalType(in);"); + writer.newLine(); + writer.write(tab(3) + "if (key == null) {"); + writer.newLine(); + writer.write(tab(4) + "throw new AmqpEncodingError(\"Null Key for \" + SYMBOLIC_ID);"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + writer.newLine(); + f = 0; + for (AmqpField field : fields.values()) { + AmqpClass fieldType = field.resolveAmqpFieldType(); + writer.write(tab(3) + (f > 0 ? "else " : "") + "if (key.getValue().equals(" + toJavaConstant(field.getName()) + "_KEY.getValue())){"); + writer.newLine(); + if (fieldType.isEnumType() || fieldType.isAny() || fieldType.isPrimitive()) { + writer.write(tab(4) + "map.put(" + toJavaConstant(field.getName()) + "_KEY, " + fieldType.getMarshaller() + ".unmarshalType(in));"); + } else { + writer.write(tab(4) + "map.put(" + toJavaConstant(field.getName()) + "_KEY, " + fieldType.getMarshaller() + ".unmarshalType(new " + fieldType.getTypeMapping() + "(), in));"); + } + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); } + writer.write(tab(3) + "else {"); + writer.newLine(); + writer.write(tab(4) + "throw new UnexpectedTypeException(\"Invalid Key for \" + SYMBOLIC_ID + \" : \" + key);"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + writer.write(tab(1) + "};"); writer.newLine(); + } else { + throw new UnexpectedException("Unsupported described type: " + descriptor.getDescribedType()); } writer.newLine(); - writer.write(tab(2) + "public final byte FORMAT_CODE;"); - writer.newLine(); - writer.write(tab(2) + "public final FormatSubCategory CATEGORY;"); + writer.write(tab(1) + "public static class " + getJavaType() + "Encoded extends DescribedEncoded<" + getValueMapping() + "> implements " + beanMapping.getJavaType() + "{"); writer.newLine(); - // Write constructor: + // Write out fields: writer.newLine(); - writer.write(tab(2) + encodingName + "(byte formatCode) {"); + writer.write(tab(2) + "private " + describedType + " fields;"); writer.newLine(); - writer.write(tab(3) + "this.FORMAT_CODE = formatCode;"); + writeFields(writer, 2); writer.newLine(); - writer.write(tab(3) + "this.CATEGORY = FormatSubCategory.getCategory(formatCode);"); + + writer.newLine(); + writer.write(tab(2) + "public " + getJavaType() + "Encoded(DescribedBuffer buffer) {"); + writer.newLine(); + writer.write(tab(3) + "super(buffer);"); writer.newLine(); writer.write(tab(2) + "}"); writer.newLine(); writer.newLine(); - writer.write(tab(2) + "public final int getEncodedSize(" + TypeRegistry.getJavaType(name) + " val) throws IOException {"); + writer.write(tab(2) + "public " + getJavaType() + "Encoded(" + getJavaType() + " value) {"); writer.newLine(); - writer.write(tab(3) + "if(CATEGORY.WIDTH > 0) {"); + writer.write(tab(3) + "super(value);"); writer.newLine(); - writer.write(tab(4) + "return 1 + CATEGORY.WIDTH + AmqpMarshaller.getEncodedSizeOf" + capFirst(toJavaName(name)) + "(val, this);"); + writer.write(tab(3) + "fields = new " + describedType + "();"); writer.newLine(); - writer.write(tab(3) + "}"); + writer.write(tab(2) + "}"); + writer.newLine(); + writer.newLine(); + writer.write(tab(2) + "protected final int getDescriptorSize() {"); writer.newLine(); - writer.write(tab(3) + "return 1;"); + writer.write(tab(3) + "return DESCRIPTOR.length;"); writer.newLine(); writer.write(tab(2) + "}"); writer.newLine(); writer.newLine(); - writer.write(tab(2) + "public final int getEncodedCount(" + TypeRegistry.getJavaType(name) + " val) throws IOException {"); + writer.write(tab(2) + "protected final void marshalDescriptor(DataOutput out) throws IOException {"); writer.newLine(); - if (hasCompoundEncoding() || hasArrayEncoding()) { - writer.write(tab(3) + "return AmqpMarshaller.getEncodedCounfOf" + capFirst(toJavaName(name)) + "(val, this);"); - } else { - writer.write(tab(3) + "return 1;"); - } + writer.write(tab(3) + "out.write(DESCRIPTOR);"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(2) + "protected final void encodeDescriptor(Buffer target, int offset) throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(3) + "System.arraycopy(DESCRIPTOR, 0, target.data, target.offset + offset, DESCRIPTOR.length);"); writer.newLine(); writer.write(tab(2) + "}"); writer.newLine(); writer.newLine(); + writer.write(tab(2) + "protected final String getSymbolicId() {"); + writer.newLine(); + writer.write(tab(3) + "return SYMBOLIC_ID;"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); - writer.write(tab(2) + "public static " + encodingName + " getEncoding(byte formatCode) throws UnsupportedEncodingException {"); writer.newLine(); - writer.write(tab(3) + "for(" + encodingName + " e: " + encodingName + ".values()) {"); + writer.write(tab(2) + "protected final long getNumericId() {"); writer.newLine(); - writer.write(tab(4) + "if(e.FORMAT_CODE == formatCode) {"); + writer.write(tab(3) + "return NUMERIC_ID;"); writer.newLine(); - writer.write(tab(5) + "return e;"); + writer.write(tab(2) + "}"); + writer.newLine(); + + // Write out the field accessors: writer.newLine(); - writer.write(tab(4) + "}"); + writeFieldAccesors(writer, 2, false); writer.newLine(); - writer.write(tab(3) + "}"); + + writer.newLine(); + writer.write(tab(2) + "protected final void encodeDescribed(" + getValueMapping().getJavaType() + " value, Buffer encoded, int offset) throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(3) + "Buffer buffer = fields.getEncoded(AmqpMarshaller.SINGLETON).getBuffer();"); + writer.newLine(); + writer.write(tab(3) + "System.arraycopy(buffer, buffer.offset, encoded, encoded.offset + offset, buffer.length);"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + writer.newLine(); - writer.write(tab(3) + "throw new UnsupportedEncodingException(\"Unexpected format code for " + capFirst(name) + ": \" + formatCode);"); + writer.write(tab(2) + "protected final " + getValueMapping().getJavaType() + " decodeDescribed(EncodedBuffer encoded) throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(3) + describedType + "Encoded encodedType = " + descriptor.resolveDescribedType().getMarshaller() + ".createEncoded(encoded);"); + writer.newLine(); + writer.write(tab(3) + "encodedType.setDecoder(DECODER);"); + writer.newLine(); + writer.write(tab(3) + "fields = new " + describedType + "((Encoded<" + descriptor.resolveDescribedType().getValueMapping() + ">)encodedType);"); + writer.newLine(); + writer.write(tab(3) + "return this;"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(2) + "protected final void marshalDescribed(DataOutput out) throws IOException {"); + writer.newLine(); + writer.write(tab(3) + "fields.marshal(out, AmqpMarshaller.SINGLETON);"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(2) + "protected final " + getValueMapping().getJavaType() + " unmarshalDescribed(DataInput in) throws IOException {"); + writer.newLine(); + writer.write(tab(3) + "//TODO should actually be attempting to directly unmarshal the data here, without copying to intermediate buffer:"); + writer.newLine(); + writer.write(tab(3) + "decodeDescribed(FormatCategory.createBuffer(in.readByte(), in));"); + writer.newLine(); + writer.write(tab(3) + "return this;"); writer.newLine(); writer.write(tab(2) + "}"); writer.newLine(); writer.write(tab(1) + "}"); writer.newLine(); + + return; } - } - private boolean writeFields(BufferedWriter writer) throws IOException, UnknownTypeException { - boolean ret = false; + if (!hasMultipleEncodings() && !hasNonFixedEncoding()) { + writer.newLine(); + writer.write(tab(1) + "public static final byte FORMAT_CODE = (byte) " + encodings.getFirst().getCode() + ";"); + writer.newLine(); + writer.write(tab(1) + "public static final FormatSubCategory FORMAT_CATEGORY = FormatSubCategory.getCategory(FORMAT_CODE);"); + writer.newLine(); + // writer.write(tab(1) + "public static final " + getJavaType() + + // "Encoded ENCODING = new " + getJavaType() + "Encoded();"); + // writer.newLine(); - if (descriptor != null) { - ret = true; - String encodingType = TypeRegistry.resolveAmqpClass(descriptor.getDescribedType()).getJavaType(); writer.newLine(); - writer.write(tab(1) + "private " + encodingType + " value;"); + writer.write(tab(1) + "public static class " + getJavaType() + "Encoded extends AbstractEncoded<" + getValueMapping().getJavaType() + "> implements " + beanMapping + "{"); writer.newLine(); - } - for (AmqpField field : fields.values()) { - ret = true; - if (field.getDoc() != null) { - // TODO + writer.newLine(); + writer.write(tab(2) + "public " + getJavaType() + "Encoded (EncodedBuffer encoded) {"); + writer.newLine(); + writer.write(tab(3) + "super(encoded);"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(2) + "public " + getJavaType() + "Encoded (" + getValueMapping().getJavaType() + " value) throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(3) + "super(FORMAT_CODE, value);"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(2) + "public final void encode(" + getValueMapping().getJavaType() + " value, Buffer encoded, int offset) throws AmqpEncodingError{"); + writer.newLine(); + if (hasNonZeroEncoding()) { + writer.write(tab(3) + "ENCODER.encode" + capFirst(toJavaName(name)) + "(value, encoded, offset);"); } + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); - AmqpClass amqpType = field.resolveAmqpFieldType(); + writer.newLine(); + writer.write(tab(2) + "public final " + getValueMapping().getJavaType() + " decode(EncodedBuffer encoded) throws AmqpEncodingError{"); + writer.newLine(); + if (hasNonZeroEncoding()) { + writer.write(tab(3) + "return ENCODER.decode" + capFirst(toJavaName(name)) + "(encoded.getBuffer(), encoded.getDataOffset());"); + } else { + writer.write(tab(3) + "return ENCODER.valueOf" + capFirst(toJavaName(name)) + "();"); + } + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); - writer.write(tab(1) + "private " + amqpType.getJavaType() + " " + field.getJavaName()); + writer.newLine(); + writer.write(tab(2) + "public final void marshalData(DataOutput out) throws IOException {"); + writer.newLine(); + if (hasNonZeroEncoding()) { + writer.write(tab(3) + "ENCODER.write" + capFirst(toJavaName(name)) + "(value, out);"); + } + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); - if (field.getDefaultValue() != null) { - writer.write(" = " + field.getDefaultValue()); + writer.newLine(); + writer.write(tab(2) + "public final " + getValueMapping().getJavaType() + " unmarshalData(DataInput in) throws IOException {"); + writer.newLine(); + if (hasNonZeroEncoding()) { + writer.write(tab(3) + "return ENCODER.read" + capFirst(toJavaName(name)) + "(in);"); + } else { + writer.write(tab(3) + "return ENCODER.valueOf" + capFirst(toJavaName(name)) + "();"); } + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.write(tab(1) + "}"); + } else { + String encodingName = getEncodingName(false); - writer.write(";"); writer.newLine(); - } + for (AmqpEncoding encoding : encodings) { + writer.write(tab(1) + "public static final byte " + toJavaConstant(encoding.getName()) + "_FORMAT_CODE = (byte) " + encoding.getCode() + ";"); + writer.newLine(); + } - if (isPrimitive()) { + // Create an enum that captures the allowed encodings: + writer.newLine(); + writer.write(tab(1) + "public static enum " + encodingName + " implements Encoding{"); + writer.newLine(); + + int i = 0; + for (AmqpEncoding encoding : encodings) { + i++; + String eName = encoding.getName(); + if (eName == null) { + eName = name; + } + eName = toJavaConstant(eName); + + writer.write(tab(2) + eName + " (" + toJavaConstant(encoding.getName()) + "_FORMAT_CODE)"); + if (i < encodings.size()) { + writer.write(","); + } else { + writer.write(";"); + } + + if (encoding.getLabel() != null) { + writer.write(" // " + encoding.getLabel()); + } + + writer.newLine(); + } + + writer.newLine(); + writer.write(tab(2) + "public final byte FORMAT_CODE;"); + writer.newLine(); + writer.write(tab(2) + "public final FormatSubCategory CATEGORY;"); + writer.newLine(); + + // Write constructor: + writer.newLine(); + writer.write(tab(2) + encodingName + "(byte formatCode) {"); + writer.newLine(); + writer.write(tab(3) + "this.FORMAT_CODE = formatCode;"); + writer.newLine(); + writer.write(tab(3) + "this.CATEGORY = FormatSubCategory.getCategory(formatCode);"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(2) + "public final byte getEncodingFormatCode() {"); + writer.newLine(); + writer.write(tab(3) + "return FORMAT_CODE;"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(2) + "public final AmqpVersion getEncodingVersion() {"); + writer.newLine(); + writer.write(tab(3) + "return AmqpMarshaller.VERSION;"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(2) + "public static " + encodingName + " getEncoding(byte formatCode) throws UnexpectedTypeException {"); + writer.newLine(); + writer.write(tab(3) + "switch(formatCode) {"); + writer.newLine(); + for (AmqpEncoding encoding : encodings) { + writer.write(tab(3) + "case " + toJavaConstant(encoding.getName()) + "_FORMAT_CODE: {"); + writer.newLine(); + writer.write(tab(4) + "return " + toJavaConstant(encoding.getName()) + ";"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + } + writer.write(tab(3) + "default: {"); + writer.newLine(); + writer.write(tab(4) + "throw new UnexpectedTypeException(\"Unexpected format code for " + capFirst(name) + ": \" + formatCode);"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(2) + "static final " + getJavaType() + "Encoded createEncoded(EncodedBuffer buffer) throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(3) + "switch(buffer.getEncodingFormatCode()) {"); + writer.newLine(); + for (AmqpEncoding encoding : encodings) { + writer.write(tab(3) + "case " + toJavaConstant(encoding.getName()) + "_FORMAT_CODE: {"); + writer.newLine(); + writer.write(tab(4) + "return new " + getJavaType() + capFirst(toJavaName(encoding.getName())) + "Encoded(buffer);"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + } + writer.write(tab(3) + "default: {"); writer.newLine(); - writer.write(tab(1) + "private " + TypeRegistry.getJavaType(name) + " value;"); + writer.write(tab(4) + "throw new UnexpectedTypeException(\"Unexpected format code for " + capFirst(name) + ": \" + buffer.getEncodingFormatCode());"); writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.write(tab(2) + "static final " + getJavaType() + "Encoded createEncoded(byte formatCode, " + getValueMapping().getJavaType() + " value) throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(3) + "switch(formatCode) {"); + writer.newLine(); + for (AmqpEncoding encoding : encodings) { + writer.write(tab(3) + "case " + toJavaConstant(encoding.getName()) + "_FORMAT_CODE: {"); + writer.newLine(); + writer.write(tab(4) + "return new " + getJavaType() + capFirst(toJavaName(encoding.getName())) + "Encoded(value);"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + } + writer.write(tab(3) + "default: {"); + writer.newLine(); + writer.write(tab(4) + "throw new UnexpectedTypeException(\"Unexpected format code for " + capFirst(name) + ": \" + formatCode);"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + writer.write(tab(3) + "}"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + + writer.write(tab(1) + "}"); + writer.newLine(); + + String decoderArg = ""; + writer.write(tab(1) + "public static abstract class " + getJavaType() + "Encoded extends AbstractEncoded <" + getValueMapping().getJavaType() + "> implements " + beanMapping + " {"); + if (isList()) { + writer.newLine(); + writer.write(tab(2) + "ListDecoder decoder = Encoder.DEFAULT_LIST_DECODER;"); + writer.newLine(); + decoderArg = ", decoder"; + } + + if (isMap()) { + writer.newLine(); + writer.write(tab(2) + "MapDecoder decoder = Encoder.DEFAULT_MAP_DECODER;"); + writer.newLine(); + decoderArg = ", decoder"; + } + + writer.newLine(); + writer.write(tab(2) + "public " + getJavaType() + "Encoded(EncodedBuffer encoded) {"); + writer.newLine(); + writer.write(tab(3) + "super(encoded);"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(2) + "public " + getJavaType() + "Encoded(byte formatCode, " + getValueMapping().getJavaType() + " value) throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(3) + "super(formatCode, value);"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + if (isList()) { + writer.newLine(); + writer.write(tab(2) + "final void setDecoder(ListDecoder decoder) {"); + writer.newLine(); + writer.write(tab(3) + "this.decoder = decoder;"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + } - // If there are multiple possible encodings store the current - // encoding: - if (encodings != null && encodings.size() > 1) { + if (isMap()) { + writer.newLine(); + writer.write(tab(2) + "final void setDecoder(MapDecoder decoder) {"); + writer.newLine(); + writer.write(tab(3) + "this.decoder = decoder;"); + writer.newLine(); + writer.write(tab(2) + "}"); writer.newLine(); - writer.write(tab(1) + "private " + getEncodingName(true) + " encoding;"); + } + + if (isMap() || isList()) { + writeFieldAccesors(writer, 2, true); + } + + writer.write(tab(1) + "}"); + writer.newLine(); + + for (AmqpEncoding encoding : encodings) { + String eName = capFirst(toJavaName(encoding.getName())); + + writer.newLine(); + writeJavaComment(writer, 1, encoding.getLabel()); + writer.write(tab(1) + "private static class " + getJavaType() + eName + "Encoded extends " + getJavaType() + "Encoded {"); + writer.newLine(); + writer.newLine(); + writer.write(tab(2) + "private final " + encodingName + " encoding = " + encodingName + "." + toJavaConstant(encoding.getName()) + ";"); + + writer.newLine(); + writer.write(tab(2) + "public " + getJavaType() + eName + "Encoded(EncodedBuffer encoded) {"); + writer.newLine(); + writer.write(tab(3) + "super(encoded);"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(2) + "public " + getJavaType() + eName + "Encoded(" + getValueMapping().getJavaType() + " value) throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(3) + "super(" + encodingName + "." + toJavaConstant(encoding.getName()) + ".FORMAT_CODE, value);"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + if (hasNonZeroEncoding()) { + writer.newLine(); + writer.write(tab(2) + "protected final int computeDataSize() throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(3) + "return ENCODER.getEncodedSizeOf" + capFirst(getName() + "(value, encoding);")); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + } + + if (hasCompoundEncoding()) { + writer.newLine(); + writer.write(tab(2) + "protected final int computeDataCount() throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(3) + "return ENCODER.getEncodedCountOf" + capFirst(getName()) + "(value, encoding);"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + } + + writer.newLine(); + writer.write(tab(2) + "public final void encode(" + getValueMapping().getJavaType() + " value, Buffer encoded, int offset) throws AmqpEncodingError {"); + writer.newLine(); + if (hasNonZeroEncoding()) { + writer.write(tab(3) + "ENCODER.encode" + capFirst(toJavaName(name)) + eName + "(value, encoded, offset);"); + } + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(2) + "public final " + getValueMapping().getJavaType() + " decode(EncodedBuffer encoded) throws AmqpEncodingError {"); + writer.newLine(); + if (hasCompoundEncoding()) { + writer.write(tab(3) + "return ENCODER.decode" + capFirst(toJavaName(name)) + eName + "(encoded.getBuffer(), encoded.getDataOffset(), encoded.getDataCount(), encoded.getDataSize()" + + decoderArg + ");"); + } else if (hasNonZeroEncoding()) { + writer.write(tab(3) + "return ENCODER.decode" + capFirst(toJavaName(name)) + eName + "(encoded.getBuffer(), encoded.getDataOffset(), encoded.getDataSize()" + decoderArg + ");"); + } else { + writer.write(tab(3) + "return ENCODER.valueOf" + capFirst(toJavaName(name)) + "(encoding);"); + } + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(2) + "public final void marshalData(DataOutput out) throws IOException {"); + writer.newLine(); + if (hasNonZeroEncoding()) { + writer.write(tab(3) + "ENCODER.write" + capFirst(toJavaName(name)) + eName + "(value, out);"); + } + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(2) + "public final " + getValueMapping().getJavaType() + " unmarshalData(DataInput in) throws IOException {"); + writer.newLine(); + + if (hasCompoundEncoding()) { + writer.write(tab(3) + "return ENCODER.read" + capFirst(toJavaName(name)) + eName + "(getDataCount(), getDataSize(), in" + decoderArg + ");"); + } else if (hasNonZeroEncoding()) { + writer.write(tab(3) + "return ENCODER.read" + capFirst(toJavaName(name)) + eName + "(getDataSize(), in" + decoderArg + ");"); + } else { + writer.write(tab(3) + "return ENCODER.valueOf" + capFirst(toJavaName(name)) + "(encoding" + decoderArg + ");"); + } + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + + writer.write(tab(1) + "}"); + writer.newLine(); + } + } + } + + private boolean writeFields(BufferedWriter writer, int indent) throws IOException, UnknownTypeException { + boolean ret = false; + + for (AmqpField field : fields.values()) { + ret = true; + JavaTypeMapping valueType = field.resolveAmqpFieldType().getValueMapping(); + + writer.write(tab(indent) + "private " + valueType.getJavaType() + " " + field.getJavaName()); + + if (field.getDefaultValue() != null) { + writer.write(" = " + field.getDefaultValue()); + } + + writer.write(";"); + writer.newLine(); + } + + if (isPrimitive()) { + writer.write(tab(indent) + "private " + getValueMapping().getJavaType() + " value;"); + writer.newLine(); + } + return ret; + } + + private void writeBeanImpl(BufferedWriter writer, int indent) throws IOException, UnknownTypeException { + + if (isPrimitive() || isDescribed()) { + + writer.newLine(); + writer.write(tab(indent) + "private " + beanMapping + " bean = this;"); + writer.newLine(); + writeFields(writer, indent); + + // CONSTRUCTORS: + writer.newLine(); + writer.write(tab(indent) + "public " + typeMapping + "() {"); + writer.newLine(); + writer.write(tab(indent) + "}"); + writer.newLine(); + + if (isPrimitive()) { + + writer.newLine(); + writer.write(tab(indent) + "public " + typeMapping + "(" + getValueMapping() + " value) {"); + writer.newLine(); + writer.write(tab(++indent) + "this.value = value;"); + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + } + + writer.newLine(); + writer.write(tab(indent) + "public " + typeMapping + "(Encoded<" + getValueMapping() + "> encoded) {"); + writer.newLine(); + if (isPrimitive()) { + writer.write(tab(++indent) + "this.value = encoded.getValue();"); + } else { + writer.write(tab(++indent) + "this.bean = encoded.getValue();"); + } + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(indent) + "public " + typeMapping + "(" + beanMapping + " other) {"); + writer.newLine(); + writer.write(tab(++indent) + "this.bean = other;"); + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + + // METHODS: + if (isCommand()) { + writer.newLine(); + writer.write(tab(indent) + "public final void handle(AmqpCommandHandler handler) throws Exception {"); + writer.newLine(); + writer.write(tab(++indent) + "handler.handle" + capFirst(toJavaName(name)) + "(this);"); + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + } + + writer.newLine(); + writer.write(tab(indent) + "protected final Encoded<" + getValueMapping() + "> encode(AmqpMarshaller marshaller) throws AmqpEncodingError{"); + writer.newLine(); + writer.write(tab(++indent) + "return marshaller.encode(this);"); + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + + writeFieldAccesors(writer, indent, false); + } else if (isRestricted()) { + AmqpClass restrictedType = resolveRestrictedType(); + + // CONSTRUCTORS: + writer.newLine(); + writer.write(tab(indent) + "public " + typeMapping + "() {"); + writer.newLine(); + writer.write(tab(indent + 1) + "super();"); + writer.newLine(); + writer.write(tab(indent) + "}"); + writer.newLine(); + + if (restrictedType.isPrimitive()) { + + writer.newLine(); + writer.write(tab(indent) + "public " + typeMapping + "(" + restrictedType.getValueMapping() + " value) {"); + writer.newLine(); + writer.write(tab(++indent) + "super(value);"); + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + } + + writer.newLine(); + writer.write(tab(indent) + "public " + typeMapping + "(Encoded<" + restrictedType.getValueMapping() + "> encoded) {"); + writer.newLine(); + writer.write(tab(++indent) + "super(encoded);"); + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(indent) + "public " + typeMapping + "(" + restrictedType.getBeanMapping() + " other) {"); + writer.newLine(); + writer.write(tab(++indent) + "super(other);"); + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + } + + } + + private boolean writeFieldAccesors(BufferedWriter writer, int indent, boolean encoder) throws IOException, UnknownTypeException { + boolean ret = false; + + for (AmqpField field : fields.values()) { + ret = true; + + JavaTypeMapping valueType = field.resolveAmqpFieldType().getValueMapping(); + // Setter: + writer.newLine(); + field.writeJavaDoc(writer, indent); + writer.write(tab(indent) + "public final void set" + capFirst(field.getJavaName()) + "(" + valueType + " " + toJavaName(field.getName()) + ") {"); + writer.newLine(); + writer.write(tab(++indent) + "this." + field.getJavaName() + " = " + toJavaName(field.getName()) + ";"); + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + writer.newLine(); + // Getter: + field.writeJavaDoc(writer, indent); + writer.write(tab(indent) + "public final " + valueType + " get" + capFirst(field.getJavaName()) + "() {"); + writer.newLine(); + writer.write(tab(++indent) + "return " + field.getJavaName() + ";"); + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + } + + if (isMap()) { + writer.write(tab(indent) + "public void put(AmqpType key, AmqpType value) {"); + writer.newLine(); + writer.write(tab(++indent) + "this.value.put(key, value);"); + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(indent) + "public AmqpType get(AmqpType key) {"); + writer.newLine(); + writer.write(tab(++indent) + "return value.get(key);"); + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + + } else if (isList()) { + writer.write(tab(indent) + "public void set(int index, AmqpType value) {"); + writer.newLine(); + writer.write(tab(++indent) + "this.value.add(index, value);"); + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(indent) + "public AmqpType get(int index) {"); + writer.newLine(); + writer.write(tab(++indent) + "return value.get(index);"); + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + } + + if (!encoder && isPrimitive()) { + + // Getter: + writer.write(tab(indent) + "public final " + valueMapping + " getValue() {"); + writer.newLine(); + writer.write(tab(++indent) + "return value;"); + writer.newLine(); + writer.write(tab(--indent) + "}"); + writer.newLine(); + } + return ret; + } + + private void generateBeanInterface(Generator generator) throws IOException, UnknownTypeException { + + if (!needsMarshaller()) { + return; + } + + String packageName = beanMapping.getPackageName(); + + File file = new File(generator.getOutputDirectory() + File.separator + new String(packageName).replace(".", File.separator) + File.separator + beanMapping + ".java"); + file.getParentFile().mkdirs(); + if (file.exists()) { + file.delete(); + } + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + + writeJavaCopyWrite(writer); + writer.write("package " + packageName + ";\n"); + writer.newLine(); + + writeImports(writer, generator, true); + + writer.write("public interface " + beanMapping); + // if (isDescribed()) { + // writer.write(" extends " + + // descriptor.resolveDescribedType().getBeanMapping()); + // } + writer.write(" {"); + writer.newLine(); + + if (isDescribed()) { + writer.newLine(); + for (AmqpField field : fields.values()) { + + JavaTypeMapping valueType = field.resolveAmqpFieldType().getValueMapping(); + // Setter: + writer.newLine(); + field.writeJavaDoc(writer, 1); + writer.write(tab(1) + "public void set" + capFirst(field.getJavaName()) + "(" + valueType + " " + toJavaName(field.getName()) + ");"); + writer.newLine(); + + // Getter: + writer.newLine(); + field.writeJavaDoc(writer, 1); + writer.write(tab(1) + "public " + valueType + " get" + capFirst(field.getJavaName()) + "();"); + writer.newLine(); + } + } + + int indent = 1; + if (isMap()) { + writer.write(tab(indent) + "public void put(AmqpType key, AmqpType value);"); + writer.newLine(); + writer.newLine(); + writer.write(tab(indent) + "public AmqpType get(AmqpType key);"); + writer.newLine(); + + } else if (isList()) { + writer.write(tab(indent) + "public void set(int index, AmqpType value);"); + writer.newLine(); + writer.newLine(); + writer.write(tab(indent) + "public AmqpType get(int index);"); + writer.newLine(); + } + + if (isPrimitive()) { + // Getter: + writer.newLine(); + writer.write(tab(1) + "public " + valueMapping + " getValue();"); + writer.newLine(); + } + + writer.newLine(); + writer.write("}"); + + writer.flush(); + writer.close(); + + } + + private void generateMarshaller(Generator generator) throws IOException, UnknownTypeException { + if (!(isPrimitive() || descriptor != null)) { + return; + } + + String packageName = generator.getMarshallerPackage(); + + File file = new File(generator.getOutputDirectory() + File.separator + new String(packageName).replace(".", File.separator) + File.separator + typeMapping + "Marshaller.java"); + file.getParentFile().mkdirs(); + if (file.exists()) { + file.delete(); + } + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + + writeJavaCopyWrite(writer); + writer.write("package " + packageName + ";\n"); + writer.newLine(); + if (writeImports(writer, generator, true)) { + writer.newLine(); + } + + // Write out the descriptor (for compound types): + if (descriptor != null) { + writer.write("public class " + typeMapping.getShortName() + "Marshaller implements DescribedTypeMarshaller<" + typeMapping + ">{"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(1) + "static final " + typeMapping + "Marshaller SINGLETON = new " + typeMapping + "Marshaller();"); + writer.newLine(); + writer.write(tab(1) + "private static final Encoder ENCODER = Encoder.SINGLETON;"); + writer.newLine(); + + writer.newLine(); + writer.write(tab(1) + "public static final String SYMBOLIC_ID = \"" + descriptor.getSymbolicName() + "\";"); + writer.newLine(); + writer.write(tab(1) + "//Format code: " + descriptor.getFormatCode() + ":"); + writer.newLine(); + writer.write(tab(1) + "public static final long CATEGORY = " + descriptor.getCategory() + ";"); + writer.newLine(); + writer.write(tab(1) + "public static final long DESCRIPTOR_ID = " + descriptor.getDescriptorId() + ";"); + writer.newLine(); + writer.write(tab(1) + "public static final long NUMERIC_ID = CATEGORY << 32 | DESCRIPTOR_ID; //(" + (descriptor.getCategory() << 32 | descriptor.getDescriptorId()) + "L)"); + writer.newLine(); + writer.write(tab(1) + "//Hard coded descriptor:"); + writer.newLine(); + writer.write(tab(1) + "public static final byte [] DESCRIPTOR = new byte [] {"); + writer.newLine(); + // TODO retrieve ulong encoding from the ulong itself: + writer.write(tab(2) + "(byte) 0x80, // ulong descriptor encoding)"); + writer.newLine(); + // Add the category code: + writer.write(tab(2)); + String categoryHex = padHex(descriptor.getFormatCode().substring(2, descriptor.getFormatCode().indexOf(":")), 8); + for (int i = 0; i < 8; i += 2) { + writer.write("(byte) 0x" + categoryHex.substring(i, i + 2) + ", "); + } + writer.write(" // CATEGORY CODE"); + writer.newLine(); + writer.write(tab(2)); + // Add the descriptor id code: + String descriptorIdHex = padHex(descriptor.getFormatCode().substring(descriptor.getFormatCode().indexOf(":") + 3), 8); + + for (int i = 0; i < 8; i += 2) { + writer.write("(byte) 0x" + descriptorIdHex.substring(i, i + 2)); + if (i < 6) { + writer.write(", "); + } + } + writer.write(" // DESCRIPTOR ID CODE"); + writer.newLine(); + writer.write(tab(1) + "};"); + writer.newLine(); + + String describedType = descriptor.getDescribedType(); + String typeMarshaller = null; + String typeDataStructure = null; + + if (describedType.equals("map")) { + writer.newLine(); + writer.write(tab(1) + "//Accessor keys for field mapped fields:"); + writer.newLine(); + for (AmqpField field : fields.values()) { + + writer.write(tab(1) + "private static final AmqpSymbol " + toJavaConstant(field.getName()) + "_KEY = " + " new AmqpSymbol(\"" + field.getName() + "\");"); + writer.newLine(); + } writer.newLine(); + + typeMarshaller = "AmqpMapMarshaller"; + typeDataStructure = "AmqpMap"; + } else if (describedType.equals("list")) { + typeMarshaller = "AmqpListMarshaller"; + typeDataStructure = "AmqpList"; + } else { + throw new UnknownTypeException("Support for " + descriptor.getDescribedType() + " as a described type isn't yet implemented"); } - } - return ret; - } - private boolean writeConstructors(BufferedWriter writer) throws IOException, UnknownTypeException { - boolean ret = false; + writeEncodings(writer); - if (isPrimitive()) { writer.newLine(); - writer.write(tab(1) + "public " + typeMapping.getShortName() + "() {"); + writer.write(tab(1) + "public static final Encoded<" + beanMapping + "> encode(" + typeMapping + " value) throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(2) + "return new " + typeMapping.getJavaType() + "Encoded(value);"); writer.newLine(); writer.write(tab(1) + "}"); writer.newLine(); writer.newLine(); - writer.write(tab(1) + "public " + typeMapping.getShortName() + "(" + valueMapping.getJavaType() + " value) {"); + writer.write(tab(1) + "public static final T decodeType(T value, EncodedBuffer buffer) throws AmqpEncodingError {"); writer.newLine(); - writer.write(tab(2) + "this.value = value;"); + writer.write(tab(2) + "byte fc = buffer.getEncodingFormatCode();"); writer.newLine(); - writer.write(tab(1) + "}"); + writer.write(tab(2) + "if (fc == Encoder.NULL_FORMAT_CODE) {"); writer.newLine(); - } - - return ret; - } - - private boolean writeFieldAccesors(BufferedWriter writer) throws IOException, UnknownTypeException { - boolean ret = false; - - for (AmqpField field : fields.values()) { - ret = true; - if (field.getDoc() != null) { - // TODO - } - - AmqpClass amqpType = field.resolveAmqpFieldType(); - - // Setter: + writer.write(tab(3) + "return null;"); writer.newLine(); - field.writeJavaDoc(writer, 1); - writer.write(tab(1) + "public final void set" + capFirst(field.getJavaName()) + "(" + amqpType.resolveValueType() + " " + toJavaName(field.getName()) + ") {"); + writer.write(tab(2) + "}"); writer.newLine(); - if (amqpType.isPrimitive() && !amqpType.getName().equals("*")) { - writer.write(tab(2) + "this." + field.getJavaName() + ".setValue(" + toJavaName(field.getName()) + ");"); - } else { - writer.write(tab(2) + "this." + field.getJavaName() + " = " + toJavaName(field.getName()) + ";"); - } writer.newLine(); - writer.write(tab(1) + "}"); + writer.write(tab(2) + "DescribedBuffer db = buffer.asDescribed();"); writer.newLine(); + writer.write(tab(2) + "AmqpType descriptor = AmqpMarshaller.SINGLETON.decodeType(db.getDescriptor());"); writer.newLine(); - // Getter: - field.writeJavaDoc(writer, 1); - writer.write(tab(1) + "public final " + amqpType.resolveValueType() + " get" + capFirst(field.getJavaName()) + "() {"); + writer.write(tab(2) + "if(!(descriptor instanceof AmqpLong && ((AmqpLong)descriptor).getValue().longValue() == NUMERIC_ID ||"); writer.newLine(); - if (amqpType.isPrimitive() && !amqpType.getName().equals("*")) { - writer.write(tab(2) + "return " + field.getJavaName() + ".getValue();"); - } else { - writer.write(tab(2) + "return " + field.getJavaName() + ";"); - } + writer.write(tab(3) + " descriptor instanceof AmqpSymbol && ((AmqpSymbol)descriptor).getValue().equals(SYMBOLIC_ID))) {"); + writer.newLine(); + writer.write(tab(3) + "throw new UnexpectedTypeException(\"descriptor mismatch: \" + descriptor);"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + writer.write(tab(2) + "value.setEncoded(new " + getJavaType() + "Encoded(db));"); + writer.newLine(); + writer.write(tab(2) + "return value;"); writer.newLine(); writer.write(tab(1) + "}"); writer.newLine(); - } - - if (isPrimitive()) { - String valueType = TypeRegistry.getJavaType(name); writer.newLine(); - writer.write(tab(1) + "public final void setValue(" + valueType + " value) {"); + writer.write(tab(1) + "public static final T unmarshalType(T value, DataInput in) throws IOException {"); writer.newLine(); - writer.write(tab(2) + "this.value = value;"); - if (hasMultipleEncodings()) { - writer.newLine(); - writer.write(tab(2) + "this.encoding = null;"); - writer.newLine(); - writer.write(tab(2) + "encodedSize = -1;"); - writer.newLine(); - writer.write(tab(2) + "encodedCount = -1;"); - } + writer.write(tab(2) + "byte fc = in.readByte();"); writer.newLine(); - writer.write(tab(1) + "}"); + writer.write(tab(2) + "if (fc == Encoder.NULL_FORMAT_CODE) {"); writer.newLine(); + writer.write(tab(3) + "return null;"); writer.newLine(); - // Getter: - writer.write(tab(1) + "public final " + valueType + " getValue() {"); + writer.write(tab(2) + "}"); + writer.newLine(); + writer.newLine(); + writer.write(tab(2) + "if (fc != Encoder.DESCRIBED_FORMAT_CODE) {"); + writer.newLine(); + writer.write(tab(3) + "throw new UnexpectedTypeException(\"unexpected format code: \" + fc);"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + writer.newLine(); + writer.write(tab(2) + "DescribedBuffer db = new DescribedBuffer(fc, in);"); + writer.newLine(); + writer.write(tab(2) + "AmqpType descriptor = AmqpMarshaller.SINGLETON.decodeType(db.getDescriptor());"); + writer.newLine(); + writer.write(tab(2) + "if(!(descriptor instanceof AmqpLong && ((AmqpLong)descriptor).getValue().longValue() == NUMERIC_ID ||"); + writer.newLine(); + writer.write(tab(3) + " descriptor instanceof AmqpSymbol && ((AmqpSymbol)descriptor).getValue().equals(SYMBOLIC_ID))) {"); + writer.newLine(); + writer.write(tab(3) + "throw new UnexpectedTypeException(\"descriptor mismatch: \" + descriptor);"); + writer.newLine(); + writer.write(tab(2) + "}"); + writer.newLine(); + writer.write(tab(2) + "value.setEncoded(new " + getJavaType() + "Encoded(db));"); writer.newLine(); writer.write(tab(2) + "return value;"); writer.newLine(); writer.write(tab(1) + "}"); writer.newLine(); - } - return ret; - } - private boolean writeSerializers(BufferedWriter writer) throws IOException, UnknownTypeException { - boolean ret = false; + writer.newLine(); + writer.write(tab(1) + "public final " + typeMapping + " decodeDescribedType(AmqpType descriptor, DescribedBuffer encoded) throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(2) + getJavaType() + " rc = new " + getJavaType() + "();"); + writer.newLine(); + writer.write(tab(2) + "rc.setEncoded(new " + getJavaType() + "Encoded(encoded));"); + writer.newLine(); + writer.write(tab(2) + "return rc;"); + writer.newLine(); + writer.write(tab(1) + "}"); + writer.newLine(); - if (!(isPrimitive() || descriptor != null)) { - return false; } - ret = true; - - writer.newLine(); - writer.write(tab(1) + "public static final " + typeMapping.javaType + " createFromStream(DataInput dis) throws IOException {"); - writer.newLine(); - writer.write(tab(2) + typeMapping.javaType + " rc = new " + typeMapping.javaType + "();"); - writer.newLine(); - writer.write(tab(2) + "rc.unmarshal(dis);"); - writer.newLine(); - writer.write(tab(2) + "return rc;"); - writer.newLine(); - writer.write(tab(1) + "}"); - writer.newLine(); + // Add accessors for primitive encoded sizes: + if (isPrimitive()) { - writer.newLine(); - writer.write(tab(1) + "public final void marshal(DataOutput dos) throws IOException {"); - writer.newLine(); - writer.write(tab(2) + "marshalConstructor(dos);"); - writer.newLine(); - writer.write(tab(2) + "marshalData(dos);"); - writer.newLine(); - writer.write(tab(1) + "}"); - writer.newLine(); + writer.write("public class " + typeMapping.getShortName() + "Marshaller {"); + writer.newLine(); - writer.newLine(); - writer.write(tab(1) + "public final void unmarshal(DataInput dis) throws IOException {"); - writer.newLine(); - writer.write(tab(2) + "unmarshalConstructor(dis);"); - writer.newLine(); - writer.write(tab(2) + "unmarshalData(dis);"); - writer.newLine(); - writer.write(tab(1) + "}"); - writer.newLine(); + writer.newLine(); + writer.write(tab(1) + "private static final Encoder ENCODER = Encoder.SINGLETON;"); + writer.newLine(); - // Add accessors for primitive encoded sizes: - if (isPrimitive()) { + writeEncodings(writer); writer.newLine(); // Handle fixed width encodings: - if (encodings != null && encodings.size() == 1 && "fixed".equals(encodings.getFirst().getCategory())) { - AmqpEncoding encoding = encodings.getFirst(); - - writer.write(tab(1) + "public final int getEncodedSize() throws IOException{"); + if (!hasMultipleEncodings() && !hasNonFixedEncoding()) { + writer.newLine(); + writer.write(tab(1) + "public static final " + getJavaType() + "Encoded encode(" + getJavaType() + " data) throws AmqpEncodingError {"); writer.newLine(); - writer.write(tab(2) + "return " + (1 + new Integer(encoding.getWidth())) + ";"); + writer.write(tab(2) + "return new " + getJavaType() + "Encoded(data.getValue());"); writer.newLine(); writer.write(tab(1) + "}"); writer.newLine(); writer.newLine(); - writer.write(tab(1) + "public final int getEncodedCount() throws IOException{"); + writer.write(tab(1) + "static final " + getJavaType() + "Encoded createEncoded(EncodedBuffer buffer) throws AmqpEncodingError {"); + writer.newLine(); + writer.write(tab(2) + "if(buffer.getEncodingFormatCode() == AmqpNullMarshaller.FORMAT_CODE) {"); + writer.newLine(); + writer.write(tab(3) + "return null;"); writer.newLine(); - writer.write(tab(2) + "return 1;"); + writer.write(tab(2) + "}"); + writer.newLine(); + writer.write(tab(2) + "if(buffer.getEncodingFormatCode() != FORMAT_CODE) {"); + writer.newLine(); [... 443 lines stripped ...]