KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > speedo > generation > recompiler > UpToDateVisitor


1 /**
2  * Copyright (C) 2001-2004 France Telecom R&D
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18 package org.objectweb.speedo.generation.recompiler;
19
20 import org.objectweb.speedo.generation.mivisitor.MetaInfoVisitorImpl;
21 import org.objectweb.speedo.generation.mivisitor.MetaInfoVisitor;
22 import org.objectweb.speedo.generation.api.SpeedoCompilerParameter;
23 import org.objectweb.speedo.metadata.SpeedoXMLDescriptor;
24 import org.objectweb.speedo.metadata.SpeedoClass;
25 import org.objectweb.speedo.api.SpeedoException;
26 import org.objectweb.speedo.mapper.lib.Object2StringSerializer;
27 import org.objectweb.speedo.tools.StringReplace;
28 import org.objectweb.speedo.mim.api.SpeedoProxy;
29 import org.objectweb.util.monolog.api.BasicLevel;
30
31 import java.io.File JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.ArrayList JavaDoc;
34 import java.util.Arrays JavaDoc;
35 import java.net.URLClassLoader JavaDoc;
36 import java.net.URL JavaDoc;
37 import java.net.MalformedURLException JavaDoc;
38
39 /**
40  * Checks the date of the source and the built files:
41  * - .jdo / JMI file
42  * - .java / .class
43  *
44  * For each .jdo file, if the .jdo or a .java has been modified all classes
45  * are removed in order to re-enhance all classed.
46  *
47  * TODO: check aware classes
48  *
49  * @author S.Chassande-Barrioz
50  */

