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     * 
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    }