/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.activemq.openwire.tool; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import org.codehaus.jam.JAnnotation; import org.codehaus.jam.JAnnotationValue; import org.codehaus.jam.JClass; import org.codehaus.jam.JProperty; /** * */ public class CppMarshallingClassesGenerator extends CppMarshallingHeadersGenerator { protected String getFilePostFix() { return ".cpp"; } protected void generateUnmarshalBodyForProperty(PrintWriter out, JProperty property, JAnnotationValue size) { out.print(" "); String setter = property.getSetter().getSimpleName(); String type = property.getType().getSimpleName(); if (type.equals("boolean")) { out.println("info." + setter + "( bs.readBoolean() );"); } else if (type.equals("byte")) { out.println("info." + setter + "( DataStreamMarshaller.readByte(dataIn) );"); } else if (type.equals("char")) { out.println("info." + setter + "( DataStreamMarshaller.readChar(dataIn) );"); } else if (type.equals("short")) { out.println("info." + setter + "( DataStreamMarshaller.readShort(dataIn) );"); } else if (type.equals("int")) { out.println("info." + setter + "( DataStreamMarshaller.readInt(dataIn) );"); } else if (type.equals("long")) { out.println("info." + setter + "( UnmarshalLong(wireFormat, dataIn, bs) );"); } else if (type.equals("String")) { out.println("info." + setter + "( readString(dataIn, bs) );"); } else if (type.equals("byte[]") || type.equals("ByteSequence")) { if (size != null) { out.println("info." + setter + "( readBytes(dataIn, " + size.asInt() + ") );"); } else { out.println("info." + setter + "( readBytes(dataIn, bs.readBoolean()) );"); } } else if (isThrowable(property.getType())) { out.println("info." + setter + "( unmarshalBrokerError(wireFormat, dataIn, bs) );"); } else if (isCachedProperty(property)) { out.println("info." + setter + "( (" + type + ") unmarshalCachedObject(wireFormat, dataIn, bs) );"); } else { out.println("info." + setter + "( (" + type + ") unmarshalNestedObject(wireFormat, dataIn, bs) );"); } } protected void generateUnmarshalBodyForArrayProperty(PrintWriter out, JProperty property, JAnnotationValue size) { JClass propertyType = property.getType(); String arrayType = propertyType.getArrayComponentType().getSimpleName(); String setter = property.getGetter().getSimpleName(); out.println(); if (size != null) { out.println(" {"); out.println(" " + arrayType + "[] value = new " + arrayType + "[" + size.asInt() + "];"); out.println(" " + "for( int i=0; i < " + size.asInt() + "; i++ ) {"); out.println(" value[i] = (" + arrayType + ") unmarshalNestedObject(wireFormat,dataIn, bs);"); out.println(" }"); out.println(" info." + setter + "( value );"); out.println(" }"); } else { out.println(" if (bs.readBoolean()) {"); out.println(" short size = DataStreamMarshaller.readShort(dataIn);"); out.println(" " + arrayType + "[] value = new " + arrayType + "[size];"); out.println(" for( int i=0; i < size; i++ ) {"); out.println(" value[i] = (" + arrayType + ") unmarshalNestedObject(wireFormat,dataIn, bs);"); out.println(" }"); out.println(" info." + setter + "( value );"); out.println(" }"); out.println(" else {"); out.println(" info." + setter + "( null );"); out.println(" }"); } } protected int generateMarshal1Body(PrintWriter out) { List properties = getProperties(); int baseSize = 0; for (Iterator iter = properties.iterator(); iter.hasNext();) { JProperty property = (JProperty)iter.next(); JAnnotation annotation = property.getAnnotation("openwire:property"); JAnnotationValue size = annotation.getValue("size"); JClass propertyType = property.getType(); String type = propertyType.getSimpleName(); String getter = "info." + property.getGetter().getSimpleName() + "()"; out.print(indent); if (type.equals("boolean")) { out.println("bs.writeBoolean(" + getter + ");"); } else if (type.equals("byte")) { baseSize += 1; } else if (type.equals("char")) { baseSize += 1; } else if (type.equals("short")) { baseSize += 1; } else if (type.equals("int")) { baseSize += 1; } else if (type.equals("long")) { out.println("rc += marshal1Long(wireFormat, " + getter + ", bs);"); } else if (type.equals("String")) { out.println("rc += writeString(" + getter + ", bs);"); } else if (type.equals("byte[]") || type.equals("ByteSequence")) { if (size == null) { out.println("bs.writeBoolean(" + getter + "!=null);"); out.println(" rc += " + getter + "==null ? 0 : " + getter + ".Length+4;"); } else { baseSize += size.asInt(); } } else if (propertyType.isArrayType()) { if (size != null) { out.println("rc += marshalObjectArrayConstSize(wireFormat, " + getter + ", bs, " + size.asInt() + ");"); } else { out.println("rc += marshalObjectArray(wireFormat, " + getter + ", bs);"); } } else if (isThrowable(propertyType)) { out.println("rc += marshalBrokerError(wireFormat, " + getter + ", bs);"); } else { if (isCachedProperty(property)) { out.println("rc += marshal1CachedObject(wireFormat, " + getter + ", bs);"); } else { out.println("rc += marshal1NestedObject(wireFormat, " + getter + ", bs);"); } } } return baseSize; } protected void generateMarshal2Body(PrintWriter out) { List properties = getProperties(); for (Iterator iter = properties.iterator(); iter.hasNext();) { JProperty property = (JProperty)iter.next(); JAnnotation annotation = property.getAnnotation("openwire:property"); JAnnotationValue size = annotation.getValue("size"); JClass propertyType = property.getType(); String type = propertyType.getSimpleName(); String getter = "info." + property.getGetter().getSimpleName() + "()"; out.print(indent); if (type.equals("boolean")) { out.println("bs.readBoolean();"); } else if (type.equals("byte")) { out.println("DataStreamMarshaller.writeByte(" + getter + ", dataOut);"); } else if (type.equals("char")) { out.println("DataStreamMarshaller.writeChar(" + getter + ", dataOut);"); } else if (type.equals("short")) { out.println("DataStreamMarshaller.writeShort(" + getter + ", dataOut);"); } else if (type.equals("int")) { out.println("DataStreamMarshaller.writeInt(" + getter + ", dataOut);"); } else if (type.equals("long")) { out.println("marshal2Long(wireFormat, " + getter + ", dataOut, bs);"); } else if (type.equals("String")) { out.println("writeString(" + getter + ", dataOut, bs);"); } else if (type.equals("byte[]") || type.equals("ByteSequence")) { if (size != null) { out.println("dataOut.write(" + getter + ", 0, " + size.asInt() + ");"); } else { out.println("if(bs.readBoolean()) {"); out.println(" DataStreamMarshaller.writeInt(" + getter + ".Length, dataOut);"); out.println(" dataOut.write(" + getter + ");"); out.println(" }"); } } else if (propertyType.isArrayType()) { if (size != null) { out.println("marshalObjectArrayConstSize(wireFormat, " + getter + ", dataOut, bs, " + size.asInt() + ");"); } else { out.println("marshalObjectArray(wireFormat, " + getter + ", dataOut, bs);"); } } else if (isThrowable(propertyType)) { out.println("marshalBrokerError(wireFormat, " + getter + ", dataOut, bs);"); } else { if (isCachedProperty(property)) { out.println("marshal2CachedObject(wireFormat, " + getter + ", dataOut, bs);"); } else { out.println("marshal2NestedObject(wireFormat, " + getter + ", dataOut, bs);"); } } } } protected void generateFile(PrintWriter out) throws Exception { generateLicence(out); out.println("#include \"marshal/" + className + ".hpp\""); out.println(""); out.println("using namespace apache::activemq::client::marshal;"); out.println(""); out.println("/*"); out.println(" * Marshalling code for Open Wire Format for " + jclass.getSimpleName() + ""); out.println(" *"); out.println(" * NOTE!: This file is autogenerated - do not modify!"); out.println(" * if you need to make a change, please see the Groovy scripts in the"); out.println(" * activemq-core module"); out.println(" */"); out.println(""); out.println("" + className + "::" + className + "()"); out.println("{"); out.println(" // no-op"); out.println("}"); out.println(""); out.println("" + className + "::~" + className + "()"); out.println("{"); out.println(" // no-op"); out.println("}"); out.println(""); if (!isAbstractClass()) { out.println(""); out.println(""); out.println("IDataStructure* " + className + "::createObject() "); out.println("{"); out.println(" return new " + jclass.getSimpleName() + "();"); out.println("}"); out.println(""); out.println("char " + className + "::getDataStructureType() "); out.println("{"); out.println(" return " + jclass.getSimpleName() + ".ID_" + jclass.getSimpleName() + ";"); out.println("}"); } out.println(""); out.println(" /* "); out.println(" * Un-marshal an object instance from the data input stream"); out.println(" */ "); out.println("void " + className + "::unmarshal(ProtocolFormat& wireFormat, Object o, BinaryReader& dataIn, BooleanStream& bs) "); out.println("{"); out.println(" base.unmarshal(wireFormat, o, dataIn, bs);"); List properties = getProperties(); boolean marshallerAware = isMarshallerAware(); if (!properties.isEmpty() || marshallerAware) { out.println(""); out.println(" " + jclass.getSimpleName() + "& info = (" + jclass.getSimpleName() + "&) o;"); } if (marshallerAware) { out.println(""); out.println(" info.beforeUnmarshall(wireFormat);"); out.println(" "); } generateTightUnmarshalBody(out); if (marshallerAware) { out.println(""); out.println(" info.afterUnmarshall(wireFormat);"); } out.println(""); out.println("}"); out.println(""); out.println(""); out.println("/*"); out.println(" * Write the booleans that this object uses to a BooleanStream"); out.println(" */"); out.println("int " + className + "::marshal1(ProtocolFormat& wireFormat, Object& o, BooleanStream& bs) {"); out.println(" " + jclass.getSimpleName() + "& info = (" + jclass.getSimpleName() + "&) o;"); if (marshallerAware) { out.println(""); out.println(" info.beforeMarshall(wireFormat);"); } out.println(""); out.println(" int rc = base.marshal1(wireFormat, info, bs);"); int baseSize = generateMarshal1Body(out); out.println(""); out.println(" return rc + " + baseSize + ";"); out.println("}"); out.println(""); out.println("/* "); out.println(" * Write a object instance to data output stream"); out.println(" */"); out.println("void " + className + "::marshal2(ProtocolFormat& wireFormat, Object& o, BinaryWriter& dataOut, BooleanStream& bs) {"); out.println(" base.marshal2(wireFormat, o, dataOut, bs);"); if (!properties.isEmpty() || marshallerAware) { out.println(""); out.println(" " + jclass.getSimpleName() + "& info = (" + jclass.getSimpleName() + "&) o;"); } generateMarshal2Body(out); if (marshallerAware) { out.println(""); out.println(" info.afterMarshall(wireFormat);"); } out.println(""); out.println("}"); } @SuppressWarnings("unchecked") public void generateFactory(PrintWriter out) { generateLicence(out); out.println(""); out.println("// Marshalling code for Open Wire Format"); out.println("//"); out.println("//"); out.println("// NOTE!: This file is autogenerated - do not modify!"); out.println("// if you need to make a change, please see the Groovy scripts in the"); out.println("// activemq-openwire module"); out.println("//"); out.println(""); out.println("#include \"marshal/" + className + ".hpp\""); out.println(""); List list = new ArrayList(getConcreteClasses()); Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { JClass c1 = (JClass)o1; JClass c2 = (JClass)o2; return c1.getSimpleName().compareTo(c2.getSimpleName()); } }); for (Iterator iter = list.iterator(); iter.hasNext();) { JClass jclass = (JClass)iter.next(); out.println("#include \"marshal/" + jclass.getSimpleName() + "Marshaller.hpp\""); } out.println(""); out.println(""); out.println("using namespace apache::activemq::client::marshal;"); out.println(""); out.println(""); out.println("void MarshallerFactory::configure(ProtocolFormat& format) "); out.println("{"); for (Iterator iter = list.iterator(); iter.hasNext();) { JClass jclass = (JClass)iter.next(); out.println(" format.addMarshaller(new " + jclass.getSimpleName() + "Marshaller());"); } out.println(""); out.println("}"); } }