FileDocCategorySizeDatePackage
Compiler.javaAPI DocGlassfish v2 API13145Fri Jun 22 05:48:24 BST 2007com.sun.ejb.codegen

Compiler

public abstract class Compiler extends Object

Fields Summary
protected static final String
JAVA_EXT_DIRS_SYS_PROP
protected File
jdkDir
protected String
installRoot
protected List
options
protected List
files
protected File
fileOfFilenames
protected boolean
useFileContainingFilenames
protected static final Logger
logger
protected static final com.sun.enterprise.util.i18n.StringManager
localStrings
protected static final String
hostUniqueStr
Constructors Summary
Compiler(List theOptions, List theFiles)


	     
	
		if(theOptions == null || theOptions.size() <= 0)
			throw new JavaCompilerException("java_compiler.badargs",
				"JavaCompiler given null or empty {0} list",
				new Object[] { "options" } );
		if(theFiles == null || theFiles.size() <= 0)
			throw new JavaCompilerException("java_compiler.badargs",
				"JavaCompiler given null or empty {0} list",
				new Object[] { "file" } );
		

		options = theOptions;
		files	= theFiles;
		init();
	
Methods Summary
protected voidaddJavaFiles(java.util.List list)

		// if we aren't using a File -- add all the filenames & return
		if(!useFileContainingFilenames)
		{
			list.addAll(files);
			return;
		}
		
		// attempt to write the filenames into a file
		writeFileOfFilenames();
		
		if(fileOfFilenames == null)
		{
			// oops -- error writing the file.  Let's try the normal method
			// and hope for the best instead of bailing out!
			list.addAll(files);
			return;
		}
		
		list.add("@" + FileUtils.safeGetCanonicalPath(fileOfFilenames));
	
final voidcompile()

		try
		{
			internal_compile();
		}
		catch(JavaCompilerException jce)
		{
			throw jce;
		}
		catch(Throwable t)
		{
			// might be a ProcessExecutorException
			throw new JavaCompilerException(t);
		}
		finally
		{
			if (fileOfFilenames != null) 
			{
				if(!fileOfFilenames.delete()) // todo: add log message here!!!
					fileOfFilenames.deleteOnExit();
			}
		}
	
