### Eclipse Workspace Patch 1.0 #P org.eclipse.pde.core Index: src/org/eclipse/pde/internal/core/pderesources.properties =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/pderesources.properties,v retrieving revision 1.107 diff -u -r1.107 pderesources.properties --- src/org/eclipse/pde/internal/core/pderesources.properties 24 Feb 2009 03:10:32 -0000 1.107 +++ src/org/eclipse/pde/internal/core/pderesources.properties 6 Mar 2009 18:58:40 -0000 @@ -193,6 +193,7 @@ FeatureExportOperation_0=Exported Repository FeatureExportOperation_CompilationErrors=Compilation errors occurred during the operation. A zip file containing the build logs has been generated and placed at {0} FeatureExportOperation_runningAssemblyScript=Running assembly script +FeatureExportOperation_publishingMetadata=Publishing metadata FeatureExportOperation_runningBuildScript=Running build script FeatureExportOperation_runningPackagerScript=Running packager script FeatureExportOperation_workspaceBuildErrorsFoundDuringExport=Export completed successfully, but build problems were detected in the following required projects: {0} Index: src/org/eclipse/pde/internal/core/PDECoreMessages.java =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECoreMessages.java,v retrieving revision 1.64 diff -u -r1.64 PDECoreMessages.java --- src/org/eclipse/pde/internal/core/PDECoreMessages.java 24 Feb 2009 03:10:32 -0000 1.64 +++ src/org/eclipse/pde/internal/core/PDECoreMessages.java 6 Mar 2009 18:58:40 -0000 @@ -257,6 +257,8 @@ public static String FeatureExportOperation_runningAssemblyScript; + public static String FeatureExportOperation_publishingMetadata; + public static String FeatureExportOperation_runningBuildScript; public static String FeatureExportOperation_runningPackagerScript; Index: src/org/eclipse/pde/internal/core/exports/ProductExportOperation.java =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/exports/ProductExportOperation.java,v retrieving revision 1.43 diff -u -r1.43 ProductExportOperation.java --- src/org/eclipse/pde/internal/core/exports/ProductExportOperation.java 27 Feb 2009 14:31:41 -0000 1.43 +++ src/org/eclipse/pde/internal/core/exports/ProductExportOperation.java 6 Mar 2009 18:58:40 -0000 @@ -1,474 +1,479 @@ -/******************************************************************************* - * Copyright (c) 2006, 2009 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.pde.internal.core.exports; - -import java.io.*; -import java.lang.reflect.InvocationTargetException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.*; -import javax.xml.parsers.*; -import org.eclipse.ant.core.AntRunner; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.*; -import org.eclipse.osgi.service.resolver.BundleDescription; -import org.eclipse.osgi.util.NLS; -import org.eclipse.pde.core.plugin.*; -import org.eclipse.pde.internal.build.*; -import org.eclipse.pde.internal.build.packager.PackageScriptGenerator; -import org.eclipse.pde.internal.core.*; -import org.eclipse.pde.internal.core.ifeature.IFeature; -import org.eclipse.pde.internal.core.ifeature.IFeatureModel; -import org.eclipse.pde.internal.core.iproduct.*; -import org.eclipse.pde.internal.core.iproduct.IProduct; -import org.eclipse.pde.internal.core.util.CoreUtility; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -public class ProductExportOperation extends FeatureExportOperation { - - private String fFeatureLocation; - private String fRoot; - private IProduct fProduct; - - public ProductExportOperation(FeatureExportInfo info, String name, IProduct product, String root) { - super(info, name); - fProduct = product; - fRoot = root; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.exports.FeatureExportOperation#run(org.eclipse.core.runtime.IProgressMonitor) - */ - protected IStatus run(IProgressMonitor monitor) { - String[][] configurations = fInfo.targets; - if (configurations == null) - configurations = new String[][] {{TargetPlatform.getOS(), TargetPlatform.getWS(), TargetPlatform.getOSArch(), TargetPlatform.getNL()}}; - - Properties versionAdvice = new Properties(); - try { - monitor.beginTask("", 10 * configurations.length); //$NON-NLS-1$ - for (int i = 0; i < configurations.length; i++) { - try { - String[] config = configurations[i]; - if (config[0].equals("macosx") && fInfo.targets == null) //$NON-NLS-1$ - createMacScript(config, new SubProgressMonitor(monitor, 1)); - // create a feature to wrap all plug-ins and features - String featureID = "org.eclipse.pde.container.feature"; //$NON-NLS-1$ - fFeatureLocation = fBuildTempLocation + File.separator + featureID; - - createFeature(featureID, fFeatureLocation, config, true); - createBuildPropertiesFile(fFeatureLocation, config); - doExport(featureID, null, fFeatureLocation, config[0], config[1], config[2], new SubProgressMonitor(monitor, 8)); - } catch (IOException e) { - PDECore.log(e); - } catch (InvocationTargetException e) { - return new Status(IStatus.ERROR, PDECore.PLUGIN_ID, PDECoreMessages.FeatureBasedExportOperation_ProblemDuringExport, e.getTargetException()); - } catch (CoreException e) { - return e.getStatus(); - } finally { - - // Append platform specific version information so that it is available for the p2 post script - String versionsPrefix = fProduct.useFeatures() ? IPDEBuildConstants.DEFAULT_FEATURE_VERSION_FILENAME_PREFIX : IPDEBuildConstants.DEFAULT_PLUGIN_VERSION_FILENAME_PREFIX; - File versionFile = new File(fFeatureLocation, versionsPrefix + IPDEBuildConstants.PROPERTIES_FILE_SUFFIX); - InputStream stream = null; - try { - stream = new BufferedInputStream(new FileInputStream(versionFile)); - versionAdvice.load(stream); - } catch (IOException e) { - } finally { - try { - if (stream != null) - stream.close(); - } catch (IOException e) { - } - } - - // Clean up generated files - for (int j = 0; j < fInfo.items.length; j++) { - try { - deleteBuildFiles(fInfo.items[j]); - } catch (CoreException e) { - PDECore.log(e); - } - } - cleanup(fInfo.targets == null ? null : configurations[i], new SubProgressMonitor(monitor, 1)); - } - } - - try { - // Run postscript to generate p2 metadata for product - String postScript = PackageScriptGenerator.generateP2ProductScript(fFeatureLocation, fProduct.getModel().getInstallLocation(), versionAdvice); - if (postScript != null) { - try { - Map properties = new HashMap(); - setP2MetaDataProperties(properties); - runScript(postScript, null, properties, monitor); - } catch (InvocationTargetException e) { - return new Status(IStatus.ERROR, PDECore.PLUGIN_ID, PDECoreMessages.FeatureBasedExportOperation_ProblemDuringExport, e.getTargetException()); - } - } - } catch (CoreException e) { - return e.getStatus(); - } - - cleanup(null, new SubProgressMonitor(monitor, 1)); - if (hasAntErrors()) { - return new Status(IStatus.WARNING, PDECore.PLUGIN_ID, NLS.bind(PDECoreMessages.FeatureExportOperation_CompilationErrors, fInfo.destinationDirectory)); - } - - } finally { - monitor.done(); - } - return Status.OK_STATUS; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.pde.internal.ui.wizards.exports.FeatureExportJob#getPaths() - */ - protected String[] getPaths() { - String[] paths = super.getPaths(); - String[] all = new String[paths.length + 1]; - all[0] = fFeatureLocation + File.separator + "feature.xml"; //$NON-NLS-1$ - System.arraycopy(paths, 0, all, 1, paths.length); - return all; - } - - private void createBuildPropertiesFile(String featureLocation, String[] config) { - File file = new File(featureLocation); - if (!file.exists() || !file.isDirectory()) - file.mkdirs(); - - boolean hasLaunchers = PDECore.getDefault().getFeatureModelManager().getDeltaPackFeature() != null; - Properties properties = new Properties(); - properties.put(IBuildPropertiesConstants.ROOT, getRootFileLocations(hasLaunchers)); //To copy a folder - if (!hasLaunchers) { - properties.put("root.permissions.755", getLauncherName()); //$NON-NLS-1$ - if (TargetPlatform.getWS().equals("motif") && TargetPlatform.getOS().equals("linux")) { //$NON-NLS-1$ //$NON-NLS-2$ - properties.put("root.linux.motif.x86.permissions.755", "libXm.so.2"); //$NON-NLS-1$ //$NON-NLS-2$ - } else if (TargetPlatform.getOS().equals("macosx")) { //$NON-NLS-1$ - properties.put("root.macosx.carbon.ppc.permissions.755", //$NON-NLS-1$ - "${launcherName}.app/Contents/MacOS/${launcherName}"); //$NON-NLS-1$ - } - } - - IJREInfo jreInfo = fProduct.getJREInfo(); - File vm = jreInfo != null ? jreInfo.getJVMLocation(config[0]) : null; - if (vm != null) { - properties.put("root." + config[0] + //$NON-NLS-1$ - "." + config[1] + //$NON-NLS-1$ - "." + config[2] + //$NON-NLS-1$ - ".folder.jre", //$NON-NLS-1$ - "absolute:" + vm.getAbsolutePath()); //$NON-NLS-1$ - String perms = (String) properties.get("root.permissions.755"); //$NON-NLS-1$ - if (perms != null) { - StringBuffer buffer = new StringBuffer(perms); - buffer.append(","); //$NON-NLS-1$ - buffer.append("jre/bin/java"); //$NON-NLS-1$ - properties.put("root.permissions.755", buffer.toString()); //$NON-NLS-1$ - } - } - - if (fInfo.exportSource && fInfo.exportSourceBundle) { - properties.put("individualSourceBundles", "true"); //$NON-NLS-1$ //$NON-NLS-2$ - Dictionary environment = new Hashtable(4); - environment.put("osgi.os", TargetPlatform.getOS()); //$NON-NLS-1$ - environment.put("osgi.ws", TargetPlatform.getWS()); //$NON-NLS-1$ - environment.put("osgi.arch", TargetPlatform.getOSArch()); //$NON-NLS-1$ - environment.put("osgi.nl", TargetPlatform.getNL()); //$NON-NLS-1$ - List workspacePlugins = Arrays.asList(PluginRegistry.getWorkspaceModels()); - for (int i = 0; i < fInfo.items.length; i++) { - if (fInfo.items[i] instanceof IFeatureModel) { - IFeature feature = ((IFeatureModel) fInfo.items[i]).getFeature(); - properties.put("generate.feature@" + feature.getId() + ".source", feature.getId()); //$NON-NLS-1$ //$NON-NLS-2$ - } else { - BundleDescription bundle = null; - if (fInfo.items[i] instanceof IPluginModelBase) { - bundle = ((IPluginModelBase) fInfo.items[i]).getBundleDescription(); - } - if (bundle == null) { - if (fInfo.items[i] instanceof BundleDescription) - bundle = (BundleDescription) fInfo.items[i]; - } - if (bundle == null) - continue; - - if (shouldAddPlugin(bundle, environment) && workspacePlugins.contains(PluginRegistry.findModel(bundle))) { - properties.put("generate.plugin@" + bundle.getSymbolicName() + ".source", bundle.getSymbolicName()); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - } - } - save(new File(file, "build.properties"), properties, "Build Configuration"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - private String getRootFileLocations(boolean hasLaunchers) { - StringBuffer buffer = new StringBuffer(); - - File homeDir = new File(TargetPlatform.getLocation()); - if (!hasLaunchers) { - if (homeDir.exists() && homeDir.isDirectory()) { - appendAbsolutePath(buffer, new File(homeDir, "startup.jar")); //$NON-NLS-1$ - if (!TargetPlatform.getOS().equals("macosx")) { //$NON-NLS-1$ - // try to retrieve the exact eclipse launcher path - // see bug 205833 - File file = null; - if (System.getProperties().get("eclipse.launcher") != null) { //$NON-NLS-1$ - String launcherPath = System.getProperties().get("eclipse.launcher").toString(); //$NON-NLS-1$ - file = new File(launcherPath); - if (file.exists() && !file.isDirectory()) { - appendAbsolutePath(buffer, file); - } else { // just assume traditional eclipse paths - appendEclipsePath(buffer, homeDir); - } - } else { // just assume traditional eclipse paths - appendEclipsePath(buffer, homeDir); - } - file = new File(homeDir, "libXm.so.2"); //$NON-NLS-1$ - if (file.exists()) { - appendAbsolutePath(buffer, file); - } - } - } - } - - return buffer.toString(); - } - - private void appendEclipsePath(StringBuffer buffer, File homeDir) { - File file = null; - file = new File(homeDir, "eclipse"); //$NON-NLS-1$ - if (file.exists()) { - appendAbsolutePath(buffer, file); - } - file = new File(homeDir, "eclipse.exe"); //$NON-NLS-1$ - if (file.exists()) { - appendAbsolutePath(buffer, file); - } - } - - private void appendAbsolutePath(StringBuffer buffer, File file) { - if (buffer.length() > 0) - buffer.append(","); //$NON-NLS-1$ - - buffer.append("absolute:file:"); //$NON-NLS-1$ - buffer.append(file.getAbsolutePath()); - } - - protected HashMap createAntBuildProperties(String os, String ws, String arch) { - HashMap properties = super.createAntBuildProperties(os, ws, arch); - properties.put(IXMLConstants.PROPERTY_LAUNCHER_NAME, getLauncherName()); - - ILauncherInfo info = fProduct.getLauncherInfo(); - if (info != null) { - String images = null; - if (os.equals("win32")) { //$NON-NLS-1$ - images = getWin32Images(info); - } else if (os.equals("solaris")) { //$NON-NLS-1$ - images = getSolarisImages(info); - } else if (os.equals("linux")) { //$NON-NLS-1$ - images = getExpandedPath(info.getIconPath(ILauncherInfo.LINUX_ICON)); - } else if (os.equals("macosx")) { //$NON-NLS-1$ - images = getExpandedPath(info.getIconPath(ILauncherInfo.MACOSX_ICON)); - } - if (images != null && images.length() > 0) - properties.put(IXMLConstants.PROPERTY_LAUNCHER_ICONS, images); - } - - fAntBuildProperties.put(IXMLConstants.PROPERTY_COLLECTING_FOLDER, fRoot); - fAntBuildProperties.put(IXMLConstants.PROPERTY_ARCHIVE_PREFIX, fRoot); - - return properties; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.exports.FeatureExportOperation#setP2MetaDataProperties(java.util.Map) - */ - protected void setP2MetaDataProperties(Map map) { - if (fInfo.exportMetadata) { - map.put(IXMLConstants.TARGET_P2_METADATA, IBuildPropertiesConstants.TRUE); - map.put(IBuildPropertiesConstants.PROPERTY_P2_FLAVOR, P2Utils.P2_FLAVOR_DEFAULT); - map.put(IBuildPropertiesConstants.PROPERTY_P2_PUBLISH_ARTIFACTS, IBuildPropertiesConstants.TRUE); - map.put(IBuildPropertiesConstants.PROPERTY_P2_COMPRESS, IBuildPropertiesConstants.TRUE); - try { - map.put(IBuildPropertiesConstants.PROPERTY_P2_METADATA_REPO, new File(fInfo.destinationDirectory + "/repository").toURL().toString()); //$NON-NLS-1$ - map.put(IBuildPropertiesConstants.PROPERTY_P2_ARTIFACT_REPO, new File(fInfo.destinationDirectory + "/repository").toURL().toString()); //$NON-NLS-1$ - map.put(IBuildPropertiesConstants.PROPERTY_P2_METADATA_REPO_NAME, NLS.bind(PDECoreMessages.ProductExportOperation_0, fProduct.getId())); - map.put(IBuildPropertiesConstants.PROPERTY_P2_ARTIFACT_REPO_NAME, NLS.bind(PDECoreMessages.ProductExportOperation_0, fProduct.getId())); - } catch (MalformedURLException e) { - PDECore.log(e); - } - } - } - - private String getLauncherName() { - ILauncherInfo info = fProduct.getLauncherInfo(); - if (info != null) { - String name = info.getLauncherName(); - if (name != null && name.length() > 0) { - name = name.trim(); - if (name.endsWith(".exe")) //$NON-NLS-1$ - name = name.substring(0, name.length() - 4); - return name; - } - } - return "eclipse"; //$NON-NLS-1$ - } - - private String getWin32Images(ILauncherInfo info) { - StringBuffer buffer = new StringBuffer(); - if (info.usesWinIcoFile()) { - append(buffer, info.getIconPath(ILauncherInfo.P_ICO_PATH)); - } else { - append(buffer, info.getIconPath(ILauncherInfo.WIN32_16_LOW)); - append(buffer, info.getIconPath(ILauncherInfo.WIN32_16_HIGH)); - append(buffer, info.getIconPath(ILauncherInfo.WIN32_32_HIGH)); - append(buffer, info.getIconPath(ILauncherInfo.WIN32_32_LOW)); - append(buffer, info.getIconPath(ILauncherInfo.WIN32_48_HIGH)); - append(buffer, info.getIconPath(ILauncherInfo.WIN32_48_LOW)); - } - return buffer.length() > 0 ? buffer.toString() : null; - } - - private String getSolarisImages(ILauncherInfo info) { - StringBuffer buffer = new StringBuffer(); - append(buffer, info.getIconPath(ILauncherInfo.SOLARIS_LARGE)); - append(buffer, info.getIconPath(ILauncherInfo.SOLARIS_MEDIUM)); - append(buffer, info.getIconPath(ILauncherInfo.SOLARIS_SMALL)); - append(buffer, info.getIconPath(ILauncherInfo.SOLARIS_TINY)); - return buffer.length() > 0 ? buffer.toString() : null; - } - - private void append(StringBuffer buffer, String path) { - path = getExpandedPath(path); - if (path != null) { - if (buffer.length() > 0) - buffer.append(","); //$NON-NLS-1$ - buffer.append(path); - } - } - - private String getExpandedPath(String path) { - if (path == null || path.length() == 0) - return null; - IResource resource = PDECore.getWorkspace().getRoot().findMember(new Path(path)); - if (resource != null) { - IPath fullPath = resource.getLocation(); - return fullPath == null ? null : fullPath.toOSString(); - } - return null; - } - - protected void setupGenerator(BuildScriptGenerator generator, String featureID, String versionId, String os, String ws, String arch, String featureLocation) throws CoreException { - super.setupGenerator(generator, featureID, versionId, os, ws, arch, featureLocation); - generator.setGenerateVersionsList(true); - if (fProduct != null) - generator.setProduct(fProduct.getModel().getInstallLocation()); - } - - private void createMacScript(String[] config, IProgressMonitor monitor) { - String entryName = TargetPlatformHelper.getTargetVersion() >= 3.3 ? "macosx/Info.plist" //$NON-NLS-1$ - : "macosx/Info.plist.32"; //$NON-NLS-1$ - URL url = PDECore.getDefault().getBundle().getEntry(entryName); - if (url == null) - return; - - File scriptFile = null; - File plist = null; - InputStream in = null; - String location = PDECore.getDefault().getStateLocation().toOSString(); - try { - in = url.openStream(); - File dir = new File(location, "Eclipse.app/Contents"); //$NON-NLS-1$ - dir.mkdirs(); - plist = new File(dir, "Info.plist"); //$NON-NLS-1$ - CoreUtility.readFile(in, plist); - scriptFile = createScriptFile("macbuild.xml"); //$NON-NLS-1$ - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - Document doc = factory.newDocumentBuilder().newDocument(); - - Element root = doc.createElement("project"); //$NON-NLS-1$ - root.setAttribute("name", "project"); //$NON-NLS-1$ //$NON-NLS-2$ - root.setAttribute("default", "default"); //$NON-NLS-1$ //$NON-NLS-2$ - doc.appendChild(root); - - Element property = doc.createElement("property"); //$NON-NLS-1$ - property.setAttribute("name", "eclipse.base"); //$NON-NLS-1$ //$NON-NLS-2$ - property.setAttribute("value", "${assemblyTempDir}/${collectingFolder}"); //$NON-NLS-1$ //$NON-NLS-2$ - root.appendChild(property); - - Element target = doc.createElement("target"); //$NON-NLS-1$ - target.setAttribute("name", "default"); //$NON-NLS-1$ //$NON-NLS-2$ - root.appendChild(target); - - Element copy = doc.createElement("copy"); //$NON-NLS-1$ - StringBuffer toDir = new StringBuffer("${eclipse.base}/"); //$NON-NLS-1$ - toDir.append(config[0]); - toDir.append("."); //$NON-NLS-1$ - toDir.append(config[1]); - toDir.append("."); //$NON-NLS-1$ - toDir.append(config[2]); - toDir.append("/${collectingFolder}"); //$NON-NLS-1$ - copy.setAttribute("todir", toDir.toString()); //$NON-NLS-1$ - copy.setAttribute("failonerror", "false"); //$NON-NLS-1$ //$NON-NLS-2$ - copy.setAttribute("overwrite", "true"); //$NON-NLS-1$ //$NON-NLS-2$ - target.appendChild(copy); - - Element fileset = doc.createElement("fileset"); //$NON-NLS-1$ - fileset.setAttribute("dir", "${installFolder}"); //$NON-NLS-1$ //$NON-NLS-2$ - fileset.setAttribute("includes", "Eclipse.app/Contents/MacOS/eclipse"); //$NON-NLS-1$ //$NON-NLS-2$ - copy.appendChild(fileset); - - fileset = doc.createElement("fileset"); //$NON-NLS-1$ - fileset.setAttribute("dir", "${template}"); //$NON-NLS-1$ //$NON-NLS-2$ - fileset.setAttribute("includes", "Eclipse.app/Contents/Info.plist"); //$NON-NLS-1$ //$NON-NLS-2$ - copy.appendChild(fileset); - - XMLPrintHandler.writeFile(doc, scriptFile); - - AntRunner runner = new AntRunner(); - HashMap map = new HashMap(); - if (!fInfo.toDirectory) { - String filename = fInfo.zipFileName; - map.put(IXMLConstants.PROPERTY_ARCHIVE_FULLPATH, fInfo.destinationDirectory + File.separator + filename); - } else { - map.put(IXMLConstants.PROPERTY_ASSEMBLY_TMP, fInfo.destinationDirectory); - } - map.put(IXMLConstants.PROPERTY_COLLECTING_FOLDER, fRoot); - map.put("installFolder", TargetPlatform.getLocation()); //$NON-NLS-1$ - map.put("template", location); //$NON-NLS-1$ - runner.addUserProperties(map); - runner.setBuildFileLocation(scriptFile.getAbsolutePath()); - runner.setExecutionTargets(new String[] {"default"}); //$NON-NLS-1$ - runner.run(new SubProgressMonitor(monitor, 1)); - } catch (FactoryConfigurationError e) { - } catch (ParserConfigurationException e) { - } catch (CoreException e) { - } catch (IOException e) { - } finally { - try { - if (in != null) - in.close(); - } catch (IOException e) { - } - CoreUtility.deleteContent(new File(location, "Eclipse.app")); //$NON-NLS-1$ - if (scriptFile != null && scriptFile.exists()) - scriptFile.delete(); - monitor.done(); - } - } - - protected void setAdditionalAttributes(Element plugin, BundleDescription bundle) { - plugin.setAttribute("unpack", Boolean.toString(CoreUtility.guessUnpack(bundle))); //$NON-NLS-1$ - } -} +/******************************************************************************* + * Copyright (c) 2006, 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.internal.core.exports; + +import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.*; +import javax.xml.parsers.*; +import org.eclipse.ant.core.AntRunner; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.*; +import org.eclipse.osgi.service.resolver.BundleDescription; +import org.eclipse.osgi.util.NLS; +import org.eclipse.pde.core.plugin.*; +import org.eclipse.pde.internal.build.*; +import org.eclipse.pde.internal.build.packager.PackageScriptGenerator; +import org.eclipse.pde.internal.core.*; +import org.eclipse.pde.internal.core.ifeature.IFeature; +import org.eclipse.pde.internal.core.ifeature.IFeatureModel; +import org.eclipse.pde.internal.core.iproduct.*; +import org.eclipse.pde.internal.core.iproduct.IProduct; +import org.eclipse.pde.internal.core.util.CoreUtility; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class ProductExportOperation extends FeatureExportOperation { + + private String fFeatureLocation; + private String fRoot; + private IProduct fProduct; + + public ProductExportOperation(FeatureExportInfo info, String name, IProduct product, String root) { + super(info, name); + fProduct = product; + fRoot = root; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.exports.FeatureExportOperation#run(org.eclipse.core.runtime.IProgressMonitor) + */ + protected IStatus run(IProgressMonitor monitor) { + String[][] configurations = fInfo.targets; + if (configurations == null) + configurations = new String[][] {{TargetPlatform.getOS(), TargetPlatform.getWS(), TargetPlatform.getOSArch(), TargetPlatform.getNL()}}; + + Properties versionAdvice = new Properties(); + try { + monitor.beginTask("", 10 * configurations.length); //$NON-NLS-1$ + for (int i = 0; i < configurations.length; i++) { + try { + String[] config = configurations[i]; + if (config[0].equals("macosx") && fInfo.targets == null) //$NON-NLS-1$ + createMacScript(config, new SubProgressMonitor(monitor, 1)); + // create a feature to wrap all plug-ins and features + String featureID = "org.eclipse.pde.container.feature"; //$NON-NLS-1$ + fFeatureLocation = fBuildTempLocation + File.separator + featureID; + + createFeature(featureID, fFeatureLocation, config, true); + createBuildPropertiesFile(fFeatureLocation, config); + doExport(featureID, null, fFeatureLocation, config[0], config[1], config[2], new SubProgressMonitor(monitor, 8)); + } catch (IOException e) { + PDECore.log(e); + } catch (InvocationTargetException e) { + return new Status(IStatus.ERROR, PDECore.PLUGIN_ID, PDECoreMessages.FeatureBasedExportOperation_ProblemDuringExport, e.getTargetException()); + } catch (CoreException e) { + return e.getStatus(); + } finally { + + // Append platform specific version information so that it is available for the p2 post script + String versionsPrefix = fProduct.useFeatures() ? IPDEBuildConstants.DEFAULT_FEATURE_VERSION_FILENAME_PREFIX : IPDEBuildConstants.DEFAULT_PLUGIN_VERSION_FILENAME_PREFIX; + File versionFile = new File(fFeatureLocation, versionsPrefix + IPDEBuildConstants.PROPERTIES_FILE_SUFFIX); + InputStream stream = null; + try { + stream = new BufferedInputStream(new FileInputStream(versionFile)); + versionAdvice.load(stream); + } catch (IOException e) { + } finally { + try { + if (stream != null) + stream.close(); + } catch (IOException e) { + } + } + + // Clean up generated files + for (int j = 0; j < fInfo.items.length; j++) { + try { + deleteBuildFiles(fInfo.items[j]); + } catch (CoreException e) { + PDECore.log(e); + } + } + cleanup(fInfo.targets == null ? null : configurations[i], new SubProgressMonitor(monitor, 1)); + } + } + + try { + // Run postscript to generate p2 metadata for product + String postScript = PackageScriptGenerator.generateP2ProductScript(fFeatureLocation, fProduct.getModel().getInstallLocation(), versionAdvice); + if (postScript != null) { + try { + Map properties = new HashMap(); + setP2MetaDataProperties(properties); + runScript(postScript, null, properties, monitor); + } catch (InvocationTargetException e) { + return new Status(IStatus.ERROR, PDECore.PLUGIN_ID, PDECoreMessages.FeatureBasedExportOperation_ProblemDuringExport, e.getTargetException()); + } + } + } catch (CoreException e) { + return e.getStatus(); + } + + cleanup(null, new SubProgressMonitor(monitor, 1)); + if (hasAntErrors()) { + return new Status(IStatus.WARNING, PDECore.PLUGIN_ID, NLS.bind(PDECoreMessages.FeatureExportOperation_CompilationErrors, fInfo.destinationDirectory)); + } + + } finally { + monitor.done(); + } + return Status.OK_STATUS; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.pde.internal.ui.wizards.exports.FeatureExportJob#getPaths() + */ + protected String[] getPaths() { + String[] paths = super.getPaths(); + String[] all = new String[paths.length + 1]; + all[0] = fFeatureLocation + File.separator + "feature.xml"; //$NON-NLS-1$ + System.arraycopy(paths, 0, all, 1, paths.length); + return all; + } + + private void createBuildPropertiesFile(String featureLocation, String[] config) { + File file = new File(featureLocation); + if (!file.exists() || !file.isDirectory()) + file.mkdirs(); + + boolean hasLaunchers = PDECore.getDefault().getFeatureModelManager().getDeltaPackFeature() != null; + Properties properties = new Properties(); + properties.put(IBuildPropertiesConstants.ROOT, getRootFileLocations(hasLaunchers)); //To copy a folder + if (!hasLaunchers) { + properties.put("root.permissions.755", getLauncherName()); //$NON-NLS-1$ + if (TargetPlatform.getWS().equals("motif") && TargetPlatform.getOS().equals("linux")) { //$NON-NLS-1$ //$NON-NLS-2$ + properties.put("root.linux.motif.x86.permissions.755", "libXm.so.2"); //$NON-NLS-1$ //$NON-NLS-2$ + } else if (TargetPlatform.getOS().equals("macosx")) { //$NON-NLS-1$ + properties.put("root.macosx.carbon.ppc.permissions.755", //$NON-NLS-1$ + "${launcherName}.app/Contents/MacOS/${launcherName}"); //$NON-NLS-1$ + } + } + + IJREInfo jreInfo = fProduct.getJREInfo(); + File vm = jreInfo != null ? jreInfo.getJVMLocation(config[0]) : null; + if (vm != null) { + properties.put("root." + config[0] + //$NON-NLS-1$ + "." + config[1] + //$NON-NLS-1$ + "." + config[2] + //$NON-NLS-1$ + ".folder.jre", //$NON-NLS-1$ + "absolute:" + vm.getAbsolutePath()); //$NON-NLS-1$ + String perms = (String) properties.get("root.permissions.755"); //$NON-NLS-1$ + if (perms != null) { + StringBuffer buffer = new StringBuffer(perms); + buffer.append(","); //$NON-NLS-1$ + buffer.append("jre/bin/java"); //$NON-NLS-1$ + properties.put("root.permissions.755", buffer.toString()); //$NON-NLS-1$ + } + } + + if (fInfo.exportSource && fInfo.exportSourceBundle) { + properties.put("individualSourceBundles", "true"); //$NON-NLS-1$ //$NON-NLS-2$ + Dictionary environment = new Hashtable(4); + environment.put("osgi.os", TargetPlatform.getOS()); //$NON-NLS-1$ + environment.put("osgi.ws", TargetPlatform.getWS()); //$NON-NLS-1$ + environment.put("osgi.arch", TargetPlatform.getOSArch()); //$NON-NLS-1$ + environment.put("osgi.nl", TargetPlatform.getNL()); //$NON-NLS-1$ + List workspacePlugins = Arrays.asList(PluginRegistry.getWorkspaceModels()); + for (int i = 0; i < fInfo.items.length; i++) { + if (fInfo.items[i] instanceof IFeatureModel) { + IFeature feature = ((IFeatureModel) fInfo.items[i]).getFeature(); + properties.put("generate.feature@" + feature.getId() + ".source", feature.getId()); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + BundleDescription bundle = null; + if (fInfo.items[i] instanceof IPluginModelBase) { + bundle = ((IPluginModelBase) fInfo.items[i]).getBundleDescription(); + } + if (bundle == null) { + if (fInfo.items[i] instanceof BundleDescription) + bundle = (BundleDescription) fInfo.items[i]; + } + if (bundle == null) + continue; + + if (shouldAddPlugin(bundle, environment) && workspacePlugins.contains(PluginRegistry.findModel(bundle))) { + properties.put("generate.plugin@" + bundle.getSymbolicName() + ".source", bundle.getSymbolicName()); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + } + save(new File(file, "build.properties"), properties, "Build Configuration"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private String getRootFileLocations(boolean hasLaunchers) { + StringBuffer buffer = new StringBuffer(); + + File homeDir = new File(TargetPlatform.getLocation()); + if (!hasLaunchers) { + if (homeDir.exists() && homeDir.isDirectory()) { + appendAbsolutePath(buffer, new File(homeDir, "startup.jar")); //$NON-NLS-1$ + if (!TargetPlatform.getOS().equals("macosx")) { //$NON-NLS-1$ + // try to retrieve the exact eclipse launcher path + // see bug 205833 + File file = null; + if (System.getProperties().get("eclipse.launcher") != null) { //$NON-NLS-1$ + String launcherPath = System.getProperties().get("eclipse.launcher").toString(); //$NON-NLS-1$ + file = new File(launcherPath); + if (file.exists() && !file.isDirectory()) { + appendAbsolutePath(buffer, file); + } else { // just assume traditional eclipse paths + appendEclipsePath(buffer, homeDir); + } + } else { // just assume traditional eclipse paths + appendEclipsePath(buffer, homeDir); + } + file = new File(homeDir, "libXm.so.2"); //$NON-NLS-1$ + if (file.exists()) { + appendAbsolutePath(buffer, file); + } + } + } + } + + return buffer.toString(); + } + + private void appendEclipsePath(StringBuffer buffer, File homeDir) { + File file = null; + file = new File(homeDir, "eclipse"); //$NON-NLS-1$ + if (file.exists()) { + appendAbsolutePath(buffer, file); + } + file = new File(homeDir, "eclipse.exe"); //$NON-NLS-1$ + if (file.exists()) { + appendAbsolutePath(buffer, file); + } + } + + private void appendAbsolutePath(StringBuffer buffer, File file) { + if (buffer.length() > 0) + buffer.append(","); //$NON-NLS-1$ + + buffer.append("absolute:file:"); //$NON-NLS-1$ + buffer.append(file.getAbsolutePath()); + } + + protected HashMap createAntBuildProperties(String os, String ws, String arch) { + HashMap properties = super.createAntBuildProperties(os, ws, arch); + properties.put(IXMLConstants.PROPERTY_LAUNCHER_NAME, getLauncherName()); + + ILauncherInfo info = fProduct.getLauncherInfo(); + if (info != null) { + String images = null; + if (os.equals("win32")) { //$NON-NLS-1$ + images = getWin32Images(info); + } else if (os.equals("solaris")) { //$NON-NLS-1$ + images = getSolarisImages(info); + } else if (os.equals("linux")) { //$NON-NLS-1$ + images = getExpandedPath(info.getIconPath(ILauncherInfo.LINUX_ICON)); + } else if (os.equals("macosx")) { //$NON-NLS-1$ + images = getExpandedPath(info.getIconPath(ILauncherInfo.MACOSX_ICON)); + } + if (images != null && images.length() > 0) + properties.put(IXMLConstants.PROPERTY_LAUNCHER_ICONS, images); + } + + fAntBuildProperties.put(IXMLConstants.PROPERTY_COLLECTING_FOLDER, fRoot); + fAntBuildProperties.put(IXMLConstants.PROPERTY_ARCHIVE_PREFIX, fRoot); + + return properties; + } + + protected boolean publishingP2Metadata() { + //not supported yet + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.exports.FeatureExportOperation#setP2MetaDataProperties(java.util.Map) + */ + protected void setP2MetaDataProperties(Map map) { + if (fInfo.exportMetadata) { + map.put(IXMLConstants.TARGET_P2_METADATA, IBuildPropertiesConstants.TRUE); + map.put(IBuildPropertiesConstants.PROPERTY_P2_FLAVOR, P2Utils.P2_FLAVOR_DEFAULT); + map.put(IBuildPropertiesConstants.PROPERTY_P2_PUBLISH_ARTIFACTS, IBuildPropertiesConstants.TRUE); + map.put(IBuildPropertiesConstants.PROPERTY_P2_COMPRESS, IBuildPropertiesConstants.TRUE); + try { + map.put(IBuildPropertiesConstants.PROPERTY_P2_METADATA_REPO, new File(fInfo.destinationDirectory + "/repository").toURL().toString()); //$NON-NLS-1$ + map.put(IBuildPropertiesConstants.PROPERTY_P2_ARTIFACT_REPO, new File(fInfo.destinationDirectory + "/repository").toURL().toString()); //$NON-NLS-1$ + map.put(IBuildPropertiesConstants.PROPERTY_P2_METADATA_REPO_NAME, NLS.bind(PDECoreMessages.ProductExportOperation_0, fProduct.getId())); + map.put(IBuildPropertiesConstants.PROPERTY_P2_ARTIFACT_REPO_NAME, NLS.bind(PDECoreMessages.ProductExportOperation_0, fProduct.getId())); + } catch (MalformedURLException e) { + PDECore.log(e); + } + } + } + + private String getLauncherName() { + ILauncherInfo info = fProduct.getLauncherInfo(); + if (info != null) { + String name = info.getLauncherName(); + if (name != null && name.length() > 0) { + name = name.trim(); + if (name.endsWith(".exe")) //$NON-NLS-1$ + name = name.substring(0, name.length() - 4); + return name; + } + } + return "eclipse"; //$NON-NLS-1$ + } + + private String getWin32Images(ILauncherInfo info) { + StringBuffer buffer = new StringBuffer(); + if (info.usesWinIcoFile()) { + append(buffer, info.getIconPath(ILauncherInfo.P_ICO_PATH)); + } else { + append(buffer, info.getIconPath(ILauncherInfo.WIN32_16_LOW)); + append(buffer, info.getIconPath(ILauncherInfo.WIN32_16_HIGH)); + append(buffer, info.getIconPath(ILauncherInfo.WIN32_32_HIGH)); + append(buffer, info.getIconPath(ILauncherInfo.WIN32_32_LOW)); + append(buffer, info.getIconPath(ILauncherInfo.WIN32_48_HIGH)); + append(buffer, info.getIconPath(ILauncherInfo.WIN32_48_LOW)); + } + return buffer.length() > 0 ? buffer.toString() : null; + } + + private String getSolarisImages(ILauncherInfo info) { + StringBuffer buffer = new StringBuffer(); + append(buffer, info.getIconPath(ILauncherInfo.SOLARIS_LARGE)); + append(buffer, info.getIconPath(ILauncherInfo.SOLARIS_MEDIUM)); + append(buffer, info.getIconPath(ILauncherInfo.SOLARIS_SMALL)); + append(buffer, info.getIconPath(ILauncherInfo.SOLARIS_TINY)); + return buffer.length() > 0 ? buffer.toString() : null; + } + + private void append(StringBuffer buffer, String path) { + path = getExpandedPath(path); + if (path != null) { + if (buffer.length() > 0) + buffer.append(","); //$NON-NLS-1$ + buffer.append(path); + } + } + + private String getExpandedPath(String path) { + if (path == null || path.length() == 0) + return null; + IResource resource = PDECore.getWorkspace().getRoot().findMember(new Path(path)); + if (resource != null) { + IPath fullPath = resource.getLocation(); + return fullPath == null ? null : fullPath.toOSString(); + } + return null; + } + + protected void setupGenerator(BuildScriptGenerator generator, String featureID, String versionId, String os, String ws, String arch, String featureLocation) throws CoreException { + super.setupGenerator(generator, featureID, versionId, os, ws, arch, featureLocation); + generator.setGenerateVersionsList(true); + if (fProduct != null) + generator.setProduct(fProduct.getModel().getInstallLocation()); + } + + private void createMacScript(String[] config, IProgressMonitor monitor) { + String entryName = TargetPlatformHelper.getTargetVersion() >= 3.3 ? "macosx/Info.plist" //$NON-NLS-1$ + : "macosx/Info.plist.32"; //$NON-NLS-1$ + URL url = PDECore.getDefault().getBundle().getEntry(entryName); + if (url == null) + return; + + File scriptFile = null; + File plist = null; + InputStream in = null; + String location = PDECore.getDefault().getStateLocation().toOSString(); + try { + in = url.openStream(); + File dir = new File(location, "Eclipse.app/Contents"); //$NON-NLS-1$ + dir.mkdirs(); + plist = new File(dir, "Info.plist"); //$NON-NLS-1$ + CoreUtility.readFile(in, plist); + scriptFile = createScriptFile("macbuild.xml"); //$NON-NLS-1$ + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + Document doc = factory.newDocumentBuilder().newDocument(); + + Element root = doc.createElement("project"); //$NON-NLS-1$ + root.setAttribute("name", "project"); //$NON-NLS-1$ //$NON-NLS-2$ + root.setAttribute("default", "default"); //$NON-NLS-1$ //$NON-NLS-2$ + doc.appendChild(root); + + Element property = doc.createElement("property"); //$NON-NLS-1$ + property.setAttribute("name", "eclipse.base"); //$NON-NLS-1$ //$NON-NLS-2$ + property.setAttribute("value", "${assemblyTempDir}/${collectingFolder}"); //$NON-NLS-1$ //$NON-NLS-2$ + root.appendChild(property); + + Element target = doc.createElement("target"); //$NON-NLS-1$ + target.setAttribute("name", "default"); //$NON-NLS-1$ //$NON-NLS-2$ + root.appendChild(target); + + Element copy = doc.createElement("copy"); //$NON-NLS-1$ + StringBuffer toDir = new StringBuffer("${eclipse.base}/"); //$NON-NLS-1$ + toDir.append(config[0]); + toDir.append("."); //$NON-NLS-1$ + toDir.append(config[1]); + toDir.append("."); //$NON-NLS-1$ + toDir.append(config[2]); + toDir.append("/${collectingFolder}"); //$NON-NLS-1$ + copy.setAttribute("todir", toDir.toString()); //$NON-NLS-1$ + copy.setAttribute("failonerror", "false"); //$NON-NLS-1$ //$NON-NLS-2$ + copy.setAttribute("overwrite", "true"); //$NON-NLS-1$ //$NON-NLS-2$ + target.appendChild(copy); + + Element fileset = doc.createElement("fileset"); //$NON-NLS-1$ + fileset.setAttribute("dir", "${installFolder}"); //$NON-NLS-1$ //$NON-NLS-2$ + fileset.setAttribute("includes", "Eclipse.app/Contents/MacOS/eclipse"); //$NON-NLS-1$ //$NON-NLS-2$ + copy.appendChild(fileset); + + fileset = doc.createElement("fileset"); //$NON-NLS-1$ + fileset.setAttribute("dir", "${template}"); //$NON-NLS-1$ //$NON-NLS-2$ + fileset.setAttribute("includes", "Eclipse.app/Contents/Info.plist"); //$NON-NLS-1$ //$NON-NLS-2$ + copy.appendChild(fileset); + + XMLPrintHandler.writeFile(doc, scriptFile); + + AntRunner runner = new AntRunner(); + HashMap map = new HashMap(); + if (!fInfo.toDirectory) { + String filename = fInfo.zipFileName; + map.put(IXMLConstants.PROPERTY_ARCHIVE_FULLPATH, fInfo.destinationDirectory + File.separator + filename); + } else { + map.put(IXMLConstants.PROPERTY_ASSEMBLY_TMP, fInfo.destinationDirectory); + } + map.put(IXMLConstants.PROPERTY_COLLECTING_FOLDER, fRoot); + map.put("installFolder", TargetPlatform.getLocation()); //$NON-NLS-1$ + map.put("template", location); //$NON-NLS-1$ + runner.addUserProperties(map); + runner.setBuildFileLocation(scriptFile.getAbsolutePath()); + runner.setExecutionTargets(new String[] {"default"}); //$NON-NLS-1$ + runner.run(new SubProgressMonitor(monitor, 1)); + } catch (FactoryConfigurationError e) { + } catch (ParserConfigurationException e) { + } catch (CoreException e) { + } catch (IOException e) { + } finally { + try { + if (in != null) + in.close(); + } catch (IOException e) { + } + CoreUtility.deleteContent(new File(location, "Eclipse.app")); //$NON-NLS-1$ + if (scriptFile != null && scriptFile.exists()) + scriptFile.delete(); + monitor.done(); + } + } + + protected void setAdditionalAttributes(Element plugin, BundleDescription bundle) { + plugin.setAttribute("unpack", Boolean.toString(CoreUtility.guessUnpack(bundle))); //$NON-NLS-1$ + } +} Index: src/org/eclipse/pde/internal/core/exports/SiteBuildOperation.java =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/exports/SiteBuildOperation.java,v retrieving revision 1.11 diff -u -r1.11 SiteBuildOperation.java --- src/org/eclipse/pde/internal/core/exports/SiteBuildOperation.java 3 Feb 2009 21:20:53 -0000 1.11 +++ src/org/eclipse/pde/internal/core/exports/SiteBuildOperation.java 6 Mar 2009 18:58:40 -0000 @@ -1,211 +1,215 @@ -/******************************************************************************* - * Copyright (c) 2006, 2008 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.pde.internal.core.exports; - -import java.io.File; -import java.net.MalformedURLException; -import java.util.Map; -import java.util.regex.Pattern; -import org.eclipse.core.resources.*; -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.jobs.MultiRule; -import org.eclipse.pde.internal.build.IBuildPropertiesConstants; -import org.eclipse.pde.internal.build.IXMLConstants; -import org.eclipse.pde.internal.core.P2Utils; -import org.eclipse.pde.internal.core.PDECore; -import org.eclipse.pde.internal.core.ifeature.IFeature; -import org.eclipse.pde.internal.core.ifeature.IFeatureModel; -import org.eclipse.pde.internal.core.isite.*; -import org.eclipse.pde.internal.core.site.WorkspaceSiteModel; -import org.eclipse.pde.internal.core.util.PatternConstructor; -import org.osgi.framework.Version; - -/** - * Performs a site build operation that will build any features needed by the site and generate - * p2 metadata for those features. - * - * @see FeatureBasedExportOperation - * @see FeatureExportOperation - */ -public class SiteBuildOperation extends FeatureBasedExportOperation { - - private long fBuildTime; - - private IFeatureModel[] fFeatureModels; - private ISiteModel fSiteModel; - private IContainer fSiteContainer; - - public SiteBuildOperation(IFeatureModel[] features, ISiteModel site, String jobName) { - super(getInfo(features, site), jobName); - fFeatureModels = features; - fSiteModel = site; - fSiteContainer = site.getUnderlyingResource().getParent(); - setRule(MultiRule.combine(fSiteContainer.getProject(), getRule())); - } - - private static FeatureExportInfo getInfo(IFeatureModel[] models, ISiteModel siteModel) { - FeatureExportInfo info = new FeatureExportInfo(); - info.useJarFormat = true; - info.toDirectory = true; - info.allowBinaryCycles = true; - info.destinationDirectory = siteModel.getUnderlyingResource().getParent().getLocation().toOSString(); - info.items = models; - return info; - } - - protected IStatus run(IProgressMonitor monitor) { - fBuildTime = System.currentTimeMillis(); - IStatus status = super.run(monitor); - try { - fSiteContainer.refreshLocal(IResource.DEPTH_INFINITE, monitor); - updateSiteFeatureVersions(); - } catch (CoreException ce) { - return ce.getStatus(); - } - return status; - } - - private void updateSiteFeatureVersions() throws CoreException { - for (int i = 0; i < fFeatureModels.length; i++) { - IFeature feature = fFeatureModels[i].getFeature(); - Version pvi = Version.parseVersion(feature.getVersion()); - - if ("qualifier".equals(pvi.getQualifier())) { //$NON-NLS-1$ - String newVersion = findBuiltVersion(feature.getId(), pvi.getMajor(), pvi.getMinor(), pvi.getMicro()); - if (newVersion == null) { - continue; - } - ISiteFeature reVersionCandidate = findSiteFeature(feature, pvi); - if (reVersionCandidate != null) { - reVersionCandidate.setVersion(newVersion); - reVersionCandidate.setURL("features/" + feature.getId() + "_" //$NON-NLS-1$ //$NON-NLS-2$ - + newVersion + ".jar"); //$NON-NLS-1$ - } - } - } - ((WorkspaceSiteModel) fSiteModel).save(); - } - - private ISiteFeature findSiteFeature(IFeature feature, Version pvi) { - ISiteFeature reversionCandidate = null; - // first see if version with qualifier being qualifier is present among - // site features - ISiteFeature[] siteFeatures = fSiteModel.getSite().getFeatures(); - for (int s = 0; s < siteFeatures.length; s++) { - if (siteFeatures[s].getId().equals(feature.getId()) && siteFeatures[s].getVersion().equals(feature.getVersion())) { - return siteFeatures[s]; - } - } - String highestQualifier = null; - // then find feature with the highest qualifier - for (int s = 0; s < siteFeatures.length; s++) { - if (siteFeatures[s].getId().equals(feature.getId())) { - Version candidatePvi = Version.parseVersion(siteFeatures[s].getVersion()); - if (pvi.getMajor() == candidatePvi.getMajor() && pvi.getMinor() == candidatePvi.getMinor() && pvi.getMicro() == candidatePvi.getMicro()) { - if (reversionCandidate == null || candidatePvi.getQualifier().compareTo(highestQualifier) > 0) { - reversionCandidate = siteFeatures[s]; - highestQualifier = candidatePvi.getQualifier(); - } - } - } - } - return reversionCandidate; - } - - /** - * Finds the highest version from feature jars. ID and version components - * are constant. Qualifier varies - * - * @param builtJars - * candidate jars in format id_version.jar - * @param id - * @param major - * @param minor - * @param service - */ - private String findBuiltVersion(String id, int major, int minor, int service) { - IFolder featuresFolder = fSiteContainer.getFolder(new Path("features")); //$NON-NLS-1$ - if (!featuresFolder.exists()) { - return null; - } - IResource[] featureJars = null; - try { - featureJars = featuresFolder.members(); - } catch (CoreException ce) { - return null; - } - Pattern pattern = PatternConstructor.createPattern(id + "_" //$NON-NLS-1$ - + major + "." //$NON-NLS-1$ - + minor + "." //$NON-NLS-1$ - + service + "*.jar", true); //$NON-NLS-1$ - // finding the newest feature archive - String newestName = null; - long newestTime = 0; - for (int i = 0; i < featureJars.length; i++) { - File file = new File(featureJars[i].getLocation().toOSString()); - long jarTime = file.lastModified(); - String jarName = featureJars[i].getName(); - - if (jarTime < fBuildTime) { - continue; - } - if (jarTime <= newestTime) { - continue; - } - if (pattern.matcher(jarName).matches()) { - newestName = featureJars[i].getName(); - newestTime = jarTime; - } - } - if (newestName == null) { - return null; - } - - return newestName.substring(id.length() + 1, newestName.length() - 4); - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.exports.FeatureBasedExportOperation#createPostProcessingFiles() - */ - protected void createPostProcessingFiles() { - createPostProcessingFile(new File(fFeatureLocation, FEATURE_POST_PROCESSING)); - createPostProcessingFile(new File(fFeatureLocation, PLUGIN_POST_PROCESSING)); - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.exports.FeatureExportOperation#setP2MetaDataProperties(java.util.Map) - */ - protected void setP2MetaDataProperties(Map map) { - if (fInfo.toDirectory) { - map.put(IXMLConstants.TARGET_P2_METADATA, IBuildPropertiesConstants.TRUE); - map.put(IBuildPropertiesConstants.PROPERTY_P2_FLAVOR, P2Utils.P2_FLAVOR_DEFAULT); - map.put(IBuildPropertiesConstants.PROPERTY_P2_PUBLISH_ARTIFACTS, IBuildPropertiesConstants.FALSE); - map.put(IBuildPropertiesConstants.PROPERTY_P2_FINAL_MODE_OVERRIDE, IBuildPropertiesConstants.TRUE); - map.put(IBuildPropertiesConstants.PROPERTY_P2_COMPRESS, IBuildPropertiesConstants.TRUE); - IResource siteXML = fSiteModel.getUnderlyingResource(); - if (siteXML.exists() && siteXML.getLocationURI() != null) { - map.put(IBuildPropertiesConstants.PROPERTY_P2_CATEGORY_SITE, URIUtil.toUnencodedString(siteXML.getLocationURI())); - } - ISiteDescription description = fSiteModel.getSite().getDescription(); - if (description != null && description.getName() != null && description.getName().length() > 0) { - map.put(IBuildPropertiesConstants.PROPERTY_P2_METADATA_REPO_NAME, description.getName()); - map.put(IBuildPropertiesConstants.PROPERTY_P2_ARTIFACT_REPO_NAME, description.getName()); - } - try { - map.put(IBuildPropertiesConstants.PROPERTY_P2_METADATA_REPO, new File(fInfo.destinationDirectory).toURL().toString()); - map.put(IBuildPropertiesConstants.PROPERTY_P2_ARTIFACT_REPO, new File(fInfo.destinationDirectory).toURL().toString()); - } catch (MalformedURLException e) { - PDECore.log(e); - } - } - } - -} +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.internal.core.exports; + +import java.io.File; +import java.net.MalformedURLException; +import java.util.Map; +import java.util.regex.Pattern; +import org.eclipse.core.resources.*; +import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.jobs.MultiRule; +import org.eclipse.pde.internal.build.IBuildPropertiesConstants; +import org.eclipse.pde.internal.build.IXMLConstants; +import org.eclipse.pde.internal.core.P2Utils; +import org.eclipse.pde.internal.core.PDECore; +import org.eclipse.pde.internal.core.ifeature.IFeature; +import org.eclipse.pde.internal.core.ifeature.IFeatureModel; +import org.eclipse.pde.internal.core.isite.*; +import org.eclipse.pde.internal.core.site.WorkspaceSiteModel; +import org.eclipse.pde.internal.core.util.PatternConstructor; +import org.osgi.framework.Version; + +/** + * Performs a site build operation that will build any features needed by the site and generate + * p2 metadata for those features. + * + * @see FeatureBasedExportOperation + * @see FeatureExportOperation + */ +public class SiteBuildOperation extends FeatureBasedExportOperation { + + private long fBuildTime; + + private IFeatureModel[] fFeatureModels; + private ISiteModel fSiteModel; + private IContainer fSiteContainer; + + public SiteBuildOperation(IFeatureModel[] features, ISiteModel site, String jobName) { + super(getInfo(features, site), jobName); + fFeatureModels = features; + fSiteModel = site; + fSiteContainer = site.getUnderlyingResource().getParent(); + setRule(MultiRule.combine(fSiteContainer.getProject(), getRule())); + } + + private static FeatureExportInfo getInfo(IFeatureModel[] models, ISiteModel siteModel) { + FeatureExportInfo info = new FeatureExportInfo(); + info.useJarFormat = true; + info.toDirectory = true; + info.allowBinaryCycles = true; + info.destinationDirectory = siteModel.getUnderlyingResource().getParent().getLocation().toOSString(); + info.items = models; + return info; + } + + protected IStatus run(IProgressMonitor monitor) { + fBuildTime = System.currentTimeMillis(); + IStatus status = super.run(monitor); + try { + fSiteContainer.refreshLocal(IResource.DEPTH_INFINITE, monitor); + updateSiteFeatureVersions(); + } catch (CoreException ce) { + return ce.getStatus(); + } + return status; + } + + private void updateSiteFeatureVersions() throws CoreException { + for (int i = 0; i < fFeatureModels.length; i++) { + IFeature feature = fFeatureModels[i].getFeature(); + Version pvi = Version.parseVersion(feature.getVersion()); + + if ("qualifier".equals(pvi.getQualifier())) { //$NON-NLS-1$ + String newVersion = findBuiltVersion(feature.getId(), pvi.getMajor(), pvi.getMinor(), pvi.getMicro()); + if (newVersion == null) { + continue; + } + ISiteFeature reVersionCandidate = findSiteFeature(feature, pvi); + if (reVersionCandidate != null) { + reVersionCandidate.setVersion(newVersion); + reVersionCandidate.setURL("features/" + feature.getId() + "_" //$NON-NLS-1$ //$NON-NLS-2$ + + newVersion + ".jar"); //$NON-NLS-1$ + } + } + } + ((WorkspaceSiteModel) fSiteModel).save(); + } + + private ISiteFeature findSiteFeature(IFeature feature, Version pvi) { + ISiteFeature reversionCandidate = null; + // first see if version with qualifier being qualifier is present among + // site features + ISiteFeature[] siteFeatures = fSiteModel.getSite().getFeatures(); + for (int s = 0; s < siteFeatures.length; s++) { + if (siteFeatures[s].getId().equals(feature.getId()) && siteFeatures[s].getVersion().equals(feature.getVersion())) { + return siteFeatures[s]; + } + } + String highestQualifier = null; + // then find feature with the highest qualifier + for (int s = 0; s < siteFeatures.length; s++) { + if (siteFeatures[s].getId().equals(feature.getId())) { + Version candidatePvi = Version.parseVersion(siteFeatures[s].getVersion()); + if (pvi.getMajor() == candidatePvi.getMajor() && pvi.getMinor() == candidatePvi.getMinor() && pvi.getMicro() == candidatePvi.getMicro()) { + if (reversionCandidate == null || candidatePvi.getQualifier().compareTo(highestQualifier) > 0) { + reversionCandidate = siteFeatures[s]; + highestQualifier = candidatePvi.getQualifier(); + } + } + } + } + return reversionCandidate; + } + + /** + * Finds the highest version from feature jars. ID and version components + * are constant. Qualifier varies + * + * @param builtJars + * candidate jars in format id_version.jar + * @param id + * @param major + * @param minor + * @param service + */ + private String findBuiltVersion(String id, int major, int minor, int service) { + IFolder featuresFolder = fSiteContainer.getFolder(new Path("features")); //$NON-NLS-1$ + if (!featuresFolder.exists()) { + return null; + } + IResource[] featureJars = null; + try { + featureJars = featuresFolder.members(); + } catch (CoreException ce) { + return null; + } + Pattern pattern = PatternConstructor.createPattern(id + "_" //$NON-NLS-1$ + + major + "." //$NON-NLS-1$ + + minor + "." //$NON-NLS-1$ + + service + "*.jar", true); //$NON-NLS-1$ + // finding the newest feature archive + String newestName = null; + long newestTime = 0; + for (int i = 0; i < featureJars.length; i++) { + File file = new File(featureJars[i].getLocation().toOSString()); + long jarTime = file.lastModified(); + String jarName = featureJars[i].getName(); + + if (jarTime < fBuildTime) { + continue; + } + if (jarTime <= newestTime) { + continue; + } + if (pattern.matcher(jarName).matches()) { + newestName = featureJars[i].getName(); + newestTime = jarTime; + } + } + if (newestName == null) { + return null; + } + + return newestName.substring(id.length() + 1, newestName.length() - 4); + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.exports.FeatureBasedExportOperation#createPostProcessingFiles() + */ + protected void createPostProcessingFiles() { + createPostProcessingFile(new File(fFeatureLocation, FEATURE_POST_PROCESSING)); + createPostProcessingFile(new File(fFeatureLocation, PLUGIN_POST_PROCESSING)); + } + + protected boolean publishingP2Metadata() { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.exports.FeatureExportOperation#setP2MetaDataProperties(java.util.Map) + */ + protected void setP2MetaDataProperties(Map map) { + if (fInfo.toDirectory) { + map.put(IXMLConstants.TARGET_P2_METADATA, IBuildPropertiesConstants.TRUE); + map.put(IBuildPropertiesConstants.PROPERTY_P2_FLAVOR, P2Utils.P2_FLAVOR_DEFAULT); + map.put(IBuildPropertiesConstants.PROPERTY_P2_PUBLISH_ARTIFACTS, IBuildPropertiesConstants.FALSE); + map.put(IBuildPropertiesConstants.PROPERTY_P2_FINAL_MODE_OVERRIDE, IBuildPropertiesConstants.TRUE); + map.put(IBuildPropertiesConstants.PROPERTY_P2_COMPRESS, IBuildPropertiesConstants.TRUE); + IResource siteXML = fSiteModel.getUnderlyingResource(); + if (siteXML.exists() && siteXML.getLocationURI() != null) { + map.put(IBuildPropertiesConstants.PROPERTY_P2_CATEGORY_SITE, URIUtil.toUnencodedString(siteXML.getLocationURI())); + } + ISiteDescription description = fSiteModel.getSite().getDescription(); + if (description != null && description.getName() != null && description.getName().length() > 0) { + map.put(IBuildPropertiesConstants.PROPERTY_P2_METADATA_REPO_NAME, description.getName()); + map.put(IBuildPropertiesConstants.PROPERTY_P2_ARTIFACT_REPO_NAME, description.getName()); + } + try { + String destination = new File(fBuildTempMetadataLocation).toURL().toString(); + map.put(IBuildPropertiesConstants.PROPERTY_P2_BUILD_REPO, destination); + } catch (MalformedURLException e) { + PDECore.log(e); + } + } + } + +} Index: src/org/eclipse/pde/internal/core/exports/FeatureExportOperation.java =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/exports/FeatureExportOperation.java,v retrieving revision 1.27 diff -u -r1.27 FeatureExportOperation.java --- src/org/eclipse/pde/internal/core/exports/FeatureExportOperation.java 24 Feb 2009 22:51:05 -0000 1.27 +++ src/org/eclipse/pde/internal/core/exports/FeatureExportOperation.java 6 Mar 2009 18:58:40 -0000 @@ -246,7 +246,7 @@ fHasErrors = false; try { - monitor.beginTask("", 10); //$NON-NLS-1$ + monitor.beginTask("", 10 + (publishingP2Metadata() ? 2 : 0)); //$NON-NLS-1$ monitor.setTaskName(PDECoreMessages.FeatureExportJob_taskName); HashMap properties = createAntBuildProperties(os, ws, arch); BuildScriptGenerator generator = new BuildScriptGenerator(); @@ -260,6 +260,11 @@ if (fInfo.exportSource && !fInfo.exportSourceBundle) runScript(getBuildScriptName(featureLocation), new String[] {"build.sources"}, properties, new SubProgressMonitor(monitor, 1)); //$NON-NLS-1$ + if (publishingP2Metadata()) { + monitor.setTaskName(PDECoreMessages.FeatureExportOperation_publishingMetadata); + runScript(getAssembleP2ScriptName(featureID, featureLocation), new String[] {"main"}, properties, new SubProgressMonitor(monitor, 2)); //$NON-NLS-1$ + } + monitor.setTaskName(PDECoreMessages.FeatureExportOperation_runningAssemblyScript); runScript(getAssemblyScriptName(featureID, os, ws, arch, featureLocation), new String[] {"main"}, //$NON-NLS-1$ properties, new SubProgressMonitor(monitor, 2)); @@ -336,6 +341,10 @@ + ".xml"; //$NON-NLS-1$ } + protected String getAssembleP2ScriptName(String featureID, String featureLocation) { + return featureLocation + IPath.SEPARATOR + "assemble." + featureID + ".p2.xml"; //$NON-NLS-1$ //$NON-NLS-2$ + } + /** * Execute the script at the given location. * @@ -474,6 +483,14 @@ } /** + * Whether or not to use new metadata publishing or old generation + */ + protected boolean publishingP2Metadata() { + //for now we can only support when exporting a single platform + return fInfo.useJarFormat && fInfo.exportMetadata && (fInfo.targets == null || fInfo.targets.length == 1); + } + + /** * Adds the necessary properties to invoke the p2 metadata generator. This method will * be called when creating the ant build properties map. * @@ -486,15 +503,21 @@ map.put(IBuildPropertiesConstants.PROPERTY_P2_PUBLISH_ARTIFACTS, IBuildPropertiesConstants.FALSE); map.put(IBuildPropertiesConstants.PROPERTY_P2_FINAL_MODE_OVERRIDE, IBuildPropertiesConstants.TRUE); map.put(IBuildPropertiesConstants.PROPERTY_P2_COMPRESS, IBuildPropertiesConstants.TRUE); + map.put(IBuildPropertiesConstants.PROPERTY_P2_GATHERING, Boolean.toString(publishingP2Metadata())); try { String destination = ""; //$NON-NLS-1$ - if (fInfo.toDirectory) { - destination = new File(fInfo.destinationDirectory).toURL().toString(); - } else { + if (publishingP2Metadata()) { destination = new File(fBuildTempMetadataLocation).toURL().toString(); + map.put(IBuildPropertiesConstants.PROPERTY_P2_BUILD_REPO, destination); + } else { + if (fInfo.toDirectory) { + destination = new File(fInfo.destinationDirectory).toURL().toString(); + } else { + destination = new File(fBuildTempMetadataLocation).toURL().toString(); + } + map.put(IBuildPropertiesConstants.PROPERTY_P2_METADATA_REPO, destination); + map.put(IBuildPropertiesConstants.PROPERTY_P2_ARTIFACT_REPO, destination); } - map.put(IBuildPropertiesConstants.PROPERTY_P2_METADATA_REPO, destination); - map.put(IBuildPropertiesConstants.PROPERTY_P2_ARTIFACT_REPO, destination); map.put(IBuildPropertiesConstants.PROPERTY_P2_METADATA_REPO_NAME, PDECoreMessages.FeatureExportOperation_0); map.put(IBuildPropertiesConstants.PROPERTY_P2_ARTIFACT_REPO_NAME, PDECoreMessages.FeatureExportOperation_0); } catch (MalformedURLException e) { @@ -530,6 +553,26 @@ if (!file.mkdirs()) throw new InvocationTargetException(new Exception(PDECoreMessages.ExportWizard_badDirectory)); } + + File metadataTemp = new File(fBuildTempMetadataLocation); + if (file.exists()) { + //make sure our build metadata repo is clean + deleteDir(metadataTemp); + } + } + + private void deleteDir(File dir) { + if (dir.exists()) { + if (dir.isDirectory()) { + File[] children = dir.listFiles(); + if (children != null) { + for (int i = 0; i < children.length; i++) { + deleteDir(children[i]); + } + } + } + dir.delete(); + } } protected void doExport(IFeatureModel model, String[] config, IProgressMonitor monitor) throws CoreException, InvocationTargetException { @@ -579,6 +622,7 @@ // allow for binary cycles Properties properties = new Properties(); properties.put(IBuildPropertiesConstants.PROPERTY_ALLOW_BINARY_CYCLES, Boolean.toString(fInfo.allowBinaryCycles)); + properties.put(IBuildPropertiesConstants.PROPERTY_P2_GATHERING, Boolean.toString(publishingP2Metadata())); generator.setImmutableAntProperties(properties); // allow for custom execution environments