⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 standardpreverifierfactory.java

📁 eclipseme的最新版本的source,欢迎j2me程序员使用
💻 JAVA
字号:
/**
 * Copyright (c) 2003-2006 Craig Setera
 * All Rights Reserved.
 * Licensed under the Eclipse Public License - v 1.0
 * For more information see http://www.eclipse.org/legal/epl-v10.html
 */
package eclipseme.core.model.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.CoreException;

import eclipseme.core.internal.utils.Utils;

/**
 * A factory implementation for generating instances of
 * StandardPreverifier with the appropriate parameters.  
 * Those parameters are retrieved by running the preverifier
 * and using the output to make an educated guess concerning
 * the required parameter structure.
 * <p>
 * There are three main categories of preverifiers that are supported
 * by this class, all of which are presumably derived from (or are copies
 * of) Sun preverifiers:
 * </p>
 * <ul>
 * <li>
 * The most basic preverifier takes no command line arguments to "tune"
 * its performance.  An example is the preverifier that comes with the
 * Motorola SDK 4.1, Emulator 7.2.  Its "usage" goes something like this:<br>
 * <pre>
Usage: preverify [options] classnames|dirnames ...

where options include:
   -classpath &lt;directories separated by ';'&gt;
                  Directories in which to look for classes
   -d &lt;directory&gt; Directory in which output is written (default is ./output/)
   &#x40;&lt;filename&gt;    Read command line arguments from a text file   
   </pre>
   <p>
 * With this category, we do not differentiate between CLDC 1.0 and CLDC 1.1
 * preverification.
 * </p>
 * </li>
 * <li>
 * The second, more recent category of preverifier has command line arguments
 * that allow the user to affect exactly what checks are performed during
 * preverification.  Usage for this category looks like this:
 * <pre>
Usage: preverify [options] classnames|dirnames ...

where options include:
   -classpath     &lt;directories separated by ';'&gt;
                  Directories in which to look for classes
   -d &lt;directory&gt; Directory in which output is written (default is ./output/)
   -cldc          Checks for existence of language features prohibited
                  by CLDC (native methods, floating point and finalizers)
   -nofinalize    No finalizers allowed
   -nonative      No native methods allowed
   -nofp          No floating point operations allowed
   &#x40;&lt;filename&gt;    Read command line arguments from a text file
                  Command line arguments must all be on a single line
                  Directory names must be enclosed in double quotes (")
</pre>
 * Some preverifiers in this category support a <code>-cldc1.0</code> argument
 * instead of, or in addition to the <code>-cldc</code> argument.
 * <p>
 * CLDC 1.0 preverification should prevent the use of floating point (<code>-nofp</code>)
 * native methods (<code>-nonative</code>) and finalizers (<code>-nofinalize</code>), all
 * of which is accomplished by the use of the <code>-cldc</code> (or <code>-cldc1.0</code>)
 * parameter.  For CLDC 1.1, however, floating point is allowed, although finalizers and
 * native methods are still prohibited.
 * </p>
 * <p>
 * For this category of preverifiers, we use the options <code>-nofp&nbsp;-nonative&nbsp;-nofinalize</code>
 * for CLDC 1.0 preverification and <code>-nonative&nbsp;-nofinalize</code> for CLDC 1.1
 * preverification.  We don't attempt to use the <code>-cldc</code> or <code>-cldc1.0</code>
 * argument for CLDC 1.0 because it's simpler and more bullet-proof just to use the
 * individual arguments.
 * </p>
 * </li>
 * <li>
 * The third category of preverifiers represent a yet more modern evolution.  These
 * add a <code>-target</code> option that effectively selects between two different
 * preverifiers.  Usage typically looks like this:
 * <pre>
Usage: preverify [options] classnames|dirnames ...

where options include:
   -classpath     &lt;directories separated by ';'&gt;
                  Directories in which to look for classes
   -d &lt;directory&gt; Directory in which output is written (default is ./output/)
   [ -cldc1.0 | -cldc ]
                  Checks for existence of language features prohibited
                  by CLDC 1.0 (native methods, floating point and finalizers)
   -target &lt;CLDC1.1 | CLDC1.0&gt;
                  Which preverifier to run
   -nofinalize    No finalizers allowed
   -nonative      No native methods allowed
   -nofp          No floating point operations allowed
   &#x40;&lt;filename&gt;    Read command line arguments from a text file
                  Command line arguments must all be on a single line
                  Directory names must be enclosed in double quotes (")
</pre>
 * <p>
 * Thus, this category of preverifier is essentially identical to the second
 * set, but with the addition of the <code>-target</code> option.  Oddly enough,
 * experience shows that specifying CLDC 1.1 or CLDC 1.0 using the <code>-target</code>
 * option does <u>not</u> result in automatic selection of the appropriate
 * <code>-nofp</code>, <code>-nonative</code>, and/or <code>-nofinalize</code>
 * options.  Thus, we include these in addition to the <code>-target</code>
 * option.
 * </p>
 * <p>
 * As a result, for this category of preverifiers, we use the options 
 * <code>-target&nbsp;CLDC1.0&nbsp;-nofp&nbsp;-nonative&nbsp;-nofinalize</code>
 * for CLDC 1.0 preverification and <code>-target&nbsp;CLDC1.0&nbsp;-nonative&nbsp;-nofinalize</code> for CLDC 1.1
 * </p>
 * </li>
 * </ul>
 * <p>
 * The basic strategy of this class is to run the preverifier without any 
 * command line arguments and capture the result.  We then inspect the output
 * for the presence of the various options and, when we find them, add them
 * to the arguments we will use for the various preverifications.  Note that
 * we have to check both the stdout results and the stderr results, because some
 * preverifiers send their usage to stdout (Sun) and other send it to stderr
 * (Motorola).
 * </p>
 * <p />
 * Copyright (c) 2003-2006 Craig Setera<br>
 * All Rights Reserved.<br>
 * Licensed under the Eclipse Public License - v 1.0<p/>
 * <br>
 * $Revision: 1.1 $
 * <br>
 * $Date: 2006/02/11 21:26:56 $
 * <br>
 * @author Craig Setera
 * @author Kevin Hunter
 */