protected static java.lang.StringensureDoubleBackslashes(java.lang.String original)

        StringBuffer answer = new StringBuffer();
        int match = -1; // the index where the next single backslash occurs
        int placeAfterPreviousSlash = 0; // the index just after the most-recently-located backslash
        while ((match = original.indexOf("\\", placeAfterPreviousSlash)) != -1) {
            /*
             *Before we replace this slash, make sure this is not already a double-backslash that
             *we should leave as-is.  We need to insert an added backslash if any of the following is true:
             *  - the slash we found is the last character in the string
             *  - the slash found is NOT at the end and is not followed by another slash
             */
            boolean slashIsAtEnd = (match + 1) >= original.length();
            boolean slashIsDoubled = (! slashIsAtEnd) && (original.charAt(match + 1) == '\\");
            if (slashIsAtEnd || ! slashIsDoubled) {
                /*
                 *Append the part of the original string just after the previously-found backslash
                 *up to and including the just-found backslash.  Then append the second backslash to 
                 *create a quoted backslash in the result.
                 */
                answer.append(original.substring(placeAfterPreviousSlash, match + 1)).append("\\");
            }
            if (slashIsDoubled) {
                placeAfterPreviousSlash = match + 2;
            } else {
                placeAfterPreviousSlash = match + 1;
            }
        }
        answer.append(original.substring(placeAfterPreviousSlash));
        return answer.toString();
    
protected static java.lang.StringgetSystemPropertyIgnoreCase(java.lang.String key)

		Properties	p	= System.getProperties();
		Set			set = p.entrySet();

		for(Iterator it = set.iterator(); it.hasNext(); )
		{
			Map.Entry	me		= (Map.Entry)it.next();
			String		propKey = (String)me.getKey();
			
			if(key.compareToIgnoreCase(propKey) == 0)
				return (String)me.getValue();
		}
		
		return null;
	
protected static intgetTimeout(java.lang.String what, int defValue, int min, int max)

		int		to			= defValue;
		String	sysValue	= System.getProperty(what);

		if(sysValue != null)
		{
			try
			{
				to = Integer.parseInt(sysValue);
			}
			catch(Exception e)
			{
				to = defValue;
			}
		}
		
		if(to < min || to > max)
			to = defValue;

		return to;
	
final voidinit()

		installRoot = System.getProperty(Constants.INSTALL_ROOT);
		initJDKDir();
		logger.log(Level.FINE, "[Compiler] JDK Directory: " + ((jdkDir == null) ? "null" : jdkDir.getPath()));
		
		String enableJavacFileStr = System.getProperty(Constants.ENABLE_JAVAC_FILE);

		if(enableJavacFileStr != null)
			useFileContainingFilenames = Boolean.valueOf(enableJavacFileStr).booleanValue();
		else
			useFileContainingFilenames = OS.isWindows();

		internal_init();
	
final voidinitJDKDir()

            //Try this jre's parent
            String jreHome = System.getProperty("java.home");
            if(StringUtils.ok(jreHome)) {
                // on the mac the java.home does not point to the jre
                // subdirectory.
                if (OS.isDarwin()) {
                    jdkDir = new File(jreHome);
                } else {
                    jdkDir = (new File(jreHome)).getParentFile();	//jdk_dir/jre/..
                }
                
                if(FileUtils.safeIsDirectory(jdkDir)) {
                    jdkDir = FileUtils.safeGetCanonicalFile(jdkDir);
                    return;
                }
            }
        
		jdkDir = null;
                
		// Check for "JAVA_HOME" -- which is set via Server.xml during initialization
		// of the Server that is calling us.  
		
		String jh = System.getProperty("JAVA_HOME");
		
		if(StringUtils.ok(jh))
		{
			jdkDir = new File(jh);	// e.g. c:/ias7/jdk

			if(FileUtils.safeIsDirectory(jdkDir))
			{
				jdkDir = FileUtils.safeGetCanonicalFile(jdkDir);
				return;
			}
		}

		jdkDir = null;
		
		//Somehow, JAVA_HOME is not set. Try the "well-known" location...
		if(installRoot != null) {
			jdkDir = new File(installRoot + "/jdk");

			if(FileUtils.safeIsDirectory(jdkDir)) {
				jdkDir = FileUtils.safeGetCanonicalFile(jdkDir);
				return;
			}
		}
		
                //Give up!!
		jdkDir = null;
	
protected abstract voidinternal_compile()

protected abstract voidinternal_init()

protected voidlogCompilerName(java.lang.String compilerName)

		logger.log(Level.FINE, "[EJBC] Successfully compiled with " + compilerName);
	
protected static java.lang.StringprepareFileSpec(java.lang.String fileSpec)
Enclose the file spec in double quote marks and replace backslashes with double backslashes.

Embedded spaces in file paths confuse the compiler into thinking that the command line argument has ended at the space, whereas in fact the argument should continue on. By enclosing the file paths in double quote marks we prevent this.

param
the file spec to be prepared
return
the adjusted file spec

        String result = "\"" + ensureDoubleBackslashes(fileSpec) + "\"";
        return result;
    
protected voidrunProcess(java.lang.String[] cmds, long timeout)

		ProcessExecutor exec = new ProcessExecutor(cmds, timeout);
		exec.execute();
		// they are always empty! FIXME
		//logger.log(Level.FINER, "STDOUT: " + exec.getStdout());
		//logger.log(Level.FINER, "STDERR: " + exec.getStderr());
	
protected voidwriteFileOfFilenames()
Construct a temporary file containing a list of java separated by line breaks.

Sets fileOfFilenames to the created temp file object, or to null if there was a problem.

		fileOfFilenames = null;
		BufferedWriter writer = null;
		
		try 
		{
			fileOfFilenames = File.createTempFile(
				hostUniqueStr +
				Long.toString(UniqueIdGenerator.getInstance().getNextUniqueId(), 16) +
				"_", ".s1a");

			writer = new BufferedWriter(new FileWriter(fileOfFilenames));

			for(Iterator it = files.iterator(); it.hasNext(); )
			{
                                /*
                                 *If the file spec includes any embedded blank, enclose the file spec
                                 *in double quote marks and make sure single backslashes are doubled
                                 *because Java's string manipulation treats single backslashes as 
                                 *quote characters.
                                 */
                                String fileSpec = (String) it.next();
                                if (fileSpec.indexOf(' ") != -1) {
                                    fileSpec = prepareFileSpec(fileSpec);
                                }
				writer.write(fileSpec);
				writer.newLine();
			}
		}
		catch(Exception e)
		{
			fileOfFilenames = null;
		}
		
		finally 
		{
			try 
			{
				if (writer != null) 
				{
					writer.close();
				}
			} 
			catch(Exception ex) 
			{
			}
		}