1 11 package org.eclipse.equinox.launcher; 12 13 import java.io.*; 14 import java.lang.reflect.InvocationTargetException ; 15 import java.lang.reflect.Method ; 16 import java.net.*; 17 import java.security.*; 18 import java.util.*; 19 import java.util.zip.ZipEntry ; 20 import java.util.zip.ZipFile ; 21 import org.eclipse.equinox.internal.launcher.Constants; 22 23 32 public class Main { 33 36 protected boolean debug = false; 37 38 41 protected String bootLocation = null; 42 43 46 protected URL installLocation = null; 47 48 51 protected URL configurationLocation = null; 52 53 56 protected String parentConfigurationLocation = null; 57 58 61 protected String framework = OSGI; 62 63 66 protected String devClassPath = null; 67 68 71 private Properties devClassPathProps = null; 72 73 76 protected boolean inDevelopmentMode = false; 77 78 81 protected String os = null; 82 protected String ws = null; 83 protected String arch = null; 84 85 private String library = null; 88 private String exitData = null; 89 90 private String vm = null; 91 private String [] vmargs = null; 92 private String [] commands = null; 93 String [] extensionPaths = null; 94 95 JNIBridge bridge = null; 96 97 private boolean showSplash = false; 99 private String splashLocation = null; 100 private String endSplash = null; 101 private boolean initialize = false; 102 private boolean splashDown = false; 103 public final class SplashHandler extends Thread { 104 public void run() { 105 takeDownSplash(); 106 } 107 public void updateSplash() { 108 if(bridge != null) { 109 bridge.updateSplash(); 110 } 111 } 112 } 113 private final Thread splashHandler = new SplashHandler(); 114 115 public static final String SPLASH_HANDLE = "org.eclipse.equinox.launcher.splash.handle"; public static final String SPLASH_LOCATION = "org.eclipse.equinox.launcher.splash.location"; 119 private static final String FRAMEWORK = "-framework"; private static final String INSTALL = "-install"; private static final String INITIALIZE = "-initialize"; private static final String VM = "-vm"; private static final String VMARGS = "-vmargs"; private static final String DEBUG = "-debug"; private static final String DEV = "-dev"; private static final String CONFIGURATION = "-configuration"; private static final String NOSPLASH = "-nosplash"; private static final String SHOWSPLASH = "-showsplash"; private static final String EXITDATA = "-exitdata"; private static final String NAME = "-name"; private static final String LAUNCHER = "-launcher"; private static final String LIBRARY = "--launcher.library"; private static final String NL = "-nl"; private static final String ENDSPLASH = "-endsplash"; private static final String SPLASH_IMAGE = "splash.bmp"; private static final String CLEAN = "-clean"; private static final String NOEXIT = "-noExit"; private static final String OS = "-os"; private static final String WS = "-ws"; private static final String ARCH = "-arch"; private static final String STARTUP = "-startup"; 144 private static final String OSGI = "org.eclipse.osgi"; private static final String STARTER = "org.eclipse.core.runtime.adaptor.EclipseStarter"; private static final String PLATFORM_URL = "platform:/base/"; private static final String ECLIPSE_PROPERTIES = "eclipse.properties"; private static final String FILE_SCHEME = "file:"; protected static final String REFERENCE_SCHEME = "reference:"; protected static final String JAR_SCHEME = "jar:"; 152 private static final String CONFIG_DIR = "configuration/"; private static final String CONFIG_FILE = "config.ini"; private static final String CONFIG_FILE_TEMP_SUFFIX = ".tmp"; private static final String CONFIG_FILE_BAK_SUFFIX = ".bak"; private static final String ECLIPSE = "eclipse"; private static final String PRODUCT_SITE_MARKER = ".eclipseproduct"; private static final String PRODUCT_SITE_ID = "id"; private static final String PRODUCT_SITE_VERSION = "version"; 162 private static final String PROP_USER_HOME = "user.home"; private static final String PROP_USER_DIR = "user.dir"; private static final String PROP_INSTALL_AREA = "osgi.install.area"; private static final String PROP_CONFIG_AREA = "osgi.configuration.area"; private static final String PROP_CONFIG_AREA_DEFAULT = "osgi.configuration.area.default"; private static final String PROP_BASE_CONFIG_AREA = "osgi.baseConfiguration.area"; private static final String PROP_SHARED_CONFIG_AREA = "osgi.sharedConfiguration.area"; private static final String PROP_CONFIG_CASCADED = "osgi.configuration.cascaded"; protected static final String PROP_FRAMEWORK = "osgi.framework"; private static final String PROP_SPLASHPATH = "osgi.splashPath"; private static final String PROP_SPLASHLOCATION = "osgi.splashLocation"; private static final String PROP_CLASSPATH = "osgi.frameworkClassPath"; private static final String PROP_EXTENSIONS = "osgi.framework.extensions"; private static final String PROP_FRAMEWORK_SYSPATH = "osgi.syspath"; private static final String PROP_FRAMEWORK_SHAPE = "osgi.framework.shape"; private static final String PROP_LOGFILE = "osgi.logfile"; private static final String PROP_REQUIRED_JAVA_VERSION = "osgi.requiredJavaVersion"; private static final String PROP_PARENT_CLASSLOADER = "osgi.parentClassloader"; private static final String PROP_FRAMEWORK_PARENT_CLASSLOADER = "osgi.frameworkParentClassloader"; private static final String PROP_NL = "osgi.nl"; static final String PROP_NOSHUTDOWN = "osgi.noShutdown"; private static final String PROP_DEBUG = "osgi.debug"; 186 private static final String PROP_EXITCODE = "eclipse.exitcode"; private static final String PROP_EXITDATA = "eclipse.exitdata"; 189 private static final String PROP_VM = "eclipse.vm"; private static final String PROP_VMARGS = "eclipse.vmargs"; private static final String PROP_COMMANDS = "eclipse.commands"; private static final String PROP_ECLIPSESECURITY = "eclipse.security"; 194 private static final String NONE = "@none"; private static final String NO_DEFAULT = "@noDefault"; private static final String USER_HOME = "@user.home"; private static final String USER_DIR = "@user.dir"; 200 private static final String PARENT_CLASSLOADER_APP = "app"; private static final String PARENT_CLASSLOADER_EXT = "ext"; private static final String PARENT_CLASSLOADER_BOOT = "boot"; private static final String PARENT_CLASSLOADER_CURRENT = "current"; 206 protected static final String SESSION = "!SESSION"; protected static final String ENTRY = "!ENTRY"; protected static final String MESSAGE = "!MESSAGE"; protected static final String STACK = "!STACK"; protected static final int ERROR = 4; 212 protected static final String PLUGIN_ID = "org.eclipse.equinox.launcher"; protected File logFile = null; 214 protected BufferedWriter log = null; 215 protected boolean newSession = true; 216 217 222 static class Identifier { 223 private static final String DELIM = ". _-"; private int major, minor, service; 225 Identifier(int major, int minor, int service) { 226 super(); 227 this.major = major; 228 this.minor = minor; 229 this.service = service; 230 } 231 234 Identifier(String versionString) { 235 super(); 236 StringTokenizer tokenizer = new StringTokenizer(versionString, DELIM); 237 238 if (tokenizer.hasMoreTokens()) 240 major = Integer.parseInt(tokenizer.nextToken()); 241 242 if (tokenizer.hasMoreTokens()) 244 minor = Integer.parseInt(tokenizer.nextToken()); 245 246 try { 247 if (tokenizer.hasMoreTokens()) 249 service = Integer.parseInt(tokenizer.nextToken()); 250 } catch (NumberFormatException nfe) { 251 } 254 } 255 264 boolean isGreaterEqualTo(Identifier minimum) { 265 if (major < minimum.major) 266 return false; 267 if (major > minimum.major) 268 return true; 269 if (minor < minimum.minor) 271 return false; 272 if (minor > minimum.minor) 273 return true; 274 return service >= minimum.service; 276 } 277 } 278 279 private String getWS() { 280 if (ws != null) 281 return ws; 282 String os = getOS(); 283 if (os.equals(Constants.OS_WIN32)) 284 return Constants.WS_WIN32; 285 if (os.equals(Constants.OS_LINUX)) 286 return Constants.WS_GTK; 287 if (os.equals(Constants.OS_MACOSX)) 288 return Constants.WS_CARBON; 289 if (os.equals(Constants.OS_HPUX)) 290 return Constants.WS_MOTIF; 291 if (os.equals(Constants.OS_AIX)) 292 return Constants.WS_MOTIF; 293 if (os.equals(Constants.OS_SOLARIS)) 294 return Constants.WS_MOTIF; 295 if (os.equals(Constants.OS_QNX)) 296 return Constants.WS_PHOTON; 297 return Constants.WS_UNKNOWN; 298 } 299 private String getOS() { 300 if (os != null) 301 return os; 302 String osName = System.getProperties().getProperty("os.name"); if (osName.regionMatches(true, 0, Constants.OS_WIN32, 0, 3)) 304 return Constants.OS_WIN32; 305 if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_SUNOS)) 307 return Constants.OS_SOLARIS; 308 if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_LINUX)) 309 return Constants.OS_LINUX; 310 if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_QNX)) 311 return Constants.OS_QNX; 312 if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_AIX)) 313 return Constants.OS_AIX; 314 if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_HPUX)) 315 return Constants.OS_HPUX; 316 if (osName.regionMatches(true, 0, Constants.INTERNAL_OS_MACOSX, 0, Constants.INTERNAL_OS_MACOSX.length())) 318 return Constants.OS_MACOSX; 319 return Constants.OS_UNKNOWN; 320 } 321 private String getArch() { 322 if (arch != null) 323 return arch; 324 String name = System.getProperties().getProperty("os.arch"); if (name.equalsIgnoreCase(Constants.INTERNAL_ARCH_I386)) 327 return Constants.ARCH_X86; 328 else if (name.equalsIgnoreCase(Constants.INTERNAL_AMD64)) 330 return Constants.ARCH_X86_64; 331 332 return name; 333 } 334 335 338 private void setupJNI(URL[] defaultPath) { 339 String libPath = null; 340 341 if (library != null) { 342 File lib = new File (library); 343 if(lib.isDirectory()) { 344 libPath = searchFor("eclipse", lib.getAbsolutePath()); } else if(lib.exists()){ 346 libPath = lib.getAbsolutePath(); 347 } 348 } 349 if(libPath == null) { 350 String fragmentOS = getOS(); 352 StringBuffer buffer = new StringBuffer (PLUGIN_ID); 353 buffer.append('.'); 354 buffer.append(getWS()); 355 buffer.append('.'); 356 buffer.append(fragmentOS); 357 if(!fragmentOS.equals("macosx")){ buffer.append('.'); 359 buffer.append(getArch()); 360 } 361 String fragmentName = buffer.toString(); 362 String fragment = null; 363 if (inDevelopmentMode) { 364 String devPathList = devClassPathProps.getProperty(PLUGIN_ID); 365 String [] locations = getArrayFromList(devPathList); 366 if (locations.length > 0) { 367 File location = new File (locations[0]); 368 if (location.isAbsolute()) { 369 String dir = location.getParent(); 370 fragment = searchFor(fragmentName, dir); 371 if (fragment != null) 372 libPath = searchFor("eclipse", fragment); } 374 } 375 } 376 if (libPath == null && bootLocation != null) { 377 URL[] urls = defaultPath; 378 if (urls != null && urls.length > 0) { 379 for (int i = urls.length - 1; i >= 0 && libPath == null; i--) { 381 File entryFile = new File (urls[i].getFile()); 382 String dir = entryFile.getParent(); 383 if (inDevelopmentMode) { 384 String devDir = dir + "/" + PLUGIN_ID + "/fragments"; fragment = searchFor(fragmentName, devDir); 386 } 387 if (fragment == null) 388 fragment = searchFor(fragmentName, dir); 389 if (fragment != null) 390 libPath = searchFor("eclipse", fragment); } 392 } 393 } 394 if(libPath == null) { 395 URL install = getInstallLocation(); 396 String location = install.getFile(); 397 location += "/plugins/"; fragment = searchFor(fragmentName, location); 399 if (fragment != null) 400 libPath = searchFor("eclipse", fragment); } 402 } 403 library = libPath; 404 if(library != null) 405 bridge = new JNIBridge(library); 406 } 407 408 414 protected void basicRun(String [] args) throws Exception { 415 System.getProperties().put("eclipse.startTime", Long.toString(System.currentTimeMillis())); commands = args; 417 String [] passThruArgs = processCommandLine(args); 418 419 if (!debug) 420 debug = System.getProperty(PROP_DEBUG) != null; 422 setupVMProperties(); 423 processConfiguration(); 424 425 getInstallLocation(); 429 430 URL[] bootPath = getBootPath(bootLocation); 432 433 setupJNI(bootPath); 435 436 if (!checkVersion(System.getProperty("java.version"), System.getProperty(PROP_REQUIRED_JAVA_VERSION))) return; 440 441 setSecurityPolicy(bootPath); 442 handleSplash(bootPath); 445 446 beforeFwkInvocation(); 447 invokeFramework(passThruArgs, bootPath); 448 } 449 450 protected void beforeFwkInvocation() { 451 } 453 454 protected void setSecurityPolicy(URL[] bootPath) { 455 String eclipseSecurity = System.getProperty(PROP_ECLIPSESECURITY); 456 if (eclipseSecurity != null) { 457 SecurityManager sm = System.getSecurityManager(); 458 boolean setSM = false; 459 if (sm == null) { 460 if (eclipseSecurity.length() < 1) { 461 eclipseSecurity = "java.lang.SecurityManager"; } 463 try { 464 Class clazz = Class.forName(eclipseSecurity); 465 sm = (SecurityManager ) clazz.newInstance(); 466 setSM = true; 467 } 468 catch (Throwable t) { 469 System.getProperties().put("java.security.manager", eclipseSecurity); } 471 } 472 473 ProtectionDomain domain = Main.class.getProtectionDomain(); 474 CodeSource source = null; 475 if (domain != null) 476 source = Main.class.getProtectionDomain().getCodeSource(); 477 if (domain == null || source == null) { 478 log("Can not automatically set the security manager. Please use a policy file."); return; 480 } 481 URL[] rootURLs = new URL[bootPath.length + 1]; 483 rootURLs[0] = source.getLocation(); 484 System.arraycopy(bootPath, 0, rootURLs, 1, bootPath.length); 485 Policy eclipsePolicy = new EclipsePolicy(Policy.getPolicy(), rootURLs); 487 Policy.setPolicy(eclipsePolicy); 488 if (setSM) 489 System.setSecurityManager(sm); 490 } 491 } 492 493 private void invokeFramework(String [] passThruArgs, URL[] bootPath) throws ClassNotFoundException , NoSuchMethodException , IllegalAccessException , Error , Exception , InvocationTargetException { 494 String type = System.getProperty(PROP_FRAMEWORK_PARENT_CLASSLOADER, System.getProperty(PROP_PARENT_CLASSLOADER, PARENT_CLASSLOADER_BOOT)); 495 ClassLoader parent = null; 496 if (PARENT_CLASSLOADER_APP.equalsIgnoreCase(type)) 497 parent = ClassLoader.getSystemClassLoader(); 498 else if (PARENT_CLASSLOADER_EXT.equalsIgnoreCase(type)) { 499 ClassLoader appCL = ClassLoader.getSystemClassLoader(); 500 if (appCL != null) 501 parent = appCL.getParent(); 502 } else if (PARENT_CLASSLOADER_CURRENT.equalsIgnoreCase(type)) 503 parent = this.getClass().getClassLoader(); 504 URLClassLoader loader = new StartupClassLoader(bootPath, parent); 505 Class clazz = loader.loadClass(STARTER); 506 Method method = clazz.getDeclaredMethod("run", new Class [] {String [].class, Runnable .class}); try { 508 method.invoke(clazz, new Object [] {passThruArgs, splashHandler}); 509 } catch (InvocationTargetException e) { 510 if (e.getTargetException() instanceof Error ) 511 throw (Error ) e.getTargetException(); 512 else if (e.getTargetException() instanceof Exception ) 513 throw (Exception ) e.getTargetException(); 514 else 515 throw e; 517 } 518 } 519 520 527 private boolean checkVersion(String availableVersion, String requiredVersion) { 528 if (requiredVersion == null || availableVersion == null) 529 return true; 530 try { 531 Identifier required = new Identifier(requiredVersion); 532 Identifier available = new Identifier(availableVersion); 533 boolean compatible = available.isGreaterEqualTo(required); 534 if (!compatible) { 535 System.getProperties().put(PROP_EXITCODE, "14"); System.getProperties().put(PROP_EXITDATA, "<title>Incompatible JVM</title>Version " + availableVersion + " of the JVM is not suitable for this product. Version: "+ requiredVersion + " or greater is required."); } 539 return compatible; 540 } catch (SecurityException e) { 541 return true; 544 } catch (NumberFormatException e) { 545 return true; 548 } 549 } 550 551 557 protected String decode(String urlString) { 558 try { 560 Class clazz = URLDecoder.class; 561 Method method = clazz.getDeclaredMethod("decode", new Class [] {String .class, String .class}); if (urlString.indexOf('+') >= 0) { 565 int len = urlString.length(); 566 StringBuffer buf = new StringBuffer (len); 567 for (int i = 0; i < len; i++) { 568 char c = urlString.charAt(i); 569 if (c == '+') 570 buf.append("%2B"); else 572 buf.append(c); 573 } 574 urlString = buf.toString(); 575 } 576 Object result = method.invoke(null, new Object [] {urlString, "UTF-8"}); if (result != null) 578 return (String ) result; 579 } catch (Exception e) { 580 } 582 boolean replaced = false; 584 byte[] encodedBytes = urlString.getBytes(); 585 int encodedLength = encodedBytes.length; 586 byte[] decodedBytes = new byte[encodedLength]; 587 int decodedLength = 0; 588 for (int i = 0; i < encodedLength; i++) { 589 byte b = encodedBytes[i]; 590 if (b == '%') { 591 if(i+2 >= encodedLength) 592 throw new IllegalArgumentException ("Malformed URL (\""+urlString+"\"): % must be followed by 2 digits."); byte enc1 = encodedBytes[++i]; 594 byte enc2 = encodedBytes[++i]; 595 b = (byte) ((hexToByte(enc1) << 4) + hexToByte(enc2)); 596 replaced = true; 597 } 598 decodedBytes[decodedLength++] = b; 599 } 600 if (!replaced) 601 return urlString; 602 try { 603 return new String (decodedBytes, 0, decodedLength, "UTF-8"); } catch (UnsupportedEncodingException e) { 605 return new String (decodedBytes, 0, decodedLength); 607 } 608 } 609 610 616 protected String [] getArrayFromList(String prop) { 617 if (prop == null || prop.trim().equals("")) return new String [0]; 619 Vector list = new Vector(); 620 StringTokenizer tokens = new StringTokenizer(prop, ","); while (tokens.hasMoreTokens()) { 622 String token = tokens.nextToken().trim(); 623 if (!token.equals("")) list.addElement(token); 625 } 626 return list.isEmpty() ? new String [0] : (String []) list.toArray(new String [list.size()]); 627 } 628 629 637 private URL[] getDevPath(URL base) throws IOException { 638 ArrayList result = new ArrayList(5); 639 if (inDevelopmentMode) 640 addDevEntries(base, result, OSGI); 641 addBaseJars(base, result); 643 return (URL[]) result.toArray(new URL[result.size()]); 644 } 645 646 URL constructURL(URL url, String name) { 647 651 String externalForm = url.toExternalForm(); 652 if (externalForm.endsWith(".jar")) { try { 654 return new URL(JAR_SCHEME + url + "!/" + name); } catch (MalformedURLException e) { 656 } 658 } 659 660 try { 661 return new URL(url, name); 662 } catch (MalformedURLException e) { 663 return null; 665 } 666 } 667 private void readFrameworkExtensions(URL base, ArrayList result) throws IOException { 668 String [] extensions = getArrayFromList(System.getProperties().getProperty(PROP_EXTENSIONS)); 669 String parent = new File (base.getFile()).getParent().toString(); 670 ArrayList extensionResults = new ArrayList(extensions.length); 671 for (int i = 0; i < extensions.length; i++) { 672 String path = searchFor(extensions[i], parent); 674 if (path == null) { 675 log("Could not find extension: " + extensions[i]); continue; 677 } 678 if (debug) 679 System.out.println("Loading extension: " + extensions[i]); 681 URL extensionURL = null; 682 if (installLocation.getProtocol().equals("file")) { extensionResults.add(path); 684 extensionURL = new File (path).toURL(); 685 } else 686 extensionURL = new URL(installLocation.getProtocol(), installLocation.getHost(), installLocation.getPort(), path); 687 688 Properties extensionProperties = null; 690 try { 691 extensionProperties = loadProperties(constructURL(extensionURL, ECLIPSE_PROPERTIES)); 692 } catch (IOException e) { 693 if (debug) 694 System.out.println("\t" + ECLIPSE_PROPERTIES + " not found"); } 696 String extensionClassPath = null; 697 if (extensionProperties != null) 698 extensionClassPath = extensionProperties.getProperty(PROP_CLASSPATH); 699 else extensionProperties = new Properties(); 701 String [] entries = extensionClassPath == null || extensionClassPath.length() == 0 ? new String [] {""} : getArrayFromList(extensionClassPath); String qualifiedPath; 703 if (System.getProperty(PROP_CLASSPATH)==null) 704 qualifiedPath = "."; else 706 qualifiedPath = ""; for (int j = 0; j < entries.length; j++) 708 qualifiedPath += ", " + FILE_SCHEME + path + entries[j]; extensionProperties.put(PROP_CLASSPATH, qualifiedPath); 710 mergeProperties(System.getProperties(), extensionProperties); 711 if (inDevelopmentMode) 712 addDevEntries(extensionURL, result, extensions[i]); 713 } 714 extensionPaths = (String []) extensionResults.toArray(new String [extensionResults.size()]); 715 } 716 717 private void addBaseJars(URL base, ArrayList result) throws IOException { 718 String baseJarList = System.getProperty(PROP_CLASSPATH); 719 if (baseJarList == null) { 720 readFrameworkExtensions(base, result); 721 baseJarList = System.getProperties().getProperty(PROP_CLASSPATH); 722 } 723 724 File fwkFile = new File (base.getFile()); 725 boolean fwkIsDirectory = fwkFile.isDirectory(); 726 if (fwkIsDirectory) { 728 System.getProperties().put(PROP_FRAMEWORK_SHAPE, "folder"); } else { 730 System.getProperties().put(PROP_FRAMEWORK_SHAPE, "jar"); } 732 String fwkPath = new File (new File (base.getFile()).getParent()).getAbsolutePath(); 733 if (Character.isUpperCase(fwkPath.charAt(0))) { 734 char[] chars = fwkPath.toCharArray(); 735 chars[0] = Character.toLowerCase(chars[0]); 736 fwkPath = new String (chars); 737 } 738 System.getProperties().put(PROP_FRAMEWORK_SYSPATH, fwkPath); 739 740 String [] baseJars = getArrayFromList(baseJarList); 741 if (baseJars.length == 0) { 742 if (!inDevelopmentMode && new File (base.getFile()).isDirectory()) 743 throw new IOException("Unable to initialize " + PROP_CLASSPATH); addEntry(base, result); 745 return; 746 } 747 for (int i = 0; i < baseJars.length; i++) { 748 String string = baseJars[i]; 749 try { 750 754 if (string.equals(".")) { addEntry(base, result); 756 } 757 URL url = null; 758 if (string.startsWith(FILE_SCHEME)) 759 url = new File (string.substring(5)).toURL(); 760 else 761 url = new URL(string); 762 addEntry(url, result); 763 } catch (MalformedURLException e) { 764 addEntry(new URL(base, string), result); 765 } 766 } 767 } 768 769 protected void addEntry(URL url, List result) { 770 if (new File (url.getFile()).exists()) 771 result.add(url); 772 } 773 774 private void addDevEntries(URL base, List result, String symbolicName) throws MalformedURLException { 775 if (devClassPathProps == null) 776 return; String devPathList = devClassPathProps.getProperty(symbolicName); 778 if (devPathList == null) 779 devPathList = devClassPathProps.getProperty("*"); String [] locations = getArrayFromList(devPathList); 781 for (int i = 0; i < locations.length; i++) { 782 String location = locations[i]; 783 File path = new File (location); 784 URL url; 785 if (path.isAbsolute()) 786 url = path.toURL(); 787 else { 788 char lastChar = location.charAt(location.length() - 1); 790 if ((location.endsWith(".jar") || (lastChar == '/' || lastChar == '\\'))) url = new URL(base, location); 792 else 793 url = new URL(base, location + "/"); } 795 addEntry(url, result); 796 } 797 } 798 799 806 protected URL[] getBootPath(String base) throws IOException { 807 URL url = null; 808 if (base != null) { 809 url = buildURL(base, true); 810 } else { 811 url = getInstallLocation(); 813 String path = new File (url.getFile(), "plugins").toString(); path = searchFor(framework, path); 815 if (path == null) 816 throw new RuntimeException ("Could not find framework"); if (url.getProtocol().equals("file")) url = new File (path).toURL(); 819 else 820 url = new URL(url.getProtocol(), url.getHost(), url.getPort(), path); 821 } 822 if (System.getProperty(PROP_FRAMEWORK) == null) 823 System.getProperties().put(PROP_FRAMEWORK, url.toExternalForm()); 824 if (debug) 825 System.out.println("Framework located:\n " + url.toExternalForm()); URL[] result = getDevPath(url); 828 if (debug) { 829 System.out.println("Framework classpath:"); for (int i = 0; i < result.length; i++) 831 System.out.println(" " + result[i].toExternalForm()); } 833 return result; 834 } 835 836 844 protected String searchFor(final String target, String start) { 845 return searchFor(target, null, start); 846 } 847 protected String searchFor(final String target, final String targetSuffix, String start) { 848 String [] candidates = new File (start).list(); 850 if (candidates == null) 851 return null; 852 853 ArrayList matches = new ArrayList(2); 854 for (int i = 0; i < candidates.length; i++) 855 if (candidates[i].equals(target) || candidates[i].startsWith(target + "_")) matches.add(candidates[i]); 857 String [] names = (String []) matches.toArray(new String [matches.size()]); 858 int result = findMax(names); 859 if (result == -1) 860 return null; 861 File candidate = new File (start, names[result]); 862 return candidate.getAbsolutePath().replace(File.separatorChar, '/') + (candidate.isDirectory() ? "/" : ""); } 864 865 protected int findMax(String [] candidates) { 866 int result = -1; 867 Object maxVersion = null; 868 for (int i = 0; i < candidates.length; i++) { 869 String name = candidates[i]; 870 String version = ""; int index = name.indexOf('_'); 872 if (index != -1) 873 version = name.substring(index + 1); 874 Object currentVersion = getVersionElements(version); 875 if (maxVersion == null) { 876 result = i; 877 maxVersion = currentVersion; 878 } else { 879 if (compareVersion((Object []) maxVersion, (Object []) currentVersion) < 0) { 880 result = i; 881 maxVersion = currentVersion; 882 } 883 } 884 } 885 return result; 886 } 887 894 private int compareVersion(Object [] left, Object [] right) { 895 896 int result = ((Integer ) left[0]).compareTo((Integer ) right[0]); if (result != 0) 898 return result; 899 900 result = ((Integer ) left[1]).compareTo((Integer ) right[1]); if (result != 0) 902 return result; 903 904 result = ((Integer ) left[2]).compareTo((Integer ) right[2]); if (result != 0) 906 return result; 907 908 return ((String ) left[3]).compareTo((String ) right[3]); } 910 911 919 private Object [] getVersionElements(String version) { 920 if (version.endsWith(".jar")) version = version.substring(0, version.length() - 4); 922 Object [] result = {new Integer (0), new Integer (0), new Integer (0), ""}; StringTokenizer t = new StringTokenizer(version, "."); String token; 925 int i = 0; 926 while (t.hasMoreTokens() && i < 4) { 927 token = t.nextToken(); 928 if (i < 3) { 929 try { 931 result[i++] = new Integer (token); 932 } catch (Exception e) { 933 break; 935 } 936 } else { 937 result[i++] = token; 939 } 940 } 941 return result; 942 } 943 944 private static URL buildURL(String spec, boolean trailingSlash) { 945 if (spec == null) 946 return null; 947 boolean isFile = spec.startsWith(FILE_SCHEME); 948 try { 949 if (isFile) { 950 File toAdjust = new File (spec.substring(5)); 951 if (toAdjust.isDirectory()) 952 return adjustTrailingSlash(toAdjust.toURL(), trailingSlash); 953 return toAdjust.toURL(); 954 } 955 return new URL(spec); 956 } catch (MalformedURLException e) { 957 if (isFile) 960 return null; 961 try { 962 File toAdjust = new File (spec); 963 if (toAdjust.isDirectory()) 964 return adjustTrailingSlash(toAdjust.toURL(), trailingSlash); 965 return toAdjust.toURL(); 966 } catch (MalformedURLException e1) { 967 return null; 968 } 969 } 970 } 971 972 private static URL adjustTrailingSlash(URL url, boolean trailingSlash) throws MalformedURLException { 973 String file = url.getFile(); 974 if (trailingSlash == (file.endsWith("/"))) return url; 976 file = trailingSlash ? file + "/" : file.substring(0, file.length() - 1); return new URL(url.getProtocol(), url.getHost(), file); 978 } 979 980 private URL buildLocation(String property, URL defaultLocation, String userDefaultAppendage) { 981 URL result = null; 982 String location = System.getProperty(property); 983 System.getProperties().remove(property); 984 try { 987 if (location == null) 988 result = defaultLocation; 989 else if (location.equalsIgnoreCase(NONE)) 990 return null; 991 else if (location.equalsIgnoreCase(NO_DEFAULT)) 992 result = buildURL(location, true); 993 else { 994 if (location.startsWith(USER_HOME)) { 995 String base = substituteVar(location, USER_HOME, PROP_USER_HOME); 996 location = new File (base, userDefaultAppendage).getAbsolutePath(); 997 } else if (location.startsWith(USER_DIR)) { 998 String base = substituteVar(location, USER_DIR, PROP_USER_DIR); 999 location = new File (base, userDefaultAppendage).getAbsolutePath(); 1000 } 1001 result = buildURL(location, true); 1002 } 1003 } finally { 1004 if (result != null) 1005 System.getProperties().put(property, result.toExternalForm()); 1006 } 1007 return result; 1008 } 1009 1010 private String substituteVar(String source, String var, String prop) { 1011 String value = System.getProperty(prop, ""); return value + source.substring(var.length()); 1013 } 1014 1015 1022 private String computeDefaultConfigurationLocation() { 1023 1030 URL install = getInstallLocation(); 1031 if (install.getProtocol().equals("file")) { File installDir = new File (install.getFile()); 1034 if (canWrite(installDir)) 1035 return installDir.getAbsolutePath() + File.separator + CONFIG_DIR; 1036 } 1037 return computeDefaultUserAreaLocation(CONFIG_DIR); 1039 } 1040 1041 private static boolean canWrite(File installDir) { 1042 if (installDir.canWrite() == false) 1043 return false; 1044 1045 if (!installDir.isDirectory()) 1046 return false; 1047 1048 File fileTest = null; 1049 try { 1050 fileTest = File.createTempFile("writtableArea", ".dll", installDir); } catch (IOException e) { 1054 return false; 1056 } finally { 1057 if (fileTest != null) 1058 fileTest.delete(); 1059 } 1060 return true; 1061 } 1062 1063 1070 private String computeDefaultUserAreaLocation(String pathAppendage) { 1071 URL installURL = getInstallLocation(); 1076 if (installURL == null) 1077 return null; 1078 File installDir = new File (installURL.getFile()); 1079 int hashCode; 1081 try { 1082 hashCode = installDir.getCanonicalPath().hashCode(); 1083 } catch (IOException ioe) { 1084 hashCode = installDir.getAbsolutePath().hashCode(); 1086 } 1087 if (hashCode < 0) 1088 hashCode = -(hashCode); 1089 String installDirHash = String.valueOf(hashCode); 1090 1091 String appName = "." + ECLIPSE; File eclipseProduct = new File (installDir, PRODUCT_SITE_MARKER); 1093 if (eclipseProduct.exists()) { 1094 Properties props = new Properties(); 1095 try { 1096 props.load(new FileInputStream(eclipseProduct)); 1097 String appId = props.getProperty(PRODUCT_SITE_ID); 1098 if (appId == null || appId.trim().length() == 0) 1099 appId = ECLIPSE; 1100 String appVersion = props.getProperty(PRODUCT_SITE_VERSION); 1101 if (appVersion == null || appVersion.trim().length() == 0) 1102 appVersion = ""; appName += File.separator + appId + "_" + appVersion + "_" + installDirHash; } catch (IOException e) { 1105 appName += File.separator + installDirHash; 1109 } 1110 } else { 1111 appName += File.separator + installDirHash; 1113 } 1114 String userHome = System.getProperty(PROP_USER_HOME); 1115 return new File (userHome, appName + "/" + pathAppendage).getAbsolutePath(); } 1117 1118 1123 public static void main(String argString) { 1124 Vector list = new Vector(5); 1125 for (StringTokenizer tokens = new StringTokenizer(argString, " "); tokens.hasMoreElements();) list.addElement(tokens.nextElement()); 1127 main((String []) list.toArray(new String [list.size()])); 1128 } 1129 1130 1145 public static void main(String [] args) { 1146 int result = 0; 1147 try { 1148 result = new Main().run(args); 1149 } catch (Throwable t) { 1150 t.printStackTrace(); 1153 } finally { 1154 if (!Boolean.getBoolean(PROP_NOSHUTDOWN)) 1155 System.exit(result); 1157 } 1158 } 1159 1160 1161 1170 public int run(String [] args) { 1171 int result = 0; 1172 try { 1173 basicRun(args); 1174 String exitCode = System.getProperty(PROP_EXITCODE); 1175 try { 1176 result = exitCode == null ? 0 : Integer.parseInt(exitCode); 1177 } catch (NumberFormatException e) { 1178 result = 17; 1179 } 1180 } catch (Throwable e) { 1181 if (!"13".equals(System.getProperty(PROP_EXITCODE))) { log("Exception launching the Eclipse Platform:"); log(e); 1186 String message = "An error has occurred"; if (logFile == null) 1188 message += " and could not be logged: \n" + e.getMessage(); else 1190 message += ". See the log file\n" + logFile.getAbsolutePath(); System.getProperties().put(PROP_EXITDATA, message); 1192 } 1193 result = 13; 1197 } finally { 1198 takeDownSplash(); 1200 if(bridge != null) 1201 bridge.uninitialize(); 1202 } 1203 System.getProperties().put(PROP_EXITCODE, Integer.toString(result)); 1205 setExitData(); 1206 return result; 1207 } 1208 1209 private void setExitData() { 1210 String data = System.getProperty(PROP_EXITDATA); 1211 if (data == null || bridge == null) 1212 return; 1213 bridge.setExitData(exitData, data); 1214 } 1215 1216 1225 protected String [] processCommandLine(String [] args) { 1226 if (args.length == 0) 1227 return args; 1228 int[] configArgs = new int[args.length]; 1229 configArgs[0] = -1; int configArgIndex = 0; 1231 for (int i = 0; i < args.length; i++) { 1232 boolean found = false; 1233 if (args[i].equalsIgnoreCase(DEBUG)) { 1236 debug = true; 1237 continue; 1239 } 1240 1241 if (args[i].equalsIgnoreCase(NOSPLASH)) { 1244 splashDown = true; 1245 found = true; 1246 } 1247 1248 if (args[i].equalsIgnoreCase(NOEXIT)) { 1249 System.getProperties().put(PROP_NOSHUTDOWN, "true"); found = true; 1251 } 1252 1253 if (args[i].equalsIgnoreCase(INITIALIZE)) { 1255 initialize = true; 1256 continue; 1258 } 1259 1260 if (args[i].equalsIgnoreCase(DEV) && ((i + 1 == args.length) || ((i + 1 < args.length) && (args[i + 1].startsWith("-"))))) { inDevelopmentMode = true; 1266 continue; 1268 } 1269 1270 if (args[i].equalsIgnoreCase(SHOWSPLASH)) { 1272 showSplash = true; 1273 found = true; 1274 if (i + 1 < args.length && !args[i+1].startsWith("-")) { configArgs[configArgIndex++] = i++; 1277 splashLocation = args[i]; 1278 } 1279 } 1280 1281 if (found) { 1283 configArgs[configArgIndex++] = i; 1284 continue; 1285 } 1286 1287 if (args[i].equalsIgnoreCase(VMARGS)) { 1291 args[i] = null; 1293 i++; 1294 vmargs = new String [args.length - i]; 1295 for (int j = 0; i < args.length; i++) { 1296 vmargs[j++] = args[i]; 1297 args[i] = null; 1298 } 1299 continue; 1300 } 1301 1302 if (i == args.length - 1 || args[i + 1].startsWith("-")) continue; 1306 String arg = args[++i]; 1307 1308 if (args[i - 1].equalsIgnoreCase(DEV)) { 1310 inDevelopmentMode = true; 1311 devClassPathProps = processDevArg(arg); 1312 if (devClassPathProps != null) { 1313 devClassPath = devClassPathProps.getProperty(OSGI); 1314 if (devClassPath == null) 1315 devClassPath = devClassPathProps.getProperty("*"); } 1317 continue; 1318 } 1319 1320 if (args[i - 1].equalsIgnoreCase(FRAMEWORK)) { 1322 framework = arg; 1323 found = true; 1324 } 1325 1326 if (args[i - 1].equalsIgnoreCase(OS)) { 1327 os = arg; 1328 continue; 1330 } 1331 1332 if (args[i - 1].equalsIgnoreCase(WS)) { 1333 ws = arg; 1334 continue; 1335 } 1336 1337 if (args[i - 1].equalsIgnoreCase(ARCH)) { 1338 arch = arg; 1339 continue; 1340 } 1341 1342 if (args[i - 1].equalsIgnoreCase(INSTALL)) { 1346 System.getProperties().put(PROP_INSTALL_AREA, arg); 1347 found = true; 1348 } 1349 1350 if (args[i - 1].equalsIgnoreCase(CONFIGURATION)) { 1354 System.getProperties().put(PROP_CONFIG_AREA, arg); 1355 found = true; 1356 } 1357 1358 if (args[i - 1].equalsIgnoreCase(EXITDATA)) { 1359 exitData = arg; 1360 found = true; 1361 } 1362 1363 if (args[i - 1].equalsIgnoreCase(NAME)) { 1365 found = true; 1368 } 1369 1370 if (args[i - 1].equalsIgnoreCase(STARTUP)) { 1372 found = true; 1375 } 1376 1377 if (args[i - 1].equalsIgnoreCase(LAUNCHER)) { 1379 found = true; 1382 } 1383 1384 if (args[i - 1].equalsIgnoreCase(LIBRARY)) { 1385 library = arg; 1386 found = true; 1387 } 1388 1389 if (args[i - 1].equalsIgnoreCase(ENDSPLASH)) { 1391 endSplash = arg; 1392 found = true; 1393 } 1394 1395 if (args[i - 1].equalsIgnoreCase(VM)) { 1397 vm = arg; 1398 found = true; 1399 } 1400 1401 if (args[i - 1].equalsIgnoreCase(NL)) { 1403 System.getProperties().put(PROP_NL, arg); 1404 found = true; 1405 } 1406 1407 if (found) { 1409 configArgs[configArgIndex++] = i - 1; 1410 configArgs[configArgIndex++] = i; 1411 } 1412 } 1413 String [] passThruArgs = new String [args.length - configArgIndex - (vmargs == null ? 0 : vmargs.length + 1)]; 1415 configArgIndex = 0; 1416 int j = 0; 1417 for (int i = 0; i < args.length; i++) { 1418 if (i == configArgs[configArgIndex]) 1419 configArgIndex++; 1420 else if (args[i] != null) 1421 passThruArgs[j++] = args[i]; 1422 } 1423 return passThruArgs; 1424 } 1425 1426 private Properties processDevArg(String arg) { 1427 if (arg == null) 1428 return null; 1429 try { 1430 URL location = new URL(arg); 1431 return load(location, null); 1432 } catch (MalformedURLException e) { 1433 Properties result = new Properties(); 1435 result.put("*", arg); return result; 1437 } catch (IOException e) { 1438 return null; 1440 } 1441 } 1442 1443 private URL getConfigurationLocation() { 1444 if (configurationLocation != null) 1445 return configurationLocation; 1446 configurationLocation = buildLocation(PROP_CONFIG_AREA, null, ""); if (configurationLocation == null) { 1448 configurationLocation = buildLocation(PROP_CONFIG_AREA_DEFAULT, null, ""); if (configurationLocation == null) 1450 configurationLocation = buildURL(computeDefaultConfigurationLocation(), true); 1451 } 1452 if (configurationLocation != null) 1453 System.getProperties().put(PROP_CONFIG_AREA, configurationLocation.toExternalForm()); 1454 if (debug) 1455 System.out.println("Configuration location:\n " + configurationLocation); return configurationLocation; 1457 } 1458 1459 private void processConfiguration() { 1460 URL baseConfigurationLocation = null; 1466 Properties baseConfiguration = null; 1467 if (System.getProperty(PROP_CONFIG_AREA) == null) { 1468 String baseLocation = System.getProperty(PROP_BASE_CONFIG_AREA); 1469 if (baseLocation != null) 1470 baseConfigurationLocation = buildURL(baseLocation, true); 1473 if (baseConfigurationLocation == null) 1474 try { 1475 baseConfigurationLocation = new URL(getInstallLocation(), CONFIG_DIR); 1479 } catch (MalformedURLException e) { 1480 } 1482 baseConfiguration = loadConfiguration(baseConfigurationLocation); 1483 if (baseConfiguration != null) { 1484 String location = baseConfiguration.getProperty(PROP_CONFIG_AREA); 1487 if (location != null) 1488 System.getProperties().put(PROP_CONFIG_AREA, location); 1489 location = baseConfiguration.getProperty(PROP_INSTALL_AREA); 1493 if (location != null && System.getProperty(PROP_INSTALL_AREA) == null) 1494 System.getProperties().put(PROP_INSTALL_AREA, location); 1495 } 1496 } 1497 1498 Properties configuration = baseConfiguration; 1506 if (configuration == null || !getConfigurationLocation().equals(baseConfigurationLocation)) 1507 configuration = loadConfiguration(getConfigurationLocation()); 1508 mergeProperties(System.getProperties(), configuration); 1509 if ("false".equalsIgnoreCase(System.getProperty(PROP_CONFIG_CASCADED))) System.getProperties().remove(PROP_SHARED_CONFIG_AREA); 1512 else { 1513 ensureAbsolute(PROP_SHARED_CONFIG_AREA); 1514 URL sharedConfigURL = buildLocation(PROP_SHARED_CONFIG_AREA, null, ""); if (sharedConfigURL == null) 1516 try { 1517 sharedConfigURL = new URL(getInstallLocation(), CONFIG_DIR); 1519 } catch (MalformedURLException e) { 1520 } 1522 if (sharedConfigURL != null) { 1524 if (sharedConfigURL.equals(getConfigurationLocation())) 1525 System.getProperties().remove(PROP_SHARED_CONFIG_AREA); 1527 else { 1528 configuration = baseConfiguration; 1531 if (!sharedConfigURL.equals(baseConfigurationLocation)) 1532 configuration = loadConfiguration(sharedConfigURL); 1533 mergeProperties(System.getProperties(), configuration); 1534 System.getProperties().put(PROP_SHARED_CONFIG_AREA, sharedConfigURL.toExternalForm()); 1535 if (debug) 1536 System.out.println("Shared configuration location:\n " + sharedConfigURL.toExternalForm()); } 1538 } 1539 } 1540 String urlString = System.getProperty(PROP_FRAMEWORK, null); 1542 if (urlString != null) { 1543 URL url = buildURL(urlString, true); 1544 System.getProperties().put(PROP_FRAMEWORK, url.toExternalForm()); 1545 bootLocation = resolve(urlString); 1546 } 1547 } 1548 1549 1555 private void ensureAbsolute(String locationProperty) { 1556 String propertyValue = System.getProperty(locationProperty); 1557 if (propertyValue == null) 1558 return; 1560 URL locationURL = null; 1561 try { 1562 locationURL = new URL(propertyValue); 1563 } catch (MalformedURLException e) { 1564 return; 1566 } 1567 String locationPath = locationURL.getPath(); 1568 if (locationPath.startsWith("/")) return; 1571 URL installURL = getInstallLocation(); 1572 if (!locationURL.getProtocol().equals(installURL.getProtocol())) 1573 return; 1575 try { 1576 URL absoluteURL = new URL(installURL, locationPath); 1577 System.getProperties().put(locationProperty, absoluteURL.toExternalForm()); 1578 } catch (MalformedURLException e) { 1579 } 1581 } 1582 1583 1586 private URL getInstallLocation() { 1587 if (installLocation != null) 1588 return installLocation; 1589 1590 String installArea = System.getProperty(PROP_INSTALL_AREA); 1592 if (installArea != null) { 1593 installLocation = buildURL(installArea, true); 1594 if (installLocation == null) 1595 throw new IllegalStateException ("Install location is invalid: " + installArea); System.getProperties().put(PROP_INSTALL_AREA, installLocation.toExternalForm()); 1597 if (debug) 1598 System.out.println("Install location:\n " + installLocation); return installLocation; 1600 } 1601 1602 ProtectionDomain domain = Main.class.getProtectionDomain(); 1603 CodeSource source = null; 1604 URL result = null; 1605 if (domain != null) 1606 source = domain.getCodeSource(); 1607 if (source == null || domain == null) { 1608 if (debug) 1609 System.out.println("CodeSource location is null. Defaulting the install location to file:startup.jar"); try { 1611 result = new URL("file:startup.jar"); } catch (MalformedURLException e2) { 1613 } 1615 } 1616 if (source != null) 1617 result = source.getLocation(); 1618 1619 String path = decode(result.getFile()); 1620 File file = new File (path); 1622 path = file.toString().replace('\\', '/'); 1623 if (File.separatorChar == '\\') 1627 if (Character.isUpperCase(path.charAt(0))) { 1628 char[] chars = path.toCharArray(); 1629 chars[0] = Character.toLowerCase(chars[0]); 1630 path = new String (chars); 1631 } 1632 if (path.toLowerCase().endsWith(".jar")) path = path.substring(0, path.lastIndexOf("/") + 1); if (path.toLowerCase().endsWith("/plugins/")) path = path.substring(0, path.length() - "/plugins/".length()); try { 1637 try { 1638 path = new File (path).toURL().getFile(); 1641 } catch (MalformedURLException e1) { 1642 } 1644 installLocation = new URL(result.getProtocol(), result.getHost(), result.getPort(), path); 1645 System.getProperties().put(PROP_INSTALL_AREA, installLocation.toExternalForm()); 1646 } catch (MalformedURLException e) { 1647 } 1649 if (debug) 1650 System.out.println("Install location:\n " + installLocation); return installLocation; 1652 } 1653 1654 1657 private Properties loadConfiguration(URL url) { 1658 Properties result = null; 1659 try { 1660 url = new URL(url, CONFIG_FILE); 1661 } catch (MalformedURLException e) { 1662 return null; 1663 } 1664 try { 1665 if (debug) 1666 System.out.print("Configuration file:\n " + url.toString()); result = loadProperties(url); 1668 if (debug) 1669 System.out.println(" loaded"); } catch (IOException e) { 1671 if (debug) 1672 System.out.println(" not found or not read"); } 1674 return result; 1675 } 1676 1677 private Properties loadProperties(URL url) throws IOException { 1678 if (url == null) 1680 return null; 1681 Properties result = null; 1682 IOException originalException = null; 1683 try { 1684 result = load(url, null); } catch (IOException e1) { 1686 originalException = e1; 1687 try { 1688 result = load(url, CONFIG_FILE_TEMP_SUFFIX); } catch (IOException e2) { 1690 try { 1691 result = load(url, CONFIG_FILE_BAK_SUFFIX); } catch (IOException e3) { 1693 throw originalException; } 1695 } 1696 } 1697 return result; 1698 } 1699 1700 1703 private Properties load(URL url, String suffix) throws IOException { 1704 if (suffix != null && !suffix.equals("")) url = new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile() + suffix); 1707 1708 Properties props = new Properties(); 1710 InputStream is = null; 1711 try { 1712 is = url.openStream(); 1713 props.load(is); 1714 } finally { 1715 if (is != null) 1716 try { 1717 is.close(); 1718 } catch (IOException e) { 1719 } 1721 } 1722 return props; 1723 } 1724 1725 1747 private void handleSplash(URL[] defaultPath) { 1748 if (initialize || splashDown || bridge == null) { 1751 showSplash = false; 1752 endSplash = null; 1753 return; 1754 } 1755 1756 if (showSplash || endSplash != null) { 1757 try { 1760 Runtime.getRuntime().addShutdownHook(splashHandler); 1761 } catch(Throwable ex) { 1762 } 1764 } 1765 1766 if (endSplash != null) { 1768 showSplash = false; 1769 return; 1770 } 1771 1772 if (!showSplash) 1774 return; 1775 1776 splashLocation = getSplashLocation(defaultPath); 1778 if (debug) 1779 System.out.println("Splash location:\n " + splashLocation); if (splashLocation == null) 1781 return; 1782 1783 bridge.showSplash(splashLocation); 1784 long handle = bridge.getSplashHandle(); 1785 if(handle != 0 && handle != -1) { 1786 System.getProperties().put(SPLASH_HANDLE, String.valueOf(handle)); 1787 System.getProperties().put(SPLASH_LOCATION, splashLocation); 1788 bridge.updateSplash(); 1789 } 1790 } 1791 1792 1795 protected void takeDownSplash() { 1796 if (splashDown || bridge == null) return; 1798 1799 splashDown = bridge.takeDownSplash(); 1800 System.getProperties().remove(SPLASH_HANDLE); 1801 1802 try { 1803 Runtime.getRuntime().removeShutdownHook(splashHandler); 1804 } catch (Throwable e) { 1805 } 1807 } 1808 1809 1814 private String getSplashLocation(URL[] bootPath) { 1815 if(splashLocation != null && !Character.isDigit(splashLocation.charAt(0)) && new File (splashLocation).exists()) { 1818 System.getProperties().put(PROP_SPLASHLOCATION, splashLocation); 1819 return splashLocation; 1820 } 1821 String result = System.getProperty(PROP_SPLASHLOCATION); 1822 if (result != null) 1823 return result; 1824 String splashPath = System.getProperty(PROP_SPLASHPATH); 1825 if (splashPath != null) { 1826 String [] entries = getArrayFromList(splashPath); 1827 ArrayList path = new ArrayList(entries.length); 1828 for (int i = 0; i < entries.length; i++) { 1829 String entry = resolve(entries[i]); 1830 if (entry == null || entry.startsWith(FILE_SCHEME)) { 1831 File entryFile = new File (entry.substring(5).replace('/', File.separatorChar)); 1832 entry = searchFor(entryFile.getName(), entryFile.getParent()); 1833 if (entry != null) 1834 path.add(entry); 1835 } else 1836 log("Invalid splash path entry: " + entries[i]); } 1838 result = searchForSplash((String []) path.toArray(new String [path.size()])); 1840 if (result != null) { 1841 System.getProperties().put(PROP_SPLASHLOCATION, result); 1842 return result; 1843 } 1844 } 1845 1846 String temp = bootPath[0].getFile(); temp = temp.replace('/', File.separatorChar); 1849 int ix = temp.lastIndexOf("plugins" + File.separator); if (ix != -1) { 1851 int pix = temp.indexOf(File.separator, ix + 8); 1852 if (pix != -1) { 1853 temp = temp.substring(0, pix); 1854 result = searchForSplash(new String [] {temp}); 1855 if (result != null) 1856 System.getProperties().put(PROP_SPLASHLOCATION, result); 1857 } 1858 } 1859 return result; 1860 } 1861 1862 1865 private String searchForSplash(String [] searchPath) { 1866 if (searchPath == null) 1867 return null; 1868 1869 String locale = (String ) System.getProperties().get(PROP_NL); 1871 if (locale == null) 1872 locale = Locale.getDefault().toString(); 1873 String [] nlVariants = buildNLVariants(locale); 1874 1875 for (int i=0; i<nlVariants.length; i++) { 1876 for (int j=0; j<searchPath.length; j++) { 1877 if (isJAR(searchPath[j])) { 1879 String result = extractSplashFromJAR(searchPath[j], nlVariants[i]); 1880 if (result != null) 1881 return result; 1882 } else { 1883 String path = searchPath[j]; 1885 if (!path.endsWith(File.separator)) 1886 path += File.separator; 1887 path += nlVariants[i]; 1888 File result = new File (path); 1889 if (result.exists()) 1890 return result.getAbsolutePath(); } 1892 } 1893 } 1894 1895 return null; 1897 } 1898 1899 1903 private static void transferStreams(InputStream source, OutputStream destination) { 1904 byte[] buffer = new byte[8096]; 1905 try { 1906 while (true) { 1907 int bytesRead = -1; 1908 try { 1909 bytesRead = source.read(buffer); 1910 } catch (IOException e) { 1911 return; 1912 } 1913 if (bytesRead == -1) 1914 break; 1915 try { 1916 destination.write(buffer, 0, bytesRead); 1917 } catch (IOException e) { 1918 return; 1919 } 1920 } 1921 } finally { 1922 try { 1923 source.close(); 1924 } catch (IOException e) { 1925 } finally { 1927 try { 1929 destination.close(); 1930 } catch (IOException e) { 1931 } 1933 } 1934 } 1935 } 1936 1937 1941 private String extractSplashFromJAR(String jarPath, String splashPath) { 1942 String configLocation = System.getProperty(PROP_CONFIG_AREA); 1943 if (configLocation == null) { 1944 log("Configuration area not set yet. Unable to extract splash from JAR'd plug-in: " + jarPath); return null; 1946 } 1947 URL configURL = buildURL(configLocation, false); 1948 if (configURL == null) 1949 return null; 1950 File splash = new File (configURL.getPath(), PLUGIN_ID); 1952 File jarFile = new File (jarPath); 1954 String cache = jarFile.getName(); 1955 if(cache.endsWith(".jar")) cache = cache.substring(0, cache.length() - 4); 1957 splash = new File (splash, cache); 1958 splash = new File (splash, splashPath); 1959 if (splash.exists()) { 1961 boolean clean = false; 1963 for (int i=0; i<commands.length; i++) { 1964 if (CLEAN.equalsIgnoreCase(commands[i])) { 1965 clean = true; 1966 splash.delete(); 1967 break; 1968 } 1969 } 1970 if (!clean) 1971 return splash.getAbsolutePath(); 1972 } 1973 ZipFile file; 1974 try { 1975 file = new ZipFile (jarPath); 1976 } catch (IOException e) { 1977 log("Exception looking for splash in JAR file: " + jarPath); log(e); 1979 return null; 1980 } 1981 ZipEntry entry = file.getEntry(splashPath.replace(File.separatorChar, '/')); 1982 if (entry == null) 1983 return null; 1984 InputStream input = null; 1985 try { 1986 input = file.getInputStream(entry); 1987 } catch (IOException e) { 1988 log("Exception opening splash: " + entry.getName() + " in JAR file: " + jarPath); log(e); 1990 return null; 1991 } 1992 new File (splash.getParent()).mkdirs(); 1993 OutputStream output; 1994 try { 1995 output = new BufferedOutputStream(new FileOutputStream(splash)); 1996 } catch (FileNotFoundException e) { 1997 try { 1998 input.close(); 1999 } catch (IOException e1) { 2000 } 2002 return null; 2003 } 2004 transferStreams(input, output); 2005 return splash.exists() ? splash.getAbsolutePath() : null; 2006 } 2007 2008 2012 private boolean isJAR(String path) { 2013 if (path.endsWith(File.separator)) 2014 return false; 2015 int index = path.lastIndexOf('.'); 2016 if (index == -1) 2017 return false; 2018 index++; 2019 if (index >= path.length()) 2021 return false; 2022 return "JAR".equalsIgnoreCase(path.substring(index)); } 2024 2025 2032 private static String [] buildNLVariants(String locale) { 2033 String nl = locale; 2035 ArrayList result = new ArrayList(4); 2036 int lastSeparator; 2037 while (true) { 2038 result.add("nl" + File.separatorChar + nl.replace('_', File.separatorChar) + File.separatorChar + SPLASH_IMAGE); lastSeparator = nl.lastIndexOf('_'); 2040 if (lastSeparator == -1) 2041 break; 2042 nl = nl.substring(0, lastSeparator); 2043 } 2044 result.add(SPLASH_IMAGE); 2046 return (String []) result.toArray(new String [result.size()]); 2047 } 2048 2049 2052 private String resolve(String urlString) { 2053 if (urlString.startsWith(REFERENCE_SCHEME)) { 2055 urlString = urlString.substring(10); 2056 System.getProperties().put(PROP_FRAMEWORK, urlString); 2057 } 2058 if (urlString.startsWith(PLATFORM_URL)) { 2059 String path = urlString.substring(PLATFORM_URL.length()); 2060 return getInstallLocation() + path; 2061 } 2062 return urlString; 2063 } 2064 2065 2068 protected synchronized void log(Object obj) { 2069 if (obj == null) 2070 return; 2071 try { 2072 openLogFile(); 2073 try { 2074 if (newSession) { 2075 log.write(SESSION); 2076 log.write(' '); 2077 String timestamp = new Date().toString(); 2078 log.write(timestamp); 2079 log.write(' '); 2080 for (int i = SESSION.length() + timestamp.length(); i < 78; i++) 2081 log.write('-'); 2082 log.newLine(); 2083 newSession = false; 2084 } 2085 write(obj); 2086 } finally { 2087 if (logFile == null) { 2088 if (log != null) 2089 log.flush(); 2090 } else 2091 closeLogFile(); 2092 } 2093 } catch (Exception e) { 2094 System.err.println("An exception occurred while writing to the platform log:"); e.printStackTrace(System.err); 2096 System.err.println("Logging to the console instead."); try { 2099 log = logForStream(System.err); 2100 write(obj); 2101 log.flush(); 2102 } catch (Exception e2) { 2103 System.err.println("An exception occurred while logging to the console:"); e2.printStackTrace(System.err); 2105 } 2106 } finally { 2107 log = null; 2108 } 2109 } 2110 2111 2114 private void write(Object obj) throws IOException { 2115 if (obj == null) 2116 return; 2117 if (obj instanceof Throwable ) { 2118 log.write(STACK); 2119 log.newLine(); 2120 ((Throwable ) obj).printStackTrace(new PrintWriter(log)); 2121 } else { 2122 log.write(ENTRY); 2123 log.write(' '); 2124 log.write(PLUGIN_ID); 2125 log.write(' '); 2126 log.write(String.valueOf(ERROR)); 2127 log.write(' '); 2128 log.write(String.valueOf(0)); 2129 log.write(' '); 2130 log.write(getDate(new Date())); 2131 log.newLine(); 2132 log.write(MESSAGE); 2133 log.write(' '); 2134 log.write(String.valueOf(obj)); 2135 } 2136 log.newLine(); 2137 } 2138 2139 protected String getDate(Date date) { 2140 Calendar c = Calendar.getInstance(); 2141 c.setTime(date); 2142 StringBuffer sb = new StringBuffer (); 2143 appendPaddedInt(c.get(Calendar.YEAR), 4, sb).append('-'); 2144 appendPaddedInt(c.get(Calendar.MONTH) + 1, 2, sb).append('-'); 2145 appendPaddedInt(c.get(Calendar.DAY_OF_MONTH), 2, sb).append(' '); 2146 appendPaddedInt(c.get(Calendar.HOUR_OF_DAY), 2, sb).append(':'); 2147 appendPaddedInt(c.get(Calendar.MINUTE), 2, sb).append(':'); 2148 appendPaddedInt(c.get(Calendar.SECOND), 2, sb).append('.'); 2149 appendPaddedInt(c.get(Calendar.MILLISECOND), 3, sb); 2150 return sb.toString(); 2151 } 2152 2153 private StringBuffer appendPaddedInt(int value, int pad, StringBuffer buffer) { 2154 pad = pad - 1; 2155 if (pad == 0) 2156 return buffer.append(Integer.toString(value)); 2157 int padding = (int) Math.pow(10, pad); 2158 if (value >= padding) 2159 return buffer.append(Integer.toString(value)); 2160 while (padding > value && padding > 1) { 2161 buffer.append('0'); 2162 padding = padding / 10; 2163 } 2164 buffer.append(value); 2165 return buffer; 2166 } 2167 2168 private void computeLogFileLocation() { 2169 String logFileProp = System.getProperty(PROP_LOGFILE); 2170 if (logFileProp != null) { 2171 if (logFile == null || !logFileProp.equals(logFile.getAbsolutePath())) { 2172 logFile = new File (logFileProp); 2173 new File (logFile.getParent()).mkdirs(); 2174 } 2175 return; 2176 } 2177 2178 URL base = buildURL(System.getProperty(PROP_CONFIG_AREA), false); 2180 if (base == null) 2181 return; 2182 logFile = new File (base.getPath(), Long.toString(System.currentTimeMillis()) + ".log"); new File (logFile.getParent()).mkdirs(); 2184 System.getProperties().put(PROP_LOGFILE, logFile.getAbsolutePath()); 2185 } 2186 2187 2191 private int hexToByte(byte b) { 2192 switch (b) { 2193 case '0' : 2194 return 0; 2195 case '1' : 2196 return 1; 2197 case '2' : 2198 return 2; 2199 case '3' : 2200 return 3; 2201 case '4' : 2202 return 4; 2203 case '5' : 2204 return 5; 2205 case '6' : 2206 return 6; 2207 case '7' : 2208 return 7; 2209 case '8' : 2210 return 8; 2211 case '9' : 2212 return 9; 2213 case 'A' : 2214 case 'a' : 2215 return 10; 2216 case 'B' : 2217 case 'b' : 2218 return 11; 2219 case 'C' : 2220 case 'c' : 2221 return 12; 2222 case 'D' : 2223 case 'd' : 2224 return 13; 2225 case 'E' : 2226 case 'e' : 2227 return 14; 2228 case 'F' : 2229 case 'f' : 2230 return 15; 2231 default : 2232 throw new IllegalArgumentException ("Switch error decoding URL"); } 2234 } 2235 2236 private void openLogFile() throws IOException { 2237 computeLogFileLocation(); 2238 try { 2239 log = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(logFile.getAbsolutePath(), true), "UTF-8")); } catch (IOException e) { 2241 logFile = null; 2242 throw e; 2243 } 2244 } 2245 2246 private BufferedWriter logForStream(OutputStream output) { 2247 try { 2248 return new BufferedWriter(new OutputStreamWriter(output, "UTF-8")); } catch (UnsupportedEncodingException e) { 2250 return new BufferedWriter(new OutputStreamWriter(output)); 2251 } 2252 } 2253 2254 private void closeLogFile() throws IOException { 2255 try { 2256 if (log != null) { 2257 log.flush(); 2258 log.close(); 2259 } 2260 } finally { 2261 log = null; 2262 } 2263 } 2264 2265 private void mergeProperties(Properties destination, Properties source) { 2266 if (destination == null || source == null) 2267 return; 2268 for (Enumeration e = source.keys(); e.hasMoreElements();) { 2269 String key = (String ) e.nextElement(); 2270 if (key.equals(PROP_CLASSPATH)) { 2271 String destinationClasspath = destination.getProperty(PROP_CLASSPATH); 2272 String sourceClasspath = source.getProperty(PROP_CLASSPATH); 2273 if (destinationClasspath == null) 2274 destinationClasspath = sourceClasspath; 2275 else 2276 destinationClasspath = destinationClasspath + sourceClasspath; 2277 destination.put(PROP_CLASSPATH, destinationClasspath); 2278 continue; 2279 } 2280 String value = source.getProperty(key); 2281 if (destination.getProperty(key) == null) 2282 destination.put(key, value); 2283 } 2284 } 2285 2286 private void setupVMProperties() { 2287 if (vm != null) 2288 System.getProperties().put(PROP_VM, vm); 2289 setMultiValueProperty(PROP_VMARGS, vmargs); 2290 setMultiValueProperty(PROP_COMMANDS, commands); 2291 } 2292 2293 private void setMultiValueProperty(String property, String [] value) { 2294 if (value != null) { 2295 StringBuffer result = new StringBuffer (300); 2296 for (int i = 0; i < value.length; i++) { 2297 if (value[i] != null) { 2298 result.append(value[i]); 2299 result.append('\n'); 2300 } 2301 } 2302 System.getProperties().put(property, result.toString()); 2303 } 2304 } 2305 2306 2319 private class EclipsePolicy extends Policy { 2320 private Policy policy; 2322 2323 private URL[] urls; 2325 2326 private PermissionCollection allPermissions; 2328 2329 Permission allPermission = new AllPermission(); 2331 2332 EclipsePolicy(Policy policy, URL[] urls) { 2333 this.policy = policy; 2334 this.urls = urls; 2335 allPermissions = new PermissionCollection() { 2336 private static final long serialVersionUID = 3258131349494708277L; 2337 2338 public void add(Permission permission) { 2340 } 2342 2343 public boolean implies(Permission permission) { 2344 return true; 2345 } 2346 2347 public Enumeration elements() { 2348 return new Enumeration() { 2349 int cur = 0; 2350 2351 public boolean hasMoreElements() { 2352 return cur < 1; 2353 } 2354 2355 public Object nextElement() { 2356 if (cur == 0) { 2357 cur = 1; 2358 return allPermission; 2359 } 2360 throw new NoSuchElementException(); 2361 } 2362 }; 2363 } 2364 }; 2365 } 2366 2367 public PermissionCollection getPermissions(CodeSource codesource) { 2368 if (contains(codesource.getLocation())) 2369 return allPermissions; 2370 return policy == null ? allPermissions : policy.getPermissions(codesource); 2371 } 2372 2373 public PermissionCollection getPermissions(ProtectionDomain domain) { 2374 if (contains(domain.getCodeSource().getLocation())) 2375 return allPermissions; 2376 return policy == null ? allPermissions : policy.getPermissions(domain); 2377 } 2378 2379 public boolean implies(ProtectionDomain domain, Permission permission) { 2380 if (contains(domain.getCodeSource().getLocation())) 2381 return true; 2382 return policy == null ? true : policy.implies(domain, permission); 2383 } 2384 2385 public void refresh() { 2386 if (policy != null) 2387 policy.refresh(); 2388 } 2389 2390 private boolean contains(URL url) { 2391 for (int i = 0; i < urls.length; i++) { 2393 if (urls[i] == url) 2395 return true; 2396 } 2397 return false; 2398 } 2399 } 2400 2401 private class StartupClassLoader extends URLClassLoader { 2402 2403 public StartupClassLoader(URL[] urls) { 2404 super(urls); 2405 } 2406 2407 public StartupClassLoader(URL[] urls, ClassLoader parent) { 2408 super(urls, parent); 2409 } 2410 2411 public StartupClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) { 2412 super(urls, parent, factory); 2413 } 2414 2415 protected String findLibrary(String name) { 2416 if (extensionPaths == null) 2417 return super.findLibrary(name); 2418 String libName = System.mapLibraryName(name); 2419 for (int i = 0; i < extensionPaths.length; i++) { 2420 File libFile = new File (extensionPaths[i], libName); 2421 if (libFile.isFile()) 2422 return libFile.getAbsolutePath(); 2423 } 2424 return super.findLibrary(name); 2425 } 2426 } 2427} 2428 | Popular Tags |