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.PrintWriter; 020 import java.util.ArrayList; 021 import java.util.Collections; 022 import java.util.Comparator; 023 import java.util.Iterator; 024 import java.util.List; 025 026 import org.codehaus.jam.JAnnotation; 027 import org.codehaus.jam.JAnnotationValue; 028 import org.codehaus.jam.JClass; 029 import org.codehaus.jam.JProperty; 030 031 /** 032 * @version $Revision: 381410 $ 033 */ 034 public class CppMarshallingClassesGenerator extends CppMarshallingHeadersGenerator { 035 036 protected String getFilePostFix() { 037 return ".cpp"; 038 } 039 040 protected void generateUnmarshalBodyForProperty(PrintWriter out, JProperty property, JAnnotationValue size) { 041 out.print(" "); 042 String setter = property.getSetter().getSimpleName(); 043 String type = property.getType().getSimpleName(); 044 045 if (type.equals("boolean")) { 046 out.println("info." + setter + "( bs.readBoolean() );"); 047 } else if (type.equals("byte")) { 048 out.println("info." + setter + "( DataStreamMarshaller.readByte(dataIn) );"); 049 } else if (type.equals("char")) { 050 out.println("info." + setter + "( DataStreamMarshaller.readChar(dataIn) );"); 051 } else if (type.equals("short")) { 052 out.println("info." + setter + "( DataStreamMarshaller.readShort(dataIn) );"); 053 } else if (type.equals("int")) { 054 out.println("info." + setter + "( DataStreamMarshaller.readInt(dataIn) );"); 055 } else if (type.equals("long")) { 056 out.println("info." + setter + "( UnmarshalLong(wireFormat, dataIn, bs) );"); 057 } else if (type.equals("String")) { 058 out.println("info." + setter + "( readString(dataIn, bs) );"); 059 } else if (type.equals("byte[]") || type.equals("ByteSequence")) { 060 if (size != null) { 061 out.println("info." + setter + "( readBytes(dataIn, " + size.asInt() + ") );"); 062 } else { 063 out.println("info." + setter + "( readBytes(dataIn, bs.readBoolean()) );"); 064 } 065 } else if (isThrowable(property.getType())) { 066 out.println("info." + setter + "( unmarshalBrokerError(wireFormat, dataIn, bs) );"); 067 } else if (isCachedProperty(property)) { 068 out.println("info." + setter + "( (" + type + ") unmarshalCachedObject(wireFormat, dataIn, bs) );"); 069 } else { 070 out.println("info." + setter + "( (" + type + ") unmarshalNestedObject(wireFormat, dataIn, bs) );"); 071 } 072 } 073 074 protected void generateUnmarshalBodyForArrayProperty(PrintWriter out, JProperty property, JAnnotationValue size) { 075 JClass propertyType = property.getType(); 076 String arrayType = propertyType.getArrayComponentType().getSimpleName(); 077 String setter = property.getGetter().getSimpleName(); 078 out.println(); 079 if (size != null) { 080 out.println(" {"); 081 out.println(" " + arrayType + "[] value = new " + arrayType + "[" + size.asInt() + "];"); 082 out.println(" " + "for( int i=0; i < " + size.asInt() + "; i++ ) {"); 083 out.println(" value[i] = (" + arrayType + ") unmarshalNestedObject(wireFormat,dataIn, bs);"); 084 out.println(" }"); 085 out.println(" info." + setter + "( value );"); 086 out.println(" }"); 087 } else { 088 out.println(" if (bs.readBoolean()) {"); 089 out.println(" short size = DataStreamMarshaller.readShort(dataIn);"); 090 out.println(" " + arrayType + "[] value = new " + arrayType + "[size];"); 091 out.println(" for( int i=0; i < size; i++ ) {"); 092 out.println(" value[i] = (" + arrayType + ") unmarshalNestedObject(wireFormat,dataIn, bs);"); 093 out.println(" }"); 094 out.println(" info." + setter + "( value );"); 095 out.println(" }"); 096 out.println(" else {"); 097 out.println(" info." + setter + "( null );"); 098 out.println(" }"); 099 } 100 } 101 102 protected int generateMarshal1Body(PrintWriter out) { 103 List properties = getProperties(); 104 int baseSize = 0; 105 for (Iterator iter = properties.iterator(); iter.hasNext();) { 106 JProperty property = (JProperty)iter.next(); 107 JAnnotation annotation = property.getAnnotation("openwire:property"); 108 JAnnotationValue size = annotation.getValue("size"); 109 JClass propertyType = property.getType(); 110 String type = propertyType.getSimpleName(); 111 String getter = "info." + property.getGetter().getSimpleName() + "()"; 112 113 out.print(indent); 114 if (type.equals("boolean")) { 115 out.println("bs.writeBoolean(" + getter + ");"); 116 } else if (type.equals("byte")) { 117 baseSize += 1; 118 } else if (type.equals("char")) { 119 baseSize += 1; 120 } else if (type.equals("short")) { 121 baseSize += 1; 122 } else if (type.equals("int")) { 123 baseSize += 1; 124 } else if (type.equals("long")) { 125 out.println("rc += marshal1Long(wireFormat, " + getter + ", bs);"); 126 } else if (type.equals("String")) { 127 out.println("rc += writeString(" + getter + ", bs);"); 128 } else if (type.equals("byte[]") || type.equals("ByteSequence")) { 129 if (size == null) { 130 out.println("bs.writeBoolean(" + getter + "!=null);"); 131 out.println(" rc += " + getter + "==null ? 0 : " + getter + ".Length+4;"); 132 } else { 133 baseSize += size.asInt(); 134 } 135 } else if (propertyType.isArrayType()) { 136 if (size != null) { 137 out.println("rc += marshalObjectArrayConstSize(wireFormat, " + getter + ", bs, " + size.asInt() + ");"); 138 } else { 139 out.println("rc += marshalObjectArray(wireFormat, " + getter + ", bs);"); 140 } 141 } else if (isThrowable(propertyType)) { 142 out.println("rc += marshalBrokerError(wireFormat, " + getter + ", bs);"); 143 } else { 144 if (isCachedProperty(property)) { 145 out.println("rc += marshal1CachedObject(wireFormat, " + getter + ", bs);"); 146 } else { 147 out.println("rc += marshal1NestedObject(wireFormat, " + getter + ", bs);"); 148 } 149 } 150 } 151 return baseSize; 152 } 153 154 protected void generateMarshal2Body(PrintWriter out) { 155 List properties = getProperties(); 156 for (Iterator iter = properties.iterator(); iter.hasNext();) { 157 JProperty property = (JProperty)iter.next(); 158 JAnnotation annotation = property.getAnnotation("openwire:property"); 159 JAnnotationValue size = annotation.getValue("size"); 160 JClass propertyType = property.getType(); 161 String type = propertyType.getSimpleName(); 162 String getter = "info." + property.getGetter().getSimpleName() + "()"; 163 164 out.print(indent); 165 if (type.equals("boolean")) { 166 out.println("bs.readBoolean();"); 167 } else if (type.equals("byte")) { 168 out.println("DataStreamMarshaller.writeByte(" + getter + ", dataOut);"); 169 } else if (type.equals("char")) { 170 out.println("DataStreamMarshaller.writeChar(" + getter + ", dataOut);"); 171 } else if (type.equals("short")) { 172 out.println("DataStreamMarshaller.writeShort(" + getter + ", dataOut);"); 173 } else if (type.equals("int")) { 174 out.println("DataStreamMarshaller.writeInt(" + getter + ", dataOut);"); 175 } else if (type.equals("long")) { 176 out.println("marshal2Long(wireFormat, " + getter + ", dataOut, bs);"); 177 } else if (type.equals("String")) { 178 out.println("writeString(" + getter + ", dataOut, bs);"); 179 } else if (type.equals("byte[]") || type.equals("ByteSequence")) { 180 if (size != null) { 181 out.println("dataOut.write(" + getter + ", 0, " + size.asInt() + ");"); 182 } else { 183 out.println("if(bs.readBoolean()) {"); 184 out.println(" DataStreamMarshaller.writeInt(" + getter + ".Length, dataOut);"); 185 out.println(" dataOut.write(" + getter + ");"); 186 out.println(" }"); 187 } 188 } else if (propertyType.isArrayType()) { 189 if (size != null) { 190 out.println("marshalObjectArrayConstSize(wireFormat, " + getter + ", dataOut, bs, " + size.asInt() + ");"); 191 } else { 192 out.println("marshalObjectArray(wireFormat, " + getter + ", dataOut, bs);"); 193 } 194 } else if (isThrowable(propertyType)) { 195 out.println("marshalBrokerError(wireFormat, " + getter + ", dataOut, bs);"); 196 } else { 197 if (isCachedProperty(property)) { 198 out.println("marshal2CachedObject(wireFormat, " + getter + ", dataOut, bs);"); 199 } else { 200 out.println("marshal2NestedObject(wireFormat, " + getter + ", dataOut, bs);"); 201 } 202 } 203 } 204 } 205 206 protected void generateFile(PrintWriter out) throws Exception { 207 generateLicence(out); 208 209 out.println("#include \"marshal/" + className + ".hpp\""); 210 out.println(""); 211 out.println("using namespace apache::activemq::client::marshal;"); 212 out.println(""); 213 out.println("/*"); 214 out.println(" * Marshalling code for Open Wire Format for " + jclass.getSimpleName() + ""); 215 out.println(" *"); 216 out.println(" * NOTE!: This file is autogenerated - do not modify!"); 217 out.println(" * if you need to make a change, please see the Groovy scripts in the"); 218 out.println(" * activemq-core module"); 219 out.println(" */"); 220 out.println(""); 221 out.println("" + className + "::" + className + "()"); 222 out.println("{"); 223 out.println(" // no-op"); 224 out.println("}"); 225 out.println(""); 226 out.println("" + className + "::~" + className + "()"); 227 out.println("{"); 228 out.println(" // no-op"); 229 out.println("}"); 230 out.println(""); 231 232 if (!isAbstractClass()) { 233 out.println(""); 234 out.println(""); 235 out.println("IDataStructure* " + className + "::createObject() "); 236 out.println("{"); 237 out.println(" return new " + jclass.getSimpleName() + "();"); 238 out.println("}"); 239 out.println(""); 240 out.println("char " + className + "::getDataStructureType() "); 241 out.println("{"); 242 out.println(" return " + jclass.getSimpleName() + ".ID_" + jclass.getSimpleName() + ";"); 243 out.println("}"); 244 } 245 246 out.println(""); 247 out.println(" /* "); 248 out.println(" * Un-marshal an object instance from the data input stream"); 249 out.println(" */ "); 250 out.println("void " + className + "::unmarshal(ProtocolFormat& wireFormat, Object o, BinaryReader& dataIn, BooleanStream& bs) "); 251 out.println("{"); 252 out.println(" base.unmarshal(wireFormat, o, dataIn, bs);"); 253 254 List properties = getProperties(); 255 boolean marshallerAware = isMarshallerAware(); 256 if (!properties.isEmpty() || marshallerAware) { 257 out.println(""); 258 out.println(" " + jclass.getSimpleName() + "& info = (" + jclass.getSimpleName() + "&) o;"); 259 } 260 261 if (marshallerAware) { 262 out.println(""); 263 out.println(" info.beforeUnmarshall(wireFormat);"); 264 out.println(" "); 265 } 266 267 generateTightUnmarshalBody(out); 268 269 if (marshallerAware) { 270 out.println(""); 271 out.println(" info.afterUnmarshall(wireFormat);"); 272 } 273 274 out.println(""); 275 out.println("}"); 276 out.println(""); 277 out.println(""); 278 out.println("/*"); 279 out.println(" * Write the booleans that this object uses to a BooleanStream"); 280 out.println(" */"); 281 out.println("int " + className + "::marshal1(ProtocolFormat& wireFormat, Object& o, BooleanStream& bs) {"); 282 out.println(" " + jclass.getSimpleName() + "& info = (" + jclass.getSimpleName() + "&) o;"); 283 284 if (marshallerAware) { 285 out.println(""); 286 out.println(" info.beforeMarshall(wireFormat);"); 287 } 288 289 out.println(""); 290 out.println(" int rc = base.marshal1(wireFormat, info, bs);"); 291 292 int baseSize = generateMarshal1Body(out); 293 294 out.println(""); 295 out.println(" return rc + " + baseSize + ";"); 296 out.println("}"); 297 out.println(""); 298 out.println("/* "); 299 out.println(" * Write a object instance to data output stream"); 300 out.println(" */"); 301 out.println("void " + className + "::marshal2(ProtocolFormat& wireFormat, Object& o, BinaryWriter& dataOut, BooleanStream& bs) {"); 302 out.println(" base.marshal2(wireFormat, o, dataOut, bs);"); 303 304 if (!properties.isEmpty() || marshallerAware) { 305 out.println(""); 306 out.println(" " + jclass.getSimpleName() + "& info = (" + jclass.getSimpleName() + "&) o;"); 307 } 308 309 generateMarshal2Body(out); 310 311 if (marshallerAware) { 312 out.println(""); 313 out.println(" info.afterMarshall(wireFormat);"); 314 } 315 316 out.println(""); 317 out.println("}"); 318 } 319 320 @SuppressWarnings("unchecked") 321 public void generateFactory(PrintWriter out) { 322 generateLicence(out); 323 out.println(""); 324 out.println("// Marshalling code for Open Wire Format"); 325 out.println("//"); 326 out.println("//"); 327 out.println("// NOTE!: This file is autogenerated - do not modify!"); 328 out.println("// if you need to make a change, please see the Groovy scripts in the"); 329 out.println("// activemq-openwire module"); 330 out.println("//"); 331 out.println(""); 332 out.println("#include \"marshal/" + className + ".hpp\""); 333 out.println(""); 334 335 List list = new ArrayList(getConcreteClasses()); 336 Collections.sort(list, new Comparator() { 337 public int compare(Object o1, Object o2) { 338 JClass c1 = (JClass)o1; 339 JClass c2 = (JClass)o2; 340 return c1.getSimpleName().compareTo(c2.getSimpleName()); 341 } 342 }); 343 344 for (Iterator iter = list.iterator(); iter.hasNext();) { 345 JClass jclass = (JClass)iter.next(); 346 out.println("#include \"marshal/" + jclass.getSimpleName() + "Marshaller.hpp\""); 347 } 348 349 out.println(""); 350 out.println(""); 351 out.println("using namespace apache::activemq::client::marshal;"); 352 out.println(""); 353 out.println(""); 354 out.println("void MarshallerFactory::configure(ProtocolFormat& format) "); 355 out.println("{"); 356 357 for (Iterator iter = list.iterator(); iter.hasNext();) { 358 JClass jclass = (JClass)iter.next(); 359 out.println(" format.addMarshaller(new " + jclass.getSimpleName() + "Marshaller());"); 360 } 361 362 out.println(""); 363 out.println("}"); 364 365 } 366 }