| /** |
| * 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 */"); |
| } |
| } |