/** * 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.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import org.codehaus.jam.JAnnotation; import org.codehaus.jam.JAnnotationValue; import org.codehaus.jam.JClass; import org.codehaus.jam.JProperty; /** * */ public class CHeadersGenerator extends SingleSourceGenerator { protected String targetDir = "./src/lib/openwire"; public Object run() { filePostFix = ".h"; if (destFile == null) { destFile = new File(targetDir + "/ow_commands_v" + getOpenwireVersion() + ".h"); } return super.run(); } public String getTargetDir() { return targetDir; } public void setTargetDir(String targetDir) { this.targetDir = targetDir; } 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(" */"); } String changeCase(String value) { StringBuffer b = new StringBuffer(); char[] cs = value.toCharArray(); for (int i = 0; i < cs.length; i++) { char c = cs[i]; if (Character.isUpperCase((char)c)) { b.append('_'); b.append(Character.toLowerCase((char)c)); } else { b.append(c); } } return b.toString(); } String toPropertyCase(String value) { return value.substring(0, 1).toLowerCase() + value.substring(1); } /** * Sort the class list so that base classes come up first. */ protected List<JClass> sort(List<JClass> source) { LinkedHashMap<JClass, JClass> rc = new LinkedHashMap<JClass, JClass>(); ArrayList<JClass> classes = new ArrayList<JClass>(source); Collections.sort(classes, new Comparator<JClass>() { public int compare(JClass c1, JClass c2) { return c1.getSimpleName().compareTo(c2.getSimpleName()); } }); // lets make a map of all the class names HashMap<JClass, JClass> classNames = new HashMap<JClass, JClass>(); for (Iterator iter = classes.iterator(); iter.hasNext();) { JClass c = (JClass)iter.next(); classNames.put(c, c); } // Add all classes that have no parent first for (Iterator iter = classes.iterator(); iter.hasNext();) { JClass c = (JClass)iter.next(); if (!classNames.containsKey(c.getSuperclass())) { rc.put(c, c); } } // now lets add the rest for (Iterator iter = classes.iterator(); iter.hasNext();) { JClass c = (JClass)iter.next(); if (!rc.containsKey(c)) { rc.put(c, c); } } return new ArrayList<JClass>(rc.keySet()); } void generateFields(PrintWriter out, JClass jclass) { if (jclass.getSuperclass() == null || jclass.getSuperclass().getSimpleName().equals("Object")) { out.println(""); out.println(" ow_byte structType;"); } else { generateFields(out, jclass.getSuperclass()); } ArrayList<JProperty> properties = new ArrayList<JProperty>(); jclass.getDeclaredProperties(); for (int i = 0; i < jclass.getDeclaredProperties().length; i++) { JProperty p = jclass.getDeclaredProperties()[i]; if (isValidProperty(p)) { properties.add(p); } } for (Iterator<JProperty> iter = properties.iterator(); iter.hasNext();) { JProperty property = iter.next(); JAnnotation annotation = property.getGetter().getAnnotation("openwire:property"); // JAnnotationValue size = annotation.getValue("size"); String name = toPropertyCase(property.getSimpleName()); // boolean cached = isCachedProperty(property); String type = property.getType().getQualifiedName(); if (type.equals("boolean")) { out.println(" ow_" + type + " " + name + ";"); } else if (type.equals("byte")) { out.println(" ow_" + type + " " + name + ";"); } else if (type.equals("char")) { out.println(" ow_" + type + " " + name + ";"); } else if (type.equals("short")) { out.println(" ow_" + type + " " + name + ";"); } else if (type.equals("int")) { out.println(" ow_" + type + " " + name + ";"); } else if (type.equals("long")) { out.println(" ow_" + type + " " + name + ";"); } else if (type.equals("byte[]")) { out.println(" ow_byte_array *" + name + ";"); } else if (type.equals("org.apache.activeio.packet.ByteSequence")) { out.println(" ow_byte_array *" + name + ";"); } else if (type.equals("org.apache.activeio.packet.ByteSequence")) { out.println(" ow_byte_array *" + name + ";"); } else if (type.equals("java.lang.String")) { out.println(" ow_string *" + name + ";"); } else { if (property.getType().isArrayType()) { out.println(" ow_DataStructure_array *" + name + ";"); } else if (isThrowable(property.getType())) { out.println(" ow_throwable *" + name + ";"); } else { out.println(" struct ow_" + property.getType().getSimpleName() + " *" + name + ";"); } } } } protected void generateSetup(PrintWriter out) { generateLicence(out); out.println(""); out.println("/*****************************************************************************************"); out.println(" * "); out.println(" * NOTE!: This file is auto generated - do not modify!"); out.println(" * if you need to make a change, please see the modify the groovy scripts in the"); out.println(" * under src/gram/script and then use maven openwire:generate to regenerate "); out.println(" * this file."); out.println(" * "); out.println(" *****************************************************************************************/"); out.println(" "); out.println("#ifndef OW_COMMANDS_V" + openwireVersion + "_H"); out.println("#define OW_COMMANDS_V" + openwireVersion + "_H"); out.println(""); out.println("#include \"ow.h\""); out.println(""); out.println("#ifdef __cplusplus"); out.println("extern \"C\" {"); out.println("#endif /* __cplusplus */"); out.println(" "); out.println("#define OW_WIREFORMAT_VERSION " + openwireVersion + ""); out.println("#define OW_WIREFORMAT_STACK_TRACE_MASK 0x00000001;"); out.println("#define OW_WIREFORMAT_TCP_NO_DELAY_MASK 0x00000002;"); out.println("#define OW_WIREFORMAT_CACHE_MASK 0x00000004;"); out.println("#define OW_WIREFORMAT_COMPRESSION_MASK 0x00000008;"); for (Iterator iterator = sortedClasses.iterator(); iterator.hasNext();) { JClass jclass = (JClass)iterator.next(); String name = jclass.getSimpleName(); String type = ("ow_" + name).toUpperCase() + "_TYPE"; if (!isAbstract(jclass)) { out.println("#define " + type + " " + getOpenWireOpCode(jclass)); } } out.println(" "); out.println("apr_status_t ow_bitmarshall(ow_bit_buffer *buffer, ow_DataStructure *object);"); out.println("apr_status_t ow_marshall(ow_byte_buffer *buffer, ow_DataStructure *object);"); } protected void generateFile(PrintWriter out) throws Exception { String structName = jclass.getSimpleName(); out.println(""); out.println("typedef struct ow_" + structName + " {"); // This recusivly generates the field definitions of the class and it's // supper classes. generateFields(out, jclass); out.println(""); out.println("} ow_" + structName + ";"); out.println("ow_" + structName + " *ow_" + structName + "_create(apr_pool_t *pool);"); out.println("ow_boolean ow_is_a_" + structName + "(ow_DataStructure *object);"); } protected void generateTearDown(PrintWriter out) { out.println(""); out.println("#ifdef __cplusplus"); out.println("}"); out.println("#endif"); out.println(""); out.println("#endif /* ! OW_COMMANDS_V" + openwireVersion + "_H */"); } }