### Eclipse Workspace Patch 1.0 #P org.eclipse.mtj.core Index: src/org/eclipse/mtj/internal/core/project/midp/MidletSuiteProject.java =================================================================== --- src/org/eclipse/mtj/internal/core/project/midp/MidletSuiteProject.java (revision 1130) +++ src/org/eclipse/mtj/internal/core/project/midp/MidletSuiteProject.java (working copy) @@ -60,6 +60,7 @@ import org.eclipse.jdt.core.JavaConventions; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.mtj.core.IMTJCoreConstants; import org.eclipse.mtj.core.MTJCore; import org.eclipse.mtj.core.build.preverifier.IPreverificationError; import org.eclipse.mtj.core.build.preverifier.IPreverifier; @@ -74,7 +75,6 @@ import org.eclipse.mtj.core.project.runtime.MTJRuntimeList; import org.eclipse.mtj.core.sdk.device.IDevice; import org.eclipse.mtj.core.sdk.device.midp.IMIDPDevice; -import org.eclipse.mtj.internal.core.IMTJCoreConstants; import org.eclipse.mtj.internal.core.Messages; import org.eclipse.mtj.internal.core.build.BuildSpecManipulator; import org.eclipse.mtj.internal.core.build.BuildStateMachine; @@ -97,6 +97,8 @@ *

