📄 standardpreverifierfactory.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 <directories separated by ';'>
Directories in which to look for classes
-d <directory> Directory in which output is written (default is ./output/)
@<filename> 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 <directories separated by ';'>
Directories in which to look for classes
-d <directory> 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
@<filename> 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 -nonative -nofinalize</code>
* for CLDC 1.0 preverification and <code>-nonative -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 <directories separated by ';'>
Directories in which to look for classes
-d <directory> 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 <CLDC1.1 | CLDC1.0>
Which preverifier to run
-nofinalize No finalizers allowed
-nonative No native methods allowed
-nofp No floating point operations allowed
@<filename> 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 CLDC1.0 -nofp -nonative -nofinalize</code>
* for CLDC 1.0 preverification and <code>-target CLDC1.0 -nonative -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 + -