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 */ 017package org.apache.activemq.openwire.tool; 018 019import java.io.File; 020import java.io.PrintWriter; 021import java.util.Iterator; 022import java.util.List; 023 024import org.codehaus.jam.JClass; 025import org.codehaus.jam.JProperty; 026 027/** 028 * 029 */ 030public 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}