* * @author Craig Setera + * Gustavo de Paula (Motorola) - Add proguard preverifier options + * David Aragão (Motorola) - Add proguard preverifier refactoring * @noextend This class is not intended to be subclassed by clients. */ public final class MidletSuiteProject implements IMidletSuiteProject { @@ -123,10 +125,8 @@ */ public static String getDefaultJadFileName(IProject project) { String projectName = project.getName(); - return NLS.bind(IMTJCoreConstants.VERSION_NLS_BIND_TEMPLATE, - new String[] { projectName.replace(' ', '_'), - APP_DESCRIPTOR_FILE_EXT }); //$NON-NLS-1$ - + return NLS.bind("{0}.{1}", new String[] { + projectName.replace(' ', '_'), APP_DESCRIPTOR_FILE_EXT }); //$NON-NLS-1$ } // The java project on which this MIDlet suite is based @@ -164,7 +164,7 @@ initializeMetadata(); MTJRuntime mtjRuntime = getRuntimeList().getActiveMTJRuntime(); - if ((mtjRuntime != null) && (mtjRuntime.getDevice() == null)) { + if (mtjRuntime != null && mtjRuntime.getDevice() == null) { try { if (getProject().findMarkers( IMTJCoreConstants.JAVAME_MISSING_DEVICE_MARKER, false, @@ -205,9 +205,8 @@ * org.eclipse.mtj.core.project.IMTJProject#createPackage(org.eclipse.core * .runtime.IProgressMonitor, boolean, boolean) */ - public void createPackage(boolean obfuscate, - boolean packageInactiveConfigs, IProgressMonitor monitor) - throws CoreException { + public void createPackage(IProgressMonitor monitor, boolean obfuscate, + boolean packageInactiveConfigs) throws CoreException { Map args = new HashMap(); args.put(PackageBuilder.ARG_DO_PACKAGE, Boolean.TRUE.toString()); @@ -224,7 +223,7 @@ BuildSpecManipulator manipulator = new BuildSpecManipulator(this .getProject()); // Set builder arguments - manipulator.setBuilderArguments(IMTJCoreConstants.PACKAGE_BUILDER_ID, + manipulator.setBuilderArguments(org.eclipse.mtj.internal.core.IMTJCoreConstants.PACKAGE_BUILDER_ID, args); manipulator.commitChanges(monitor); @@ -235,7 +234,7 @@ } // Reset builder Arguments - manipulator.setBuilderArguments(IMTJCoreConstants.PACKAGE_BUILDER_ID, + manipulator.setBuilderArguments(org.eclipse.mtj.internal.core.IMTJCoreConstants.PACKAGE_BUILDER_ID, new HashMap()); manipulator.commitChanges(monitor); @@ -794,7 +793,7 @@ stateMachine.start(monitor); getProject().build(IncrementalProjectBuilder.FULL_BUILD, - IMTJCoreConstants.PACKAGE_BUILDER_ID, args, monitor); + org.eclipse.mtj.internal.core.IMTJCoreConstants.PACKAGE_BUILDER_ID, args, monitor); } } // restore project settings after packaging configs @@ -905,4 +904,12 @@ } } + @Override + public void createPackage(boolean obfuscate, + boolean packageInactiveConfigs, IProgressMonitor monitor) + throws CoreException { + // TODO Auto-generated method stub + + } + } Index: src/org/eclipse/mtj/internal/core/IMTJCoreConstants.java =================================================================== --- src/org/eclipse/mtj/internal/core/IMTJCoreConstants.java (revision 1130) +++ src/org/eclipse/mtj/internal/core/IMTJCoreConstants.java (working copy) @@ -76,7 +76,11 @@ public static final String PREF_PREVERIFY_CONFIG_LOCATION = "preverify_config_location"; //$NON-NLS-1$ public static final String PREF_PREVERIFY_CONFIG_VALUE = "preverify_config_value"; //$NON-NLS-1$ public static final String PREF_DEFAULT_PREVERIFIER = "default_preverifier"; //$NON-NLS-1$ - + public static final String PREF_PREVERIFY_TYPE = "preverify_type"; //$NON-NLS-1$ + public static final String PREF_PREVERIFY_TYPE_EMULATOR = "preverify_emulator"; //$NON-NLS-1$ + public static final String PREF_PREVERIFY_TYPE_BUILTIN = "preverify_builtin"; //$NON-NLS-1$ + public static final String PREF_PREVERIFY_TYPE_PROGUARD = "preverify_proguard"; //$NON-NLS-1$ + public static final String PREF_PREVERIFY_CONFIG_LOCATION_JAD = "jad"; //$NON-NLS-1$ public static final String PREF_PREVERIFY_CONFIG_LOCATION_PLATFORM = "platform"; //$NON-NLS-1$ public static final String PREF_PREVERIFY_CONFIG_LOCATION_SPECIFIED = "specified"; //$NON-NLS-1$ Index: src/org/eclipse/mtj/internal/core/PreferenceAccessor.java =================================================================== --- src/org/eclipse/mtj/internal/core/PreferenceAccessor.java (revision 1130) +++ src/org/eclipse/mtj/internal/core/PreferenceAccessor.java (working copy) @@ -44,6 +44,8 @@ * A helper wrapper around the more complex preferences supported by MTJ. * * @author Craig Setera + * + * Gustavo de Paula (Motorola) - Add proguard preverifier */ public class PreferenceAccessor { @@ -354,4 +356,17 @@ return prefNode; } + + /** + * + * @param project + * @return + */ + public String getPreverifierType (IProject project) { + IEclipsePreferences preferences = getProjectPreferences(project, + IMTJCoreConstants.PREF_PREVERIFY_USE_PROJECT, + IMTJCoreConstants.PREF_PREVERIFY_TYPE); + return preferences.get(IMTJCoreConstants.PREF_PREVERIFY_TYPE, + MTJCorePreferenceInitializer.PREF_DEF_PREVERIFY_TYPE); + } } Index: src/org/eclipse/mtj/internal/core/MTJCorePreferenceInitializer.java =================================================================== --- src/org/eclipse/mtj/internal/core/MTJCorePreferenceInitializer.java (revision 1130) +++ src/org/eclipse/mtj/internal/core/MTJCorePreferenceInitializer.java (working copy) @@ -55,7 +55,9 @@ public static final String PREF_DEF_PREVERIFY_CONFIG_LOCATION = PREF_PREVERIFY_CONFIG_LOCATION_PLATFORM; public static final String PREF_DEF_PREVERIFY_CONFIG_VALUE = ""; //$NON-NLS-1$ public static final String PREF_DEF_DEFAULT_PREVERIFIER = ""; //$NON-NLS-1$ - + //public static final boolean PREF_DEF_PREVERIFY_BUILT_IN = false; + public static final String PREF_DEF_PREVERIFY_TYPE = IMTJCoreConstants.PREF_PREVERIFY_TYPE_EMULATOR; + public static final String PREF_DEF_WTK_ROOT = ""; //$NON-NLS-1$ public static final String PREF_DEF_ANTENNA_JAR = ""; //$NON-NLS-1$ @@ -103,9 +105,10 @@ PREF_DEF_PREVERIFY_CONFIG_LOCATION); prefs.setDefault(PREF_PREVERIFY_CONFIG_VALUE, PREF_DEF_PREVERIFY_CONFIG_VALUE); - prefs - .setDefault(PREF_DEFAULT_PREVERIFIER, - PREF_DEF_DEFAULT_PREVERIFIER); + prefs.setDefault(PREF_PREVERIFY_CONFIG_VALUE, + PREF_DEF_PREVERIFY_TYPE); + prefs.setDefault(PREF_DEFAULT_PREVERIFIER, + PREF_DEF_DEFAULT_PREVERIFIER); prefs.setDefault(PREF_ANTENNA_JAR, PREF_DEF_ANTENNA_JAR); prefs.setDefault(PREF_WTK_ROOT, PREF_DEF_WTK_ROOT); Index: src/org/eclipse/mtj/core/build/preverifier/ProguardPreverifier.java =================================================================== --- src/org/eclipse/mtj/core/build/preverifier/ProguardPreverifier.java (revision 0) +++ src/org/eclipse/mtj/core/build/preverifier/ProguardPreverifier.java (revision 0) @@ -0,0 +1,563 @@ +/** + * Copyright (c) 2003,2008 Motorola Inc. and others. + * All Rights Reserved. + * Licensed under the Eclipse Public License - v 1.0 + * For more information see http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Gustavo de Paula (Motorola) - Initial Creation + */ +package org.eclipse.mtj.core.build.preverifier; + +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.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +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.IJavaProject; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.launching.IVMInstall; +import org.eclipse.jdt.launching.JavaRuntime; +import org.eclipse.mtj.core.MTJCore; +import org.eclipse.mtj.core.persistence.IPersistenceProvider; +import org.eclipse.mtj.core.persistence.PersistenceException; +import org.eclipse.mtj.core.project.IMTJProject; +import org.eclipse.mtj.core.project.midp.IMidletSuiteProject; +import org.eclipse.mtj.internal.core.IMTJCoreConstants; +import org.eclipse.mtj.internal.core.build.BuildConsoleProxy; +import org.eclipse.mtj.internal.core.build.BuildLoggingConfiguration; +import org.eclipse.mtj.internal.core.build.IBuildConsoleProxy; +import org.eclipse.mtj.internal.core.build.preverifier.IClassErrorInformation; +import org.eclipse.mtj.internal.core.build.preverifier.PreverificationError; +import org.eclipse.mtj.internal.core.build.preverifier.PreverificationErrorLocation; +import org.eclipse.mtj.internal.core.build.preverifier.PreverificationErrorLocationType; +import org.eclipse.mtj.internal.core.build.preverifier.PreverificationErrorType; +import org.eclipse.mtj.internal.core.util.TemporaryFileManager; +import org.eclipse.mtj.internal.core.util.Utils; +import org.eclipse.mtj.internal.core.util.log.MTJLogger; + + +/** + * Use proguard to preverify the MIDlet suite classes. Design and code is mostly + * based on org.eclipse.mtj.core.model.impl.StandardPreverifier. + * + * TODO Refactore code to have a common class to be used both by StandPreverifier and ProguardPreverifier + * + * @author wgp010 + */ +public class ProguardPreverifier implements IPreverifier { + + /** + * The list of locations in which to look for the java executable in + * candidate VM install locations, relative to the VM install location. + * Code from org.eclipse.mtj.core.model.implJavaEmulatorDevice. + * TODO Refactore to have a common place for it + */ + private static final String[] CANDIDATE_JAVA_LOCATIONS = { + "bin" + File.separatorChar + "java", //$NON-NLS-2$ //$NON-NLS-1$ + "bin" + File.separatorChar + "java.exe", //$NON-NLS-2$ //$NON-NLS-1$ + "jre" + File.separatorChar + "bin" + File.separatorChar + "java", //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ + "jre" + File.separatorChar + "bin" + File.separatorChar + "java.exe" }; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ + + /** + * Path to proguard lib + */ + private String proguardJarFilePath = null; + + /** + * Max number of characters in the command + */ + 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 = "^Unable to access jarfile (\\S*)$"; + + // The compiled pattern for regular expression matching + private static final Pattern PREV_ERR_PATTERN = Pattern.compile( + PREV_ERR_REGEX, Pattern.MULTILINE); + + /** + * Class constructor + */ + public ProguardPreverifier () { + this.proguardJarFilePath = MTJCore.getProguardJarFile().getAbsolutePath(); + } + + @Override + public PreverificationError[] preverify(IMTJProject mtjProject, + IResource[] toVerify, IFolder outputFolder, IProgressMonitor monitor) + throws CoreException { + ArrayList allErrors = new ArrayList(); + + // Create the temporary file of commands for + // the verifier + ensureFolderExists(outputFolder, monitor); + + // construct the command line to call proguard + ArrayList baseArguments = constructCommandLine(); + + // read the final arguments that will be added to proguard command line. those parameters should be added + // after the -injar parameter + File outputFile = outputFolder.getLocation().toFile(); + String[] configurationParameters = getProguardFinalConfigurationParameters(mtjProject, outputFile.getAbsolutePath()); + + ArrayList arguments = new ArrayList(baseArguments); + + //add the output folder + addOutputToInJar (arguments, mtjProject); + + for (int i = 0; i < toVerify.length; i++) { + IResource resource = toVerify[i]; + + //add projects and jar files + switch (resource.getType()) { + case IResource.FOLDER: + case IResource.PROJECT: + addFileToInJar(arguments, resource.getLocation().toOSString()); + break; + + case IResource.FILE: + if (resource.getName().endsWith(".jar")) { + addFileToInJar(arguments, resource.getLocation().toOSString()); + } + break; + } + + if (commandLength(arguments) > MAX_COMMAND_LENGTH) { + // Configuration parameters + for (String configuration:configurationParameters) { + arguments.add(configuration); + } + + // 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); + //add the output folder + addOutputToInJar (arguments, mtjProject); + } + } + + if (arguments.size() != baseArguments.size()) { + for (String configuration:configurationParameters) { + arguments.add(configuration); + } + + // 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()]); + } + + @Override + public PreverificationError[] preverifyJarFile( + IMTJProject mtjProject, File jarFile, + IFolder outputFolder, IProgressMonitor monitor) + throws CoreException{ + // Rather than trying to preverify a jar file, we will expand it + // first and then preverify against the expanded classes. + File srcDirectory = new File(""); + try { + srcDirectory = TemporaryFileManager.instance.createTempDirectory( + jarFile.getName().replace('.', '_') + "_", ".tmp"); + } catch (IOException ioe) { + IStatus status = new Status(IStatus.ERROR, + IMTJCoreConstants.PLUGIN_ID, "Failed to create directory.", + ioe); + throw new CoreException(status); + } + srcDirectory.mkdirs(); + + try { + Utils.extractArchive(jarFile, srcDirectory); + } catch (SecurityException se) { + IStatus status = new Status(IStatus.ERROR, + IMTJCoreConstants.PLUGIN_ID, + "Failed to inflate jar file due to a security violation.", + se); + throw new CoreException(status); + } catch (IOException ioe) { + IStatus status = new Status(IStatus.ERROR, + IMTJCoreConstants.PLUGIN_ID, "Failed to inflate jar file.", + ioe); + throw new CoreException(status); + } + + // Create the target directory for the preverification. We will + // tell the preverifier to use this when doing the preverification. + File tgtDirectory = new File(""); + try { + tgtDirectory = TemporaryFileManager.instance.createTempDirectory( + jarFile.getName().replace('.', '_') + "_", ".tmp"); + } catch (IOException ioe) { + IStatus status = new Status(IStatus.ERROR, + IMTJCoreConstants.PLUGIN_ID, "Failed to create directory.", + ioe); + throw new CoreException(status); + } + tgtDirectory.mkdirs(); + + ArrayList arguments = constructCommandLine(); + arguments.add(srcDirectory.toString()); + + // Launch the system process + String[] commandLine = (String[]) arguments + .toArray(new String[arguments.size()]); + PreverificationError[] errors = runPreverifier(commandLine, + null, 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"); + } + }; + try { + Utils.copy(srcDirectory, tgtDirectory, classFilter); + } catch (SecurityException se) { + IStatus status = new Status(IStatus.ERROR, + IMTJCoreConstants.PLUGIN_ID, + "Failed copy specified source due to a security violation.", + se); + throw new CoreException(status); + } catch (IOException ioe) { + IStatus status = new Status(IStatus.ERROR, + IMTJCoreConstants.PLUGIN_ID, "Failed to copy specified source.", + ioe); + throw new CoreException(status); + } + + // Finally, re-jar the output of the pre-verification into the requested + // jar file... + File outputJarFile = new File(outputFolder.getLocation().toFile(), + jarFile.getName()); + try { + Utils.createArchive(outputJarFile, tgtDirectory); + } catch (IOException ioe) { + IStatus status = new Status(IStatus.ERROR, + IMTJCoreConstants.PLUGIN_ID, "Failed to create zip source folder.", + ioe); + throw new CoreException(status); + } + + return errors; + } + + public void loadUsing(IPersistenceProvider persistenceProvider) + throws PersistenceException { + // Not necessary to load any data + } + + public void storeUsing(IPersistenceProvider persistenceProvider) + throws PersistenceException { + // Not necessary to store any data + } + + /** + * Run the preverifier program and capture the errors that occurred during + * pre-verification. + * + * @param commandLine + * @param environment + * @throws CoreException + */ + private PreverificationError[] runPreverifier(String[] commandLine, + String[] environment, IProgressMonitor monitor) + throws CoreException { + final ArrayList errorList = new ArrayList(); + + IProcess process = Utils.launchApplication(commandLine, null, + environment, "Preverifier", "CLDC Preverifier"); + + // Listen on the process output streams + IStreamsProxy proxy = process.getStreamsProxy(); + if (BuildLoggingConfiguration.getInstance().isPreverifierOutputEnabled()) { + BuildConsoleProxy.getInstance() + .traceln("======================== Launching Preverification ========================="); + BuildConsoleProxy.getInstance().addConsoleStreamListener( + IBuildConsoleProxy.Stream.ERROR, proxy + .getErrorStreamMonitor()); + BuildConsoleProxy.getInstance().addConsoleStreamListener( + IBuildConsoleProxy.Stream.OUTPUT, proxy + .getOutputStreamMonitor()); + } + + proxy.getErrorStreamMonitor().addListener(new IStreamListener() { + public void streamAppended(String text, IStreamMonitor monitor) { + handleErrorReceived(text, errorList); + } + }); + + // Wait until completion + while ((!monitor.isCanceled()) && (!process.isTerminated())) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + ; + } + + if (BuildLoggingConfiguration.getInstance().isPreverifierOutputEnabled()) { + BuildConsoleProxy.getInstance() + .traceln("======================== Preverification exited with code: " + + process.getExitValue()); + } + + return (PreverificationError[]) errorList + .toArray(new PreverificationError[errorList.size()]); + } + + /** + * Handle the arrival of text on the error stream. + * + * TODO Change to support proguard error messages + * + * @param text + * @param errorList + */ + private void handleErrorReceived(String text, List errorList) { + text = text.trim(); + Matcher matcher = PREV_ERR_PATTERN.matcher(text); + if (matcher.find()) { + // Found a match for the error... + if (matcher.groupCount() > 0) { + final String classname = matcher.group(1); + + String errorText = "Error preverifying class"; + if (matcher.end() < text.length()) { + StringBuffer sb = new StringBuffer(errorText); + sb.append(": "); + + String detail = text.substring(matcher.end()); + detail = detail.trim(); + sb.append(detail); + errorText = sb.toString(); + } + + IClassErrorInformation classInfo = new IClassErrorInformation() { + public String getName() { + return classname; + } + + public String getSourceFile() { + return null; + } + }; + + PreverificationErrorLocation location = new PreverificationErrorLocation( + PreverificationErrorLocationType.UNKNOWN_LOCATION, + classInfo); + PreverificationError error = new PreverificationError( + PreverificationErrorType.UNKNOWN_ERROR, location, text); + errorList.add(error); + } + } else { + MTJLogger.log(IStatus.WARNING, text); + } + } + /** + * Ensure the specified output folder exists or create if it does not + * already exist. + * + * @param folder + * @param monitor + * @throws CoreException + */ + private void ensureFolderExists(IFolder folder, IProgressMonitor monitor) + throws CoreException { + // Make sure the output folder exists before we start + if (!folder.exists()) { + folder.create(true, true, monitor); + } + } + + /** + * Construct the command line for the specified pre-verification. + * + * @param midletProject + * @param target + * @return + * @throws CoreException + */ + private ArrayList constructCommandLine() throws CoreException { + ArrayList arguments = new ArrayList(); + + // The program we are running... + arguments.add(this.getJavaExecutable().getAbsolutePath()); + arguments.add("-jar"); + arguments.add(this.proguardJarFilePath); + + return arguments; + } + + /** + * Return the parameters to be used for controlling the proguard preverifier + * + * @param midletProject + * @return + * @throws CoreException if an error occurs working with the MIDlet project. + */ + private String [] getProguardFinalConfigurationParameters(IMTJProject mtjProject, String output) throws CoreException { + return new String [] { + "-outjars", + "'"+output+"'", + "-libraryjars", + this.getFullClasspath(mtjProject), + "'-ignorewarnings'", + "-dontusemixedcaseclassnames", + "-dontshrink", + "-dontoptimize", + "-dontobfuscate", + "-microedition" + }; + } + + /** + * Get the full classpath including all J2ME libraries. + * + * @param midletProject + * @return + * @throws CoreException + */ + private String getFullClasspath(IMTJProject mtjProject) + throws CoreException { + IJavaProject javaProject = mtjProject.getJavaProject(); + + String[] entries = JavaRuntime.computeDefaultRuntimeClassPath(javaProject); + + // start in 1 to remove the output folder from the runtime. the output folder should be included in the + // -injar proguard options + StringBuffer sb = new StringBuffer(); + for (int i = 1; i < entries.length; i++) { + if (i != 1) { + sb.append(File.pathSeparatorChar); + } + sb.append("'"+entries[i]+"'"); + } + + return sb.toString(); + } + + /** + * Add the output folder target to be verified. + * + * @param args + * @param resource + * @throws JavaModelException + */ + private void addOutputToInJar(List args, IMTJProject mtjProject) + throws JavaModelException { + + // Find the source directory this class resides in + String outputPath = null; + + String s1 = mtjProject.getProject().getLocation().toOSString(); + String s2 = mtjProject.getJavaProject().getOutputLocation().removeFirstSegments(1).toOSString(); + //IPath.SEPARATOR + outputPath = s1 + File.separatorChar + s2; + + if (outputPath != null) { + args.add("-injars"); + args.add("'"+outputPath+"'"); + } + } + + /** + * Add any file to be preverified + * + * @param args + * @param resource + * @throws JavaModelException + */ + private void addFileToInJar(List args, String filePath) + throws JavaModelException { + if (filePath != null) { + args.add("-injars"); + args.add("'"+filePath+"'"); + } + } + + + /** + * 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; + } + + /** + * Return the Java executable to be used for launching this device. + * Code from org.eclipse.mtj.core.model.implJavaEmulatorDevice. + * TODO Refactore to have a common place for it + * + * @return + */ + private File getJavaExecutable() { + File executable = null; + + IVMInstall vmInstall = JavaRuntime.getDefaultVMInstall(); + File installLocation = vmInstall.getInstallLocation(); + + for (int i = 0; i < CANDIDATE_JAVA_LOCATIONS.length; i++) { + String javaLocation = CANDIDATE_JAVA_LOCATIONS[i]; + File javaExecutable = new File(installLocation, javaLocation); + if (javaExecutable.exists()) { + executable = javaExecutable; + break; + } + } + return executable; + } + + @Override + public File getPreverifierExecutable() { + // TODO Auto-generated method stub + return null; + } +} \ No newline at end of file Index: src/org/eclipse/mtj/core/IMTJCoreConstants.java =================================================================== --- src/org/eclipse/mtj/core/IMTJCoreConstants.java (revision 0) +++ src/org/eclipse/mtj/core/IMTJCoreConstants.java (revision 0) @@ -0,0 +1,207 @@ +/** + * Copyright (c) 2003,2009 Craig Setera and others. + * + * All Rights Reserved. + * Licensed under the Eclipse Public License - v 1.0 + * For more information see http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Craig Setera (EclipseME) - Initial implementation + * Diego Sandin (Motorola) - Refactoring package and class name + * to follow eclipse standards + * Hugo Raniere (Motorola) - Removing Preprocessor code + * Feng Wang (Sybase) - Add LAUNCH_FROM_JAD_FOLDER constant for + * launching from JAD. + * Hugo Raniere (Motorola) - Adding key to represent default preverifier + * Diego Sandin (Motorola) - Re-enabling Preprocessor code + * Hugo Raniere (Motorola) - Adding key to represent a java me problem marker + * Diego Sandin (Motorola) - Adding key to represent a missing device definition + * problem marker + * Gang Ma (Sybase) - Adding key to represent preprocess debug level + * David Marques(Motorola) - Adding key to represent process type. + * David Marques(Motorola) - Adding L10N Nature Constant. + * Gustavo de Paula (Motorola) - Add types of preverifiers + * + */ +package org.eclipse.mtj.core; + +/** + * Constant definitions for use throughout the plug-in. + *

+ * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. Please do not use this API without consulting with + * the MTJ team. + *

+ * + * @since 1.0 + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IMTJCoreConstants { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.mtj.core"; //$NON-NLS-1$ + + // Directory preference keys and defaults + public static final String PREF_DEPLOYMENT_DIR = "deployment_dir"; //$NON-NLS-1$ + public static final String PREF_VERIFIED_DIR = "verified_dir"; //$NON-NLS-1$ + + // New project creation preferences + public static final String PREF_USE_RESOURCES_DIR = "use_resources_dir"; //$NON-NLS-1$ + public static final String PREF_RESOURCES_DIR = "resources_dir"; //$NON-NLS-1$ + public static final String PREF_FORCE_JAVA11 = "force_java11"; //$NON-NLS-1$ + + // Over the Air preferences + public static final String PREF_OTA_SERVER_START_AT_START = "ota_start_at_start"; //$NON-NLS-1$ + public static final String PREF_OTA_PORT_DEFINED = "ota_port_defined"; //$NON-NLS-1$ + public static final String PREF_OTA_PORT = "ota_port"; //$NON-NLS-1$ + public static final String PREF_OTA_AUTODEPLOY = "ota_autodeploy"; //$NON-NLS-1$ + + // Proguard obfuscation preferences + public static final String PREF_OBFUSCATION_USE_PROJECT = "obfuscate_use_project"; //$NON-NLS-1$ + public static final String PREF_PROGUARD_DIR = "proguard_dir"; //$NON-NLS-1$ + public static final String PREF_PROGUARD_USE_SPECIFIED = "proguard_use_specified"; //$NON-NLS-1$ + public static final String PREF_PROGUARD_OPTIONS = "proguard_options"; //$NON-NLS-1$ + public static final String PREF_PROGUARD_KEEP = "proguard_keep"; //$NON-NLS-1$ + + // Packaging related preferences + public static final String PREF_PKG_USE_PROJECT = "pkg_use_project"; //$NON-NLS-1$ + public static final String PREF_PKG_AUTOVERSION = "pkg_autoversion"; //$NON-NLS-1$ + public static final String PREF_PKG_EXCLUDED_PROPS = "pkg_excluded_props"; //$NON-NLS-1$ + public static final String PREF_PKG_BUILD_XML = "pkg_build_xml"; //$NON-NLS-1$ + + // Preverifier related preferences + public static final String PREF_PREVERIFY_USE_PROJECT = "pkg_use_project"; //$NON-NLS-1$ + + public static final String PREF_PREVERIFY_CONFIG_LOCATION = "preverify_config_location"; //$NON-NLS-1$ + public static final String PREF_PREVERIFY_CONFIG_VALUE = "preverify_config_value"; //$NON-NLS-1$ + public static final String PREF_DEFAULT_PREVERIFIER = "default_preverifier"; //$NON-NLS-1$ + public static final String PREF_PREVERIFY_TYPE = "preverify_type"; + public static final String PREF_PREVERIFY_TYPE_EMULATOR = "preverify_emulator"; + public static final String PREF_PREVERIFY_TYPE_DEFAULT = "preverify_default"; + public static final String PREF_PREVERIFY_TYPE_PROGUARD = "preverify_proguard"; + + public static final String PREF_PREVERIFY_CONFIG_LOCATION_JAD = "jad"; //$NON-NLS-1$ + public static final String PREF_PREVERIFY_CONFIG_LOCATION_PLATFORM = "platform"; //$NON-NLS-1$ + public static final String PREF_PREVERIFY_CONFIG_LOCATION_SPECIFIED = "specified"; //$NON-NLS-1$ + + public static final String MANIFEST_FILE_NAME = "META-INF/MANIFEST.MF"; + + // Antenna settings + public static final String PREF_WTK_ROOT = "wtk_root"; //$NON-NLS-1$ + public static final String PREF_ANTENNA_JAR = "antenna_jar"; //$NON-NLS-1$ + + // Miscellaneous preferences + public static final String PREF_RMTDBG_TIMEOUT = "rmt_debug_delay"; //$NON-NLS-1$ + public static final String PREF_RMTDBG_INTERVAL = "rmt_debug_poll_interval"; //$NON-NLS-1$ + public static final String PREF_AUTO_LAUNCH_MIGRATION = "auto_launch_migration"; //$NON-NLS-1$ + + // Preprocessor preferences + public static final String PREF_PREPROCESS_USE_PROJECT = "preprocess_use_project"; //$NON-NLS-1$ + public static final String PREF_PREPROCESS_DEBUG_LEVEL = "preprocess_debuglevel"; //$NON-NLS-1$ + + /** + * Debugging property keys Key that uses "true" or "false" to control + * whether or not to dump the launch command line for the emulator + */ + public static final String PROP_DUMP_LAUNCH = "mtj.dump.launch"; //$NON-NLS-1$ + + /** The superclass of all MIDlets */ + public static final String MIDLET_SUPERCLASS = "javax.microedition.midlet.MIDlet"; //$NON-NLS-1$ + + // Project folder names... + + /** + * The directory used to hold temporary files such as preverified and + * incrementally built jar files + */ + public static final String TEMP_FOLDER_NAME = ".mtj.tmp"; //$NON-NLS-1$ + + /** + * The sub-folder of the TEMP folder that holds runtime classes + */ + public static final String RUNTIME_FOLDER_NAME = "runtime"; + + // The sub-folder of the TEMP folder that holds verified classes and + // libraries + public static final String VERIFIED_FOLDER_NAME = "verified"; //$NON-NLS-1$ + + // The sub-folder of the TEMP folder that holds the JAR and JAD files for + // execution by the emulator + public static final String EMULATION_FOLDER_NAME = "emulation"; //$NON-NLS-1$ + + // The sub-folder of the ".mtj.tmp" folder that holds JAR and JAD for + // launching from JAD emulation + public static final String LAUNCH_FROM_JAD_FOLDER = "launchFromJAD"; //$NON-NLS-1$ + + // Miscellaneous + public static final String PROGUARD_JAR = "proguard.jar"; //$NON-NLS-1$ + + public static final String MTJ_NATURE_ID = PLUGIN_ID + ".nature"; //$NON-NLS-1$ + public static final String J2ME_PREPROCESSED_NATURE_ID = PLUGIN_ID + + ".preprocessedNature"; //$NON-NLS-1$ + + public static final String J2ME_PREPROCESSING_NATURE_ID = PLUGIN_ID + + ".preprocessingNature"; //$NON-NLS-1$ + public static final String J2ME_PREVERIFIER_ID = PLUGIN_ID + ".preverifier"; //$NON-NLS-1$ + public static final String J2ME_PREPROCESSOR_ID = PLUGIN_ID + + ".preprocessor"; //$NON-NLS-1$ + public static final String JAVAME_PROBLEM_MARKER = PLUGIN_ID + ".problem"; //$NON-NLS-1$ + + /** + * Missing device definition resource marker ID + */ + public static final String JAVAME_MISSING_DEVICE_MARKER = PLUGIN_ID + + ".device.missing"; //$NON-NLS-1$ + + public static final String J2ME_PREPROCESSED_CONTAINER = PLUGIN_ID + + ".PP_CONTAINER"; //$NON-NLS-1$ + public static final String J2ME_TOOLKIT_TYPES_ID = "wirelessToolkitTypes"; //$NON-NLS-1$ + public static final String J2ME_CONFIGURATIONS_ID = "configurations"; //$NON-NLS-1$ + public static final String J2ME_PROFILES_ID = "profiles"; //$NON-NLS-1$ + + public static final String MTJ_PROCESS_TYPE = "MTJProcess"; //$NON-NLS-1$ + + // //////////////////////////////////////////////////////////////////// + // Error messages + // //////////////////////////////////////////////////////////////////// + /** No MIDlets defined during OTA launch */ + public static final int ERR_OTA_NO_MIDLETS = 100; + + /** Errors occurred during obfuscation */ + public static final int ERR_OBFUSCATION_ERRORS = 101; + + /** Error searching for jar executable */ + public static final int ERR_COULD_NOT_FIND_JAR_TOOL = 102; + + /** Need signature passwords (not really an error, but triggers a dialog) */ + public static final int INFO_NEED_SIGNATURE_PASSWORDS = 103; + + /** + * Need check for debug setting(not really an error, but triggers a dialog + * if the current debugger setting is not satisfied to debug a MIDlet) + */ + public static final int INFO_DEBUGGER_SETTINGS_CHECK = 104; + + /** + * This constant is the old eclipse me nature id. + */ + public static final String ECLIPSE_ME_NATURE = "eclipseme.core.nature"; //$NON-NLS-1$ + + /** + * This constant holds the L10N Nature ID + */ + public static final String L10N_NATURE_ID = PLUGIN_ID + ".l10nNature"; //$NON-NLS-1$ + + /** + * This constant holds the L10N Builder ID + */ + public static final String L10N_BUILDER_ID = PLUGIN_ID + ".l10nBuilder"; //$NON-NLS-1$ + + /** + * This constant holds the JMUnit Nature ID + */ + public static final String JMUNIT_NATURE_ID = "org.eclipse.mtj.jmunit.jmunitNature"; //$NON-NLS-1$ + + public static final String VERSION_NLS_BIND_TEMPLATE = "{0}.{1}"; +} #P org.eclipse.mtj.ui Index: src/org/eclipse/mtj/internal/ui/preferences/PreverificationPreferencePage.java =================================================================== --- src/org/eclipse/mtj/internal/ui/preferences/PreverificationPreferencePage.java (revision 1130) +++ src/org/eclipse/mtj/internal/ui/preferences/PreverificationPreferencePage.java (working copy) @@ -27,7 +27,6 @@ import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.resources.ProjectScope; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -34,14 +33,17 @@ import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.jface.preference.FileFieldEditor; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.mtj.core.IMTJCoreConstants; import org.eclipse.mtj.core.MTJCore; import org.eclipse.mtj.core.build.preverifier.IPreverifier; import org.eclipse.mtj.core.sdk.device.IAPI; -import org.eclipse.mtj.internal.core.IMTJCoreConstants; +import org.eclipse.mtj.internal.core.PreferenceAccessor; import org.eclipse.mtj.internal.core.sdk.device.midp.Configuration; import org.eclipse.mtj.internal.core.util.log.MTJLogger; import org.eclipse.mtj.internal.ui.IEmbeddableWorkbenchPreferencePage; @@ -59,6 +61,9 @@ import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; +import org.eclipse.jface.preference.RadioGroupFieldEditor; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; /** * Preference page implementation for setting preverification preferences. @@ -64,8 +69,9 @@ * Preference page implementation for setting preverification preferences. * * @author Craig Setera + * Gustavo de Paula (Motorola) - Change preverification to add proguard support */ -public class PreverificationPreferencePage extends PreferencePage implements +public class PreverificationPreferencePage extends FieldEditorPreferencePage implements IEmbeddableWorkbenchPreferencePage { private static final String[] BUTTON_TEXTS = new String[] { @@ -81,9 +87,15 @@ private Combo configCombo; private IAPI[] configSpecs; private FileFieldEditor defaultPreverifierField; + private Group defaultPreverifierGroup; private boolean embeddedInProperties; + + // The java project on which this MIDlet suite is based + private IJavaProject javaProject; private Button[] preverificationRadios; + + private RadioGroupFieldEditor radioGroupFieldEditor; /** * Default constructor. @@ -211,7 +223,7 @@ * @param composite */ private void addDefaultPreverifierControls(Composite composite) { - Group defaultPreverifierGroup = new Group(composite, SWT.NONE); + defaultPreverifierGroup = new Group(composite, SWT.NONE); defaultPreverifierGroup .setText(MTJUIMessages.PreverificationPreferencePage_defaultPreverifierGroup_label_text); defaultPreverifierGroup.setLayout(new GridLayout(3, false)); @@ -230,7 +242,7 @@ IMTJCoreConstants.PREF_DEFAULT_PREVERIFIER, MTJUIMessages.PreverificationPreferencePage_defaultPreverifierField_label_text, defaultPreverifierGroup); - + String[] extensions = null; if (Platform.getOS().equals(Platform.OS_WIN32)) { extensions = new String[] { "*.exe" }; //$NON-NLS-1$ @@ -312,7 +324,7 @@ .getDefaultString(IMTJCoreConstants.PREF_PREVERIFY_CONFIG_VALUE); for (int i = 0; i < configSpecs.length; i++) { IAPI spec = configSpecs[i]; - if (spec.toString().equals(config)) { + if (spec.getIdentifier().equals(config)) { specIndex = i; break; } @@ -339,6 +351,14 @@ preverificationRadios[i].setSelection(fieldValue .equals(location)); } + + IPreferenceStore preverifierTypestore = radioGroupFieldEditor.getPreferenceStore(); + String asd = preverifierTypestore.getString(IMTJCoreConstants.PREF_PREVERIFY_TYPE); + if (asd.equals("preverify_default")) { + defaultPreverifierField.setEnabled(true, defaultPreverifierGroup); + }else { + defaultPreverifierField.setEnabled(false, defaultPreverifierGroup); + } int specIndex = 0; String config = store @@ -345,7 +365,7 @@ .getString(IMTJCoreConstants.PREF_PREVERIFY_CONFIG_VALUE); for (int i = 0; i < configSpecs.length; i++) { IAPI spec = configSpecs[i]; - if (spec.toString().equals(config)) { + if (spec.getIdentifier().equals(config)) { specIndex = i; break; } @@ -432,7 +452,7 @@ int index = configCombo.getSelectionIndex(); store.setValue(IMTJCoreConstants.PREF_PREVERIFY_CONFIG_VALUE, - configSpecs[index].toString()); + configSpecs[index].getIdentifier()); if (defaultPreverifierField != null) { setDefaultPreverifier(); defaultPreverifierField.store(); @@ -454,6 +474,52 @@ return prefNode.getBoolean( IMTJCoreConstants.PREF_PREVERIFY_USE_PROJECT, false); } + + /** + * Add the controls that are for work-in-progress function. + * + * @param composite + */ + private void addTypeOfPreverifier(final Composite composite) { + radioGroupFieldEditor = new RadioGroupFieldEditor (IMTJCoreConstants.PREF_PREVERIFY_TYPE, + "Preverifier to use", 1, + new String [][] { + {"Default Preverifier", IMTJCoreConstants.PREF_PREVERIFY_TYPE_DEFAULT}, + {"Emulator Preverifier", IMTJCoreConstants.PREF_PREVERIFY_TYPE_EMULATOR}, + {"Proguard Preverifier", IMTJCoreConstants.PREF_PREVERIFY_TYPE_PROGUARD} + }, + composite, + true + ); + radioGroupFieldEditor.setPreferenceStore(getPreferenceStore()); + radioGroupFieldEditor.load(); + radioGroupFieldEditor.fillIntoGrid(composite, 1); + + radioGroupFieldEditor.setPropertyChangeListener(new IPropertyChangeListener(){ + public void propertyChange(PropertyChangeEvent event){ + String newValue = (String)event.getNewValue(); + System.out.println(newValue); + if(!newValue.equals(event.getOldValue())){ + if (newValue.equals("preverify_default")) { + defaultPreverifierField.setEnabled(true, defaultPreverifierGroup); + }else if (newValue.equals("preverify_proguard")||newValue.equals("preverify_emulator")) { + defaultPreverifierField.setEnabled(false, defaultPreverifierGroup); + } + } + } + }); + + + + // * "GeneralPage.DoubleClick", resName, 1, + // * new String[][] { + // * {"Open Browser", "open"}, + // * {"Expand Tree", "expand"} + // * }, + // * parent + + addField(radioGroupFieldEditor); + } /* (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) @@ -464,8 +530,10 @@ Composite composite = new Composite(parent, SWT.NONE); composite.setLayout(new GridLayout(1, false)); composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - + addConfigurationControls(composite); + + addTypeOfPreverifier(composite); if (!embeddedInProperties) { addDefaultPreverifierControls(composite); @@ -472,7 +540,7 @@ } else { noDefaultAndApplyButton(); } - + setControlsFromPreferences(); return composite; @@ -477,4 +545,19 @@ return composite; } + + @Override + protected void createFieldEditors() { + // TODO Auto-generated method stub + + } + + private String getPreverifierType() { + return PreferenceAccessor.instance.getPreverifierType(getProject()); + + } + + public IProject getProject() { + return javaProject.getProject(); + } }