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 }