KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > ejb > codegen > Compiler


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * JavaCompiler.java
26  *
27  * Created on June 22, 2002, 8:56 PM
28  *
29  * @author bnevins
30  * @version $Revision: 1.3 $
31  * <BR> <I>$Source: /cvs/glassfish/appserv-core/src/java/com/sun/ejb/codegen/Compiler.java,v $
32  *
33  */

34
35 package com.sun.ejb.codegen;
36
37 import java.util.*;
38 import java.io.*;
39 import java.util.logging.*;
40 import com.sun.logging.LogDomains;
41 import com.sun.enterprise.instance.UniqueIdGenerator;
42 import com.sun.enterprise.server.Constants;
43 import com.sun.enterprise.util.OS;
44 import com.sun.enterprise.util.i18n.StringManager;
45 import com.sun.enterprise.util.io.FileUtils;
46 import com.sun.enterprise.util.StringUtils;
47
48 abstract class Compiler
49 {
50     protected static final String JavaDoc JAVA_EXT_DIRS_SYS_PROP = "java.ext.dirs";
51
52     Compiler(List theOptions, List theFiles) throws JavaCompilerException
53     {
54         if(theOptions == null || theOptions.size() <= 0)
55             throw new JavaCompilerException("java_compiler.badargs",
56                 "JavaCompiler given null or empty {0} list",
57                 new Object JavaDoc[] { "options" } );
58         if(theFiles == null || theFiles.size() <= 0)
59             throw new JavaCompilerException("java_compiler.badargs",
60                 "JavaCompiler given null or empty {0} list",
61                 new Object JavaDoc[] { "file" } );
62         
63
64         options = theOptions;
65         files = theFiles;
66         init();
67     }
68     
69     ///////////////////////////////////////////////////////////////////////////
70

71     final void compile() throws JavaCompilerException
72     {
73         try
74         {
75             internal_compile();
76         }
77         catch(JavaCompilerException jce)
78         {
79             throw jce;
80         }
81         catch(Throwable JavaDoc t)
82         {
83             // might be a ProcessExecutorException
84
throw new JavaCompilerException(t);
85         }
86         finally
87         {
88             if (fileOfFilenames != null)
89             {
90                 if(!fileOfFilenames.delete()) // todo: add log message here!!!
91
fileOfFilenames.deleteOnExit();
92             }
93         }
94     }
95     
96     ///////////////////////////////////////////////////////////////////////////
97

98     abstract protected void internal_compile() throws JavaCompilerException, ProcessExecutorException;
99     abstract protected void internal_init();
100     
101     ///////////////////////////////////////////////////////////////////////////
102

103     final void init()
104     {
105         installRoot = System.getProperty(Constants.INSTALL_ROOT);
106         initJDKDir();
107         logger.log(Level.FINE, "[Compiler] JDK Directory: " + ((jdkDir == null) ? "null" : jdkDir.getPath()));
108         
109         String JavaDoc enableJavacFileStr = System.getProperty(Constants.ENABLE_JAVAC_FILE);
110
111         if(enableJavacFileStr != null)
112             useFileContainingFilenames = Boolean.valueOf(enableJavacFileStr).booleanValue();
113         else
114             useFileContainingFilenames = OS.isWindows();
115
116         internal_init();
117     }
118     
119     ///////////////////////////////////////////////////////////////////////////
120

121     final void initJDKDir() {
122         // Check for "JAVA_HOME" -- which is set via Server.xml during initialization
123
// of the Server that is calling us.
124

125         String JavaDoc jh = System.getProperty("JAVA_HOME");
126         
127         if(StringUtils.ok(jh))
128         {
129             jdkDir = new File(jh); // e.g. c:/ias7/jdk
130

131             if(FileUtils.safeIsDirectory(jdkDir))
132             {
133                 jdkDir = FileUtils.safeGetCanonicalFile(jdkDir);
134                 return;
135             }
136         }
137
138         jdkDir = null;
139         
140         //Somehow, JAVA_HOME is not set. Try the "well-known" location...
141
if(installRoot != null) {
142             jdkDir = new File(installRoot + "/jdk");
143
144             if(FileUtils.safeIsDirectory(jdkDir)) {
145                 jdkDir = FileUtils.safeGetCanonicalFile(jdkDir);
146                 return;
147             }
148         }
149         
150         //can't find it! Give a last try. Try this jre's parent
151
jdkDir = null;
152
153         String JavaDoc jreHome = System.getProperty("java.home");
154         
155         if(StringUtils.ok(jreHome)) {
156                     
157                     // on the mac the java.home does not point to the jre
158
// subdirectory.
159
if (OS.isDarwin()) {
160                         jdkDir = new File(jreHome);
161                     } else {
162             jdkDir = (new File(jreHome)).getParentFile(); //jdk_dir/jre/..
163
}
164             
165             if(FileUtils.safeIsDirectory(jdkDir)) {
166                 jdkDir = FileUtils.safeGetCanonicalFile(jdkDir);
167                 return;
168             }
169         }
170
171         //Give up!!
172
jdkDir = null;
173     }
174     
175     ///////////////////////////////////////////////////////////////////////////
176

177     protected void runProcess(String JavaDoc[] cmds, long timeout) throws ProcessExecutorException
178     {
179         ProcessExecutor exec = new ProcessExecutor(cmds, timeout);
180         exec.execute();
181         // they are always empty! FIXME
182
//logger.log(Level.FINER, "STDOUT: " + exec.getStdout());
183
//logger.log(Level.FINER, "STDERR: " + exec.getStderr());
184
}
185     
186     ///////////////////////////////////////////////////////////////////////////
187

188     protected void logCompilerName(String JavaDoc compilerName)
189     {
190         logger.log(Level.FINE, "[EJBC] Successfully compiled with " + compilerName);
191     }
192     
193     ///////////////////////////////////////////////////////////////////////////
194

195     protected static String JavaDoc getSystemPropertyIgnoreCase(final String JavaDoc key)
196     {
197         Properties p = System.getProperties();
198         Set set = p.entrySet();
199
200         for(Iterator it = set.iterator(); it.hasNext(); )
201         {
202             Map.Entry me = (Map.Entry)it.next();
203             String JavaDoc propKey = (String JavaDoc)me.getKey();
204             
205             if(key.compareToIgnoreCase(propKey) == 0)
206                 return (String JavaDoc)me.getValue();
207         }
208         
209         return null;
210     }
211     
212     ///////////////////////////////////////////////////////////////////////////
213

214     protected void addJavaFiles(List list)
215     {
216         // if we aren't using a File -- add all the filenames & return
217
if(!useFileContainingFilenames)
218         {
219             list.addAll(files);
220             return;
221         }
222         
223         // attempt to write the filenames into a file
224
writeFileOfFilenames();
225         
226         if(fileOfFilenames == null)
227         {
228             // oops -- error writing the file. Let's try the normal method
229
// and hope for the best instead of bailing out!
230
list.addAll(files);
231             return;
232         }
233         
234         list.add("@" + FileUtils.safeGetCanonicalPath(fileOfFilenames));
235     }
236     
237     ///////////////////////////////////////////////////////////////////////////
238

239     /**
240      * Construct a temporary file containing a list of java separated
241      * by line breaks.
242      * <p> Sets fileOfFilenames to the created temp file object, or to null if
243      * there was a problem.
244      */

245     protected void writeFileOfFilenames()
246     {
247         fileOfFilenames = null;
248         BufferedWriter writer = null;
249         
250         try
251         {
252             fileOfFilenames = File.createTempFile(
253                 hostUniqueStr +
254                 Long.toString(UniqueIdGenerator.getInstance().getNextUniqueId(), 16) +
255                 "_", ".s1a");
256
257             writer = new BufferedWriter(new FileWriter(fileOfFilenames));
258
259             for(Iterator it = files.iterator(); it.hasNext(); )
260             {
261                                 /*
262                                  *If the file spec includes any embedded blank, enclose the file spec
263                                  *in double quote marks and make sure single backslashes are doubled
264                                  *because Java's string manipulation treats single backslashes as
265                                  *quote characters.
266                                  */

267                                 String JavaDoc fileSpec = (String JavaDoc) it.next();
268                                 if (fileSpec.indexOf(' ') != -1) {
269                                     fileSpec = prepareFileSpec(fileSpec);
270                                 }
271                 writer.write(fileSpec);
272                 writer.newLine();
273             }
274         }
275         catch(Exception JavaDoc e)
276         {
277             fileOfFilenames = null;
278         }
279         
280         finally
281         {
282             try
283             {
284                 if (writer != null)
285                 {
286                     writer.close();
287                 }
288             }
289             catch(Exception JavaDoc ex)
290             {
291             }
292         }
293     }
294     
295     ///////////////////////////////////////////////////////////////////////////
296

297     protected static int getTimeout(String JavaDoc what, int defValue, int min, int max)
298     {
299         int to = defValue;
300         String JavaDoc sysValue = System.getProperty(what);
301
302         if(sysValue != null)
303         {
304             try
305             {
306                 to = Integer.parseInt(sysValue);
307             }
308             catch(Exception JavaDoc e)
309             {
310                 to = defValue;
311             }
312         }
313         
314         if(to < min || to > max)
315             to = defValue;
316
317         return to;
318     }
319     
320
321     /*
322      *Replace occurences of a single backslash character with double backslashes. This
323      *allows the backslash character to make it through the quoting process
324      *as the pseudo-command line is prepared for the Java compilation. This is especially
325      *helpful for Windows platforms
326      *
327      *@param original path specification
328      *@return path spec with single backslashes replaced by double backslashes
329      */

330     protected static String JavaDoc ensureDoubleBackslashes(String JavaDoc original) {
331         StringBuffer JavaDoc answer = new StringBuffer JavaDoc();
332         int match = -1; // the index where the next single backslash occurs
333
int placeAfterPreviousSlash = 0; // the index just after the most-recently-located backslash
334
while ((match = original.indexOf("\\", placeAfterPreviousSlash)) != -1) {
335             /*
336              *Before we replace this slash, make sure this is not already a double-backslash that
337              *we should leave as-is. We need to insert an added backslash if any of the following is true:
338              * - the slash we found is the last character in the string
339              * - the slash found is NOT at the end and is not followed by another slash
340              */

341             boolean slashIsAtEnd = (match + 1) >= original.length();
342             boolean slashIsDoubled = (! slashIsAtEnd) && (original.charAt(match + 1) == '\\');
343             if (slashIsAtEnd || ! slashIsDoubled) {
344                 /*
345                  *Append the part of the original string just after the previously-found backslash
346                  *up to and including the just-found backslash. Then append the second backslash to
347                  *create a quoted backslash in the result.
348                  */

349                 answer.append(original.substring(placeAfterPreviousSlash, match + 1)).append("\\");
350             }
351             if (slashIsDoubled) {
352                 placeAfterPreviousSlash = match + 2;
353             } else {
354                 placeAfterPreviousSlash = match + 1;
355             }
356         }
357         answer.append(original.substring(placeAfterPreviousSlash));
358         return answer.toString();
359     }
360
361      /**
362      *Enclose the file spec in double quote marks and replace backslashes with
363      *double backslashes.
364      *<p>
365      *Embedded spaces in file paths confuse the compiler into thinking that the command line
366      *argument has ended at the space, whereas in fact the argument should continue on. By
367      *enclosing the file paths in double quote marks we prevent this.
368      *
369      *@param the file spec to be prepared
370      *@return the adjusted file spec
371      */

372     protected static String JavaDoc prepareFileSpec (String JavaDoc fileSpec) {
373         String JavaDoc result = "\"" + ensureDoubleBackslashes(fileSpec) + "\"";
374         return result;
375     }
376     ///////////////////////////////////////////////////////////////////////////
377

378     protected File jdkDir = null;
379     protected String JavaDoc installRoot = null;
380     protected List options;
381     protected List files;
382     protected File fileOfFilenames = null;
383     protected boolean useFileContainingFilenames = false;
384     protected static final Logger logger = LogDomains.getLogger(LogDomains.DPL_LOGGER);
385     protected static final StringManager localStrings = StringManager.getManager(JavaCompiler.class);
386     protected static final String JavaDoc hostUniqueStr = Integer.toString((new Object JavaDoc()).hashCode(), 16) + "_";
387 }
388
389
Popular Tags