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

📄 obfuscatortool.java

📁 eclipseme的最新版本的source,欢迎j2me程序员使用
💻 JAVA
字号:
/**
 * Copyright (c) 2003 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.packaging;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.MessageFormat;
import java.util.StringTokenizer;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;

import eclipseme.core.internal.EclipseMECorePlugin;
import eclipseme.core.internal.PreferenceAccessor;
import eclipseme.core.internal.utils.TemporaryFileManager;
import eclipseme.core.internal.utils.Utils;
import eclipseme.core.internal.utils.tools.AbstractJavaTool;
import eclipseme.core.model.Classpath;
import eclipseme.core.model.IMidletSuiteProject;
import eclipseme.core.model.device.IDevice;

/**
 * Tool implementation for running the Proguard obfuscator.
 * <p>
 * <b>Note:</b> This class/interface is part of an interim API that is still under development and expected to
 * change before reaching stability. It is being made available at this early stage to solicit feedback
 * from pioneering adopters on the understanding that any code that uses this API will almost 
 * certainly be broken as the API evolves.
 * </p>
 * Copyright (c) 2003 Craig Setera<br>
 * All Rights Reserved.<br>
 * Licensed under the Eclipse Public License - v 1.0<p/>
 * <br>
 * $Revision: 1.4 $
 * <br>
 * $Date: 2006/11/12 01:11:04 $
 * <br>
 * @author Craig Setera
 */
public class ObfuscatorTool extends AbstractJavaTool {
	// Constants
	private static final String TEMPLATE_NAME = "config.pro";
	private static final String PROGUARD_CFG_NAME = "proguard.cfg";
	private static final String NAME = "Obfuscator";
	private static final String MAIN_CLASS = "proguard.ProGuard";
	private static final String MAPPING_FILE_NAME = "pro_map.txt";
	private static final String SEEDS_FILE_NAME = "pro_seeds.txt";
	
	private static final String[] EMPTY_STRING_ARRAY = new String[0];

	/**
	 * 
	 * @uml.property name="midletSuite"
	 * @uml.associationEnd 
	 * @uml.property name="midletSuite" multiplicity="(1 1)"
	 */
	// The midlet suite being packaged
	private IMidletSuiteProject midletSuite;

	
	// The temporary jar file before obfuscation
	private File sourceJarFile;
	private File targetJarFile;
	
	// The deployment directory
	private File deploymentDirectory;
	
	/**
	 * Constructor
	 * 
	 * @param midletSuite
	 */
	public ObfuscatorTool(
			IMidletSuiteProject midletSuite, 
			File sourceJarFile,
			File targetJarFile) 
	{
		this.midletSuite = midletSuite;
		this.sourceJarFile = sourceJarFile;
		this.targetJarFile = targetJarFile;
	}
	
	/**
	 * @see eclipseme.core.internal.utils.tools.AbstractJavaTool#getArguments()
	 */
	protected String[] getArguments() {
		String[] args = null;
		
		try {
			File configFile = getProguardConfigFile();
			String argument = "@" + configFile;
			args = new String[] { argument };
		} catch (Exception e) {
			EclipseMECorePlugin.log(IStatus.ERROR,"getArguments", e);
		}
		
		return args;
	}

	/**
	 * @see eclipseme.core.internal.utils.tools.AbstractJavaTool#getClassName()
	 */
	protected String getClassName() {
		return MAIN_CLASS;
	}

	/**
	 * @see eclipseme.core.internal.utils.tools.AbstractJavaTool#getClasspath()
	 */
	protected String[] getClasspath() {
		return new String[] { EclipseMECorePlugin.getProguardJarFile().toString() };
	}

	/**
	 * @see eclipseme.core.internal.utils.tools.AbstractJavaTool#getName()
	 */
	protected String getName() {
		return NAME;
	}

	/**
	 * @see eclipseme.core.internal.utils.tools.AbstractJavaTool#getVMArguments()
	 */
	protected String[] getVMArguments() {
		return EMPTY_STRING_ARRAY;
	}
	
	/**
	 * Copy the config file to a temporary location if the current
	 * config file has spaces in the path.
	 * 
	 * @param configFile
	 * @return
	 * @throws IOException
	 */
	private File copyConfigFileIfNecessary(File configFile) 
		throws IOException 
	{
		File newConfigFile = configFile;
		
		if (configFile.toString().indexOf(' ') != -1) {
			newConfigFile = TemporaryFileManager.instance.createTempFile("proguard_", ".cfg");
			Utils.copyFile(configFile, newConfigFile, null);
		}
		
		return newConfigFile;
	}

	/**
	 * Return the deployment directory.
	 * 
	 * @return Returns the deploymentDirectory.
	 * @throws CoreException 
	 * 
	 * @uml.property name="deploymentDirectory"
	 */
	private File getDeploymentDirectory() 
		throws CoreException 
	{
		if (deploymentDirectory == null) {
			String dirName = EclipseMECorePlugin.getDeploymentDirectoryName();
			deploymentDirectory = getMidletSuiteFile(dirName);
		}

		return deploymentDirectory;
	}

	/**
	 * Get the specified filename relative to the deployment directory.
	 * 
	 * @param name
	 * @return
	 * @throws CoreException 
	 */
	private File getDeploymentDirectoryFile(String name) 
		throws CoreException 
	{
		return new File(getDeploymentDirectory(), name);
	}
	
