📄 packager.java
字号:
Status s = new Status(
IStatus.ERROR,
IEclipseMECoreConstants.PLUGIN_ID,
-999,
"Illegal Manifest Entry Key or Value \"" + e.getMessage() + "\"",
e);
throw new CoreException(s);
}
}
// Open up the JAR output stream to which the contents
// will be added.
FileOutputStream fos = new FileOutputStream(jarFile);
EntryTrackingJarOutputStream jarOutputStream =
new EntryTrackingJarOutputStream(fos, jarManifest);
// Add the contents
addVerifiedClasspathContentsToJar(jarOutputStream, monitor);
// All done with the initial jar.
jarOutputStream.close();
// Obfuscate if requested
if (obfuscate) {
doObfuscation(monitor, jarIFile);
}
return resourceToFile(getJarFile(deploymentFolder, false), monitor);
}
/**
* Create a new Jar file entry given the specified information.
*
* @param jarOutputStream
* @param zipEntry
* @param is
* @throws IOException
*/
private void createJarEntry(
EntryTrackingJarOutputStream jarOutputStream,
ZipEntry zipEntry,
InputStream is)
throws IOException
{
// Copy the zip entry before adding it to the output stream
ZipEntry newEntry = new ZipEntry(zipEntry.getName());
newEntry.setTime(zipEntry.getTime());
if (zipEntry.getComment() != null) {
newEntry.setComment(zipEntry.getComment());
}
if (zipEntry.getExtra() != null) {
newEntry.setExtra(zipEntry.getExtra());
}
if (!jarOutputStream.alreadyAdded(zipEntry)) {
// Add the new ZipEntry to the stream
jarOutputStream.putNextEntry(newEntry);
Utils.copyInputToOutput(is, jarOutputStream);
// Close this entry
jarOutputStream.closeEntry();
}
}
/**
* Do the work to obfuscate the jar file.
*
* @param monitor
* @param deployedJarFile
* @throws CoreException
*/
private void doObfuscation(IProgressMonitor monitor, IFile deployedJarFile)
throws CoreException, IOException
{
logObfuscation("Obfuscating " + deployedJarFile.getLocation().toFile());
final StringBuffer errorText = new StringBuffer();
// Calculate the name of the obfuscated jar file name...
IFolder parent = (IFolder) deployedJarFile.getParent();
String jarName = deployedJarFile.getName();
jarName = jarName.substring(0, jarName.length() - 4);
jarName += "_obf.jar";
IFile obfuscatedJar = parent.getFile(jarName);
logObfuscation("Obfuscating to output jar " + obfuscatedJar.getLocation().toFile());
ObfuscatorTool obfuscator = new ObfuscatorTool(
midletSuite,
deployedJarFile.getLocation().toFile(),
obfuscatedJar.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();
proxy.getErrorStreamMonitor().addListener(new IStreamListener() {
public void streamAppended(String text, IStreamMonitor monitor) {
errorText.append(text);
}
});
if (logObfuscation) {
proxy.getOutputStreamMonitor().addListener(new IStreamListener() {
public void streamAppended(String text, IStreamMonitor monitor) {
stdoutBuffer.append(text);
}
});
}
// Wait until completion
while ((!monitor.isCanceled()) && (!process.isTerminated())) {
try { Thread.sleep(1000); } catch (InterruptedException e) {};
}
// 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(obfuscatedJar, deployedJarFile, monitor);
}
}
}
/**
* Do the preverification necessary after obfuscation occurs.
*
* @param obfuscatedJar
* @param deployedJarFile
* @param monitor
* @throws CoreException
* @throws IOException
*/
private void doPostObfuscationPreverification(
IFile obfuscatedJar,
IFile deployedJarFile,
IProgressMonitor monitor)
throws CoreException, IOException
{
logObfuscation("Doing post-obfuscation preverification");
logObfuscation("Obfuscated jar: " + obfuscatedJar.getLocation().toFile());
logObfuscation("Deployed jar file: " + deployedJarFile.getLocation().toFile());
// 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
logObfuscation("Preverifying obfuscated jar into " + tempFolder.getLocation().toFile());
File jarFile = obfuscatedJar.getLocation().toFile();
PreverificationError[] errors = midletSuite.preverifyJarFile(jarFile, tempFolder, monitor);
tempFolder.refreshLocal(IResource.DEPTH_ONE, monitor);
// Check for errors
if (errors.length > 0) {
logObfuscation(errors.length + " errors occurred during post-obfuscation preverification");
handlePreverificationErrors(errors);
}
// Copy the result back into the deployment directory
IFile finalJarFile = getJarFile(deployFolder, false);
IFile preverified = tempFolder.getFile(obfuscatedJar.getName());
Utils.copyFile(preverified, finalJarFile);
logObfuscation("Copying " + preverified + " to " + finalJarFile.getLocation().toFile());
// Clean up the temp directory
logObfuscation("Deleting " + preverified.getLocation().toFile());
preverified.delete(true, monitor);
logObfuscation("Deleting " + tempFolder.getLocation().toFile());
tempFolder.delete(true, monitor);
}
/**
* Get the folder into which the jad and jar will be written.
*
* @param monitor
* @return
* @throws CoreException
*/
private IFolder getDeploymentFolder(IProgressMonitor monitor)
throws CoreException
{
IFolder deploymentFolder =
midletSuite.getProject().getFolder(getDeploymentDirectoryName());
if (!deploymentFolder.exists()) {
deploymentFolder.create(false, true, monitor);
}
return deploymentFolder;
}
/**
* Filter out the attributes as requested by the user.
*
* @param attributes
*/
private void filterManifestAttributes(Properties attributes) {
String[] excluded =
PreferenceAccessor.instance.getExcludedManifestProperties(midletSuite.getProject());
for (int i = 0; i < excluded.length; i++) {
String excludedName = excluded[i];
if (attributes.containsKey(excludedName)) {
attributes.remove(excludedName);
}
}
}
/**
* Get the name of the directory for deployment.
*
* @return
*/
private String getDeploymentDirectoryName() {
return EclipseMECorePlugin.getDeploymentDirectoryName();
}
/**
* Get the File instance into which the JAD will be
* written.
*
* @return
*/
private IFile getJadFile(IContainer deploymentFolder) {
String jadFileName = midletSuite.getJadFile().getName();
return deploymentFolder.getFile(new Path(jadFileName));
}
/**
* Get the source JAD file instance.
*
* @return
*/
private IFile getJadSourceFile() {
return midletSuite.getJadFile();
}
/**
* Get an input stream on the JAD source file.
*
* @return
* @throws IOException
*/
private InputStream getJadSourceStream()
throws IOException, CoreException
{
return getJadSourceFile().getContents();
}
/**
* Get the IFile instance into which the JAR will be
* written.
*
* @return
*/
private IFile getJarFile(IFolder deploymentFolder, boolean obfuscateName) {
String jarFileName = midletSuite.getJarFilename();
if (obfuscateName) {
int length = jarFileName.length();
jarFileName = jarFileName.substring(0, length - 4) + "_base.jar";
}
return deploymentFolder.getFile(jarFileName);
}
/**
* Get a Manifest instance on the contents of the
* JAD source file.
*
* @return
* @throws IOException
*/
private ColonDelimitedProperties getJadSourceManifest()
throws IOException, CoreException
{
ColonDelimitedProperties properties = new ColonDelimitedProperties();
properties.load(getJadSourceStream());
return properties;
}
/**
* Get the JAD source properties as a Properties.
*
* @return
* @throws IOException
*/
private ColonDelimitedProperties getSourceJADProperties()
throws IOException, CoreException
{
ColonDelimitedProperties jadProperties = new ColonDelimitedProperties();
InputStream jadStream = getJadSourceStream();
jadProperties.load(jadStream);
jadStream.close();
return jadProperties;
}
/**
* 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());
}
/**
* Log the specified string if obfuscation logging is enabled.
*
* @param text
*/
private void logObfuscation(String text) {
if (logObfuscation) {
EclipseMECorePlugin.log(IStatus.INFO, text);
}
}
/**
* Convert the specified resource handle to a File handle.
*
* @param resource
* @param monitor
* @return
* @throws CoreException
*/
private File resourceToFile(IResource resource, IProgressMonitor monitor)
throws CoreException
{
return resource.getLocation().toFile();
}
/**
* Update the JAD version in the manifest properties.
* @throws IOException
* @throws CoreException
*/
private void updateJADVersion(IProgressMonitor monitor)
throws IOException, CoreException
{
// Read the source jad file and update the jar file
// length property.
ColonDelimitedProperties jadProperties = getSourceJADProperties();
// 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());
IFile jadSourceFile = getJadSourceFile();
IContainer folder = (IContainer) jadSourceFile.getParent();
writeJad(folder, jadProperties, monitor);
jadSourceFile.refreshLocal(IResource.DEPTH_ONE, monitor);
}
/**
* Write out the JAD properties to the specified folder.
*
* @param outputFolder
* @param jadProperties
* @param monitor
* @throws IOException
* @throws CoreException
*/
private void writeJad(
IContainer outputFolder,
ColonDelimitedProperties jadProperties,
IProgressMonitor monitor)
throws IOException, CoreException
{
// Write the new version
IFile jadFile = getJadFile(outputFolder);
File outputFile = resourceToFile(jadFile, monitor);
FileOutputStream stream = new FileOutputStream(outputFile);
jadProperties.store(stream, "");
stream.close();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -