/** * 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.File; import java.io.PrintWriter; import java.util.Iterator; import java.util.List; import org.codehaus.jam.JClass; import org.codehaus.jam.JProperty; /** * */ public class CppClassesGenerator extends MultiSourceGenerator { protected String targetDir = "./src/main/cpp"; public Object run() { filePostFix = getFilePostFix(); if (destDir == null) { destDir = new File(targetDir + "/activemq/command"); } return super.run(); } protected String getFilePostFix() { return ".cpp"; } /** * Converts the Java type to a C++ type name */ public String toCppType(JClass type) { String name = type.getSimpleName(); if (name.equals("String")) { return "p<string>"; } else if (type.isArrayType()) { if (name.equals("byte[]")) { name = "char[]"; } else if (name.equals("DataStructure[]")) { name = "IDataStructure[]"; } return "array<" + name.substring(0, name.length() - 2) + ">"; } else if (name.equals("Throwable") || name.equals("Exception")) { return "p<BrokerError>"; } else if (name.equals("ByteSequence")) { return "array<char>"; } else if (name.equals("boolean")) { return "bool"; } else if (name.equals("long")) { return "long long"; } else if (name.equals("byte")) { return "char"; } else if (name.equals("Command") || name.equals("DataStructure")) { return "p<I" + name + ">"; } else if (!type.isPrimitiveType()) { return "p<" + name + ">"; } else { return name; } } /** * Converts the Java type to a C++ default value */ public String toCppDefaultValue(JClass type) { String name = type.getSimpleName(); if (name.equals("boolean")) { return "false"; } else if (!type.isPrimitiveType()) { return "NULL"; } else { return "0"; } } /** * Converts the Java type to the name of the C++ marshal method to be used */ public String toMarshalMethodName(JClass type) { String name = type.getSimpleName(); if (name.equals("String")) { return "marshalString"; } else if (type.isArrayType()) { if (type.getArrayComponentType().isPrimitiveType() && name.equals("byte[]")) { return "marshalByteArray"; } else { return "marshalObjectArray"; } } else if (name.equals("ByteSequence")) { return "marshalByteArray"; } else if (name.equals("short")) { return "marshalShort"; } else if (name.equals("int")) { return "marshalInt"; } else if (name.equals("long")) { return "marshalLong"; } else if (name.equals("byte")) { return "marshalByte"; } else if (name.equals("double")) { return "marshalDouble"; } else if (name.equals("float")) { return "marshalFloat"; } else if (name.equals("boolean")) { return "marshalBoolean"; } else if (!type.isPrimitiveType()) { return "marshalObject"; } else { return name; } } /** * Converts the Java type to the name of the C++ unmarshal method to be used */ public String toUnmarshalMethodName(JClass type) { String name = type.getSimpleName(); if (name.equals("String")) { return "unmarshalString"; } else if (type.isArrayType()) { if (type.getArrayComponentType().isPrimitiveType() && name.equals("byte[]")) { return "unmarshalByteArray"; } else { return "unmarshalObjectArray"; } } else if (name.equals("ByteSequence")) { return "unmarshalByteArray"; } else if (name.equals("short")) { return "unmarshalShort"; } else if (name.equals("int")) { return "unmarshalInt"; } else if (name.equals("long")) { return "unmarshalLong"; } else if (name.equals("byte")) { return "unmarshalByte"; } else if (name.equals("double")) { return "unmarshalDouble"; } else if (name.equals("float")) { return "unmarshalFloat"; } else if (name.equals("boolean")) { return "unmarshalBoolean"; } else if (!type.isPrimitiveType()) { return "unmarshalObject"; } else { return name; } } /** * Converts the Java type to a C++ pointer cast */ public String toUnmarshalCast(JClass type) { String name = toCppType(type); if (name.startsWith("p<")) { return "p_cast<" + name.substring(2); } else if (name.startsWith("array<") && (type.isArrayType() && !type.getArrayComponentType().isPrimitiveType()) && !type.getSimpleName().equals("ByteSequence")) { return "array_cast<" + name.substring(6); } else { return ""; } } protected void generateLicence(PrintWriter out) { out.println("/**"); out.println(" * Licensed to the Apache Software Foundation (ASF) under one or more"); out.println(" * contributor license agreements. See the NOTICE file distributed with"); out.println(" * this work for additional information regarding copyright ownership."); out.println(" * The ASF licenses this file to You under the Apache License, Version 2.0"); out.println(" * (the \"License\"); you may not use this file except in compliance with"); out.println(" * the License. You may obtain a copy of the License at"); out.println(" *"); out.println(" * http://www.apache.org/licenses/LICENSE-2.0"); out.println(" *"); out.println(" * Unless required by applicable law or agreed to in writing, software"); out.println(" * distributed under the License is distributed on an \"AS IS\" BASIS,"); out.println(" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."); out.println(" * See the License for the specific language governing permissions and"); out.println(" * limitations under the License."); out.println(" */"); } protected void generateFile(PrintWriter out) throws Exception { generateLicence(out); out.println("#include \"activemq/command/" + className + ".hpp\""); out.println(""); out.println("using namespace apache::activemq::command;"); out.println(""); out.println("/*"); out.println(" *"); out.println(" * Command and marshalling code for OpenWire format for " + className + ""); 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-core module"); out.println(" *"); out.println(" */"); out.println("" + className + "::" + className + "()"); out.println("{"); List properties = getProperties(); for (Iterator iter = properties.iterator(); iter.hasNext();) { JProperty property = (JProperty)iter.next(); String value = toCppDefaultValue(property.getType()); String propertyName = property.getSimpleName(); String parameterName = decapitalize(propertyName); out.println(" this->" + parameterName + " = " + value + " ;"); } out.println("}"); out.println(""); out.println("" + className + "::~" + className + "()"); out.println("{"); out.println("}"); out.println(""); out.println("unsigned char " + className + "::getDataStructureType()"); out.println("{"); out.println(" return " + className + "::TYPE ; "); out.println("}"); for (Iterator iter = properties.iterator(); iter.hasNext();) { JProperty property = (JProperty)iter.next(); String type = toCppType(property.getType()); String propertyName = property.getSimpleName(); String parameterName = decapitalize(propertyName); out.println(""); out.println(" "); out.println("" + type + " " + className + "::get" + propertyName + "()"); out.println("{"); out.println(" return " + parameterName + " ;"); out.println("}"); out.println(""); out.println("void " + className + "::set" + propertyName + "(" + type + " " + parameterName + ")"); out.println("{"); out.println(" this->" + parameterName + " = " + parameterName + " ;"); out.println("}"); } out.println(""); out.println("int " + className + "::marshal(p<IMarshaller> marshaller, int mode, p<IOutputStream> ostream) throw (IOException)"); out.println("{"); out.println(" int size = 0 ;"); out.println(""); out.println(" size += " + baseClass + "::marshal(marshaller, mode, ostream) ; "); for (Iterator iter = properties.iterator(); iter.hasNext();) { JProperty property = (JProperty)iter.next(); String marshalMethod = toMarshalMethodName(property.getType()); String propertyName = decapitalize(property.getSimpleName()); out.println(" size += marshaller->" + marshalMethod + "(" + propertyName + ", mode, ostream) ; "); } out.println(" return size ;"); out.println("}"); out.println(""); out.println("void " + className + "::unmarshal(p<IMarshaller> marshaller, int mode, p<IInputStream> istream) throw (IOException)"); out.println("{"); out.println(" " + baseClass + "::unmarshal(marshaller, mode, istream) ; "); for (Iterator iter = properties.iterator(); iter.hasNext();) { JProperty property = (JProperty)iter.next(); String cast = toUnmarshalCast(property.getType()); String unmarshalMethod = toUnmarshalMethodName(property.getType()); String propertyName = decapitalize(property.getSimpleName()); out.println(" " + propertyName + " = " + cast + "(marshaller->" + unmarshalMethod + "(mode, istream)) ; "); } out.println("}"); } public String getTargetDir() { return targetDir; } public void setTargetDir(String targetDir) { this.targetDir = targetDir; } }