| /******************************************************************************* |
| * Copyright (c) 2007, 2010 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.build.internal.tests; |
| |
| import java.io.*; |
| import java.net.URI; |
| import java.net.URL; |
| import java.util.*; |
| import java.util.jar.*; |
| import org.apache.tools.ant.filters.ReplaceTokens; |
| import org.apache.tools.ant.util.ReaderInputStream; |
| import org.apache.tools.zip.ZipEntry; |
| import org.apache.tools.zip.ZipFile; |
| import org.eclipse.core.resources.*; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.equinox.frameworkadmin.BundleInfo; |
| import org.eclipse.equinox.simpleconfigurator.manipulator.SimpleConfiguratorManipulator; |
| import org.eclipse.pde.build.tests.Activator; |
| import org.eclipse.pde.internal.build.BundleHelper; |
| import org.eclipse.pde.internal.build.FeatureGenerator; |
| import org.eclipse.pde.internal.build.site.BuildTimeSiteFactory; |
| |
| public class Utils { |
| private static final String ID = "id"; |
| private static final String VERSION = "version"; |
| |
| /** |
| * Transfer the contents of resource into the destination IFile. During the transfer, replace all |
| * instances of "@replaceTag@" with "replaceString" |
| * |
| * @param resource - input URL |
| * @param destination - IFile destination |
| * @param replacements - map of tokens and values to replaces, file should contain "@replaceTag@" |
| * @throws IOException |
| * @throws CoreException |
| */ |
| static public void transferAndReplace(URL resource, IFile destination, Map replacements) throws IOException, CoreException { |
| Reader reader = new InputStreamReader(new BufferedInputStream(resource.openStream())); |
| final ReplaceTokens replaces = new ReplaceTokens(reader); |
| |
| for (Iterator iterator = replacements.keySet().iterator(); iterator.hasNext();) { |
| String replaceTag = (String) iterator.next(); |
| String replaceString = (String) replacements.get(replaceTag); |
| ReplaceTokens.Token token = new ReplaceTokens.Token(); |
| token.setKey(replaceTag); |
| token.setValue(replaceString); |
| replaces.addConfiguredToken(token); |
| } |
| |
| ReaderInputStream inputStream = new ReaderInputStream(replaces); |
| destination.create(inputStream, true, null); |
| inputStream.close(); |
| } |
| |
| static public String[] getVersionsNoQualifier(String[] bundles) { |
| String[] results = new String[bundles.length]; |
| for (int i = 0; i < bundles.length; i++) { |
| org.osgi.framework.Version version = Platform.getBundle(bundles[i]).getVersion(); |
| results[i] = String.valueOf(version.getMajor()) + "." + version.getMinor() + '.' + version.getMicro(); |
| } |
| return results; |
| } |
| |
| static public void generateAllElements(IFolder buildFolder, String element) throws CoreException, IOException { |
| if (element != null) { |
| // get the productBuild/allElements.xml and replace @ELEMENT@ with element |
| URL allElements = FileLocator.find(Platform.getBundle(Activator.PLUGIN_ID), new Path("/resources/allElements.xml"), null); |
| Map replacements = new HashMap(1); |
| replacements.put("ELEMENT", element); |
| transferAndReplace(allElements, buildFolder.getFile("allElements.xml"), replacements); |
| buildFolder.refreshLocal(IResource.DEPTH_INFINITE, null); |
| } |
| } |
| |
| static public void generatePluginBuildProperties(IFolder folder, Properties properties) throws FileNotFoundException, IOException { |
| Properties buildProperties = properties != null ? properties : new Properties(); |
| |
| //default contents: |
| if (!buildProperties.containsKey("source..")) |
| buildProperties.put("source..", "src/"); |
| if (!buildProperties.containsKey("output..")) |
| buildProperties.put("output..", "bin/"); |
| if (!buildProperties.containsKey("bin.includes")) |
| buildProperties.put("bin.includes", "META-INF/, ."); |
| |
| storeBuildProperties(folder, buildProperties); |
| } |
| |
| static public void generateBundleManifest(IFolder folder, String bundleId, String bundleVersion, Attributes additionalAttributes) throws CoreException, IOException { |
| Manifest manifest = new Manifest(); |
| Attributes mainAttributes = manifest.getMainAttributes(); |
| mainAttributes.put(Attributes.Name.MANIFEST_VERSION, "1.0"); |
| mainAttributes.put(new Attributes.Name("Bundle-ManifestVersion"), "2"); |
| mainAttributes.put(new Attributes.Name("Bundle-Name"), "Test Bundle " + bundleId); |
| mainAttributes.put(new Attributes.Name("Bundle-SymbolicName"), bundleId); |
| mainAttributes.put(new Attributes.Name("Bundle-Version"), bundleVersion); |
| if (additionalAttributes != null) |
| mainAttributes.putAll(additionalAttributes); |
| |
| IFile manifestFile = folder.getFile(JarFile.MANIFEST_NAME); |
| IFolder metaInf = (IFolder) manifestFile.getParent(); |
| if (!metaInf.exists()) |
| metaInf.create(true, true, null); |
| OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(manifestFile.getLocation().toFile())); |
| manifest.write(outputStream); |
| outputStream.close(); |
| } |
| |
| static public void generateBundle(IFolder folder, String bundleId) throws CoreException, IOException { |
| generateBundleManifest(folder, bundleId, "1.0.0", null); |
| generatePluginBuildProperties(folder, null); |
| writeBuffer(folder.getFile("src/foo.java"), new StringBuffer("public class foo { int i; }")); |
| folder.refreshLocal(IResource.DEPTH_INFINITE, null); |
| } |
| |
| static public void generateBundle(IFolder folder, String bundleId, String version) throws CoreException, IOException { |
| generateBundleManifest(folder, bundleId, version, null); |
| generatePluginBuildProperties(folder, null); |
| writeBuffer(folder.getFile("src/foo.java"), new StringBuffer("public class foo { int i; }")); |
| folder.refreshLocal(IResource.DEPTH_INFINITE, null); |
| } |
| |
| static public void storeBuildProperties(IFolder buildFolder, Properties buildProperties) throws FileNotFoundException, IOException { |
| storeProperties(buildFolder.getFile("build.properties"), buildProperties); |
| } |
| |
| static public void storeProperties(IFile propertiesFile, Properties buildProperties) throws FileNotFoundException, IOException { |
| File buildPropertiesFile = propertiesFile.getLocation().toFile(); |
| OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(buildPropertiesFile)); |
| buildProperties.store(outputStream, ""); |
| outputStream.close(); |
| } |
| |
| static public void generateFeature(IFolder workingDirectory, String id, String[] featureList, String[] pluginList) throws CoreException, IOException { |
| generateFeature(workingDirectory, id, featureList, pluginList, null, false, false, null); |
| } |
| |
| static public void generateFeature(IFolder workingDirectory, String id, String[] featureList, String[] pluginList, String version) throws CoreException, IOException { |
| generateFeature(workingDirectory, id, featureList, pluginList, null, false, false, version); |
| } |
| |
| static public void generateFeature(IFolder workingDirectory, String id, String[] featureList, String[] pluginList, String product, boolean includeLaunchers, boolean verify, String version) throws CoreException, IOException { |
| FeatureGenerator generator = new FeatureGenerator(); |
| if (verify) { |
| FeatureGenerator.setConfigInfo("*,*,*"); |
| String baseLocation = Platform.getInstallLocation().getURL().getPath(); |
| BuildTimeSiteFactory.setInstalledBaseSite(baseLocation); |
| File delta = findDeltaPack(); |
| if (delta != null && !delta.equals(new File(baseLocation))) |
| generator.setPluginPath(new String[] {delta.getAbsolutePath()}); |
| } |
| generator.setIncludeLaunchers(includeLaunchers); |
| generator.setVerify(verify); |
| generator.setFeatureId(id); |
| generator.setVersion(version); |
| generator.setProductFile(product); |
| generator.setFeatureList(featureList); |
| generator.setPluginList(pluginList); |
| generator.setWorkingDirectory(workingDirectory.getLocation().toOSString()); |
| generator.generate(); |
| } |
| |
| static public void generateProduct(IFile productFile, String id, String version, String[] entryList, boolean features) throws CoreException, IOException { |
| generateProduct(productFile, id, version, null, entryList, features, null); |
| } |
| |
| static public void generateProduct(IFile productFile, String id, String version, String application, String[] entryList, boolean features) throws CoreException, IOException { |
| generateProduct(productFile, id, version, application, entryList, features, null); |
| } |
| |
| static public void generateProduct(IFile productFile, String id, String version, String application, String[] entryList, boolean features, StringBuffer extra) throws CoreException, IOException { |
| generateProduct(productFile, null, id, version, application, null, entryList, features, extra); |
| } |
| |
| static public void generateProduct(IFile productFile, String id, String version, String application, String launcher, String[] entryList, boolean features, StringBuffer extra) throws CoreException, IOException { |
| generateProduct(productFile, null, id, version, application, launcher, entryList, features, extra); |
| } |
| |
| static public void generateProduct(IFile productFile, String uid, String id, String version, String application, String launcher, String[] entryList, boolean features, StringBuffer extra) throws CoreException, IOException { |
| StringBuffer buffer = new StringBuffer(); |
| buffer.append("<product "); |
| if (uid != null) { |
| buffer.append(" uid=\""); |
| buffer.append(uid); |
| buffer.append("\""); |
| } |
| if (id != null) { |
| buffer.append(" name=\""); |
| buffer.append(id); |
| buffer.append("\" id=\""); |
| buffer.append(id); |
| buffer.append("\""); |
| } |
| if (version != null) { |
| buffer.append(" version=\""); |
| buffer.append(version); |
| buffer.append("\""); |
| } |
| if (application != null) { |
| buffer.append(" application=\""); |
| buffer.append(application); |
| buffer.append("\""); |
| } |
| buffer.append(" useFeatures=\""); |
| buffer.append(new Boolean(features).toString()); |
| buffer.append("\">\n"); |
| buffer.append(" <configIni use=\"default\"/>\n"); |
| buffer.append(" <launcher name=\"" + (launcher != null ? launcher : "eclipse") + "\"/>\n"); |
| if (features) { |
| buffer.append(" <features>\n"); |
| for (int i = 0; i < entryList.length; i++) { |
| Map items = org.eclipse.pde.internal.build.Utils.parseExtraBundlesString(entryList[i], false); |
| buffer.append(" <feature id=\""); |
| buffer.append(items.get(ID)); |
| buffer.append("\""); |
| if (items.containsKey(VERSION)) { |
| buffer.append(" version=\""); |
| buffer.append(items.get(VERSION)); |
| buffer.append("\""); |
| } |
| buffer.append("/>\n"); |
| } |
| buffer.append(" </features>\n"); |
| } else { |
| buffer.append(" <plugins>\n"); |
| for (int i = 0; i < entryList.length; i++) { |
| Map items = org.eclipse.pde.internal.build.Utils.parseExtraBundlesString(entryList[i], false); |
| buffer.append(" <plugin id=\""); |
| buffer.append(items.get(ID)); |
| buffer.append("\""); |
| if (items.containsKey(VERSION)) { |
| buffer.append(" version=\""); |
| buffer.append(items.get(VERSION)); |
| buffer.append("\""); |
| } |
| buffer.append("/>\n"); |
| } |
| buffer.append(" </plugins>\n"); |
| } |
| |
| if (extra != null) |
| buffer.append(extra); |
| |
| buffer.append("</product>\n"); |
| |
| Utils.writeBuffer(productFile, buffer); |
| productFile.refreshLocal(IResource.DEPTH_INFINITE, null); |
| } |
| |
| /** |
| * Creates a IFolder resources. Will create any folders necessary under parent |
| */ |
| static public IFolder createFolder(IFolder parent, String path) throws CoreException { |
| parent.refreshLocal(IResource.DEPTH_INFINITE, null); |
| IFolder folder = parent.getFolder(path); |
| if (folder.exists()) |
| return folder; |
| IFolder container = (IFolder) folder.getParent(); |
| if (!container.exists()) { |
| LinkedList stack = new LinkedList(); |
| while (!container.equals(parent) && !container.exists()) { |
| stack.add(0, container); |
| container = (IFolder) container.getParent(); |
| } |
| |
| for (Iterator iterator = stack.iterator(); iterator.hasNext();) { |
| container = (IFolder) iterator.next(); |
| container.create(true, true, null); |
| } |
| } |
| folder.create(true, true, null); |
| return folder; |
| } |
| |
| private static File findExecutable(File baseLocation) { |
| File plugins = new File(baseLocation, "features"); |
| FilenameFilter filter = new FilenameFilter() { |
| public boolean accept(File dir, String name) { |
| return name.startsWith("org.eclipse.equinox.executable"); |
| } |
| }; |
| String[] files = plugins.list(filter); |
| |
| if (files != null && files.length > 0) |
| return baseLocation; |
| return null; |
| } |
| |
| static private File deltaLocation = null; |
| |
| public static File findDeltaPack() throws IOException { |
| if (deltaLocation != null) |
| return deltaLocation; |
| |
| File baseLocation = new File(Platform.getInstallLocation().getURL().getPath()); |
| |
| deltaLocation = findExecutable(baseLocation); |
| if (deltaLocation != null) |
| return deltaLocation; |
| |
| SimpleConfiguratorManipulator manipulator = (SimpleConfiguratorManipulator) BundleHelper.getDefault().acquireService(SimpleConfiguratorManipulator.class.getName()); |
| if (manipulator != null) { |
| BundleInfo[] bundles = manipulator.loadConfiguration(BundleHelper.getDefault().getBundle().getBundleContext(), null); |
| //find a fragment for a platform we aren't |
| String id = "org.eclipse.equinox.launcher.win32.win32.x86" + (Platform.getOSArch().equals("x86") ? "_64" : ""); |
| for (int i = 0; i < bundles.length; i++) { |
| if (bundles[i].getSymbolicName().equals(id)) { |
| URI location = bundles[i].getLocation(); |
| deltaLocation = findExecutable(URIUtil.toFile(URIUtil.append(location, "../.."))); |
| if (deltaLocation != null) |
| return deltaLocation; |
| break; |
| } |
| } |
| } |
| |
| if (Platform.OS_MACOSX.equals(Platform.getOS())) { |
| // After https://bugs.eclipse.org/431116 and related changes, the install location on the Mac |
| // moved down two directories (from <folder-containing-Eclipse.app> to Eclipse.app/Contents/Eclipse). |
| baseLocation = baseLocation.getParentFile().getParentFile(); |
| } |
| deltaLocation = findExecutable(new File(baseLocation.getParent(), "deltapack/eclipse")); |
| return deltaLocation; |
| } |
| |
| public static void writeBuffer(IFile outputFile, StringBuffer buffer) throws IOException, CoreException { |
| FileOutputStream stream = null; |
| try { |
| File output = outputFile.getLocation().toFile(); |
| output.getParentFile().mkdirs(); |
| stream = new FileOutputStream(output); |
| stream.write(buffer.toString().getBytes()); |
| } finally { |
| if (stream != null) |
| stream.close(); |
| } |
| outputFile.getParent().refreshLocal(IResource.DEPTH_INFINITE, null); |
| } |
| |
| public static void transferStreams(InputStream source, OutputStream destination) throws IOException { |
| transferStreams(source, true, destination, true); |
| } |
| |
| public static void transferStreams(InputStream source, boolean closeIn, OutputStream destination, boolean closeOut) throws IOException { |
| source = new BufferedInputStream(source); |
| destination = new BufferedOutputStream(destination); |
| try { |
| byte[] buffer = new byte[8192]; |
| while (true) { |
| int bytesRead = -1; |
| if ((bytesRead = source.read(buffer)) == -1) |
| break; |
| destination.write(buffer, 0, bytesRead); |
| } |
| } finally { |
| try { |
| if (closeIn) |
| source.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| try { |
| destination.flush(); |
| if (closeOut) |
| destination.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| } |
| } |
| |
| public static boolean extractFromZip(IFolder buildFolder, String zipFile, String zipEntry, IFile outputFile) throws CoreException { |
| File folder = new File(buildFolder.getLocation().toOSString()); |
| File archiveFile = new File(folder, zipFile); |
| if (!archiveFile.exists()) |
| return false; |
| |
| ZipFile zip = null; |
| try { |
| zip = new ZipFile(archiveFile); |
| ZipEntry entry = zip.getEntry(zipEntry); |
| if (entry == null) |
| return false; |
| InputStream stream = new BufferedInputStream(zip.getInputStream(entry)); |
| OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFile.getLocation().toFile())); |
| transferStreams(stream, out); |
| } catch (Exception e) { |
| return false; |
| } finally { |
| try { |
| if (zip != null) |
| zip.close(); |
| } catch (IOException e) { |
| return false; |
| } |
| } |
| outputFile.refreshLocal(IResource.DEPTH_ONE, null); |
| return true; |
| } |
| |
| public static Properties loadProperties(IFile propertiesFile) throws CoreException { |
| propertiesFile.refreshLocal(IResource.DEPTH_INFINITE, null); |
| if (!propertiesFile.exists()) |
| return null; |
| |
| InputStream stream = null; |
| try { |
| Properties props = new Properties(); |
| stream = propertiesFile.getContents(true); |
| props.load(stream); |
| return props; |
| } catch (IOException e) { |
| return null; |
| } finally { |
| if (stream != null) |
| try { |
| stream.close(); |
| } catch (IOException e) { |
| return null; |
| } |
| } |
| } |
| |
| public static void copy(File source, File target) throws IOException { |
| if (!source.exists()) |
| return; |
| if (source.isDirectory()) { |
| if (target.exists() && target.isFile()) |
| target.delete(); |
| if (!target.exists()) |
| target.mkdirs(); |
| File[] children = source.listFiles(); |
| for (int i = 0; i < children.length; i++) |
| copy(children[i], new File(target, children[i].getName())); |
| return; |
| } |
| InputStream input = null; |
| OutputStream output = null; |
| try { |
| input = new BufferedInputStream(new FileInputStream(source)); |
| output = new BufferedOutputStream(new FileOutputStream(target)); |
| |
| byte[] buffer = new byte[8192]; |
| int bytesRead = 0; |
| while ((bytesRead = input.read(buffer)) != -1) |
| output.write(buffer, 0, bytesRead); |
| } finally { |
| if (input != null) { |
| try { |
| input.close(); |
| } catch (IOException e) { |
| //ignore |
| } |
| } |
| if (output != null) { |
| try { |
| output.close(); |
| } catch (IOException e) { |
| //ignore |
| } |
| } |
| } |
| } |
| |
| public static Manifest loadManifest(IFile file) throws IOException { |
| IPath location = file.getLocation(); |
| |
| if (location.getFileExtension().equals(".jar")) { |
| JarFile jar = null; |
| try { |
| jar = new JarFile(location.toFile()); |
| return jar.getManifest(); |
| } finally { |
| org.eclipse.pde.internal.build.Utils.close(jar); |
| } |
| } else if (location.lastSegment().equalsIgnoreCase("MANIFEST.MF")) { |
| InputStream stream = new FileInputStream(location.toFile()); |
| try { |
| return new Manifest(stream); |
| } finally { |
| org.eclipse.pde.internal.build.Utils.close(stream); |
| } |
| } |
| return null; |
| } |
| } |