PreverificationBuilder.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
eclipseme.core.internal.preverification.builder |
![]() |
![]() |
EclipseME |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/**
* Copyright (c) 2003-2005 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.internal.preverification.builder;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.ILaunch;
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 de.schlichtherle.io.ArchiveException;
import de.schlichtherle.io.File;
import de.schlichtherle.io.FileOutputStream;
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.packaging.DeployedJADWriter;
import eclipseme.core.internal.packaging.ObfuscatorTool;
import eclipseme.core.internal.preverifier.PreverificationUtils;
import eclipseme.core.internal.utils.AbstractClasspathEntryVisitor;
import eclipseme.core.internal.utils.ColonDelimitedProperties;
import eclipseme.core.internal.utils.Utils;
import eclipseme.core.model.ApplicationDescriptor;
import eclipseme.core.model.IJADConstants;
import eclipseme.core.model.IMidletSuiteProject;
import eclipseme.core.model.MidletSuiteFactory;
import eclipseme.core.model.Version;
import eclipseme.core.model.ApplicationDescriptor.MidletDefinition;
import eclipseme.preverifier.results.PreverificationError;
/**
* Provides an incremental project builder implementation
* to do a J2ME preverification of classes. It is imperative
* that this builder follow the standard Java builder. The
* standard Java builder will generate the standard compiled
* class. The preverifier will then preverify that generated
* class.
* <p />
* Copyright (c) 2003-2007 Craig Setera<br>
* All Rights Reserved.<br>
* Licensed under the Eclipse Public License - v 1.0<p/>
* <br>
* $Revision: 1.16 $
* <br>
* $Date: 2006/11/26 21:42:00 $
* <br>
* @author Craig Setera
*/
public class PreverificationBuilder extends IncrementalProjectBuilder {
public static final String ARG_UPDATE_VERSION = "_update_version";
public static final String ARG_DO_PACKAGE = "_do_package";
public static final String ARG_DO_OBFUSCATION = "_do_obfuscation";
private static BuildLoggingConfiguration buildLoggingConfig = BuildLoggingConfiguration.instance;
// Tracks the TrueZip File instances that point to the deployed jar files
private static Map runtimeJars = new HashMap(5);
/**
* Clean the output of the specified project.
* @param project
* @param cleanDeployed Whether or not to clean the deployed directory too.
* @param monitor
*
* @throws JavaModelException
* @throws CoreException
*/
public static void cleanProject(IProject project, boolean cleanDeployed, IProgressMonitor monitor)
throws JavaModelException, CoreException
{
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("> PreverificationBuilder.cleanProject project = " + project);
}
IJavaProject javaProject = JavaCore.create(project);
BuildInfo buildInfo =
new BuildInfo(IncrementalProjectBuilder.CLEAN_BUILD, new HashMap(), javaProject);
// Clear and remove the old verified directory and runtime folders
IFolder oldVerifiedFolder = project.getFolder(EclipseMECorePlugin.getVerifiedOutputDirectoryName());
if (oldVerifiedFolder.exists()) {
Utils.clearContainer(oldVerifiedFolder, monitor);
oldVerifiedFolder.delete(true, monitor);
}
IFolder oldRuntimeFolder = project.getFolder(IEclipseMECoreConstants.TEMP_FOLDER_NAME).getFolder("runtime");
if (oldRuntimeFolder.exists()) {
Utils.clearContainer(oldRuntimeFolder, monitor);
oldRuntimeFolder.delete(true, monitor);
}
// Clear the classes and libraries
IFolder classesPreverifyFolder = buildInfo.getVerifiedClassesFolder(monitor);
Utils.clearContainer(classesPreverifyFolder, monitor);
IFolder libsPreverifyFolder = buildInfo.getVerifiedLibsFolder(monitor);
Utils.clearContainer(libsPreverifyFolder, monitor);
// Delete the runtime JAR file
IFolder runtimeFolder = buildInfo.getRuntimeFolder(monitor);
if (runtimeFolder.exists()) {
deleteRuntimeJar(project, monitor);
Utils.clearContainer(runtimeFolder, monitor);
}
// We also delete the deployed folder
if (cleanDeployed) {
IFolder deploymentFolder = getDeploymentFolder(project, monitor);
if (deploymentFolder.exists()) {
Utils.clearContainer(deploymentFolder, monitor);
}
}
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("< PreverificationBuilder.cleanProject project = " + project);
}
}
/**
* Return the File instance for the runtime jar file in the specified project.
*
* @param project
* @return
*/
public static File getRuntimeJar(IProject project, IProgressMonitor monitor)
throws CoreException
{
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("> PreverificationBuilder.getRuntimeJar project = " + project);
}
File runtimeJar = (File) runtimeJars.get(project);
if (runtimeJar == null) {
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("- PreverificationBuilder.getRuntimeJar JAR file not in cache");
}
IFolder tempFolder = project.getFolder(IEclipseMECoreConstants.TEMP_FOLDER_NAME);
IFolder runtimeFolder = tempFolder.getFolder(IEclipseMECoreConstants.EMULATION_FOLDER_NAME);
createFolders(runtimeFolder, monitor);
IJavaProject javaProject = JavaCore.create(project);
IMidletSuiteProject midletSuite =
MidletSuiteFactory.getMidletSuiteProject(javaProject);
runtimeJar = new File(runtimeFolder.getLocation().toFile(), midletSuite.getJarFilename());
runtimeJar.mkdir();
runtimeFolder.refreshLocal(IResource.DEPTH_ONE, monitor);
runtimeJars.put(project, runtimeJar);
}
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("< PreverificationBuilder.getRuntimeJar project = " + project);
}
return runtimeJar;
}
/**
* Delete the deployed jar file instance being cached (if found).
*
* @param project
* @param monitor
* @throws CoreException
*/
private static void deleteRuntimeJar(IProject project, IProgressMonitor monitor)
throws CoreException
{
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("> PreverificationBuilder.deleteRuntimeJar project = " + project);
}
File runtimeJar = (File) runtimeJars.remove(project);
if ((runtimeJar != null) && (runtimeJar.exists())) {
try {
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("- PreverificationBuilder.deleteRuntimeJar jar = " + runtimeJar);
}
// Release the initial locks on the jar file and flush the
// current buffered information
File.umount(runtimeJar, true, true, true, true);
// Delete the contents of the JAR file... this is necessary
// before TrueZip will allow us to delete the top level jar
// file. While it might be possible to get to a standard
// java.io.File object to avoid this handling, this approach
// helps to make sure that TrueZip has consistent information
// about what is on the file system.
runtimeJar.deleteAll();
// Now that the contents of the jar file are gone, TrueZip will
// allow us to completely delete the file, finally releasing the
// locks on that file.
runtimeJar.delete();
IFolder tempFolder = project.getFolder(IEclipseMECoreConstants.TEMP_FOLDER_NAME);
IFolder runtimeFolder = tempFolder.getFolder(IEclipseMECoreConstants.EMULATION_FOLDER_NAME);
runtimeFolder.refreshLocal(1, monitor);
} catch (CoreException e) {
e.printStackTrace();
throw e;
} catch (ArchiveException e) {
e.printStackTrace();
EclipseMECorePlugin.throwCoreException(IStatus.ERROR, -999, e);
}
}
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("< PreverificationBuilder.deleteRuntimeJar project = " + project);
}
}
/**
* Get the folder into which the jad and jar will be written.
*
* @param project
* @param monitor
* @return
* @throws CoreException
*/
private static IFolder getDeploymentFolder(IProject project, IProgressMonitor monitor)
throws CoreException
{
String deploymentDirectoryName = EclipseMECorePlugin.getDeploymentDirectoryName();
IFolder deploymentFolder = project.getFolder(deploymentDirectoryName);
if (!deploymentFolder.exists()) {
deploymentFolder.create(false, true, monitor);
}
return deploymentFolder;
}
/**
* Implementation of the IClasspathEntryVisitor interface
* for collecting the set of required projects
*/
private static class RequiredProjectsCPEntryVisitor
extends AbstractClasspathEntryVisitor
{
private ArrayList requiredProjects;
/** Construct a new instance. */
private RequiredProjectsCPEntryVisitor() {
requiredProjects = new ArrayList();
}
/**
* @return Returns the requiredProjects.
*/
public ArrayList getRequiredProjects() {
return requiredProjects;
}
/**
* @see eclipseme.core.internal.utils.IClasspathEntryVisitor#visitProject(IClasspathEntry, org.eclipse.jdt.core.IJavaProject, org.eclipse.jdt.core.IJavaProject, org.eclipse.core.runtime.IProgressMonitor)
*/
public boolean visitProject(
IClasspathEntry entry,
IJavaProject javaProject,
IJavaProject classpathProject,
IProgressMonitor monitor)
throws CoreException
{
boolean continueVisitation = entry.isExported();
if (continueVisitation) {
requiredProjects.add(classpathProject);
}
return continueVisitation;
}
}
/**
* Create the specified folder and all parent folders as necessary.
*
* @param folder
* @param monitor
* @throws CoreException
*/
static void createFolders(IFolder folder, IProgressMonitor monitor)
throws CoreException
{
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("> PreverificationBuilder.createFolders folder = " + folder);
}
while (!folder.exists()) {
if (folder.getParent().getType() == IResource.FOLDER) {
createFolders((IFolder) folder.getParent(), monitor);
}
folder.create(true, true, monitor);
folder.setDerived(true);
}
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("< PreverificationBuilder.createFolders folder = " + folder);
}
}
/**
* Generate a MANIFEST.MF file into the deployed folder based
* on the current information in the JAD file.
*
* @param midletSuite
* @param monitor
* @throws CoreException
*/
static void generateDeployedManifest(IMidletSuiteProject midletSuite, IProgressMonitor monitor)
throws CoreException
{
IProject project = midletSuite.getProject();
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("> PreverificationBuilder.generateDeployedManifest project = " + project);
}
if (!midletSuite.getJadFile().exists()) {
BuildConsoleProxy.instance.traceln("- PreverificationBuilder.generateDeployedManifest exiting early since " + midletSuite.getJadFile() + " does not exist");
return;
}
ApplicationDescriptor applicationDescriptor =
midletSuite.getApplicationDescriptor();
Properties manifestProperties = applicationDescriptor.getManifestProperties();
// Filter out manifest attributes
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("- PreverificationBuilder.generateDeployedManifest filtering excluded properties");
}
String[] excluded = PreferenceAccessor.instance.getExcludedManifestProperties(project);
for (int i = 0; i < excluded.length; i++) {
String excludedName = excluded[i];
if (manifestProperties.containsKey(excludedName)) {
manifestProperties.remove(excludedName);
}
}
Manifest jarManifest = new Manifest();
Attributes mainAttributes = jarManifest.getMainAttributes();
mainAttributes.putValue(Attributes.Name.MANIFEST_VERSION.toString(), "1.0");
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("- PreverificationBuilder.generateDeployedManifest setting properties into Manifest object");
}
Iterator iterator = manifestProperties.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
try {
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("- PreverificationBuilder.generateDeployedManifest -- " + entry.getKey() + " -> " + entry.getValue());
}
mainAttributes.putValue((String) entry.getKey(), (String) entry.getValue());
} catch (IllegalArgumentException e) {
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("- PreverificationBuilder.generateDeployedManifest exception: " + e);
}
Status s = new Status(
IStatus.ERROR,
IEclipseMECoreConstants.PLUGIN_ID,
-999,
"Illegal Manifest Entry Key or Value \"" + e.getMessage() + "\"",
e);
throw new CoreException(s);
}
}
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("- PreverificationBuilder.generateDeployedManifest setting MIDlet definitions");
}
Iterator iter = applicationDescriptor.getMidletDefinitions().iterator();
while (iter.hasNext()) {
MidletDefinition def = (MidletDefinition) iter.next();
String key = ApplicationDescriptor.MIDLET_PREFIX + def.getNumber();
String value = def.toString();
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("- PreverificationBuilder.generateDeployedManifest -- " + key + " -> " + value);
}
mainAttributes.putValue(key, value);
}
FileOutputStream fos = null;
File manifestFile = new File(getRuntimeJar(project, monitor), "META-INF/MANIFEST.MF");
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("- PreverificationBuilder.generateDeployedManifest writing manifest file: " + manifestFile);
}
try {
fos = new FileOutputStream(manifestFile);
jarManifest.write(fos);
} catch (IOException e) {
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("- PreverificationBuilder.generateDeployedManifest exception: " + e);
}
Status s = new Status(
IStatus.ERROR,
IEclipseMECoreConstants.PLUGIN_ID,
-999,
"Illegal Manifest Entry Key or Value \"" + e.getMessage() + "\"",
e);
throw new CoreException(s);
} finally {
if (fos != null) {
try { fos.close(); } catch (IOException e) {}
}
}
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("< PreverificationBuilder.generateDeployedManifest suite = " + midletSuite.getProject());
}
}
/**
* Construct a new builder instance.
*
*/
public PreverificationBuilder() {
}
/**
* @see org.eclipse.core.resources.IncrementalProjectBuilder#build(int, java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
*/
protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
throws CoreException
{
IProject project = getProject();
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("> PreverificationBuilder.build project = " + project);
}
IJavaProject rootJavaProject = JavaCore.create(project);
IJavaProject javaProject = rootJavaProject;
IJavaProject[] requiredProjects = getRequiredProjects(javaProject, monitor);
// TODO Fix monitoring
monitor.beginTask("Preverification", requiredProjects.length + 1);
BuildInfo buildInfo = new BuildInfo(kind, args, javaProject);
// Update the manifest version if specified
boolean updateVersionForProject =
PreferenceAccessor.instance.getAutoversionPackage(project) &&
buildInfo.isBuildArgumentTrue(ARG_UPDATE_VERSION);
if (updateVersionForProject) {
updateJADVersion(buildInfo, monitor);
} else {
generateDeployedManifest(buildInfo.getMidletSuite(), monitor);
}
// Start with our project
preverifyProject(buildInfo, monitor);
// Now prereq projects
for (int i = 0; i < requiredProjects.length; i++) {
javaProject = requiredProjects[i];
if (javaProject != null) {
buildInfo.setCurrentJavaProject(javaProject);
preverifyProject(buildInfo, monitor);
}
}
// Make sure all of the libraries in the project have been
// preverified
if (buildInfo.isClasspathChanged() && buildInfo.areLibrariesPreverified()) {
IFolder libsFolder = buildInfo.getVerifiedLibsFolder(monitor);
Utils.clearContainer(libsFolder, monitor);
buildInfo.setCurrentJavaProject(rootJavaProject);
preverifyLibraries(buildInfo, monitor);
for (int i = 0; i < requiredProjects.length; i++) {
javaProject = requiredProjects[i];
buildInfo.setCurrentJavaProject(javaProject);
preverifyLibraries(buildInfo, monitor);
}
}
// Convert to IProject instances
IProject[] interestingProjects = new IProject[requiredProjects.length];
for (int i = 0; i < requiredProjects.length; i++) {
interestingProjects[i] = requiredProjects[i].getProject();
}
// Make sure that the TrueZIP caches are forced out to the file system
// and update the JAD file to contain the correct size
if (buildInfo.isPackageDirty()) {
try {
File runtimeJar = buildInfo.getRuntimeJarFile(monitor);
File.umount(runtimeJar, true, true, true, true);
writeJADFile(buildInfo, runtimeJar, buildInfo.getRuntimeFolder(monitor), true, monitor);
} catch (ArchiveException e) {
EclipseMECorePlugin.throwCoreException(IStatus.ERROR, -999, e);
}
}
// Obfuscate as requested
if (buildInfo.isBuildArgumentTrue(ARG_DO_PACKAGE)) {
buildInfo.setPackageDirty(true);
if (buildInfo.isBuildArgumentTrue(ARG_DO_OBFUSCATION)) {
doObfuscation(buildInfo, monitor);
} else {
copyRuntimeJarToDeploymentFolder(buildInfo, monitor);
}
}
// Refresh...
if (buildInfo.isPackageDirty()) {
generateDeployedManifest(buildInfo.getMidletSuite(), monitor);
IFolder deployedFolder = getDeploymentFolder(project, monitor);
deployedFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
// Set all of the resources in the verified path
// to be derived resources
setResourcesAsDerived(buildInfo.getVerifiedClassesFolder(monitor), monitor);
setResourcesAsDerived(buildInfo.getVerifiedLibsFolder(monitor), monitor);
setResourcesAsDerived(buildInfo.getRuntimeFolder(monitor), monitor);
}
monitor.done();
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("< PreverificationBuilder.build project = " + project);
}
return interestingProjects;
}
/* (non-Javadoc)
* @see org.eclipse.core.internal.events.InternalBuilder#clean(org.eclipse.core.runtime.IProgressMonitor)
*/
protected void clean(IProgressMonitor monitor)
throws CoreException
{
IProject project = getProject();
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("> PreverificationBuilder.clean project = " + project);
}
super.clean(monitor);
cleanProject(project, false, monitor);
// Regenerate the manifest
IMidletSuiteProject suite =
MidletSuiteFactory.getMidletSuiteProject(JavaCore.create(getProject()));
generateDeployedManifest(suite, monitor);
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("< PreverificationBuilder.clean project = " + project);
}
}
/**
* Copy the runtime jar file to the deployed folder.
*
* @param buildInfo
* @param monitor
* @throws CoreException
*/
private void copyRuntimeJarToDeploymentFolder(BuildInfo buildInfo, IProgressMonitor monitor)
throws CoreException
{
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("> PreverificationBuilder.copyRuntimeJarToDeploymentFolder");
}
FileInputStream fis = null;
try {
File runtimeJar = getRuntimeJar(getProject(), monitor);
fis = new FileInputStream(runtimeJar);
IFolder deploymentFolder = getDeploymentFolder(buildInfo, monitor);
IFile deployedJar = deploymentFolder.getFile(runtimeJar.getName());
if (deployedJar.exists()) {
deployedJar.setContents(fis, true, false, monitor);
} else {
deployedJar.create(fis, true, monitor);
}
writeJADFile(buildInfo, new File(deployedJar.getLocation().toFile()), deploymentFolder, false, monitor);
} catch (IOException e) {
EclipseMECorePlugin.throwCoreException(IStatus.ERROR, 999, e);
} finally {
if (fis != null) {
try { fis.close(); } catch (IOException e) { }
}
}
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("< PreverificationBuilder.copyRuntimeJarToDeploymentFolder");
}
}
/**
* Do the work to obfuscate the jar file.
* @param deployedJarFile
* @param monitor
*
* @throws CoreException
*/
private void doObfuscation(BuildInfo buildInfo, IProgressMonitor monitor)
throws CoreException
{
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("> PreverificationBuilder.doObfuscation");
}
final StringBuffer errorText = new StringBuffer();
File runtimeJar = buildInfo.getRuntimeJarFile(monitor);
BuildConsoleProxy.instance.traceln("Obfuscating " + runtimeJar);
// Calculate the name of the obfuscated jar file name...
Path runtimeJarPath = new Path(runtimeJar.getAbsolutePath());
String basename = runtimeJarPath.lastSegment();
basename = basename.substring(0, basename.length() - 4); // Making an assumption of .jar file extension
IFolder deploymentFolder = getDeploymentFolder(buildInfo, monitor);
IFile obfuscatedJarFile = deploymentFolder.getFile(basename + "_obf.jar");
IFile deployedJarFile = deploymentFolder.getFile(runtimeJarPath.lastSegment());
BuildConsoleProxy.instance.traceln("Obfuscating to output jar " + obfuscatedJarFile.getLocation().toFile());
ObfuscatorTool obfuscator =
new ObfuscatorTool(buildInfo.getMidletSuite(), runtimeJar, obfuscatedJarFile.getLocation().toFile());
ILaunch launch = obfuscator.launch(monitor);
// Snag any error output that might occur
final StringBuffer stdoutBuffer = new StringBuffer();
IProcess[] processes = launch.getProcesses();
if ((processes != null) && (processes.length > 0)) {
IProcess process = processes[0];
IStreamsProxy proxy = process.getStreamsProxy();
// Wire up a listener to write to the console if logging is
// enabled
if (buildLoggingConfig.isObfuscationOutputEnabled()) {
BuildConsoleProxy.instance.traceln("======================== Launching Obfuscation =========================");
BuildConsoleProxy.instance.addConsoleStreamListener(
IBuildConsoleProxy.ID_ERROR_STREAM,
proxy.getErrorStreamMonitor());
BuildConsoleProxy.instance.addConsoleStreamListener(
IBuildConsoleProxy.ID_OUTPUT_STREAM,
proxy.getOutputStreamMonitor());
}
proxy.getErrorStreamMonitor().addListener(new IStreamListener() {
public void streamAppended(String text, IStreamMonitor monitor) {
errorText.append(text);
}
});
// Wait until completion
while ((!monitor.isCanceled()) && (!process.isTerminated())) {
try { Thread.sleep(1000); } catch (InterruptedException e) {};
}
if (buildLoggingConfig.isObfuscationOutputEnabled()) {
BuildConsoleProxy.instance.traceln("======================== Obfuscation exited with code: " + process.getExitValue());
}
// Log the stdout if requested
if (stdoutBuffer.length() > 0) {
EclipseMECorePlugin.log(IStatus.INFO, stdoutBuffer.toString());
}
// Let the user know that something went wrong if necessary
boolean doFinalPreverify = true;
if (errorText.length() > 0) {
String text = errorText.toString();
IStatus status = new Status(
IStatus.ERROR,
IEclipseMECoreConstants.PLUGIN_ID,
IEclipseMECoreConstants.ERR_OBFUSCATION_ERRORS,
text, null);
Boolean response = (Boolean) EclipseMECorePlugin.statusPrompt(status, this);
doFinalPreverify = (response != null) ? response.booleanValue() : false;
}
if (doFinalPreverify) {
doPostObfuscationPreverification(buildInfo, obfuscatedJarFile, deployedJarFile, monitor);
}
}
writeJADFile(buildInfo, new File(deployedJarFile.getLocation().toFile()), deploymentFolder, false, monitor);
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("< PreverificationBuilder.doObfuscation");
}
}
/**
* Do the preverification necessary after obfuscation occurs.
*
* @param obfuscatedJar
* @param deployedJarFile
* @param monitor
* @throws CoreException
* @throws IOException
*/
private void doPostObfuscationPreverification(
BuildInfo buildInfo,
IFile obfuscatedJar,
IFile deployedJarFile,
IProgressMonitor monitor)
throws CoreException
{
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("> PreverificationBuilder.doPostObfuscationPreverification");
BuildConsoleProxy.instance.traceln("- Obfuscated jar: " + obfuscatedJar.getLocation().toFile());
BuildConsoleProxy.instance.traceln("- Deployed jar file: " + deployedJarFile.getLocation().toFile());
}
try {
// Create a temporary directory to handle the preverification
// output
IFolder deployFolder = (IFolder) obfuscatedJar.getParent();
IFolder tempFolder = deployFolder.getFolder("temp");
if (!tempFolder.exists()) tempFolder.create(true, true, monitor);
// Preverify the jar file into the temp directory
BuildConsoleProxy.instance.traceln("Preverifying obfuscated jar into " + tempFolder.getLocation().toFile());
File jarFile = new File(obfuscatedJar.getLocation().toFile());
PreverificationError[] errors =
buildInfo.getMidletSuite().preverifyJarFile(jarFile, tempFolder, monitor);
tempFolder.refreshLocal(IResource.DEPTH_ONE, monitor);
// Check for errors
if (errors.length > 0) {
BuildConsoleProxy.instance.traceln(errors.length + " errors occurred during post-obfuscation preverification");
handlePreverificationErrors(errors);
}
// Copy the result back into the deployment directory
IFile finalJarFile = getJarFile(buildInfo, deployFolder, false);
IFile preverified = tempFolder.getFile(obfuscatedJar.getName());
Utils.copyFile(preverified, finalJarFile);
BuildConsoleProxy.instance.traceln("Copying " + preverified + " to " + finalJarFile.getLocation().toFile());
// Clean up the temp directory
BuildConsoleProxy.instance.traceln("Deleting " + preverified.getLocation().toFile());
preverified.delete(true, monitor);
BuildConsoleProxy.instance.traceln("Deleting " + tempFolder.getLocation().toFile());
tempFolder.delete(true, monitor);
} catch (IOException e) {
EclipseMECorePlugin.throwCoreException(IStatus.ERROR, 999, e);
}
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("< PreverificationBuilder.doPostObfuscationPreverification");
}
}
/**
* Get the folder into which the jad and jar will be written.
*
* @param monitor
* @return
* @throws CoreException
*/
private IFolder getDeploymentFolder(BuildInfo buildInfo, IProgressMonitor monitor)
throws CoreException
{
return getDeploymentFolder(buildInfo.getMidletSuite().getProject(), monitor);
}
/**
* Get the IFile instance into which the JAR will be
* written.
*
* @return
*/
private IFile getJarFile(
BuildInfo buildInfo,
IFolder deploymentFolder,
boolean obfuscateName)
{
String jarFileName = buildInfo.getMidletSuite().getJarFilename();
if (obfuscateName) {
int length = jarFileName.length();
jarFileName = jarFileName.substring(0, length - 4) + "_base.jar";
}
return deploymentFolder.getFile(jarFileName);
}
/**
* Get the projects that are required by the project being built.
*
* @param javaProject
* @param monitor
* @return
* @throws CoreException
*/
private IJavaProject[] getRequiredProjects(
IJavaProject javaProject,
IProgressMonitor monitor)
throws CoreException
{
RequiredProjectsCPEntryVisitor visitor = new RequiredProjectsCPEntryVisitor();
visitor.getRunner().run(javaProject, visitor, monitor);
ArrayList projects = visitor.getRequiredProjects();
return (IJavaProject[]) projects.toArray(new IJavaProject[projects.size()]);
}
/**
* Return the integer value of the specified component string value.
*
* @param stringValue
* @return
*/
private int getVersionComponentValue(String stringValue) {
int value = 0;
if (stringValue != null) {
try {
value = Integer.parseInt(stringValue);
} catch (NumberFormatException e) { /* Munch */ }
}
return value;
}
/**
* Add text based on the specified error to the string buffer.
*
* @param sb
* @param error
*/
/**
* Handle preverification errors that were encountered
* while obfuscating.
*
* @param errors
* @throws CoreException
*/
private void handlePreverificationErrors(PreverificationError[] errors)
throws CoreException
{
StringBuffer sb = new StringBuffer("Errors preverifying jar\n");
for (int i = 0; i < errors.length; i++) {
if (i != 0) sb.append("\n");
sb.append(PreverificationUtils.getErrorText(errors[i]));
}
EclipseMECorePlugin.throwCoreException(IStatus.ERROR, -999, sb.toString());
}
/**
* Preverify the libraries associated with the current java project
* in the build info.
*
* @param buildInfo
* @param monitor
* @throws CoreException
*/
private void preverifyLibraries(BuildInfo buildInfo, IProgressMonitor monitor)
throws CoreException
{
IProject project = buildInfo.getCurrentJavaProject().getProject();
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("> PreverificationBuilder.preverifyLibraries project = " + project);
}
if ((project != null) && project.isAccessible()) {
monitor.setTaskName("Preverifying " + project.getName());
// Figure the resource delta to be used
buildInfo.setCurrentResourceDelta(null);
if (buildInfo.getBuildKind() != FULL_BUILD) {
buildInfo.setCurrentResourceDelta(getDelta(project));
}
// Hand off to the build helper for the heavy lifting
ResourceDeltaBuilder deltaBuilder = new ResourceDeltaBuilder(buildInfo);
deltaBuilder.preverifyLibraries(monitor);
monitor.worked(1);
}
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("< PreverificationBuilder.preverifyLibraries project = " + project);
}
}
/**
* Preverify the project based on the specified build information.
*
* @param buildInfo
* @param monitor
* @throws CoreException
*/
private void preverifyProject(BuildInfo buildInfo, IProgressMonitor monitor)
throws CoreException
{
IProject project = buildInfo.getCurrentJavaProject().getProject();
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("> PreverificationBuilder.preverifyProject project = " + project);
}
if ((project != null) && project.isAccessible()) {
monitor.setTaskName("Preverifying " + project.getName());
// Figure the resource delta to be used
buildInfo.setCurrentResourceDelta(null);
if (buildInfo.getBuildKind() != FULL_BUILD) {
buildInfo.setCurrentResourceDelta(getDelta(project));
}
// Hand off to the build helper for the heavy lifting
ResourceDeltaBuilder deltaBuilder = new ResourceDeltaBuilder(buildInfo);
deltaBuilder.build(monitor);
}
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("< PreverificationBuilder.preverifyProject project = " + project);
}
}
/**
* Set the resources in the output directory to
* be derived so they are left alone by the team support.
*
* @param verifiedFolder
* @param monitor
* @throws CoreException
*/
private void setResourcesAsDerived(
IFolder verifiedFolder,
IProgressMonitor monitor)
throws CoreException
{
// Refresh from the folder down so that we can
// set derived on these...
verifiedFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
// Get the starting folder
EclipseMECorePlugin.setResourcesAsDerived(verifiedFolder);
}
/**
* Write the JAD file for the jar file into the specified location.
*
* @param buildInfo
* @param targetFolder
* @param monitor
*
* @throws CoreException
* @throws IOException
*/
private void writeJADFile(
BuildInfo buildInfo,
File jarFile,
IFolder targetFolder,
boolean incrementalBuild,
IProgressMonitor monitor)
throws CoreException
{
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("> PreverificationBuilder.writeJADFile jar = " + jarFile + "; targetFolder = " + targetFolder);
}
DeployedJADWriter writer = new DeployedJADWriter(
buildInfo.getMidletSuite(),
targetFolder,
new java.io.File(jarFile.getAbsolutePath()));
try {
writer.writeDeployedJAD(incrementalBuild, monitor);
} catch (IOException e) {
EclipseMECorePlugin.throwCoreException(IStatus.ERROR, 999, e);
}
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("< PreverificationBuilder.writeJADFile");
}
}
/**
* Update the JAD version in the manifest properties.
* @throws IOException
* @throws CoreException
*/
private void updateJADVersion(BuildInfo buildInfo, IProgressMonitor monitor)
throws CoreException
{
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("> PreverificationBuilder.updateJADVersion");
}
// Read the source jad file and update the jar file
// length property.
ApplicationDescriptor appDescriptor =
buildInfo.getMidletSuite().getApplicationDescriptor();
ColonDelimitedProperties jadProperties = appDescriptor.getManifestProperties();
// Calculate the updated version string
String versionString =
jadProperties.getProperty(IJADConstants.JAD_MIDLET_VERSION, "0.0.0");
Version version = new Version(versionString);
int major = getVersionComponentValue(version.getMajor());
int minor = getVersionComponentValue(version.getMinor());
int secondary = getVersionComponentValue(version.getSecondary());
if (secondary >= 99) {
secondary = 0;
minor++;
} else {
secondary++;
}
StringBuffer newVersion = new StringBuffer();
newVersion.append(major).append(".").append(minor).append(".").append(secondary);
// Update the JAD
jadProperties.setProperty(IJADConstants.JAD_MIDLET_VERSION, newVersion.toString());
try {
appDescriptor.store();
} catch (IOException e) {
EclipseMECorePlugin.throwCoreException(IStatus.ERROR, 999, e);
}
generateDeployedManifest(buildInfo.getMidletSuite(), monitor);
buildInfo.getMidletSuite().getJadFile().refreshLocal(IResource.DEPTH_ONE, monitor);
if (buildLoggingConfig.isPreverifierTraceEnabled()) {
BuildConsoleProxy.instance.traceln("< PreverificationBuilder.updateJADVersion");
}
}
}
The table below shows all metrics for PreverificationBuilder.java.




