KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > language > programming > java > JavaLanguage


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.components.language.programming.java;
17
18 import java.io.File JavaDoc;
19 import java.io.IOException JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.StringTokenizer JavaDoc;
22
23 import org.apache.avalon.framework.activity.Disposable;
24 import org.apache.avalon.framework.activity.Initializable;
25 import org.apache.avalon.framework.logger.LogEnabled;
26 import org.apache.avalon.framework.parameters.ParameterException;
27 import org.apache.avalon.framework.parameters.Parameters;
28 import org.apache.avalon.framework.service.ServiceException;
29 import org.apache.avalon.framework.service.ServiceManager;
30 import org.apache.avalon.framework.service.Serviceable;
31 import org.apache.avalon.framework.thread.ThreadSafe;
32
33 import org.apache.cocoon.components.classloader.ClassLoaderManager;
34 import org.apache.cocoon.components.language.LanguageException;
35 import org.apache.cocoon.components.language.markup.xsp.XSLTExtension;
36 import org.apache.cocoon.components.language.programming.CompiledProgrammingLanguage;
37 import org.apache.cocoon.components.language.programming.CompilerError;
38 import org.apache.cocoon.components.language.programming.LanguageCompiler;
39 import org.apache.cocoon.util.ClassUtils;
40 import org.apache.cocoon.util.JavaArchiveFilter;
41 import org.apache.commons.lang.SystemUtils;
42
43 /**
44  * The Java programming language processor
45  *
46  * @author <a HREF="mailto:ricardo@apache.org">Ricardo Rocha</a>
47  * @version CVS $Id: JavaLanguage.java 124779 2005-01-10 09:36:58Z antonio $
48  */

