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.FileWriter;
021 import java.io.PrintWriter;
022 import java.util.ArrayList;
023 import java.util.HashSet;
024 import java.util.List;
025 import java.util.Set;
026 import org.apache.tools.ant.Project;
027 import org.apache.tools.ant.taskdefs.FixCRLF;
028 import org.codehaus.jam.JClass;
029 import org.codehaus.jam.JProperty;
030 import org.codehaus.jam.JamClassIterator;
031
032 /**
033 * @version $Revision: 386442 $
034 */
035 public 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 }