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.FileWriter; 021import java.io.PrintWriter; 022import java.util.ArrayList; 023import java.util.HashSet; 024import java.util.List; 025import java.util.Set; 026import org.apache.tools.ant.Project; 027import org.apache.tools.ant.taskdefs.FixCRLF; 028import org.codehaus.jam.JClass; 029import org.codehaus.jam.JProperty; 030import org.codehaus.jam.JamClassIterator; 031 032/** 033 * 034 */ 035public abstract class MultiSourceGenerator extends OpenWireGenerator { 036 protected Set<String> manuallyMaintainedClasses = new HashSet<String>(); 037 protected File destDir; 038 protected File destFile; 039 040 protected JClass jclass; 041 protected JClass superclass; 042 protected String simpleName; 043 protected String className; 044 protected String baseClass; 045 protected StringBuffer buffer; 046 047 public MultiSourceGenerator() { 048 initialiseManuallyMaintainedClasses(); 049 } 050 051 public Object run() { 052 if (destDir == null) { 053 throw new IllegalArgumentException("No destDir defined!"); 054 } 055 System.out.println(getClass().getName() + " generating files in: " + destDir); 056 destDir.mkdirs(); 057 buffer = new StringBuffer(); 058 059 JamClassIterator iter = getClasses(); 060 while (iter.hasNext()) { 061 try { 062 jclass = iter.nextClass(); 063 if (isValidClass(jclass)) { 064 processClass(jclass); 065 } 066 } catch (Exception e) { 067 System.err.println("Unable to process: " + jclass); 068 e.printStackTrace(); 069 } 070 } 071 return null; 072 } 073 074 /** 075 * Returns all the valid properties available on the current class 076 */ 077 public List<JProperty> getProperties() { 078 List<JProperty> answer = new ArrayList<JProperty>(); 079 JProperty[] properties = jclass.getDeclaredProperties(); 080 for (int i = 0; i < properties.length; i++) { 081 JProperty property = properties[i]; 082 if (isValidProperty(property)) { 083 answer.add(property); 084 } 085 } 086 return answer; 087 } 088 089 protected boolean isValidClass(JClass jclass) { 090 if (jclass.getAnnotation("openwire:marshaller") == null) { 091 return false; 092 } 093 return !manuallyMaintainedClasses.contains(jclass.getSimpleName()); 094 } 095 096 protected void processClass(JClass jclass) { 097 simpleName = jclass.getSimpleName(); 098 superclass = jclass.getSuperclass(); 099 100 System.out.println(getClass().getName() + " processing class: " + simpleName); 101 102 className = getClassName(jclass); 103 104 destFile = new File(destDir, className + filePostFix); 105 106 baseClass = getBaseClassName(jclass); 107 108 PrintWriter out = null; 109 try { 110 out = new PrintWriter(new FileWriter(destFile)); 111 generateFile(out); 112 } catch (Exception e) { 113 throw new RuntimeException(e); 114 } finally { 115 if (out != null) { 116 out.close(); 117 } 118 } 119 120 // Use the FixCRLF Ant Task to make sure the file has consistent 121 // newlines 122 // so that SVN does not complain on checkin. 123 Project project = new Project(); 124 project.init(); 125 FixCRLF fixCRLF = new FixCRLF(); 126 fixCRLF.setProject(project); 127 fixCRLF.setSrcdir(destFile.getParentFile()); 128 fixCRLF.setIncludes(destFile.getName()); 129 fixCRLF.execute(); 130 } 131 132 protected abstract void generateFile(PrintWriter out) throws Exception; 133 134 protected String getBaseClassName(JClass jclass) { 135 String answer = "BaseDataStructure"; 136 if (superclass != null) { 137 String name = superclass.getSimpleName(); 138 if (name != null && !name.equals("Object")) { 139 answer = name; 140 } 141 } 142 return answer; 143 } 144 145 protected String getClassName(JClass jclass) { 146 return jclass.getSimpleName(); 147 } 148 149 public boolean isAbstractClass() { 150 return jclass != null && jclass.isAbstract(); 151 } 152 153 public String getAbstractClassText() { 154 return isAbstractClass() ? "abstract " : ""; 155 } 156 157 public boolean isMarshallerAware() { 158 return isMarshallAware(jclass); 159 } 160 161 protected void initialiseManuallyMaintainedClasses() { 162 String[] names = { 163 "ActiveMQDestination", "ActiveMQTempDestination", "ActiveMQQueue", "ActiveMQTopic", "ActiveMQTempQueue", "ActiveMQTempTopic", "BaseCommand", "ActiveMQMessage", "ActiveMQTextMessage", 164 "ActiveMQMapMessage", "ActiveMQBytesMessage", "ActiveMQStreamMessage", "ActiveMQBlobMessage", "DataStructureSupport", "WireFormatInfo", "ActiveMQObjectMessage" 165 }; 166 167 for (int i = 0; i < names.length; i++) { 168 manuallyMaintainedClasses.add(names[i]); 169 } 170 } 171 172 public String getBaseClass() { 173 return baseClass; 174 } 175 176 public void setBaseClass(String baseClass) { 177 this.baseClass = baseClass; 178 } 179 180 public String getClassName() { 181 return className; 182 } 183 184 public void setClassName(String className) { 185 this.className = className; 186 } 187 188 public File getDestDir() { 189 return destDir; 190 } 191 192 public void setDestDir(File destDir) { 193 this.destDir = destDir; 194 } 195 196 public File getDestFile() { 197 return destFile; 198 } 199 200 public void setDestFile(File destFile) { 201 this.destFile = destFile; 202 } 203 204 public JClass getJclass() { 205 return jclass; 206 } 207 208 public void setJclass(JClass jclass) { 209 this.jclass = jclass; 210 } 211 212 public Set<String> getManuallyMaintainedClasses() { 213 return manuallyMaintainedClasses; 214 } 215 216 public void setManuallyMaintainedClasses(Set<String> manuallyMaintainedClasses) { 217 this.manuallyMaintainedClasses = manuallyMaintainedClasses; 218 } 219 220 public String getSimpleName() { 221 return simpleName; 222 } 223 224 public void setSimpleName(String simpleName) { 225 this.simpleName = simpleName; 226 } 227 228 public JClass getSuperclass() { 229 return superclass; 230 } 231 232 public void setSuperclass(JClass superclass) { 233 this.superclass = superclass; 234 } 235 236}