49 public class JavaLanguage extends CompiledProgrammingLanguage
50         implements Initializable, ThreadSafe, Serviceable, Disposable {
51
52     /** The class loader */
53     private ClassLoaderManager classLoaderManager;
54
55     /** The service manager */
56     protected ServiceManager manager = null;
57
58     /** Classpath */
59     private String JavaDoc classpath;
60
61     /** The Class Loader Class Name */
62     private String JavaDoc classLoaderClass;
63     
64     /** Source code version */
65     private int compilerComplianceLevel;
66
67     /**
68      * Return the language's canonical source file extension.
69      *
70      * @return The source file extension
71      */

72     public String JavaDoc getSourceExtension() {
73         return "java";
74     }
75
76     /**
77      * Return the language's canonical object file extension.
78      *
79      * @return The object file extension
80      */

81     public String JavaDoc getObjectExtension() {
82         return "class";
83     }
84
85     /**
86      * Set the configuration parameters. This method instantiates the
87      * sitemap-specified <code>ClassLoaderManager</code>
88      *
89      * @param params The configuration parameters
90      * @throws ParameterException If the class loader manager cannot be
91      * instantiated or looked up.
92      */

93     public void parameterize(Parameters params) throws ParameterException {
94         super.parameterize(params);
95
96         
97         this.classLoaderClass = params.getParameter("class-loader", null);
98         if (this.classLoaderClass != null) {
99             try {
100                 this.classLoaderManager = (ClassLoaderManager)
101                         ClassUtils.newInstance(this.classLoaderClass);
102             } catch (Exception JavaDoc e) {
103                 throw new ParameterException("Unable to load class loader: "
104                                              + this.classLoaderClass, e);
105             }
106         } else {
107             try {
108                 getLogger().debug("Looking up " + ClassLoaderManager.ROLE);
109                 this.classLoaderManager = (ClassLoaderManager)
110                         manager.lookup(ClassLoaderManager.ROLE);
111             } catch (ServiceException e) {
112                 throw new ParameterException("Lookup of ClassLoaderManager failed", e);
113             }
114         }
115         // Get the compiler compliance level (source Code version)
116
String JavaDoc sourceVer = params.getParameter("compiler-compliance-level", "auto");
117         if (sourceVer.equalsIgnoreCase("auto")) {
118             this.compilerComplianceLevel = SystemUtils.JAVA_VERSION_INT;
119         } else {
120             try {
121                 compilerComplianceLevel = new Float JavaDoc(Float.parseFloat(sourceVer) * 100).intValue();
122             } catch (NumberFormatException JavaDoc e) {
123                 throw new ParameterException("XSP: compiler-compliance-level parameter value not valid!", e);
124             }
125         }
126     }
127
128     /**
129      * Set the global service manager.
130      *
131      * @param manager The global service manager
132      */

133     public void service(ServiceManager manager) throws ServiceException {
134         this.manager = manager;
135     }
136
137     public void initialize() throws Exception JavaDoc {
138
139         // Initialize the classpath
140
String JavaDoc systemBootClasspath = System.getProperty("sun.boot.class.path");
141         String JavaDoc systemClasspath = SystemUtils.JAVA_CLASS_PATH;
142         String JavaDoc systemExtDirs = SystemUtils.JAVA_EXT_DIRS;
143         String JavaDoc systemExtClasspath = null;
144
145         try {
146             systemExtClasspath = expandDirs(systemExtDirs);
147         } catch (Exception JavaDoc e) {
148             getLogger().warn("Could not expand Directory:" + systemExtDirs, e);
149         }
150
151         this.classpath =
152             ((super.classpath != null) ? File.pathSeparator + super.classpath : "") +
153             ((systemBootClasspath != null) ? File.pathSeparator + systemBootClasspath : "") +
154             ((systemClasspath != null) ? File.pathSeparator + systemClasspath : "") +
155             ((systemExtClasspath != null) ? File.pathSeparator + systemExtClasspath : "");
156     }
157
158     /**
159      * Actually load an object program from a class file.
160      *
161      * @param name The object program base file name
162      * @param baseDirectory The directory containing the object program file
163      * @return The loaded object program
164      * @exception LanguageException If an error occurs during loading
165      */

166     protected Class JavaDoc loadProgram(String JavaDoc name, File JavaDoc baseDirectory)
167             throws LanguageException {
168         try {
169             this.classLoaderManager.addDirectory(baseDirectory);
170             return this.classLoaderManager.loadClass(name.replace(File.separatorChar, '.'));
171         } catch (Exception JavaDoc e) {
172             throw new LanguageException("Could not load class for program '" + name + "' due to a " + e.getClass().getName() + ": " + e.getMessage());
173         }
174     }
175
176     /**
177      * Compile a source file yielding a loadable class file.
178      *
179      * @param name The object program base file name
180      * @param baseDirectory The directory containing the object program file
181      * @param encoding The encoding expected in the source file or
182      * <code>null</code> if it is the platform's default encoding
183      * @exception LanguageException If an error occurs during compilation
184      */

185     protected void compile(String JavaDoc name, File JavaDoc baseDirectory, String JavaDoc encoding)
186             throws LanguageException {
187
188         try {
189             LanguageCompiler compiler = (LanguageCompiler)this.compilerClass.newInstance();
190             // AbstractJavaCompiler is LogEnabled
191
if (compiler instanceof LogEnabled) {
192                 ((LogEnabled)compiler).enableLogging(getLogger());
193             }
194             if (compiler instanceof Serviceable) {
195                 ((Serviceable)compiler).service(this.manager);
196             }
197
198             int pos = name.lastIndexOf(File.separatorChar);
199             String JavaDoc filename = name.substring(pos + 1);
200
201             final String JavaDoc basePath = baseDirectory.getCanonicalPath();
202             String JavaDoc filepath = basePath + File.separator + name + "." + getSourceExtension();
203
204             compiler.setFile(filepath);
205             compiler.setSource(basePath);
206             compiler.setDestination(basePath);
207             compiler.setClasspath(basePath + this.classpath);
208             compiler.setCompilerComplianceLevel(compilerComplianceLevel);
209
210             if (encoding != null) {
211                 compiler.setEncoding(encoding);
212             }
213
214             if (getLogger().isDebugEnabled()) {
215                 getLogger().debug("Compiling " + filepath);
216             }
217             if (!compiler.compile()) {
218                 StringBuffer JavaDoc message = new StringBuffer JavaDoc("Error compiling ");
219                 message.append(filename);
220                 message.append(":\n");
221
222                 List JavaDoc errors = compiler.getErrors();
223                 CompilerError[] compilerErrors = new CompilerError[errors.size()];
224                 errors.toArray(compilerErrors);
225
226                 throw new LanguageException(message.toString(), filepath, compilerErrors);
227             }
228
229         } catch (InstantiationException JavaDoc e) {
230             getLogger().warn("Could not instantiate the compiler", e);
231             throw new LanguageException("Could not instantiate the compiler: " + e.getMessage());
232         } catch (IllegalAccessException JavaDoc e) {
233             getLogger().warn("Could not access the compiler class", e);
234             throw new LanguageException("Could not access the compiler class: " + e.getMessage());
235         } catch (IOException JavaDoc e) {
236             getLogger().warn("Error during compilation", e);
237             throw new LanguageException("Error during compilation: " + e.getMessage());
238         } catch (ServiceException e) {
239             getLogger().warn("Could not initialize the compiler", e);
240             throw new LanguageException("Could not initialize the compiler: " + e.getMessage());
241         }
242     }
243
244     /**
245      * Unload a previously loaded class. This method simply reinstantiates the
246      * class loader to ensure that a new version of the same class will be
247      * correctly loaded in a future loading operation
248      *
249      * @param program A previously loaded class
250      * @exception LanguageException If an error occurs during unloading
251      */

252     public void doUnload(Object JavaDoc program) throws LanguageException {
253         this.classLoaderManager.reinstantiate();
254     }
255
256     /**
257      * Escape a <code>String</code> according to the Java string constant
258      * encoding rules.
259      *
260      * @param constant The string to be escaped
261      * @return The escaped string
262      */

263     public String JavaDoc quoteString(String JavaDoc constant) {
264         return XSLTExtension.escapeJavaString(constant);
265     }
266
267     /**
268      * Expand a directory path or list of directory paths (File.pathSeparator
269      * delimited) into a list of file paths of all the jar files in those
270      * directories.
271      *
272      * @param dirPaths The string containing the directory path or list of
273      * directory paths.
274      * @return The file paths of the jar files in the directories. This is an
275      * empty string if no files were found, and is terminated by an
276      * additional pathSeparator in all other cases.
277      */

278     private String JavaDoc expandDirs(String JavaDoc dirPaths) {
279         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(dirPaths, File.pathSeparator);
280         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
281         while (st.hasMoreTokens()) {
282             String JavaDoc d = st.nextToken();
283             File JavaDoc dir = new File JavaDoc(d);
284             if (!dir.isDirectory()) {
285                 // The absence of a listed directory may not be an error.
286
if (getLogger().isWarnEnabled()) {
287                     getLogger().warn("Attempted to retrieve directory listing of non-directory " + dir.toString());
288                 }
289             } else {
290                 File JavaDoc[] files = dir.listFiles(new JavaArchiveFilter());
291                 for (int i = 0; i < files.length; i++) {
292                     buffer.append(files[i]).append(File.pathSeparator);
293                 }
294             }
295         }
296         return buffer.toString();
297     }
298
299     /**
300      * dispose
301      */

302     public void dispose() {
303         if (this.classLoaderClass == null && this.classLoaderManager != null) {
304             manager.release(this.classLoaderManager);
305             this.classLoaderManager = null;
306         }
307     }
308 }
309
Popular Tags