1 11 package org.eclipse.pde.internal.core.exports; 12 13 import java.io.BufferedReader ; 14 import java.io.File ; 15 import java.io.FileOutputStream ; 16 import java.io.FileReader ; 17 import java.io.FileWriter ; 18 import java.io.IOException ; 19 import java.io.InputStream ; 20 import java.io.PrintWriter ; 21 import java.lang.reflect.InvocationTargetException ; 22 import java.net.URL ; 23 import java.util.Dictionary ; 24 import java.util.HashMap ; 25 import java.util.HashSet ; 26 import java.util.Hashtable ; 27 import java.util.Properties ; 28 import java.util.Set ; 29 import java.util.StringTokenizer ; 30 31 import javax.xml.parsers.DocumentBuilderFactory ; 32 import javax.xml.parsers.FactoryConfigurationError ; 33 import javax.xml.parsers.ParserConfigurationException ; 34 35 import org.eclipse.ant.core.AntRunner; 36 import org.eclipse.core.resources.IResource; 37 import org.eclipse.core.runtime.CoreException; 38 import org.eclipse.core.runtime.IPath; 39 import org.eclipse.core.runtime.IProgressMonitor; 40 import org.eclipse.core.runtime.Path; 41 import org.eclipse.core.runtime.Platform; 42 import org.eclipse.core.runtime.SubProgressMonitor; 43 import org.eclipse.jdt.launching.ExecutionArguments; 44 import org.eclipse.osgi.service.resolver.BundleDescription; 45 import org.eclipse.osgi.service.resolver.HostSpecification; 46 import org.eclipse.osgi.service.resolver.State; 47 import org.eclipse.pde.core.plugin.IPluginModelBase; 48 import org.eclipse.pde.core.plugin.PluginRegistry; 49 import org.eclipse.pde.core.plugin.TargetPlatform; 50 import org.eclipse.pde.internal.build.BuildScriptGenerator; 51 import org.eclipse.pde.internal.build.IBuildPropertiesConstants; 52 import org.eclipse.pde.internal.build.IXMLConstants; 53 import org.eclipse.pde.internal.core.PDECore; 54 import org.eclipse.pde.internal.core.TargetPlatformHelper; 55 import org.eclipse.pde.internal.core.XMLPrintHandler; 56 import org.eclipse.pde.internal.core.iproduct.IArgumentsInfo; 57 import org.eclipse.pde.internal.core.iproduct.IConfigurationFileInfo; 58 import org.eclipse.pde.internal.core.iproduct.IJREInfo; 59 import org.eclipse.pde.internal.core.iproduct.ILauncherInfo; 60 import org.eclipse.pde.internal.core.iproduct.IProduct; 61 import org.eclipse.pde.internal.core.iproduct.ISplashInfo; 62 import org.eclipse.pde.internal.core.util.CoreUtility; 63 import org.osgi.framework.BundleContext; 64 import org.osgi.framework.InvalidSyntaxException; 65 import org.w3c.dom.Document ; 66 import org.w3c.dom.Element ; 67 68 public class ProductExportOperation extends FeatureExportOperation { 69 70 private String fFeatureLocation; 71 private String fRoot; 72 private IProduct fProduct; 73 74 public ProductExportOperation(FeatureExportInfo info, IProduct product, String root) { 75 super(info); 76 fProduct = product; 77 fRoot = root; 78 } 79 80 public void run(IProgressMonitor monitor) throws CoreException { 81 String [][] configurations = fInfo.targets; 82 if (configurations == null) 83 configurations = new String [][] { {TargetPlatform.getOS(), TargetPlatform.getWS(), TargetPlatform.getOSArch(), TargetPlatform.getNL() } }; 84 monitor.beginTask("", 10 * configurations.length); for (int i = 0; i < configurations.length; i++) { 86 try { 87 String [] config = configurations[i]; 88 if (config[0].equals("macosx") && fInfo.targets == null) createMacScript(config, new SubProgressMonitor(monitor, 1)); 90 String featureID = "org.eclipse.pde.container.feature"; fFeatureLocation = fBuildTempLocation + File.separator + featureID; 93 94 createFeature(featureID, fFeatureLocation, config, true); 95 createBuildPropertiesFile(fFeatureLocation, config); 96 createConfigIniFile(config); 97 createEclipseProductFile(); 98 createLauncherIniFile(config[0]); 99 doExport(featureID, 100 null, 101 fFeatureLocation, 102 config[0], 103 config[1], 104 config[2], 105 new SubProgressMonitor(monitor, 8)); 106 } catch (IOException e) { 107 } catch (InvocationTargetException e) { 108 throwCoreException(e); 109 } finally { 110 for (int j = 0; j < fInfo.items.length; j++) { 111 deleteBuildFiles(fInfo.items[j]); 112 } 113 cleanup(fInfo.targets == null ? null : configurations[i], new SubProgressMonitor(monitor, 1)); 114 } 115 } 116 monitor.done(); 117 } 118 119 private File getCustomIniFile() { 120 IConfigurationFileInfo info = fProduct.getConfigurationFileInfo(); 121 if (info != null && info.getUse().equals("custom")) { String path = getExpandedPath(info.getPath()); 123 if (path != null) { 124 File file = new File (path); 125 if (file.exists() && file.isFile()) 126 return file; 127 } 128 } 129 return null; 130 } 131 132 137 protected String [] getPaths() { 138 String [] paths = super.getPaths(); 139 String [] all = new String [paths.length + 1]; 140 all[0] = fFeatureLocation + File.separator + "feature.xml"; System.arraycopy(paths, 0, all, 1, paths.length); 142 return all; 143 } 144 145 private void createBuildPropertiesFile(String featureLocation, String [] config) { 146 File file = new File (featureLocation); 147 if (!file.exists() || !file.isDirectory()) 148 file.mkdirs(); 149 150 boolean hasLaunchers = PDECore.getDefault().getFeatureModelManager().getDeltaPackFeature() != null; 151 Properties properties = new Properties (); 152 properties.put(IBuildPropertiesConstants.ROOT, getRootFileLocations(hasLaunchers)); if (!hasLaunchers) { 154 properties.put("root.permissions.755", getLauncherName()); if (TargetPlatform.getWS().equals("motif") && TargetPlatform.getOS().equals("linux")) { properties.put("root.linux.motif.x86.permissions.755", "libXm.so.2"); } else if (TargetPlatform.getOS().equals("macosx")) { properties.put( 159 "root.macosx.carbon.ppc.permissions.755" , "${launcherName}.app/Contents/MacOS/${launcherName}"); } 162 } 163 164 IJREInfo jreInfo = fProduct.getJREInfo(); 165 String vm = jreInfo != null ? jreInfo.getJVMLocation(config[0]) : null; 166 if(vm != null) { 167 properties.put("root."+config[0]+ "."+config[1]+ "."+config[2]+ ".folder.jre", "absolute:" + vm); String perms = (String ) properties.get("root.permissions.755"); if(perms != null) { 174 StringBuffer buffer = new StringBuffer (perms); 175 buffer.append(","); buffer.append("jre/bin/java"); properties.put("root.permissions.755", buffer.toString()); } 179 } 180 181 save(new File (file, "build.properties"), properties, "Build Configuration"); } 183 184 private String getRootFileLocations(boolean hasLaunchers) { 185 StringBuffer buffer = new StringBuffer (); 186 187 File homeDir = new File (TargetPlatform.getLocation()); 188 if (!hasLaunchers) { 189 if (homeDir.exists() && homeDir.isDirectory()) { 190 buffer.append("absolute:file:"); buffer.append(new File (homeDir, "startup.jar").getAbsolutePath()); if (!TargetPlatform.getOS().equals("macosx")) { File file = new File (homeDir, "eclipse"); if (file.exists()) { 195 buffer.append(",absolute:file:"); buffer.append(file.getAbsolutePath()); 197 } 198 file = new File (homeDir, "eclipse.exe"); if (file.exists()) { 200 buffer.append(",absolute:file:"); buffer.append(file.getAbsolutePath()); 202 } 203 file = new File (homeDir, "libXm.so.2"); if (file.exists()) { 205 buffer.append(",absolute:file:"); buffer.append(file.getAbsolutePath()); 207 } 208 } 209 } 210 } 211 if (buffer.length() > 0) 213 buffer.append(","); buffer.append("/temp/"); 216 return buffer.toString(); 217 } 218 219 private void createEclipseProductFile() { 220 File dir = new File (fFeatureLocation, "temp"); if (!dir.exists() || !dir.isDirectory()) 222 dir.mkdirs(); 223 Properties properties = new Properties (); 224 IPluginModelBase model = PluginRegistry.findModel(getBrandingPlugin()); 225 if (model != null) 226 properties.put("name", model.getResourceString(fProduct.getName())); else 228 properties.put("name", fProduct.getName()); properties.put("id", fProduct.getId()); if (model != null) 231 properties.put("version", model.getPluginBase().getVersion()); save(new File (dir, ".eclipseproduct"), properties, "Eclipse Product File"); } 234 235 private void createLauncherIniFile(String os) { 236 String programArgs = getProgramArguments(os); 237 String vmArgs = getVMArguments(os); 238 239 if (programArgs.length() == 0 && vmArgs.length() == 0) 240 return; 241 242 File dir = new File (fFeatureLocation, "temp"); if (Platform.OS_MACOSX.equals(os)) { 245 dir = new File (dir, "Eclipse.app/Contents/MacOS"); } 247 if (!dir.exists() || !dir.isDirectory()) 248 dir.mkdirs(); 249 250 String lineDelimiter = Platform.OS_WIN32.equals(os)?"\r\n":"\n"; 252 PrintWriter writer = null; 253 try { 254 writer = new PrintWriter (new FileWriter (new File (dir, getLauncherName() + ".ini"))); ExecutionArguments args = new ExecutionArguments(vmArgs, programArgs); 256 257 String [] array = args.getProgramArgumentsArray(); 259 for (int i = 0; i < array.length; i++) { 260 writer.print(array[i]); 261 writer.print(lineDelimiter); 262 } 263 264 array = args.getVMArgumentsArray(); 266 if (array.length > 0) { 267 writer.print("-vmargs"); writer.print(lineDelimiter); 269 for (int i = 0; i < array.length; i++) { 270 writer.print(array[i]); 271 writer.print(lineDelimiter); 272 } 273 } 274 } catch (IOException e) { 275 } finally { 276 if (writer != null) { 277 writer.close(); 278 } 279 } 280 } 281 282 private String getProgramArguments(String os) { 283 IArgumentsInfo info = fProduct.getLauncherArguments(); 284 return info != null ? CoreUtility.normalize(info.getCompleteProgramArguments(os)) : ""; } 286 287 private String getVMArguments(String os) { 288 IArgumentsInfo info = fProduct.getLauncherArguments(); 289 return (info != null) ? CoreUtility.normalize(info.getCompleteVMArguments(os)) : ""; } 291 292 293 private void createConfigIniFile(String [] config) { 294 File dir = new File (fFeatureLocation, "temp/configuration"); if (!dir.exists() || !dir.isDirectory()) 296 dir.mkdirs(); 297 298 PrintWriter writer = null; 299 300 File custom = getCustomIniFile(); 301 if (custom != null) { 302 String path = getExpandedPath(fProduct.getConfigurationFileInfo().getPath()); 303 BufferedReader in = null; 304 try { 305 in = new BufferedReader (new FileReader (path)); 306 writer = new PrintWriter (new FileWriter (new File (dir, "config.ini"))); String line; 308 while ((line = in.readLine()) != null) { 309 writer.println(line); 310 } 311 } catch (IOException e) { 312 } finally { 313 try { 314 if (in != null) 315 in.close(); 316 if (writer != null) 317 writer.close(); 318 } catch (IOException e) { 319 } 320 } 321 return; 322 } 323 try { 324 writer = new PrintWriter (new FileWriter (new File (dir, "config.ini"))); String location = getSplashLocation(config[0], config[1], config[2]); 326 writer.println("#Product Runtime Configuration File"); writer.println(); 328 if (location != null) 329 writer.println("osgi.splashPath=" + location); writer.println("eclipse.product=" + fProduct.getId()); writer.println("osgi.bundles=" + getPluginList(config, TargetPlatform.getBundleList())); writer.println("osgi.bundles.defaultStartLevel=4"); } catch (IOException e) { 334 } finally { 335 if (writer != null) 336 writer.close(); 337 } 338 } 339 340 private String getSplashLocation(String os, String ws, String arch) { 341 ISplashInfo info = fProduct.getSplashInfo(); 342 String plugin = null; 343 if (info != null) { 344 plugin = info.getLocation(); 345 } 346 if (plugin == null || plugin.trim().length() == 0) 347 plugin = getBrandingPlugin(); 348 349 if (plugin == null) 350 return null; 351 352 StringBuffer buffer = new StringBuffer ("platform:/base/plugins/"); buffer.append(plugin.trim()); 354 355 State state = getState(os, ws, arch); 356 BundleDescription bundle = state.getBundle(plugin, null); 357 if (bundle != null) { 358 BundleDescription[] fragments = bundle.getFragments(); 359 for (int i = 0; i < fragments.length; i++) { 360 String id = fragments[i].getSymbolicName(); 361 if (fProduct.containsPlugin(id)) { 362 buffer.append(",platform:/base/plugins/"); buffer.append(id); 364 } 365 } 366 } 367 return buffer.toString(); 368 } 369 370 private String getBrandingPlugin() { 371 int dot = fProduct.getId().lastIndexOf('.'); 372 return (dot != -1) ? fProduct.getId().substring(0, dot) : null; 373 } 374 375 private String getPluginList(String [] config, String bundleList) { 376 if (fProduct.useFeatures()) 377 return bundleList; 378 379 StringBuffer buffer = new StringBuffer (); 380 381 Set initialBundleSet = new HashSet (); 383 StringTokenizer tokenizer = new StringTokenizer (bundleList, ","); while (tokenizer.hasMoreTokens()) { 385 String token = tokenizer.nextToken(); 386 int index = token.indexOf('@'); 387 String id = index != -1 ? token.substring(0, index) : token; 388 if (fProduct.containsPlugin(id)) { 389 if (buffer.length() > 0) 390 buffer.append(','); 391 buffer.append(id); 392 if (index != -1 && index < token.length() -1) 393 buffer.append(token.substring(index)); 394 initialBundleSet.add(id); 395 } 396 } 397 398 if (!fProduct.containsPlugin("org.eclipse.update.configurator")) { initialBundleSet.add("org.eclipse.osgi"); 401 Dictionary environment = new Hashtable (4); 402 environment.put("osgi.os", config[0]); environment.put("osgi.ws", config[1]); environment.put("osgi.arch", config[2]); environment.put("osgi.nl", config[3]); 407 BundleContext context = PDECore.getDefault().getBundleContext(); 408 for (int i = 0; i < fInfo.items.length; i++) { 409 BundleDescription bundle = (BundleDescription)fInfo.items[i]; 410 String filterSpec = bundle.getPlatformFilter(); 411 try { 412 if (filterSpec == null|| context.createFilter(filterSpec).match(environment)) { 413 String id = ((BundleDescription)fInfo.items[i]).getSymbolicName(); 414 if (!initialBundleSet.contains(id)) { 415 if (buffer.length() > 0) 416 buffer.append(","); buffer.append(id); 418 } 419 } 420 } catch (InvalidSyntaxException e) { 421 } 422 } 423 } 424 return buffer.toString(); 425 } 426 427 protected HashMap createAntBuildProperties(String os, String ws, String arch) { 428 HashMap properties = super.createAntBuildProperties(os, ws, arch); 429 properties.put(IXMLConstants.PROPERTY_LAUNCHER_NAME, getLauncherName()); 430 431 ILauncherInfo info = fProduct.getLauncherInfo(); 432 if (info != null) { 433 String images = null; 434 if (os.equals("win32")) { images = getWin32Images(info); 436 } else if (os.equals("solaris")) { images = getSolarisImages(info); 438 } else if (os.equals("linux")) { images = getExpandedPath(info.getIconPath(ILauncherInfo.LINUX_ICON)); 440 } else if (os.equals("macosx")) { images = getExpandedPath(info.getIconPath(ILauncherInfo.MACOSX_ICON)); 442 } 443 if (images != null && images.length() > 0) 444 properties.put(IXMLConstants.PROPERTY_LAUNCHER_ICONS, images); 445 } 446 447 fAntBuildProperties.put(IXMLConstants.PROPERTY_COLLECTING_FOLDER, fRoot); 448 fAntBuildProperties.put(IXMLConstants.PROPERTY_ARCHIVE_PREFIX, fRoot); 449 return properties; 450 } 451 452 private String getLauncherName() { 453 ILauncherInfo info = fProduct.getLauncherInfo(); 454 if (info != null) { 455 String name = info.getLauncherName(); 456 if (name != null && name.length() > 0) { 457 name = name.trim(); 458 if (name.endsWith(".exe")) name = name.substring(0, name.length() - 4); 460 return name; 461 } 462 } 463 return "eclipse"; } 465 466 private String getWin32Images(ILauncherInfo info) { 467 StringBuffer buffer = new StringBuffer (); 468 if (info.usesWinIcoFile()) { 469 append(buffer, info.getIconPath(ILauncherInfo.P_ICO_PATH)); 470 } else { 471 append(buffer, info.getIconPath(ILauncherInfo.WIN32_16_LOW)); 472 append(buffer, info.getIconPath(ILauncherInfo.WIN32_16_HIGH)); 473 append(buffer, info.getIconPath(ILauncherInfo.WIN32_32_HIGH)); 474 append(buffer, info.getIconPath(ILauncherInfo.WIN32_32_LOW)); 475 append(buffer, info.getIconPath(ILauncherInfo.WIN32_48_HIGH)); 476 append(buffer, info.getIconPath(ILauncherInfo.WIN32_48_LOW)); 477 } 478 return buffer.length() > 0 ? buffer.toString() : null; 479 } 480 481 private String getSolarisImages(ILauncherInfo info) { 482 StringBuffer buffer = new StringBuffer (); 483 append(buffer, info.getIconPath(ILauncherInfo.SOLARIS_LARGE)); 484 append(buffer, info.getIconPath(ILauncherInfo.SOLARIS_MEDIUM)); 485 append(buffer, info.getIconPath(ILauncherInfo.SOLARIS_SMALL)); 486 append(buffer, info.getIconPath(ILauncherInfo.SOLARIS_TINY)); 487 return buffer.length() > 0 ? buffer.toString() : null; 488 } 489 490 private void append(StringBuffer buffer, String path) { 491 path = getExpandedPath(path); 492 if (path != null) { 493 if (buffer.length() > 0) 494 buffer.append(","); buffer.append(path); 496 } 497 } 498 499 private String getExpandedPath(String path) { 500 if (path == null || path.length() == 0) 501 return null; 502 IResource resource = PDECore.getWorkspace().getRoot().findMember(new Path(path)); 503 if (resource != null) { 504 IPath fullPath = resource.getLocation(); 505 return fullPath == null ? null : fullPath.toOSString(); 506 } 507 return null; 508 } 509 510 private void save(File file, Properties properties, String header) { 511 try { 512 FileOutputStream stream = new FileOutputStream (file); 513 properties.store(stream, header); 514 stream.flush(); 515 stream.close(); 516 } catch (IOException e) { 517 PDECore.logException(e); 518 } 519 } 520 521 protected void setupGenerator(BuildScriptGenerator generator, String featureID, String versionId, String os, String ws, String arch, String featureLocation) throws CoreException { 522 super.setupGenerator(generator, featureID, versionId, os, ws, arch, featureLocation); 523 if (fProduct != null) 524 generator.setProduct(fProduct.getModel().getInstallLocation()); 525 } 526 527 private void createMacScript(String [] config, IProgressMonitor monitor) { 528 String entryName = TargetPlatformHelper.getTargetVersion() >= 3.3 529 ? "macosx/Info.plist" : "macosx/Info.plist.32"; URL url = PDECore.getDefault().getBundle().getEntry(entryName); if (url == null) 533 return; 534 535 File scriptFile = null; 536 File plist = null; 537 InputStream in = null; 538 String location = PDECore.getDefault().getStateLocation().toOSString(); 539 try { 540 in = url.openStream(); 541 File dir = new File (location, "Eclipse.app/Contents"); dir.mkdirs(); 543 plist = new File (dir, "Info.plist"); CoreUtility.readFile(in, plist); 545 scriptFile = createScriptFile("macbuild.xml"); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 547 Document doc = factory.newDocumentBuilder().newDocument(); 548 549 Element root = doc.createElement("project"); root.setAttribute("name", "project"); root.setAttribute("default", "default"); doc.appendChild(root); 553 554 Element property = doc.createElement("property"); property.setAttribute("name", "eclipse.base"); property.setAttribute("value", "${assemblyTempDir}/${collectingFolder}"); root.appendChild(property); 558 559 Element target = doc.createElement("target"); target.setAttribute("name", "default"); root.appendChild(target); 562 563 Element copy = doc.createElement("copy"); StringBuffer toDir = new StringBuffer ("${eclipse.base}/"); toDir.append(config[0]); 566 toDir.append("."); toDir.append(config[1]); 568 toDir.append("."); toDir.append(config[2]); 570 toDir.append("/${collectingFolder}"); copy.setAttribute("todir", toDir.toString()); copy.setAttribute("failonerror", "false"); copy.setAttribute("overwrite", "true"); target.appendChild(copy); 575 576 Element fileset = doc.createElement("fileset"); fileset.setAttribute("dir", "${installFolder}"); fileset.setAttribute("includes", "Eclipse.app/Contents/MacOS/eclipse"); copy.appendChild(fileset); 580 581 fileset = doc.createElement("fileset"); fileset.setAttribute("dir", "${template}"); fileset.setAttribute("includes", "Eclipse.app/Contents/Info.plist"); copy.appendChild(fileset); 585 586 XMLPrintHandler.writeFile(doc, scriptFile); 587 588 AntRunner runner = new AntRunner(); 589 HashMap map = new HashMap (); 590 if (!fInfo.toDirectory) { 591 String filename = fInfo.zipFileName; 592 map.put(IXMLConstants.PROPERTY_ARCHIVE_FULLPATH, fInfo.destinationDirectory + File.separator + filename); 593 } else { 594 map.put(IXMLConstants.PROPERTY_ASSEMBLY_TMP, fInfo.destinationDirectory); 595 } 596 map.put(IXMLConstants.PROPERTY_COLLECTING_FOLDER, fRoot); 597 map.put("installFolder", TargetPlatform.getLocation()); map.put("template", location); runner.addUserProperties(map); 600 runner.setBuildFileLocation(scriptFile.getAbsolutePath()); 601 runner.setExecutionTargets(new String [] {"default"}); runner.run(new SubProgressMonitor(monitor, 1)); 603 } catch (FactoryConfigurationError e) { 604 } catch (ParserConfigurationException e) { 605 } catch (CoreException e) { 606 } catch (IOException e) { 607 } finally { 608 try { 609 if (in != null) 610 in.close(); 611 } catch (IOException e) { 612 } 613 CoreUtility.deleteContent(new File (location, "Eclipse.app")); if (scriptFile != null && scriptFile.exists()) 615 scriptFile.delete(); 616 monitor.done(); 617 } 618 } 619 620 protected void setAdditionalAttributes(Element plugin, BundleDescription bundle) { 621 HostSpecification host = bundle.getHost(); 623 boolean unpack = (host != null && host.getName().equals("org.eclipse.equinox.launcher")) ? true : CoreUtility.guessUnpack(bundle); 625 plugin.setAttribute("unpack", Boolean.toString(unpack)); } 627 628 629 } 630 | Popular Tags |