public class StandardPreverifierFactory {
	private static final String optionNoFp = "-nofp";
	private static final String optionNoFinalize = "-nofinalize";
	private static final String optionNoNative = "-nonative";
	private static final String optionTarget = "-target";
	
	private static final Pattern PATTERN_NO_FP = 
		Pattern.compile("\\s+" + optionNoFp + "\\s+");
	private static final Pattern PATTERN_NO_FINALIZE = 
		Pattern.compile("\\s+" + optionNoFinalize + "\\s+");
	private static final Pattern PATTERN_NO_NATIVE = 
		Pattern.compile("\\s+" + optionNoNative + "\\s+");
	private static final Pattern PATTERN_TARGET = 
		Pattern.compile("\\s+" + optionTarget + "\\s+");

	// The programs that have been tested and their associated
	// program arguments
	private static final Map testedPrograms = new HashMap();

	/**
	 * Create a new StandardPreverifier instance for the specified
	 * executable.  Returns <code>null</code> if the preverifier 
	 * cannot be created for some reason.
	 * 
	 * @param preverifierExecutable
	 * @return
	 * @throws CoreException 
	 */
	public static StandardPreverifier createPreverifier(File preverifierExecutable) 
		throws CoreException 
	{
		StandardPreverifier preverifier = null;
		
		if (preverifierExecutable != null) {
			StandardPreverifierParameters parameters = getParameters(preverifierExecutable);
			if (parameters != null) {
				preverifier = createPreverifier(preverifierExecutable, parameters);
			}
		}
		
		return preverifier;
	}
	
	/**
	 * Return a new preverifier instance using the specified information.
	 * 
	 * @param preverifierExecutable
	 * @param parameters
	 * @return
	 */
	private static StandardPreverifier createPreverifier(
		File preverifierExecutable, 
		StandardPreverifierParameters parameters) 
	{
		StandardPreverifier preverifier = new StandardPreverifier();
		preverifier.setParameters(parameters);
		preverifier.setPreverifierExecutable(preverifierExecutable);
		
		return preverifier;
	}

	/**
	 * Return the appropriate parameters for use in running the specified
	 * preverifier executable.
	 * 
	 * @param preverifierExecutable
	 * @return
	 * @throws CoreException 
	 */
	private static StandardPreverifierParameters getParameters(File preverifierExecutable) 
		throws CoreException 
	{
		StandardPreverifierParameters parameters =
			(StandardPreverifierParameters) testedPrograms.get(preverifierExecutable);
		
		if ((parameters == null) && (executableExists(preverifierExecutable))) {
			parameters = collectParameters(preverifierExecutable);
			testedPrograms.put(preverifierExecutable, parameters);
		}
		
		return parameters;
	}

	/**
	 * Collect the appropriate parameters for use with this preverifier executable.
	 * 
	 * @param preverifierExecutable
	 * @return
	 * @throws CoreException 
	 */
	private static StandardPreverifierParameters collectParameters(File preverifierExecutable) 
		throws CoreException 
	{
		ArrayList cldc10 = new ArrayList();
		ArrayList cldc11 = new ArrayList();
		StringBuffer stdout = new StringBuffer();
		StringBuffer stderr = new StringBuffer();
		String[] commandLine = new String[] { preverifierExecutable.toString() };
		Utils.getProcessOutput("Sun Preverifier", commandLine, stdout, stderr);
		
		if (find(stdout, PATTERN_TARGET) || find(stderr, PATTERN_TARGET))
		{
			cldc10.add(optionTarget);
			cldc10.add("CLDC1.0");
			cldc11.add(optionTarget);
			cldc11.add("CLDC1.1");
		}
		
		if (find(stdout, PATTERN_NO_FP) || find(stderr, PATTERN_NO_FP))
		{
			cldc10.add(optionNoFp);
		}
		
		if (find(stdout, PATTERN_NO_FINALIZE) || find(stderr, PATTERN_NO_FINALIZE))
		{
			cldc10.add(optionNoFinalize);
			cldc11.add(optionNoFinalize);
		}
		
		if (find(stdout, PATTERN_NO_NATIVE) || find(stderr, PATTERN_NO_NATIVE))
		{
			cldc10.add(optionNoNative);
			cldc11.add(optionNoNative);
		}
		
		StandardPreverifierParameters params = new StandardPreverifierParameters();
		params.cldc10 = (String[]) cldc10.toArray(new String[cldc10.size()]);
		params.cldc11 = (String[]) cldc11.toArray(new String[cldc11.size()]);
		return params;
	}

	/**
	 * Return a boolean indicating whether the specified string buffer
	 * matches the specified pattern.
	 * 
	 * @param buffer
	 * @param pattern
	 * @return
	 */
	private static boolean find(StringBuffer buffer, Pattern pattern) {
		return pattern.matcher(buffer).find();
	}

	/**
	 * Return a boolean indicating whether the specified executable exists.
	 * 
	 * @param executable
	 * @return
	 */
	private static boolean executableExists(File executable) {
		boolean exists = executable.exists();
		if (!exists) {
			File withExe = new File(executable.toString() + ".exe");
			exists = withExe.exists();
		}
		
		return exists;
	}
	
	/**
	 * Private constructor for static-only access.
	 */
	private StandardPreverifierFactory() {
		super();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -