📄 standardpreverifier.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.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.IStreamListener;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IStreamMonitor;
import org.eclipse.debug.core.model.IStreamsProxy;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstallType;
import org.eclipse.jdt.launching.JavaRuntime;
import eclipseme.core.BuildLoggingConfiguration;
import eclipseme.core.IEclipseMECoreConstants;
import eclipseme.core.console.BuildConsoleProxy;
import eclipseme.core.console.IBuildConsoleProxy;
import eclipseme.core.internal.EclipseMECorePlugin;
import eclipseme.core.internal.PreferenceAccessor;
import eclipseme.core.internal.utils.EnvironmentVariables;
import eclipseme.core.internal.utils.TemporaryFileManager;
import eclipseme.core.internal.utils.Utils;
import eclipseme.core.model.IMidletSuiteProject;
import eclipseme.core.model.IPreverifier;
import eclipseme.core.model.Version;
import eclipseme.core.persistence.IPersistenceProvider;
import eclipseme.core.persistence.PersistenceException;
import eclipseme.preverifier.results.IClassErrorInformation;
import eclipseme.preverifier.results.PreverificationError;
import eclipseme.preverifier.results.PreverificationErrorLocation;
import eclipseme.preverifier.results.PreverificationErrorLocationType;
import eclipseme.preverifier.results.PreverificationErrorType;
/**
* A standard preverifier implementation. This preverifier
* requires the preverification binary and the available
* CLDC parameters to be specified. Once created, the
* preverifier may be stored and retrieved using the standard
* persistence mechanism.
* <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.7 $
* <br>
* $Date: 2006/12/18 02:13:47 $
* <br>
* @author Craig Setera
*/
public class StandardPreverifier implements IPreverifier {
private static final int MAX_COMMAND_LENGTH = 2000;
// The regular expression we will use to match the preverify
// error
private static final String PREV_ERR_REGEX =
"^Error preverifying class (\\S*)$";
// The compiled pattern for regular expression matching
private static final Pattern PREV_ERR_PATTERN =
Pattern.compile(PREV_ERR_REGEX, Pattern.MULTILINE);
/**
* Extract the class name from the specified
* IResource within the specified java project.
*
* @param javaProject the java project to provide the relative name
* @param resource the resource to extract a class name
* @return the class name or <code>null</code> if the resource
* name cannot be converted for some reason.
* @throws JavaModelException
*/
public static String extractClassName(
IJavaProject javaProject,
IResource resource)
throws JavaModelException
{
IPath classPath = extractResourcePath(javaProject, resource);
return (classPath == null) ? null :
classPath.removeFileExtension().toString().replace('/', '.');
}
/**
* Extract the class path from the specified
* IResource within the specified java project.
*
* @param javaProject
* @param resource
* @return the extracted resource path
* @throws JavaModelException
*/
public static IPath extractResourcePath(
IJavaProject javaProject,
IResource resource)
throws JavaModelException
{
IPath resultPath = null;
IPath projectOutputPath =
javaProject.getOutputLocation().makeAbsolute();
IPath resourcePath = resource.getFullPath();
IClasspathEntry[] classpath = javaProject.getRawClasspath();
for (int i = 0; i < classpath.length; i++) {
IClasspathEntry entry = classpath[i];
if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
IPath entryPath = entry.getOutputLocation();
entryPath = (entryPath == null) ?
projectOutputPath : entryPath.makeAbsolute();
if (entryPath.isPrefixOf(resourcePath)) {
resultPath =
resourcePath.removeFirstSegments(entryPath.segmentCount());
}
}
}
return resultPath;
}
// The executable to use for preverification
private File preverifierExecutable;
// The parameters to use
private StandardPreverifierParameters parameters;
/**
* @see eclipseme.core.persistence.IPersistable#loadUsing(eclipseme.core.persistence.IPersistenceProvider)
*/
public void loadUsing(IPersistenceProvider persistenceProvider)
throws PersistenceException
{
String preverifierExeString = persistenceProvider.loadString("preverifierExecutable");
preverifierExecutable = new File(preverifierExeString);
parameters = (StandardPreverifierParameters) persistenceProvider.loadPersistable("parameters");
}
/**
* @see eclipseme.core.model.IPreverifier#preverify(eclipseme.core.model.IMidletSuiteProject, org.eclipse.core.resources.IResource[], org.eclipse.core.resources.IFolder, org.eclipse.core.runtime.IProgressMonitor)
*/
public PreverificationError[] preverify(
IMidletSuiteProject midletProject,
IResource[] toVerify,
IFolder outputFolder,
IProgressMonitor monitor)
throws CoreException, IOException
{
ArrayList allErrors = new ArrayList();
// Create the temporary file of commands for
// the verifier
ensureFolderExists(outputFolder, monitor);
File outputFile = outputFolder.getLocation().toFile();
ArrayList baseArguments = constructCommandLine(
midletProject,
outputFile,
monitor);
ArrayList arguments = new ArrayList(baseArguments);
for (int i = 0; i < toVerify.length; i++) {
IResource resource = toVerify[i];
switch (resource.getType()) {
case IResource.FOLDER:
case IResource.PROJECT:
arguments.add(resource.getLocation().toOSString());
break;
case IResource.FILE:
if (resource.getName().endsWith(".class")) {
addClassTarget(arguments, resource);
} else if (resource.getName().endsWith(".jar")) {
arguments.add(resource.getLocation().toOSString());
}
break;
}
if (commandLength(arguments) > MAX_COMMAND_LENGTH) {
// Launch the system process
String[] commandLine = (String[]) arguments.toArray(new String[arguments.size()]);
PreverificationError[] errors = runPreverifier(commandLine, null, monitor);
allErrors.addAll(Arrays.asList(errors));
arguments = new ArrayList(baseArguments);
}
}
if (arguments.size() != baseArguments.size()) {
// Launch the system process
String[] commandLine = (String[]) arguments.toArray(new String[arguments.size()]);
PreverificationError[] errors = runPreverifier(commandLine, null, monitor);
allErrors.addAll(Arrays.asList(errors));
}
return (PreverificationError[]) allErrors.toArray(new PreverificationError[allErrors.size()]);
}
/**
* @see eclipseme.core.model.IPreverifier#preverifyJarFile(eclipseme.core.model.IMidletSuiteProject, java.io.File, org.eclipse.core.resources.IFolder, org.eclipse.core.runtime.IProgressMonitor)
*/
public PreverificationError[] preverifyJarFile(
IMidletSuiteProject midletProject,
File jarFile,
IFolder outputFolder,
IProgressMonitor monitor)
throws CoreException, IOException
{
// Rather than trying to preverify a jar file, we will expand it
// first and then preverify against the expanded classes.
File srcDirectory = TemporaryFileManager.instance.createTempDirectory(
jarFile.getName().replace('.', '_') + "_",
".tmp");
srcDirectory.mkdirs();
Utils.extractArchive(jarFile, srcDirectory);
// Create the target directory for the preverification. We will
// tell the preverifier to use this when doing the preverification.
File tgtDirectory = TemporaryFileManager.instance.createTempDirectory(
jarFile.getName().replace('.', '_') + "_",
".tmp");
tgtDirectory.mkdirs();
ArrayList arguments = constructCommandLine(
midletProject,
tgtDirectory,
monitor);
arguments.add(srcDirectory.toString());
// Launch the system process
String[] environment = getEnvironment(jarFile);
String[] commandLine = (String[]) arguments.toArray(new String[arguments.size()]);
PreverificationError[] errors = runPreverifier(commandLine, environment, monitor);
// TODO we need to test the outcome of the previous before going much further
// here...
// Copy all of the non-class resources so they end up back in the
// jar file
FileFilter classFilter = new FileFilter() {
public boolean accept(File pathname) {
return
pathname.isDirectory() ||
!pathname.getName().endsWith(".class");
}
};
Utils.copy(srcDirectory, tgtDirectory, classFilter);
// Finally, re-jar the output of the preverification into the requested jar file...
File outputJarFile = new File(outputFolder.getLocation().toFile(), jarFile.getName());
Utils.createArchive(outputJarFile, tgtDirectory);
return errors;
}
/**
* Return the length of the command-line length given the specified argument list.
*
* @param arguments
* @return
*/
private int commandLength(ArrayList arguments) {
int length = 0;
Iterator iter = arguments.iterator();
while (iter.hasNext()) {
Object arg = (Object) iter.next();
length += arg.toString().length();
if (iter.hasNext()) length++;
}
return length;
}
/**
* Construct the command line for the specified preverification.
*
* @param midletProject
* @param target
* @return
* @throws CoreException
*/
private ArrayList constructCommandLine(
IMidletSuiteProject midletProject,
File target,
IProgressMonitor monitor)
throws CoreException
{
ArrayList arguments = new ArrayList();
// The program we are running...
arguments.add(preverifierExecutable.toString());
// Configuration parameters
String[] configurationParameters = getCLDCConfigurationParameters(midletProject);
for (int i = 0; i < configurationParameters.length; i++) {
arguments.add(configurationParameters[i]);
}
addClasspath(arguments, midletProject, monitor);
addOptions(arguments, configurationParameters, target);
return arguments;
}
/**
* @return Returns the parameters.
*/
public StandardPreverifierParameters getParameters() {
return parameters;
}
/**
* @return Returns the preverifierExecutable.
*/
public File getPreverifierExecutable() {
return preverifierExecutable;
}
/**
* @param parameters The parameters to set.
*/
public void setParameters(StandardPreverifierParameters parameters) {
this.parameters = parameters;
}
/**
* @param preverifierExecutable The preverifierExecutable to set.
*/
public void setPreverifierExecutable(File preverifierExecutable) {
this.preverifierExecutable = preverifierExecutable;
}
/**
* @see eclipseme.core.persistence.IPersistable#storeUsing(eclipseme.core.persistence.IPersistenceProvider)
*/
public void storeUsing(IPersistenceProvider persistenceProvider)
throws PersistenceException
{
persistenceProvider.storeString("preverifierExecutable", preverifierExecutable.toString());
persistenceProvider.storePersistable("parameters", parameters);
}
/**
* Return the parameters to be used for controlling the CLDC
* preverification.
*
* @param midletProject
* @return
* @throws CoreException if an error occurs working with the midlet project.
*/
protected String[] getCLDCConfigurationParameters(IMidletSuiteProject midletProject)
throws CoreException
{
IProject project = midletProject.getProject();
Version configVersion =
PreferenceAccessor.instance.getPreverificationConfigurationVersion(project);
return isCLDC1_0(configVersion) ? parameters.cldc10 : parameters.cldc11;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -