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.ArrayList; 022 import java.util.Collections; 023 import java.util.Comparator; 024 import java.util.HashMap; 025 import java.util.Iterator; 026 import java.util.LinkedHashMap; 027 import java.util.List; 028 029 import org.codehaus.jam.JAnnotation; 030 import org.codehaus.jam.JAnnotationValue; 031 import org.codehaus.jam.JClass; 032 import org.codehaus.jam.JProperty; 033 034 /** 035 * @version $Revision: 383749 $ 036 */ 037 public class CHeadersGenerator extends SingleSourceGenerator { 038 039 protected String targetDir = "./src/lib/openwire"; 040 041 public Object run() { 042 filePostFix = ".h"; 043 if (destFile == null) { 044 destFile = new File(targetDir + "/ow_commands_v" + getOpenwireVersion() + ".h"); 045 } 046 return super.run(); 047 } 048 049 public String getTargetDir() { 050 return targetDir; 051 } 052 053 public void setTargetDir(String targetDir) { 054 this.targetDir = targetDir; 055 } 056 057 protected void generateLicence(PrintWriter out) { 058 out.println("/**"); 059 out.println(" * Licensed to the Apache Software Foundation (ASF) under one or more"); 060 out.println(" * contributor license agreements. See the NOTICE file distributed with"); 061 out.println(" * this work for additional information regarding copyright ownership."); 062 out.println(" * The ASF licenses this file to You under the Apache License, Version 2.0"); 063 out.println(" * (the \"License\"); you may not use this file except in compliance with"); 064 out.println(" * the License. You may obtain a copy of the License at"); 065 out.println(" *"); 066 out.println(" * http://www.apache.org/licenses/LICENSE-2.0"); 067 out.println(" *"); 068 out.println(" * Unless required by applicable law or agreed to in writing, software"); 069 out.println(" * distributed under the License is distributed on an \"AS IS\" BASIS,"); 070 out.println(" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."); 071 out.println(" * See the License for the specific language governing permissions and"); 072 out.println(" * limitations under the License."); 073 out.println(" */"); 074 } 075 076 String changeCase(String value) { 077 StringBuffer b = new StringBuffer(); 078 char[] cs = value.toCharArray(); 079 for (int i = 0; i < cs.length; i++) { 080 char c = cs[i]; 081 if (Character.isUpperCase((char)c)) { 082 b.append('_'); 083 b.append(Character.toLowerCase((char)c)); 084 } else { 085 b.append(c); 086 } 087 } 088 return b.toString(); 089 } 090 091 String toPropertyCase(String value) { 092 return value.substring(0, 1).toLowerCase() + value.substring(1); 093 } 094 095 /** 096 * Sort the class list so that base classes come up first. 097 */ 098 protected List<JClass> sort(List source) { 099 LinkedHashMap<JClass, JClass> rc = new LinkedHashMap<JClass, JClass>(); 100 ArrayList classes = new ArrayList(source); 101 Collections.sort(classes, new Comparator() { 102 public int compare(Object o1, Object o2) { 103 JClass c1 = (JClass)o1; 104 JClass c2 = (JClass)o2; 105 return c1.getSimpleName().compareTo(c2.getSimpleName()); 106 } 107 }); 108 109 // lets make a map of all the class names 110 HashMap<JClass, JClass> classNames = new HashMap<JClass, JClass>(); 111 for (Iterator iter = classes.iterator(); iter.hasNext();) { 112 JClass c = (JClass)iter.next(); 113 classNames.put(c, c); 114 } 115 116 // Add all classes that have no parent first 117 for (Iterator iter = classes.iterator(); iter.hasNext();) { 118 JClass c = (JClass)iter.next(); 119 if (!classNames.containsKey(c.getSuperclass())) { 120 rc.put(c, c); 121 } 122 } 123 124 // now lets add the rest 125 for (Iterator iter = classes.iterator(); iter.hasNext();) { 126 JClass c = (JClass)iter.next(); 127 if (!rc.containsKey(c)) { 128 rc.put(c, c); 129 } 130 } 131 132 return new ArrayList<JClass>(rc.keySet()); 133 } 134 135 void generateFields(PrintWriter out, JClass jclass) { 136 137 if (jclass.getSuperclass() == null || jclass.getSuperclass().getSimpleName().equals("Object")) { 138 out.println(""); 139 out.println(" ow_byte structType;"); 140 } else { 141 generateFields(out, jclass.getSuperclass()); 142 } 143 144 ArrayList<JProperty> properties = new ArrayList<JProperty>(); 145 jclass.getDeclaredProperties(); 146 for (int i = 0; i < jclass.getDeclaredProperties().length; i++) { 147 JProperty p = jclass.getDeclaredProperties()[i]; 148 if (isValidProperty(p)) { 149 properties.add(p); 150 } 151 } 152 for (Iterator<JProperty> iter = properties.iterator(); iter.hasNext();) { 153 JProperty property = iter.next(); 154 JAnnotation annotation = property.getGetter().getAnnotation("openwire:property"); 155 // JAnnotationValue size = annotation.getValue("size"); 156 String name = toPropertyCase(property.getSimpleName()); 157 // boolean cached = isCachedProperty(property); 158 159 String type = property.getType().getQualifiedName(); 160 if (type.equals("boolean")) { 161 out.println(" ow_" + type + " " + name + ";"); 162 } else if (type.equals("byte")) { 163 out.println(" ow_" + type + " " + name + ";"); 164 } else if (type.equals("char")) { 165 out.println(" ow_" + type + " " + name + ";"); 166 } else if (type.equals("short")) { 167 out.println(" ow_" + type + " " + name + ";"); 168 } else if (type.equals("int")) { 169 out.println(" ow_" + type + " " + name + ";"); 170 } else if (type.equals("long")) { 171 out.println(" ow_" + type + " " + name + ";"); 172 } else if (type.equals("byte[]")) { 173 out.println(" ow_byte_array *" + name + ";"); 174 } else if (type.equals("org.apache.activeio.packet.ByteSequence")) { 175 out.println(" ow_byte_array *" + name + ";"); 176 } else if (type.equals("org.apache.activeio.packet.ByteSequence")) { 177 out.println(" ow_byte_array *" + name + ";"); 178 } else if (type.equals("java.lang.String")) { 179 out.println(" ow_string *" + name + ";"); 180 } else { 181 if (property.getType().isArrayType()) { 182 out.println(" ow_DataStructure_array *" + name + ";"); 183 } else if (isThrowable(property.getType())) { 184 out.println(" ow_throwable *" + name + ";"); 185 } else { 186 out.println(" struct ow_" + property.getType().getSimpleName() + " *" + name + ";"); 187 } 188 } 189 } 190 } 191 192 protected void generateSetup(PrintWriter out) { 193 generateLicence(out); 194 out.println(""); 195 out.println("/*****************************************************************************************"); 196 out.println(" * "); 197 out.println(" * NOTE!: This file is auto generated - do not modify!"); 198 out.println(" * if you need to make a change, please see the modify the groovy scripts in the"); 199 out.println(" * under src/gram/script and then use maven openwire:generate to regenerate "); 200 out.println(" * this file."); 201 out.println(" * "); 202 out.println(" *****************************************************************************************/"); 203 out.println(" "); 204 out.println("#ifndef OW_COMMANDS_V" + openwireVersion + "_H"); 205 out.println("#define OW_COMMANDS_V" + openwireVersion + "_H"); 206 out.println(""); 207 out.println("#include \"ow.h\""); 208 out.println(""); 209 out.println("#ifdef __cplusplus"); 210 out.println("extern \"C\" {"); 211 out.println("#endif /* __cplusplus */"); 212 out.println(" "); 213 out.println("#define OW_WIREFORMAT_VERSION " + openwireVersion + ""); 214 215 out.println("#define OW_WIREFORMAT_STACK_TRACE_MASK 0x00000001;"); 216 out.println("#define OW_WIREFORMAT_TCP_NO_DELAY_MASK 0x00000002;"); 217 out.println("#define OW_WIREFORMAT_CACHE_MASK 0x00000004;"); 218 out.println("#define OW_WIREFORMAT_COMPRESSION_MASK 0x00000008;"); 219 220 for (Iterator iterator = sortedClasses.iterator(); iterator.hasNext();) { 221 JClass jclass = (JClass)iterator.next(); 222 String name = jclass.getSimpleName(); 223 String type = ("ow_" + name).toUpperCase() + "_TYPE"; 224 if (!isAbstract(jclass)) { 225 out.println("#define " + type + " " + getOpenWireOpCode(jclass)); 226 } 227 } 228 229 out.println(" "); 230 out.println("apr_status_t ow_bitmarshall(ow_bit_buffer *buffer, ow_DataStructure *object);"); 231 out.println("apr_status_t ow_marshall(ow_byte_buffer *buffer, ow_DataStructure *object);"); 232 } 233 234 protected void generateFile(PrintWriter out) throws Exception { 235 236 String structName = jclass.getSimpleName(); 237 238 out.println(""); 239 out.println("typedef struct ow_" + structName + " {"); 240 241 // This recusivly generates the field definitions of the class and it's 242 // supper classes. 243 generateFields(out, jclass); 244 245 out.println(""); 246 out.println("} ow_" + structName + ";"); 247 out.println("ow_" + structName + " *ow_" + structName + "_create(apr_pool_t *pool);"); 248 out.println("ow_boolean ow_is_a_" + structName + "(ow_DataStructure *object);"); 249 250 } 251 252 protected void generateTearDown(PrintWriter out) { 253 out.println(""); 254 out.println("#ifdef __cplusplus"); 255 out.println("}"); 256 out.println("#endif"); 257 out.println(""); 258 out.println("#endif /* ! OW_COMMANDS_V" + openwireVersion + "_H */"); 259 } 260 }