001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.activemq.openwire.tool;
018
019 import java.io.File;
020 import java.io.PrintWriter;
021 import java.util.Iterator;
022 import java.util.List;
023
024 import org.codehaus.jam.JClass;
025 import org.codehaus.jam.JProperty;
026
027 /**
028 * @version $Revision: 409828 $
029 */
030 public class CppClassesGenerator extends MultiSourceGenerator {
031
032 protected String targetDir = "./src/main/cpp";
033
034 public Object run() {
035 filePostFix = getFilePostFix();
036 if (destDir == null) {
037 destDir = new File(targetDir + "/activemq/command");
038 }
039 return super.run();
040 }
041
042 protected String getFilePostFix() {
043 return ".cpp";
044 }
045
046 /**
047 * Converts the Java type to a C++ type name
048 */
049 public String toCppType(JClass type) {
050 String name = type.getSimpleName();
051 if (name.equals("String")) {
052 return "p<string>";
053 } else if (type.isArrayType()) {
054 if (name.equals("byte[]")) {
055 name = "char[]";
056 } else if (name.equals("DataStructure[]")) {
057 name = "IDataStructure[]";
058 }
059 return "array<" + name.substring(0, name.length() - 2) + ">";
060 } else if (name.equals("Throwable") || name.equals("Exception")) {
061 return "p<BrokerError>";
062 } else if (name.equals("ByteSequence")) {
063 return "array<char>";
064 } else if (name.equals("boolean")) {
065 return "bool";
066 } else if (name.equals("long")) {
067 return "long long";
068 } else if (name.equals("byte")) {
069 return "char";
070 } else if (name.equals("Command") || name.equals("DataStructure")) {
071 return "p<I" + name + ">";
072 } else if (!type.isPrimitiveType()) {
073 return "p<" + name + ">";
074 } else {
075 return name;
076 }
077 }
078
079 /**
080 * Converts the Java type to a C++ default value
081 */
082 public String toCppDefaultValue(JClass type) {
083 String name = type.getSimpleName();
084
085 if (name.equals("boolean")) {
086 return "false";
087 } else if (!type.isPrimitiveType()) {
088 return "NULL";
089 } else {
090 return "0";
091 }
092 }
093
094 /**
095 * Converts the Java type to the name of the C++ marshal method to be used
096 */
097 public String toMarshalMethodName(JClass type) {
098 String name = type.getSimpleName();
099 if (name.equals("String")) {
100 return "marshalString";
101 } else if (type.isArrayType()) {
102 if (type.getArrayComponentType().isPrimitiveType() && name.equals("byte[]")) {
103 return "marshalByteArray";
104 } else {
105 return "marshalObjectArray";
106 }
107 } else if (name.equals("ByteSequence")) {
108 return "marshalByteArray";
109 } else if (name.equals("short")) {
110 return "marshalShort";
111 } else if (name.equals("int")) {
112 return "marshalInt";
113 } else if (name.equals("long")) {
114 return "marshalLong";
115 } else if (name.equals("byte")) {
116 return "marshalByte";
117 } else if (name.equals("double")) {
118 return "marshalDouble";
119 } else if (name.equals("float")) {
120 return "marshalFloat";
121 } else if (name.equals("boolean")) {
122 return "marshalBoolean";
123 } else if (!type.isPrimitiveType()) {
124 return "marshalObject";
125 } else {
126 return name;
127 }
128 }
129
130 /**
131 * Converts the Java type to the name of the C++ unmarshal method to be used
132 */
133 public String toUnmarshalMethodName(JClass type) {
134 String name = type.getSimpleName();
135 if (name.equals("String")) {
136 return "unmarshalString";
137 } else if (type.isArrayType()) {
138 if (type.getArrayComponentType().isPrimitiveType() && name.equals("byte[]")) {
139 return "unmarshalByteArray";
140 } else {
141 return "unmarshalObjectArray";
142 }
143 } else if (name.equals("ByteSequence")) {
144 return "unmarshalByteArray";
145 } else if (name.equals("short")) {
146 return "unmarshalShort";
147 } else if (name.equals("int")) {
148 return "unmarshalInt";
149 } else if (name.equals("long")) {
150 return "unmarshalLong";
151 } else if (name.equals("byte")) {
152 return "unmarshalByte";
153 } else if (name.equals("double")) {
154 return "unmarshalDouble";
155 } else if (name.equals("float")) {
156 return "unmarshalFloat";
157 } else if (name.equals("boolean")) {
158 return "unmarshalBoolean";
159 } else if (!type.isPrimitiveType()) {
160 return "unmarshalObject";
161 } else {
162 return name;
163 }
164 }
165
166 /**
167 * Converts the Java type to a C++ pointer cast
168 */
169 public String toUnmarshalCast(JClass type) {
170 String name = toCppType(type);
171
172 if (name.startsWith("p<")) {
173 return "p_cast<" + name.substring(2);
174 } else if (name.startsWith("array<") && (type.isArrayType() && !type.getArrayComponentType().isPrimitiveType()) && !type.getSimpleName().equals("ByteSequence")) {
175 return "array_cast<" + name.substring(6);
176 } else {
177 return "";
178 }
179 }
180
181 protected void generateLicence(PrintWriter out) {
182 out.println("/**");
183 out.println(" * Licensed to the Apache Software Foundation (ASF) under one or more");
184 out.println(" * contributor license agreements. See the NOTICE file distributed with");
185 out.println(" * this work for additional information regarding copyright ownership.");
186 out.println(" * The ASF licenses this file to You under the Apache License, Version 2.0");
187 out.println(" * (the \"License\"); you may not use this file except in compliance with");
188 out.println(" * the License. You may obtain a copy of the License at");
189 out.println(" *");
190 out.println(" * http://www.apache.org/licenses/LICENSE-2.0");
191 out.println(" *");
192 out.println(" * Unless required by applicable law or agreed to in writing, software");
193 out.println(" * distributed under the License is distributed on an \"AS IS\" BASIS,");
194 out.println(" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.");
195 out.println(" * See the License for the specific language governing permissions and");
196 out.println(" * limitations under the License.");
197 out.println(" */");
198 }
199
200 protected void generateFile(PrintWriter out) throws Exception {
201 generateLicence(out);
202 out.println("#include \"activemq/command/" + className + ".hpp\"");
203 out.println("");
204 out.println("using namespace apache::activemq::command;");
205 out.println("");
206 out.println("/*");
207 out.println(" *");
208 out.println(" * Command and marshalling code for OpenWire format for " + className + "");
209 out.println(" *");
210 out.println(" *");
211 out.println(" * NOTE!: This file is autogenerated - do not modify!");
212 out.println(" * if you need to make a change, please see the Groovy scripts in the");
213 out.println(" * activemq-core module");
214 out.println(" *");
215 out.println(" */");
216 out.println("" + className + "::" + className + "()");
217 out.println("{");
218
219 List properties = getProperties();
220 for (Iterator iter = properties.iterator(); iter.hasNext();) {
221 JProperty property = (JProperty)iter.next();
222 String value = toCppDefaultValue(property.getType());
223 String propertyName = property.getSimpleName();
224 String parameterName = decapitalize(propertyName);
225 out.println(" this->" + parameterName + " = " + value + " ;");
226 }
227 out.println("}");
228 out.println("");
229 out.println("" + className + "::~" + className + "()");
230 out.println("{");
231 out.println("}");
232 out.println("");
233 out.println("unsigned char " + className + "::getDataStructureType()");
234 out.println("{");
235 out.println(" return " + className + "::TYPE ; ");
236 out.println("}");
237 for (Iterator iter = properties.iterator(); iter.hasNext();) {
238 JProperty property = (JProperty)iter.next();
239 String type = toCppType(property.getType());
240 String propertyName = property.getSimpleName();
241 String parameterName = decapitalize(propertyName);
242 out.println("");
243 out.println(" ");
244 out.println("" + type + " " + className + "::get" + propertyName + "()");
245 out.println("{");
246 out.println(" return " + parameterName + " ;");
247 out.println("}");
248 out.println("");
249 out.println("void " + className + "::set" + propertyName + "(" + type + " " + parameterName + ")");
250 out.println("{");
251 out.println(" this->" + parameterName + " = " + parameterName + " ;");
252 out.println("}");
253 }
254 out.println("");
255 out.println("int " + className + "::marshal(p<IMarshaller> marshaller, int mode, p<IOutputStream> ostream) throw (IOException)");
256 out.println("{");
257 out.println(" int size = 0 ;");
258 out.println("");
259 out.println(" size += " + baseClass + "::marshal(marshaller, mode, ostream) ; ");
260
261 for (Iterator iter = properties.iterator(); iter.hasNext();) {
262 JProperty property = (JProperty)iter.next();
263 String marshalMethod = toMarshalMethodName(property.getType());
264 String propertyName = decapitalize(property.getSimpleName());
265 out.println(" size += marshaller->" + marshalMethod + "(" + propertyName + ", mode, ostream) ; ");
266 }
267 out.println(" return size ;");
268 out.println("}");
269 out.println("");
270 out.println("void " + className + "::unmarshal(p<IMarshaller> marshaller, int mode, p<IInputStream> istream) throw (IOException)");
271 out.println("{");
272 out.println(" " + baseClass + "::unmarshal(marshaller, mode, istream) ; ");
273 for (Iterator iter = properties.iterator(); iter.hasNext();) {
274 JProperty property = (JProperty)iter.next();
275 String cast = toUnmarshalCast(property.getType());
276 String unmarshalMethod = toUnmarshalMethodName(property.getType());
277 String propertyName = decapitalize(property.getSimpleName());
278 out.println(" " + propertyName + " = " + cast + "(marshaller->" + unmarshalMethod + "(mode, istream)) ; ");
279 }
280 out.println("}");
281 }
282
283 public String getTargetDir() {
284 return targetDir;
285 }
286
287 public void setTargetDir(String targetDir) {
288 this.targetDir = targetDir;
289 }
290
291 }