	/**
	 * Get the library jars that will not be added to the obfuscated
	 * jar file.
	 * 
	 * @return
	 */
	private String getLibraryJarsClasspath() 
		throws CoreException 
	{
		IDevice device = midletSuite.getDevice();
		Classpath deviceClasspath = device.getClasspath();
		return deviceClasspath.toString();
	}

	/**
	 * Get the Proguard configuration file.
	 * 
	 * @return
	 */
	private File getProguardConfigFile() 
		throws CoreException, IOException 
	{
		// Figure out where to place the proguard config file
		File configFile = getDeploymentDirectoryFile(PROGUARD_CFG_NAME);
		
		// Create the contents of the proguard config file
		writeConfigFileContents(configFile);
		
		// Copy the config file to a temporary location that does
		// not have spaces in the path name if necessary
		configFile = copyConfigFileIfNecessary(configFile);
		
		return configFile;
	}

	/**
	 * Get the proguard configuration file template as a string.
	 * 
	 * @return
	 * @throws IOException
	 */
	private String getProguardConfigFileTemplate() 
		throws IOException
	{
		// Write out to the string
		StringWriter sWriter = new StringWriter();
		PrintWriter writer = new PrintWriter(sWriter);
		
		// Read relative to this class...
		InputStream stream = this.getClass().getResourceAsStream(TEMPLATE_NAME);
		if (stream != null) {
			String line = null;
			BufferedReader reader = 
				new BufferedReader(new InputStreamReader(stream));
			
			while ((line = reader.readLine()) != null) {
				writer.println(line);
				writer.flush();
			}
		}
		
		return sWriter.toString();
	}
	
	/**
	 * Return the parameters to be added to the Proguard configuration for
	 * keeping classes.
	 * 
	 * @return
	 */
	private String getProguardKeepParameters() {
		StringBuffer sb = new StringBuffer();
		
		PreferenceAccessor prefs = PreferenceAccessor.instance;

		String[] keepExpressions = 
			prefs.getProguardKeepExpressions(midletSuite.getProject());
		for (int i = 0; i < keepExpressions.length; i++) {
			String expression = keepExpressions[i];
			sb.append("-keep ").append(expression).append("\n");
		}
		
		return sb.toString();
	}
	
	/**
	 * Get a File instance relative to the midlet suite.
	 * 
	 * @param name
	 * @return
	 * @throws CoreException 
	 */
	private File getMidletSuiteFile(String name) 
		throws CoreException 
	{
		IProject project = midletSuite.getJavaProject().getProject();
		File projectFile = project.getLocation().toFile();
		
		return new File(projectFile, name);
	}

	/**
	 * Get the options to be specified when calling Proguard for
	 * obfuscation.
	 * 
	 * @return
	 */
	private Object getProguardOptions() {
		IProject project = midletSuite.getProject();
		PreferenceAccessor obfuscationPrefs = PreferenceAccessor.instance;
		String specifiedOptions = obfuscationPrefs.getSpecifiedProguardOptions(project);
		boolean useSpecified = obfuscationPrefs.isUseSpecifiedProguardOptions(project); 

		return useSpecified ?
				specifiedOptions :
				obfuscationPrefs.getDefaultProguardOptions();
	}

	/**
	 * Return the string quoted as necessary if it has spaces within it.
	 * 
	 * @param string
	 * @return
	 */
	private String getQuotedString(String string) {
		StringBuffer quoted = new StringBuffer();
		
		// Break up by path separator first
		StringTokenizer st = new StringTokenizer(string, File.pathSeparator);
		while (st.hasMoreTokens())
		{
			String token = st.nextToken();
			if (token.indexOf(' ') != -1) {
				quoted.append("\"").append(token).append("\"");
			} else {
				quoted.append(token);
			}
			
			if (st.hasMoreTokens()) {
				quoted.append(File.pathSeparatorChar);
			}
		}
		
		return quoted.toString();
	}
	
	/**
	 * Return the specified template with the necessary 
	 * substitutions.
	 * 
	 * @param template
	 * @return
	 */
	private String getTemplateWithSubstitutions(String template) 
		throws CoreException 
	{
		File mappingFile = getDeploymentDirectoryFile(MAPPING_FILE_NAME);
		File seedsFile = getDeploymentDirectoryFile(SEEDS_FILE_NAME);
		
		Object[] substitutions = new Object[] {
				getQuotedString(getLibraryJarsClasspath()),
				getQuotedString(sourceJarFile.toString()),
				getQuotedString(targetJarFile.toString()),
				getQuotedString(seedsFile.toString()),
				getQuotedString(mappingFile.toString()),
				getProguardOptions(),
				getProguardKeepParameters()
		};

		return MessageFormat.format(template, substitutions);
	}

	/**
	 * Create the contents of the proguard configuration file.
	 * 
	 * @param configFile
	 */
	private void writeConfigFileContents(File configFile) 
		throws IOException, CoreException 
	{
		// Open the writer on the file
		FileWriter fWriter = new FileWriter(configFile);
		PrintWriter writer = new PrintWriter(fWriter);
		
		// Get the template and do the substitutions
		String template = getProguardConfigFileTemplate();
		String configurationFile = getTemplateWithSubstitutions(template);
		writer.println(configurationFile);
		
		// All done
		writer.close();
	}
}

⌨️ 快捷键说明

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