51 public class UpToDateVisitor extends MetaInfoVisitorImpl {
52
53     private File JavaDoc output;
54     private File JavaDoc input;
55     private ClassLoader JavaDoc classloader;
56     private List JavaDoc xmlsToRemove;
57     private List JavaDoc enhancedClasses;
58
59
60
61     /**
62      * builds a MetaInfoVisitor which is the last of the chain
63      */

64     public UpToDateVisitor() {
65     }
66
67     /**
68      * builds a MetaInfoVisitor which is the last of the chain
69      */

70     public UpToDateVisitor(MetaInfoVisitor mim) {
71         super(mim);
72     }
73
74     protected String JavaDoc getLoggerName() {
75         return super.getLoggerName() + ".uptodate";
76     }
77
78     public boolean init() throws SpeedoException {
79         super.init();
80         output = new File JavaDoc(scp.output);
81         if (!output.exists() && output.mkdirs()) {
82             throw new SpeedoException(
83                     "Impossible to create the output directory: "
84                     + output.getAbsolutePath());
85         }
86         input = new File JavaDoc(scp.input);
87         if (!input.exists()) {
88             throw new SpeedoException("No input directory: "
89                     + input.getAbsolutePath());
90         }
91         try {
92             classloader = new URLClassLoader JavaDoc(
93                 new URL JavaDoc[]{new File JavaDoc(scp.output).toURL()},
94                 getClass().getClassLoader());
95         } catch (MalformedURLException JavaDoc e) {
96
97         }
98         enhancedClasses = new ArrayList JavaDoc();
99         return !scp.getXmldescriptor().isEmpty();
100     }
101
102     public void visitCompilerParameter(SpeedoCompilerParameter scp) throws SpeedoException {
103         super.visitCompilerParameter(scp);
104         if (xmlsToRemove != null) {
105             for(int i=(xmlsToRemove.size() -1); i>=0; i--) {
106                 SpeedoXMLDescriptor xml = (SpeedoXMLDescriptor) xmlsToRemove.get(i);
107                 scp.getXmldescriptor().remove(xml.xmlFile);
108             }
109         }
110     }
111
112     public void visitXml(SpeedoXMLDescriptor xml) throws SpeedoException {
113         //compare the date of the .jdo and JMI files
114
File JavaDoc jdoFile = new File JavaDoc(scp.jdoDir, xml.xmlFile);
115         File JavaDoc jmiFile = new File JavaDoc(output,
116                 Object2StringSerializer.jdoFileName2ClassName(xml.xmlFile)
117                 + ".class");
118         if (debug) {
119             logger.log(BasicLevel.DEBUG, "JDO file: "
120                 + jdoFile.getAbsolutePath()
121                 + "\n\ttime=" + jdoFile.lastModified());
122             if (jmiFile.exists()) {
123                 logger.log(BasicLevel.DEBUG, "JMI file: "
124                         + jmiFile.getAbsolutePath()
125                         + "\n\ttime=" + jmiFile.lastModified());
126             } else {
127                 logger.log(BasicLevel.DEBUG, "NO JMI file found : "
128                         + jmiFile.getAbsolutePath());
129             }
130         }
131         xml.requireEnhancement = !jmiFile.exists()
132                 || (jdoFile.lastModified() > jmiFile.lastModified());
133         if (debug) {
134             logger.log(BasicLevel.DEBUG, "Enhancement "
135                 + (xml.requireEnhancement ? "" : "not ")
136                 + "required for the jdo file:" + xml.xmlFile);
137         }
138         enhancedClasses.clear();
139         super.visitXml(xml);
140         List JavaDoc classes = xml.getSpeedoClasses();
141
142         if (!xml.requireEnhancement) {
143             for(int i=(classes.size() -1); i>=0 && !xml.requireEnhancement; i--) {
144                 SpeedoClass sc = (SpeedoClass) classes.get(i);
145                 sc.requireEnhancement = xml.requireEnhancement;
146             }
147         }
148         if (xml.requireEnhancement) {
149             logger.log(BasicLevel.INFO, "Enhancement required for :" + xml.xmlFile);
150
151             //Remove the JMI file
152
if (debug) {
153                 logger.log(BasicLevel.DEBUG, "Removing the jmi file:"
154                     + jmiFile.getAbsolutePath());
155             }
156             if (jmiFile.exists() && !jmiFile.delete()) {
157                 throw new SpeedoException(
158                         "Impossible to remove the JMI file associated to the jdo file:"
159                         + xml.xmlFile);
160             }
161
162             for (int i = (enhancedClasses.size() - 1); i >= 0; i--) {
163                 SpeedoClass sc = (SpeedoClass) enhancedClasses.get(i);
164                 String JavaDoc baseName = StringReplace.replaceChar(
165                     '.', File.separatorChar, sc.getFQName());
166                 File JavaDoc classFile = new File JavaDoc(output, baseName + ".class");
167                 if (debug) {
168                     logger.log(BasicLevel.DEBUG, "Removing class files:" + classFile);
169                 }
170                 if (classFile.exists() && !classFile.delete()) {
171                     throw new SpeedoException("Impossible to remove the file:"
172                         + classFile.getAbsolutePath());
173                 }
174             }
175         } else {
176             if (xmlsToRemove == null) {
177                 xmlsToRemove = new ArrayList JavaDoc();
178             }
179             xmlsToRemove.add(xml);
180         }
181         enhancedClasses.clear();//garbage
182
}
183
184     public void visitClass(SpeedoClass sc) throws SpeedoException {
185         super.visitClass(sc);
186         SpeedoXMLDescriptor xml = sc.jdoPackage.jdoXMLDescriptor;
187         sc.requireEnhancement = xml.requireEnhancement;
188         String JavaDoc baseName = StringReplace.replaceChar(
189                 '.', File.separatorChar, sc.getFQName());
190         File JavaDoc classFile = new File JavaDoc(output, baseName + ".class");
191         boolean classExist = classFile.exists();
192         if (debug) {
193             logger.log(BasicLevel.DEBUG, "Examining the class: " + sc.getFQName());
194             if (classExist) {
195                 logger.log(BasicLevel.DEBUG, "class file: " + classFile.getAbsolutePath());
196             }
197         }
198
199         boolean javaModified = !classExist;
200         if (classExist) {
201             //compare the date of the .java and .class files
202
File JavaDoc javaFile = new File JavaDoc(scp.input, baseName + ".java");
203             logger.log(BasicLevel.DEBUG, "java file: " + javaFile.getAbsolutePath());
204             javaModified = (javaFile.lastModified() > classFile.lastModified());
205
206             if (!javaModified) {
207                 // Is the class already enhanced ?
208
try {
209                     Class JavaDoc clazz = classloader.loadClass(sc.getFQName());
210                     sc.classAlreadyEnhanced = implement(clazz, SpeedoProxy.class);
211                 } catch (NoClassDefFoundError JavaDoc e) {
212                     logger.log(BasicLevel.DEBUG, "Class " + sc.getFQName(), e);
213                     javaModified = true; //in order to delete and recompile the class
214
} catch (ClassNotFoundException JavaDoc e) {
215                     logger.log(BasicLevel.DEBUG, "Class " + sc.getFQName(), e);
216                 } catch (ClassFormatError JavaDoc e) {
217                     logger.log(BasicLevel.DEBUG, "Class " + sc.getFQName(), e);
218                 } catch (Throwable JavaDoc e) {
219                     String JavaDoc msg = "Impossible to analyze the class '" + sc.getFQName() + "': ";
220                     logger.log(BasicLevel.ERROR, msg, e);
221                     throw new SpeedoException(msg);
222                 }
223                 if (debug) {
224                     logger.log(BasicLevel.DEBUG, "The class " + sc.getFQName()
225                         + " is "
226                         + (sc.classAlreadyEnhanced ? "": "not ")
227                         + "already enhanced.");
228                 }
229             }
230         }
231         if (classExist && javaModified) {
232             logger.log(BasicLevel.INFO, "The class " + sc.getFQName() + " has been modified (Remove the .class).");
233             if (!classFile.delete()) {
234                     throw new SpeedoException("Impossible to remove the file:"
235                             + classFile.getAbsolutePath());
236             }
237         }
238         sc.requireEnhancement = !classExist || javaModified || !sc.classAlreadyEnhanced;
239         if (!sc.requireEnhancement) {
240             enhancedClasses.add(sc);
241         }
242
243         //if this class requires the enhancement, the xml too
244
xml.requireEnhancement |= sc.requireEnhancement ;
245     }
246
247     private boolean implement(Class JavaDoc clazz, Class JavaDoc itf) {
248         boolean res = Arrays.asList(clazz.getInterfaces()).contains(SpeedoProxy.class);
249         if (debug) {
250             logger.log(BasicLevel.DEBUG, "The class " + clazz.getName() + " is "
251                 + (res ? "" : "not ") + "a " + itf.getName());
252         }
253         return res || (clazz.getSuperclass() != null
254                 && implement(clazz.getSuperclass(), itf));
255     }
256 }
257
Popular Tags