AntennaBuildExporter.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
eclipseme.core.internal.tools |
![]() |
![]() |
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.tools;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import eclipseme.core.IEclipseMECoreConstants;
import eclipseme.core.internal.EclipseMECorePlugin;
import eclipseme.core.internal.PreferenceAccessor;
import eclipseme.core.internal.utils.FilteringClasspathEntryVisitor;
import eclipseme.core.internal.utils.Utils;
import eclipseme.core.internal.utils.XMLUtils;
import eclipseme.core.model.ApplicationDescriptor;
import eclipseme.core.model.IJADConstants;
import eclipseme.core.model.IMidletSuiteProject;
import eclipseme.core.model.device.IDevice;
/**
* Tool for exporting an Antenna build file.
* <p />
* Copyright (c) 2003-2005 Craig Setera<br>
* All Rights Reserved.<br>
* Licensed under the Eclipse Public License - v 1.0<p/>
* <br>
* $Revision: 1.25 $
* <br>
* $Date: 2007/01/20 22:39:22 $
* <br>
* @author Craig Setera
*/
public class AntennaBuildExporter {
private static final String NO_EXPORT = "_no_export";
private static final String PATH_BUILD_CLASSES_NO_EXPORT = "${path.build.classes}/" + NO_EXPORT;
private static final String PATH_BUILD_CLASSES = "${path.build.classes}";
// Holder for project-specific information built during the visitation of the classpath
private class ProjectInfo {
private String safeProjectName;
private IJavaProject javaProject;
private boolean exported;
private Element classpathElement;
private Map wtkBuildElements;
private List packageFilesetElements;
/**
* Construct a new project information instance for the
* specified java project.
*
* @param javaProject
*/
ProjectInfo(IJavaProject javaProject, boolean exported) {
this.javaProject = javaProject;
this.exported = exported;
wtkBuildElements = new HashMap();
packageFilesetElements = new ArrayList();
// Calculate a "safe" project name
safeProjectName = javaProject.getElementName();
safeProjectName = safeProjectName.replace(' ', '_');
}
/**
* Add a new fileset element to the list.
*
* @param element
*/
public void addPackageFilesetElement(Element element) {
packageFilesetElements.add(element);
}
/**
* Add a new wtkbuild element to the list.
*
* @param srcEntry
* @param element
*/
public void addWtkBuildElement(IClasspathEntry srcEntry, Element element) {
if (!wtkBuildElements.containsKey(srcEntry)) {
wtkBuildElements.put(srcEntry, element);
}
}
/**
* Return the Ant property name to be used for this project.
*/
public String getAntProjectPropertyName() {
return "project.root." + safeProjectName;
}
/**
* Return the Ant project property value.
*
* @return
*/
public String getAntProjectPropertyValue() {
String relativePath = null;
// Figure out the property value relative to the base directory
IPath projectPath = javaProject.getProject().getLocation();
relativePath = getRelativePath(basedirPath, projectPath);
if (relativePath == null) {
relativePath = projectPath.toString();
}
return relativePath;
}
/**
* Return the destination directory to be used for class build output.
*
* @return
*/
public String getBuildDestination() {
return exported ? PATH_BUILD_CLASSES : PATH_BUILD_CLASSES_NO_EXPORT;
}
/**
* Return the classpath element.
*
* @return
*/
public Element getClasspathElement() {
if (classpathElement == null) {
classpathElement = eclipseMeBuildXmlDocument.createElement("path");
classpathElement.setAttribute("id", getClasspathElementId());
Element pathElement = newChildElement(classpathElement, "path");
pathElement.setAttribute("location", PATH_BUILD_CLASSES);
pathElement = newChildElement(classpathElement, "path");
pathElement.setAttribute("location", PATH_BUILD_CLASSES_NO_EXPORT);
}
return classpathElement;
}
/**
* Return the identifier of the classpath path element.
*
* @return
*/
public String getClasspathElementId() {
return "classpath." + safeProjectName;
}
/**
* @return Returns the packageFilesetElements.
*/
public List getPackageFilesetElements() {
return packageFilesetElements;
}
/**
* @return Returns the wtkBuildElements.
*/
public Iterator getWtkBuildElements() {
return wtkBuildElements.values().iterator();
}
/**
* @return Returns the exported flag indication
*/
public boolean isExported() {
return exported;
}
}
// Classpath entry visitor for helping build the build.xml file
private class BuildClasspathEntryVisitor extends FilteringClasspathEntryVisitor
{
private Map projectInfoMap;
/**
* Construct a new visitor that will be responsible for
* creating the necessary elements.
*/
public BuildClasspathEntryVisitor(IJavaProject rootProject)
{
projectInfoMap = new LinkedHashMap();
createProjectInfo(rootProject, true);
}
/**
* Return the map of project information.
*
* @return
*/
public Map getProjectInfoMap() {
return projectInfoMap;
}
/**
* @see eclipseme.core.internal.utils.IClasspathEntryVisitor#visitLibraryEntry(org.eclipse.jdt.core.IClasspathEntry, org.eclipse.jdt.core.IJavaProject, org.eclipse.core.runtime.IProgressMonitor)
*/
public void visitLibraryEntry(
IClasspathEntry entry,
IJavaProject javaProject,
IProgressMonitor monitor)
throws CoreException
{
ProjectInfo projectInfo = getProjectInfo(javaProject);
Element classpathElement = projectInfo.getClasspathElement();
IPath libLocation = getLibraryLocation(entry);
if (libLocation != null) {
File libFile = libLocation.toFile();
Element pathElement = newChildElement(classpathElement, "path");
String relativePath = getProjectRelativeValue(javaProject, projectInfo, libLocation);
pathElement.setAttribute("location", relativePath);
addIncludesAndExcludes(entry, pathElement);
if (isLibraryExported(entry))
{
if (libFile.isDirectory()) {
// Create a new zip fileset for the packaging
Element filesetElement = eclipseMeBuildXmlDocument.createElement("fileset");
projectInfo.addPackageFilesetElement(filesetElement);
filesetElement.setAttribute("dir", relativePath);
} else {
// Create a new zip fileset for the packaging
Element zipFilesetElement =
eclipseMeBuildXmlDocument.createElement("zipfileset");
projectInfo.addPackageFilesetElement(zipFilesetElement);
zipFilesetElement.setAttribute("src", relativePath);
addIncludesAndExcludes(entry, zipFilesetElement);
}
}
}
}
/**
* @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
{
// Force the project info into the map so that it
// is held in the correct order
boolean exported = entry.isExported();
createProjectInfo(classpathProject, exported);
return super.visitProject(entry, javaProject, classpathProject, monitor);
}
/**
* @see eclipseme.core.internal.utils.IClasspathEntryVisitor#visitSourceEntry(org.eclipse.jdt.core.IClasspathEntry, org.eclipse.jdt.core.IJavaProject, org.eclipse.core.runtime.IProgressMonitor)
*/
public void visitSourceEntry(
IClasspathEntry entry,
IJavaProject javaProject,
IProgressMonitor monitor)
throws CoreException
{
IPath srcLocation = getSourceLocation(entry);
if (srcLocation != null) {
ProjectInfo projectInfo = getProjectInfo(javaProject);
// Create the wtkbuild task call
String buildTask = projectInfo.isExported() ? "wtkbuild" : "javac";
Element buildElement = eclipseMeBuildXmlDocument.createElement(buildTask);
projectInfo.addWtkBuildElement(entry, buildElement);
buildElement.setAttribute("destdir", projectInfo.getBuildDestination());
buildElement.setAttribute("sourcepath", "");
buildElement.setAttribute("encoding", "${src.encoding}");
buildElement.setAttribute("source", "1.3");
// Calculate the src directory relative to the specified
// project.
String relativePath = getProjectRelativeValue(javaProject, projectInfo, srcLocation);
buildElement.setAttribute("srcdir", relativePath);
// Add the inclusion and exclusion patterns as necessary
addIncludesAndExcludes(entry, buildElement);
// Add the classpath reference
Element classpathElement = newChildElement(buildElement, "classpath");
classpathElement.setAttribute("refid", projectInfo.getClasspathElementId());
// Make sure to copy the non-Java resources into the package
Element srcPackageElement = eclipseMeBuildXmlDocument.createElement("fileset");
srcPackageElement.setAttribute("dir", relativePath);
Element javaExclude = newChildElement(srcPackageElement, "exclude");
javaExclude.setAttribute("name", "**/*.java");
Element buildExclude = newChildElement(srcPackageElement, "exclude");
buildExclude.setAttribute("name", "build/");
addIncludesAndExcludes(entry, srcPackageElement);
projectInfo.addPackageFilesetElement(srcPackageElement);
} else {
EclipseMECorePlugin.log(
IStatus.WARNING,
"Skipping unresolvable classpath entry " + entry);
}
}
/**
* Add the inclusion and exclusion elements as necessary.
*
* @param entry
* @param element
*/
private void addIncludesAndExcludes(IClasspathEntry entry, Element element) {
for (int i = 0; i < entry.getExclusionPatterns().length; i++) {
IPath pattern = entry.getExclusionPatterns()[i];
Element exclusionElement = newChildElement(element, "exclude");
exclusionElement.setAttribute("name", pattern.toString());
}
for (int i = 0; i < entry.getInclusionPatterns().length; i++) {
IPath pattern = entry.getInclusionPatterns()[i];
Element inclusionElement = newChildElement(element, "include");
inclusionElement.setAttribute("name", pattern.toString());
}
}
/**
* Create a new project information structure.
*
* @param javaProject
* @param exported
*/
private void createProjectInfo(IJavaProject javaProject, boolean exported)
{
ProjectInfo info = new ProjectInfo(javaProject, exported);
projectInfoMap.put(javaProject, info);
}
/**
* Get the holder of information for the specified project.
*
* @param javaProject
* @return
*/
private ProjectInfo getProjectInfo(IJavaProject javaProject) {
return (ProjectInfo) projectInfoMap.get(javaProject);
}
/**
* Get the file system location for the specified classpath entry.
*
* @param entry
* @return
* @throws CoreException
*/
private IPath getLibraryLocation(IClasspathEntry entry)
throws CoreException
{
IPath libLocation = null;
Object resolved = Utils.getResolvedClasspathEntry(entry);
if (resolved instanceof IResource) {
IResource libResource = (IResource) resolved;
libLocation = libResource.getLocation();
} else if (resolved instanceof File) {
libLocation = entry.getPath();
}
return libLocation;
}
/**
* Return the project relative path.
*
* @param javaProject
* @param projectInfo
* @param location
* @return
* @throws CoreException
*/
private String getProjectRelativeValue(
IJavaProject javaProject,
ProjectInfo projectInfo,
IPath location)
throws CoreException
{
StringBuffer sb = new StringBuffer();
IPath projectPath = javaProject.getProject().getLocation();
String relativePath = getRelativePath(projectPath, location);
if (relativePath == null) {
// Can't get relation to projectPath, use location as it is
sb.append(location.toString());
} else {
sb
.append("${")
.append(projectInfo.getAntProjectPropertyName())
.append("}")
.append(relativePath);
}
return sb.toString();
}
/**
* Get the file system location for the specified classpath entry.
*
* @param entry
* @return
* @throws CoreException
*/
private IPath getSourceLocation(IClasspathEntry entry)
throws CoreException
{
IPath sourceLocation = null;
Object resolved = Utils.getResolvedClasspathEntry(entry);
if (resolved instanceof IResource) {
IResource srcResource = (IResource) resolved;
sourceLocation = srcResource.getLocation();
}
return sourceLocation;
}
}
private static final Pattern SUBSTITUTION_PATTERN =
Pattern.compile("\\@\\{(.+?)\\}");
private IMidletSuiteProject midletSuite;
private IJavaProject javaProject;
private IPath basedirPath;
private String projectName;
private Properties buildProperties;
private Document eclipseMeBuildXmlDocument;
/**
* Construct a new exporter for the specified midlet suite project.
*
* @param midletSuite
*/
public AntennaBuildExporter(IMidletSuiteProject midletSuite) {
super();
this.midletSuite = midletSuite;
this.javaProject = midletSuite.getJavaProject();
basedirPath = javaProject.getProject().getLocation();
projectName = midletSuite.getProject().getName();
}
/**
* Do the export for the midlet suite.
*
* @throws CoreException
*/
public void doExport(IProgressMonitor monitor)
throws CoreException, AntennaExportException
{
// Validate the environment is ok.
validateEnvironment(monitor);
try {
// Read in the templates
buildProperties = createInitialProperties();
eclipseMeBuildXmlDocument = readEclipseMeBuildTemplate();
// Traverse the classpath and update the results along the way
BuildClasspathEntryVisitor visitor = traverseClasspath(monitor);
updateEclipseMeBuildXml(visitor.getProjectInfoMap());
// Write out the results
exportBuildXml(monitor);
writeBuildProperties(monitor);
writeEclipseMeBuildXml(monitor);
// Refresh so these files show in the workbench.
javaProject.getProject().refreshLocal(IResource.DEPTH_ONE, monitor);
} catch (Exception e) {
if (e instanceof CoreException) {
throw (CoreException) e;
} else {
EclipseMECorePlugin.throwCoreException(IStatus.ERROR, -999, e);
}
}
}
/**
* Create the initial properties object.
*
* @return
*/
private Properties createInitialProperties() {
Properties props = new Properties();
// The basics
props.setProperty("midlet.name", javaProject.getProject().getName());
props.setProperty("path.build", "${basedir}/build");
props.setProperty("path.build.classes", "${basedir}/build/classes");
props.setProperty("path.build.output", "${basedir}/deployed");
// Antenna stuff
Preferences prefs = EclipseMECorePlugin.getDefault().getPluginPreferences();
props.setProperty(
"wtk.home",
prefs.getString(IEclipseMECoreConstants.PREF_WTK_ROOT));
props.setProperty(
"path.antenna.jar",
prefs.getString(IEclipseMECoreConstants.PREF_ANTENNA_JAR));
boolean autoVersion =
PreferenceAccessor.instance.getAutoversionPackage(midletSuite.getProject());
props.setProperty(
"flag.autoversion",
Boolean.toString(autoVersion));
props.setProperty("flag.preverify", "true");
// Set default encoding to UTF-8
props.setProperty("src.encoding", "UTF-8");
// Set the classpath to match the device
IDevice device = midletSuite.getDevice();
if (device != null) {
props.setProperty("wtk.midpapi", device.getClasspath().toString());
}
// Properties necessary for running in the emulator
props.setProperty("run.device.name", "DefaultColorPhone");
props.setProperty("run.trace.options", "");
// Add some default properties based on various things
addObfuscationProperties(props);
addVersionProperties(props);
return props;
}
/**
* Add the obfuscation-related properties.
*
* @param props
*/
private void addObfuscationProperties(Properties props) {
File proguardFile = EclipseMECorePlugin.getProguardJarFile();
boolean obfuscate = ((proguardFile != null) && proguardFile.exists());
// props.setProperty("flag.obfuscate", Boolean.toString(obfuscate));
if (obfuscate) {
File proguardHome = proguardFile.getParentFile().getParentFile();
props.setProperty("wtk.proguard.home", proguardHome.toString());
}
}
/**
* Add the appropriate J2ME version properties to match the JAD versions.
*
* @param props
*/
private void addVersionProperties(Properties props) {
ApplicationDescriptor descriptor = midletSuite.getApplicationDescriptor();
Properties manifestProperties = descriptor.getManifestProperties();
String versionString =
manifestProperties.getProperty(IJADConstants.JAD_MICROEDITION_CONFIG);
if (versionString != null) {
int index = versionString.indexOf('-');
versionString = (index == -1) ? versionString : versionString.substring(index + 1);
props.setProperty("wtk.cldc.version", versionString);
}
versionString = manifestProperties.getProperty(IJADConstants.JAD_MICROEDITION_PROFILE);
if (versionString != null) {
int index = versionString.indexOf('-');
versionString = (index == -1) ? versionString : versionString.substring(index + 1);
props.setProperty("wtk.midp.version", versionString);
}
}
/**
* Add a new argument to the WTK obfuscate element.
*
* @param wktobfuscateElement
* @param argument
*/
private void addWtkObfuscateArgument(Element wktobfuscateElement, String argument) {
Element argumentElement = newChildElement(wktobfuscateElement, "argument");
argumentElement.setAttribute("value", argument);
}
/**
* Read the build.xml template file.
*
* @param is
* @return
* @throws UnsupportedEncodingException
* @throws IOException
*/
private StringBuffer readBuildXmlTemplate(InputStream is)
throws UnsupportedEncodingException, IOException
{
// Read in the template
int charsRead;
char[] buffer = new char[1024];
Reader reader = new InputStreamReader(is, "UTF-8");
StringBuffer sb = new StringBuffer();
while ((charsRead = reader.read(buffer)) != -1) {
sb.append(buffer, 0, charsRead);
}
is.close();
return sb;
}
/**
* Read the template EclipseME build file.
* @return
* @throws IOException
* @throws SAXException
* @throws ParserConfigurationException
*/
private Document readEclipseMeBuildTemplate()
throws ParserConfigurationException, SAXException, IOException
{
Document document = null;
InputStream is = getClass().getResourceAsStream("eclipseme-build.xml");
if (is == null) {
throw new IOException("build.xml template not found");
} else {
// Read the document
document = XMLUtils.readDocument(is);
// Alter the "project" element's name attribute
Element projectElement = document.getDocumentElement();
projectElement.setAttribute("name", "eclipseme-" + projectName);
// Add some warning comments
StringBuffer comment = new StringBuffer();
comment
.append("\n\tAutomatically generated by EclipseME on ")
.append(new Date())
.append("\n\tDO NOT ALTER THIS FILE. IT WILL BE OVERWRITTEN\n\n")
.append("\tChanges may be made to build.xml and user-build.properties\n");
insertCommentBefore(projectElement, comment.toString());
}
return document;
}
/**
* Replace the build xml template values.
*
* @param sb
* @param props
*/
private void replaceTemplateValues(StringBuffer sb, Properties props) {
// Replace template values
int offset = 0;
Matcher matcher = SUBSTITUTION_PATTERN.matcher(sb);
while (matcher.find(offset)) {
String referencedValue = matcher.group(1);
String resolvedValue = props.getProperty(referencedValue, referencedValue);
sb.replace(matcher.start(), matcher.end(), resolvedValue);
// Figure out the new offset, based on the replaced
// string length
offset = matcher.start() + resolvedValue.length();
}
}
/**
* Export the build.xml file.
*
* @param monitor
* @throws SAXException
* @throws ParserConfigurationException
* @throws IOException
* @throws TransformerException
* @throws CoreException
*/
private void exportBuildXml(IProgressMonitor monitor)
throws ParserConfigurationException, SAXException, TransformerException, IOException, CoreException
{
// Check to make sure that we don't overwrite a user's build.xml file
// with our template file.
// TODO What do we do, if anything, when the build.xml file already exists?
File buildXmlFile = getMidletSuiteFile("build.xml", monitor);
if (!buildXmlFile.exists()) {
// Template values
Properties props = new Properties();
props.setProperty("eclipseme.version", EclipseMECorePlugin.getPluginVersion());
props.setProperty("date", (new Date()).toString());
props.setProperty("project.name", projectName);
InputStream is = getClass().getResourceAsStream("buildtemplate.xml");
if (is != null) {
// Read the template and do the replacements
StringBuffer sb = readBuildXmlTemplate(is);
replaceTemplateValues(sb, props);
// Write the results
FileOutputStream fos = new FileOutputStream(buildXmlFile);
OutputStreamWriter writer = new OutputStreamWriter(fos, "UTF-8");
writer.write(sb.toString());
writer.close();
}
}
}
/**
* Return the specified element within the specified parent. If more
* elements exist with that name, the first will be returned. If not
* found, <code>null</code> will be returned.
*
* @param parentElement
* @param elementName
* @return
*/
private Element findElement(Element parentElement, String elementName) {
Element element = null;
NodeList elements = parentElement.getElementsByTagName(elementName);
if (elements.getLength() > 0) {
element = (Element) elements.item(0);
}
return element;
}
/**
* Return a File reference to a file with the specified name
* in the midlet suite project.
*
* @param filename
* @param monitor
* @return
* @throws CoreException
*/
private File getMidletSuiteFile(String filename, IProgressMonitor monitor)
throws CoreException
{
IFile file = midletSuite.getProject().getFile(filename);
return file.getLocation().toFile();
}
/**
* Get the options to be specified when calling Proguard for
* obfuscation.
*
* @return
*/
private String 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 relative path.
*
* @param basePath the path that acts as the base for comparison
* @param tgtPath the path being compared to the base path
* @return relative path, or null if relation not possible
*/
private String getRelativePath(IPath basePath, IPath tgtPath)
{
String path = null;
// Find the common path prefix
int matchingSegments = tgtPath.matchingFirstSegments(basePath);
String baseDevice = basePath.getDevice();
String tgtDevice = tgtPath.getDevice();
boolean bothNull = ((baseDevice == null) && (tgtDevice == null));
if (bothNull || baseDevice.equals(tgtDevice)) {
// Step up the directory tree
StringBuffer relativePath = new StringBuffer();
int upSteps = basedirPath.segmentCount() - matchingSegments;
for (int i = 0; i < upSteps; i++) {
relativePath.append("/..");
}
// Tack on the src folder segments
tgtPath = tgtPath.removeFirstSegments(matchingSegments);
String[] segments = tgtPath.segments();
for (int i = 0; i < segments.length; i++) {
relativePath.append("/").append(segments[i]);
}
path = relativePath.toString();
}
return path;
}
/**
* Return the root of the first located Sun wireless toolkit for use
* in setting the appropriate Antenna property or <code>null</code>
* if one cannot be found.
*
* @return
*/
private File getWTKRoot() {
Preferences prefs = EclipseMECorePlugin.getDefault().getPluginPreferences();
return new File(prefs.getString(IEclipseMECoreConstants.PREF_WTK_ROOT));
}
/**
* Insert the comment text before the specified element.
*
* @param element
* @param commentString
*/
private void insertCommentBefore(Element element, String commentString) {
Document document = element.getOwnerDocument();
Comment comment = document.createComment(commentString);
document.insertBefore(comment, element);
}
/**
* Create and return a new child element under the specified parent
* element.
*
* @param parentElement
* @param name
* @return
*/
private Element newChildElement(Element parentElement, String name) {
Element element = parentElement.getOwnerDocument().createElement(name);
parentElement.appendChild(element);
return element;
}
/**
* Traverse the classpath and update the build information
* along the way.
* @throws CoreException
*/
private BuildClasspathEntryVisitor traverseClasspath(IProgressMonitor monitor)
throws CoreException
{
// Use a classpath visitor to build up the build information
BuildClasspathEntryVisitor visitor = new BuildClasspathEntryVisitor(javaProject);
visitor.getRunner(true).run(javaProject, visitor, monitor);
return visitor;
}
/**
* Update the EclipseME build file based on the classpath information
* collected during traversal.
*
* @param projectInfoMap
*/
private void updateEclipseMeBuildXml(Map projectInfoMap) {
// Collect the elements
Document doc = eclipseMeBuildXmlDocument;
Element documentElement = doc.getDocumentElement();
Element pathElement = findElement(documentElement, "path");
Element wtkBuildElement = findElement(documentElement, "wtkbuild");
Element wtkPackageElement = findElement(documentElement, "wtkpackage");
Element previousBuildElement = wtkBuildElement;
// Walk through the project info making the necessary updates
Iterator iterator = projectInfoMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
ProjectInfo info = (ProjectInfo) entry.getValue();
// Set the property for the root of the project
String propertyValue = info.getAntProjectPropertyValue();
propertyValue = (propertyValue.length() == 0) ?
"${basedir}" : "${basedir}" + propertyValue;
buildProperties.setProperty(
info.getAntProjectPropertyName(),
propertyValue);
// Insert this project's classpath path definition
pathElement.getParentNode().insertBefore(info.getClasspathElement(), pathElement);
// Insert the project's wtkbuild calls
Iterator elements = info.getWtkBuildElements();
while (elements.hasNext()) {
Element element = (Element) elements.next();
// Add these to the build file such that the prereq projects
// get built before the dependent projects
wtkBuildElement.getParentNode().insertBefore(element, previousBuildElement);
previousBuildElement = element;
}
// Insert the fileset definitions for packaging from this project
if (info.isExported()) {
// Add the classpath reference
Element classpathElement = newChildElement(wtkPackageElement, "classpath");
classpathElement.setAttribute("refid", info.getClasspathElementId());
elements = info.getPackageFilesetElements().iterator();
while (elements.hasNext()) {
Element element = (Element) elements.next();
wtkPackageElement.appendChild(element);
}
}
}
// Remove the marker elements
pathElement.getParentNode().removeChild(pathElement);
wtkBuildElement.getParentNode().removeChild(wtkBuildElement);
// Update the wtkobfuscate parameters
Element wktobfuscateElement = findElement(documentElement, "wtkobfuscate");
updateWtkObfuscateElement(wktobfuscateElement);
}
/**
* Update the WTK obfuscate element to include the parameters.
*
* @param wktobfuscateElement
*/
private void updateWtkObfuscateElement(Element wktobfuscateElement) {
String[] keepExpressions =
PreferenceAccessor.instance.getProguardKeepExpressions(midletSuite.getProject());
for (int i = 0; i < keepExpressions.length; i++) {
StringBuffer sb = new StringBuffer("'-keep ");
sb.append(keepExpressions[i]).append("'");
addWtkObfuscateArgument(wktobfuscateElement, sb.toString());
}
addWtkObfuscateArgument(wktobfuscateElement, getProguardOptions());
}
/**
* Validate that the antenna property is valid.
*
* @param monitor
* @throws AntennaExportException
*/
private void validateAntenna(IProgressMonitor monitor)
throws AntennaExportException
{
boolean valid = false;
Preferences prefs = EclipseMECorePlugin.getDefault().getPluginPreferences();
String antennaPref = prefs.getString(IEclipseMECoreConstants.PREF_ANTENNA_JAR);
File antennaFile = new File(antennaPref);
if (antennaFile.exists()) {
try {
ZipFile zipFile = new ZipFile(antennaFile);
ZipEntry entry = zipFile.getEntry("antenna.properties");
valid = (entry != null);
zipFile.close();
} catch (IOException e) {
// Assume these cases mean the file is invalid
EclipseMECorePlugin.log(IStatus.WARNING, "Error testing Antenna settings", e);
}
}
if (!valid) {
throw new AntennaExportException("Antenna library not found or not valid.\nCheck the preference settings.");
}
}
/**
* Validate the environment prior to the export. Throw
* an exception if the environment is not valid.
*
* @param monitor
* @throws AntennaExportException if the environment is not valid
*/
private void validateEnvironment(IProgressMonitor monitor)
throws AntennaExportException
{
validateAntenna(monitor);
validateWTK(monitor);
}
/**
* Validate that a Sun WTK can be found.
*
* @param monitor
* @throws AntennaExportException
*/
private void validateWTK(IProgressMonitor monitor)
throws AntennaExportException
{
File wtkRoot = getWTKRoot();
if ((wtkRoot == null) || !wtkRoot.exists()) {
throw new AntennaExportException("Sun WTK not found.\nCheck the platform definition settings.");
}
}
/**
* Write out the build properties file.
*
* @param monitor
* @throws IOException
* @throws CoreException
*/
private void writeBuildProperties(IProgressMonitor monitor)
throws IOException, CoreException
{
File buildPropsFile = getMidletSuiteFile("eclipseme-build.properties", monitor);
FileOutputStream fos = new FileOutputStream(buildPropsFile);
buildProperties.store(fos, " EclipseME Build Properties - DO NOT ALTER THIS FILE - Make changes in user-build.properties");
fos.close();
}
/**
* Write the EclipseME build.xml file.
*
* @throws TransformerException
* @throws IOException
* @throws CoreException
*/
private void writeEclipseMeBuildXml(IProgressMonitor monitor)
throws TransformerException, IOException, CoreException
{
// Write the output
File buildXmlFile = getMidletSuiteFile("eclipseme-build.xml", monitor);
XMLUtils.writeDocument(buildXmlFile, eclipseMeBuildXmlDocument);
}
}
The table below shows all metrics for AntennaBuildExporter.java.




