1 12 package org.eclipse.core.runtime.adaptor; 13 14 import java.io.*; 15 import java.lang.reflect.Constructor ; 16 import java.lang.reflect.Method ; 17 import java.net.*; 18 import java.security.CodeSource ; 19 import java.security.ProtectionDomain ; 20 import java.util.*; 21 import org.eclipse.core.runtime.internal.adaptor.*; 22 import org.eclipse.osgi.framework.adaptor.FilePath; 23 import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor; 24 import org.eclipse.osgi.framework.internal.core.*; 25 import org.eclipse.osgi.framework.internal.core.Constants; 26 import org.eclipse.osgi.framework.log.FrameworkLog; 27 import org.eclipse.osgi.framework.log.FrameworkLogEntry; 28 import org.eclipse.osgi.internal.profile.Profile; 29 import org.eclipse.osgi.service.datalocation.Location; 30 import org.eclipse.osgi.service.resolver.*; 31 import org.eclipse.osgi.service.runnable.ApplicationLauncher; 32 import org.eclipse.osgi.service.runnable.StartupMonitor; 33 import org.eclipse.osgi.util.ManifestElement; 34 import org.eclipse.osgi.util.NLS; 35 import org.osgi.framework.*; 36 import org.osgi.service.packageadmin.PackageAdmin; 37 import org.osgi.service.startlevel.StartLevel; 38 import org.osgi.util.tracker.ServiceTracker; 39 40 55 public class EclipseStarter { 56 private static FrameworkAdaptor adaptor; 57 private static BundleContext context; 58 private static boolean initialize = false; 59 public static boolean debug = false; 60 private static boolean running = false; 61 private static OSGi osgi = null; 62 private static ServiceRegistration defaultMonitorRegistration = null; 63 private static ServiceRegistration appLauncherRegistration = null; 64 private static ServiceRegistration splashStreamRegistration = null; 65 66 private static final String CLEAN = "-clean"; private static final String CONSOLE = "-console"; private static final String CONSOLE_LOG = "-consoleLog"; private static final String DEBUG = "-debug"; private static final String INITIALIZE = "-initialize"; private static final String DEV = "-dev"; private static final String WS = "-ws"; private static final String OS = "-os"; private static final String ARCH = "-arch"; private static final String NL = "-nl"; private static final String CONFIGURATION = "-configuration"; private static final String USER = "-user"; private static final String NOEXIT = "-noExit"; 81 private static final String DATA = "-data"; 85 public static final String PROP_BUNDLES = "osgi.bundles"; public static final String PROP_BUNDLES_STARTLEVEL = "osgi.bundles.defaultStartLevel"; public static final String PROP_EXTENSIONS = "osgi.framework.extensions"; public static final String PROP_INITIAL_STARTLEVEL = "osgi.startLevel"; public static final String PROP_DEBUG = "osgi.debug"; public static final String PROP_DEV = "osgi.dev"; public static final String PROP_CLEAN = "osgi.clean"; public static final String PROP_CONSOLE = "osgi.console"; public static final String PROP_CONSOLE_CLASS = "osgi.consoleClass"; public static final String PROP_CHECK_CONFIG = "osgi.checkConfiguration"; public static final String PROP_OS = "osgi.os"; public static final String PROP_WS = "osgi.ws"; public static final String PROP_NL = "osgi.nl"; public static final String PROP_ARCH = "osgi.arch"; public static final String PROP_ADAPTOR = "osgi.adaptor"; public static final String PROP_SYSPATH = "osgi.syspath"; public static final String PROP_LOGFILE = "osgi.logfile"; public static final String PROP_FRAMEWORK = "osgi.framework"; public static final String PROP_INSTALL_AREA = "osgi.install.area"; public static final String PROP_FRAMEWORK_SHAPE = "osgi.framework.shape"; public static final String PROP_NOSHUTDOWN = "osgi.noShutdown"; private static final String PROP_FORCED_RESTART = "osgi.forcedRestart"; 109 public static final String PROP_EXITCODE = "eclipse.exitcode"; public static final String PROP_EXITDATA = "eclipse.exitdata"; public static final String PROP_CONSOLE_LOG = "eclipse.consoleLog"; public static final String PROP_IGNOREAPP = "eclipse.ignoreApp"; public static final String PROP_REFRESH_BUNDLES = "eclipse.refreshBundles"; private static final String PROP_ALLOW_APPRELAUNCH = "eclipse.allowAppRelaunch"; private static final String PROP_APPLICATION_LAUNCHDEFAULT = "eclipse.application.launchDefault"; 117 private static final String FILE_SCHEME = "file:"; private static final String REFERENCE_SCHEME = "reference:"; private static final String REFERENCE_PROTOCOL = "reference"; private static final String INITIAL_LOCATION = "initial@"; 122 protected static final String DEFAULT_ADAPTOR_CLASS = "org.eclipse.osgi.baseadaptor.BaseAdaptor"; 124 private static final int DEFAULT_INITIAL_STARTLEVEL = 6; private static final String DEFAULT_BUNDLES_STARTLEVEL = "4"; protected static final String DEFAULT_CONSOLE_CLASS = "org.eclipse.osgi.framework.internal.core.FrameworkConsole"; private static final String CONSOLE_NAME = "OSGi Console"; 130 private static Runnable console; 131 private static FrameworkLog log; 132 private static HashMap searchCandidates = new HashMap(4); 134 private static EclipseAppLauncher appLauncher; 135 private static List shutdownHandlers; 136 137 141 public static void main(String [] args) throws Exception { 142 if (FrameworkProperties.getProperty("eclipse.startTime") == null) FrameworkProperties.setProperty("eclipse.startTime", Long.toString(System.currentTimeMillis())); if (FrameworkProperties.getProperty(PROP_NOSHUTDOWN) == null) 145 FrameworkProperties.setProperty(PROP_NOSHUTDOWN, "true"); if (FrameworkProperties.getProperty(Constants.OSGI_COMPATIBILITY_BOOTDELEGATION) == null) 148 FrameworkProperties.setProperty(Constants.OSGI_COMPATIBILITY_BOOTDELEGATION, "false"); run(args, null); 150 } 151 152 165 public static Object run(String [] args, Runnable endSplashHandler) throws Exception { 166 if (Profile.PROFILE && Profile.STARTUP) 167 Profile.logEnter("EclipseStarter.run()", null); if (running) 169 throw new IllegalStateException (EclipseAdaptorMsg.ECLIPSE_STARTUP_ALREADY_RUNNING); 170 boolean startupFailed = true; 171 try { 172 startup(args, endSplashHandler); 173 startupFailed = false; 174 if (Boolean.valueOf(FrameworkProperties.getProperty(PROP_IGNOREAPP)).booleanValue() || isForcedRestart()) 175 return null; 176 return run(null); 177 } catch (Throwable e) { 178 if (endSplashHandler != null) 180 endSplashHandler.run(); 181 FrameworkLogEntry logEntry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, startupFailed ? EclipseAdaptorMsg.ECLIPSE_STARTUP_STARTUP_ERROR : EclipseAdaptorMsg.ECLIPSE_STARTUP_APP_ERROR, 1, e, null); 183 if (log != null) { 184 log.log(logEntry); 185 if (context != null) logUnresolvedBundles(context.getBundles()); 187 } else 188 e.printStackTrace(); 190 } finally { 191 try { 192 if (isForcedRestart()) 195 FrameworkProperties.setProperty(PROP_EXITCODE, "23"); if (!Boolean.valueOf(FrameworkProperties.getProperty(PROP_NOSHUTDOWN)).booleanValue()) 197 shutdown(); 198 } catch (Throwable e) { 199 FrameworkLogEntry logEntry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, EclipseAdaptorMsg.ECLIPSE_STARTUP_SHUTDOWN_ERROR, 1, e, null); 200 if (log != null) 201 log.log(logEntry); 202 else 203 e.printStackTrace(); 205 } 206 if (Profile.PROFILE && Profile.STARTUP) 207 Profile.logExit("EclipseStarter.run()"); if (Profile.PROFILE) { 209 String report = Profile.getProfileLog(); 210 if (report != null && report.length() > 0) 212 System.out.println(report); 213 } 214 } 215 FrameworkProperties.setProperty(PROP_EXITCODE, "13"); FrameworkProperties.setProperty(PROP_EXITDATA, NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_ERROR_CHECK_LOG, log == null ? null : log.getFile().getPath())); 218 return null; 219 } 220 221 225 public static boolean isRunning() { 226 return running; 227 } 228 229 protected static FrameworkLog createFrameworkLog() { 230 FrameworkLog frameworkLog; 231 String logFileProp = FrameworkProperties.getProperty(EclipseStarter.PROP_LOGFILE); 232 if (logFileProp != null) { 233 frameworkLog = new EclipseLog(new File(logFileProp)); 234 } else { 235 Location location = LocationManager.getConfigurationLocation(); 236 File configAreaDirectory = null; 237 if (location != null) 238 configAreaDirectory = new File(location.getURL().getFile()); 240 241 if (configAreaDirectory != null) { 242 String logFileName = Long.toString(System.currentTimeMillis()) + ".log"; File logFile = new File(configAreaDirectory, logFileName); 244 FrameworkProperties.setProperty(EclipseStarter.PROP_LOGFILE, logFile.getAbsolutePath()); 245 frameworkLog = new EclipseLog(logFile); 246 } else 247 frameworkLog = new EclipseLog(); 248 } 249 if ("true".equals(FrameworkProperties.getProperty(EclipseStarter.PROP_CONSOLE_LOG))) frameworkLog.setConsoleLog(true); 251 return frameworkLog; 252 } 253 254 265 public static BundleContext startup(String [] args, Runnable endSplashHandler) throws Exception { 266 if (Profile.PROFILE && Profile.STARTUP) 267 Profile.logEnter("EclipseStarter.startup()", null); if (running) 269 throw new IllegalStateException (EclipseAdaptorMsg.ECLIPSE_STARTUP_ALREADY_RUNNING); 270 initializeProperties(); 271 processCommandLine(args); 272 LocationManager.initializeLocations(); 273 loadConfigurationInfo(); 274 finalizeProperties(); 275 if (Profile.PROFILE) 276 Profile.initProps(); if (Profile.PROFILE && Profile.STARTUP) 278 Profile.logTime("EclipseStarter.startup()", "props inited"); adaptor = createAdaptor(); 280 log = adaptor.getFrameworkLog(); 281 if (Profile.PROFILE && Profile.STARTUP) 282 Profile.logTime("EclipseStarter.startup()", "adapter created"); osgi = new OSGi(adaptor); 284 if (Profile.PROFILE && Profile.STARTUP) 285 Profile.logTime("EclipseStarter.startup()", "OSGi created"); context = osgi.getBundleContext(); 287 registerFrameworkShutdownHandlers(); 288 publishSplashScreen(endSplashHandler); 289 osgi.launch(); 290 if (Profile.PROFILE && Profile.STARTUP) 291 Profile.logTime("EclipseStarter.startup()", "osgi launched"); String consolePort = FrameworkProperties.getProperty(PROP_CONSOLE); 293 if (consolePort != null) { 294 startConsole(osgi, new String [0], consolePort); 295 if (Profile.PROFILE && Profile.STARTUP) 296 Profile.logTime("EclipseStarter.startup()", "console started"); } 298 if ("true".equals(FrameworkProperties.getProperty(PROP_REFRESH_BUNDLES)) && refreshPackages(getCurrentBundles(false))) return context; if (Profile.PROFILE && Profile.STARTUP) 301 Profile.logTime("EclipseStarter.startup()", "loading basic bundles"); long stateStamp = adaptor.getState().getTimeStamp(); 303 Bundle[] startBundles = loadBasicBundles(); 304 if (startBundles == null) 305 return context; setStartLevel(getStartLevel()); 309 if (Profile.PROFILE && Profile.STARTUP) 310 Profile.logTime("EclipseStarter.startup()", "StartLevel set"); ensureBundlesActive(startBundles); 313 if (debug || FrameworkProperties.getProperty(PROP_DEV) != null) 314 if (stateStamp != adaptor.getState().getTimeStamp()) 316 logUnresolvedBundles(context.getBundles()); 317 running = true; 318 if (Profile.PROFILE && Profile.STARTUP) 319 Profile.logExit("EclipseStarter.startup()"); return context; 321 } 322 323 private static int getStartLevel() { 324 String level = FrameworkProperties.getProperty(PROP_INITIAL_STARTLEVEL); 325 if (level != null) 326 try { 327 return Integer.parseInt(level); 328 } catch (NumberFormatException e) { 329 if (debug) 330 System.out.println("Start level = " + level + " parsed. Using hardcoded default: 6"); } 332 return DEFAULT_INITIAL_STARTLEVEL; 333 } 334 335 347 public static Object run(Object argument) throws Exception { 348 if (Profile.PROFILE && Profile.STARTUP) 349 Profile.logEnter("EclipseStarter.run(Object)()", null); if (!running) 351 throw new IllegalStateException (EclipseAdaptorMsg.ECLIPSE_STARTUP_NOT_RUNNING); 352 if (initialize) 354 return new Integer (0); 355 if (appLauncher == null) { 356 boolean launchDefault = Boolean.valueOf(FrameworkProperties.getProperty(PROP_APPLICATION_LAUNCHDEFAULT, "true")).booleanValue(); appLauncher = new EclipseAppLauncher(context, Boolean.valueOf(FrameworkProperties.getProperty(PROP_ALLOW_APPRELAUNCH)).booleanValue(), launchDefault, log); 359 appLauncherRegistration = context.registerService(ApplicationLauncher.class.getName(), appLauncher, null); 360 return appLauncher.start(argument); 364 } 365 return appLauncher.reStart(argument); 366 } 367 368 385 public static void shutdown() throws Exception { 386 if (!running || osgi == null) 387 return; 388 if (appLauncherRegistration != null) 389 appLauncherRegistration.unregister(); 390 if (splashStreamRegistration != null) 391 splashStreamRegistration.unregister(); 392 if (defaultMonitorRegistration != null) 393 defaultMonitorRegistration.unregister(); 394 appLauncherRegistration = null; 395 appLauncher = null; 396 splashStreamRegistration = null; 397 defaultMonitorRegistration = null; 398 stopConsole(); 399 osgi.close(); 400 osgi = null; 401 context = null; 402 running = false; 403 } 404 405 private static void ensureBundlesActive(Bundle[] bundles) { 406 ServiceTracker tracker = null; 407 try { 408 for (int i = 0; i < bundles.length; i++) { 409 if (bundles[i].getState() != Bundle.ACTIVE) { 410 if (bundles[i].getState() == Bundle.INSTALLED) { 411 log.log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_ERROR_BUNDLE_NOT_RESOLVED, bundles[i].getLocation()), 0, null, null)); 413 continue; 414 } 415 if (tracker == null) { 417 tracker = new ServiceTracker(context, StartLevel.class.getName(), null); 418 tracker.open(); 419 } 420 StartLevel sl = (StartLevel) tracker.getService(); 421 if (sl != null && (sl.getBundleStartLevel(bundles[i]) <= sl.getStartLevel())) { 422 log.log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_ERROR_BUNDLE_NOT_ACTIVE, bundles[i]), 0, null, null)); 423 } 424 } 425 } 426 } finally { 427 if (tracker != null) 428 tracker.close(); 429 } 430 } 431 432 private static void logUnresolvedBundles(Bundle[] bundles) { 433 State state = adaptor.getState(); 434 FrameworkLog logService = adaptor.getFrameworkLog(); 435 StateHelper stateHelper = adaptor.getPlatformAdmin().getStateHelper(); 436 437 VersionConstraint[] leafConstraints = stateHelper.getUnsatisfiedLeaves(state.getBundles()); 439 Map missing = new HashMap(); 441 for (int i = 0; i < leafConstraints.length; i++) { 442 if (leafConstraints[i] instanceof BundleSpecification && ((BundleSpecification) leafConstraints[i]).isOptional()) 444 continue; 445 if (leafConstraints[i] instanceof ImportPackageSpecification) { 446 if (ImportPackageSpecification.RESOLUTION_OPTIONAL.equals(((ImportPackageSpecification) leafConstraints[i]).getDirective(Constants.RESOLUTION_DIRECTIVE))) 447 continue; 448 if (ImportPackageSpecification.RESOLUTION_DYNAMIC.equals(((ImportPackageSpecification) leafConstraints[i]).getDirective(Constants.RESOLUTION_DIRECTIVE))) 449 continue; 450 } 451 BundleDescription bundle = leafConstraints[i].getBundle(); 452 ArrayList constraints = (ArrayList) missing.get(bundle); 453 if (constraints == null) { 454 constraints = new ArrayList(); 455 missing.put(bundle, constraints); 456 } 457 constraints.add(leafConstraints[i]); 458 } 459 460 if (missing.size() > 0) { 462 FrameworkLogEntry[] rootChildren = new FrameworkLogEntry[missing.size()]; 463 int rootIndex = 0; 464 for (Iterator iter = missing.keySet().iterator(); iter.hasNext(); rootIndex++) { 465 BundleDescription description = (BundleDescription) iter.next(); 466 String symbolicName = description.getSymbolicName() == null ? FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME : description.getSymbolicName(); 467 String generalMessage = NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_ERROR_BUNDLE_NOT_RESOLVED, description.getLocation()); 468 ArrayList constraints = (ArrayList) missing.get(description); 469 FrameworkLogEntry[] logChildren = new FrameworkLogEntry[constraints.size()]; 470 for (int i = 0; i < logChildren.length; i++) 471 logChildren[i] = new FrameworkLogEntry(symbolicName, FrameworkLogEntry.WARNING, 0, MessageHelper.getResolutionFailureMessage((VersionConstraint) constraints.get(i)), 0, null, null); 472 rootChildren[rootIndex] = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.WARNING, 0, generalMessage, 0, null, logChildren); 473 } 474 logService.log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.WARNING, 0, EclipseAdaptorMsg.ECLIPSE_STARTUP_ROOTS_NOT_RESOLVED, 0, null, rootChildren)); 475 } 476 477 ArrayList allChildren = new ArrayList(); 480 for (int i = 0; i < bundles.length; i++) 481 if (bundles[i].getState() == Bundle.INSTALLED) { 482 String symbolicName = bundles[i].getSymbolicName() == null ? FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME : bundles[i].getSymbolicName(); 483 String generalMessage = NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_ERROR_BUNDLE_NOT_RESOLVED, bundles[i]); 484 BundleDescription description = state.getBundle(bundles[i].getBundleId()); 485 if (description == null) 487 continue; 488 FrameworkLogEntry[] logChildren = null; 489 VersionConstraint[] unsatisfied = stateHelper.getUnsatisfiedConstraints(description); 490 if (unsatisfied.length > 0) { 491 logChildren = new FrameworkLogEntry[unsatisfied.length]; 493 for (int j = 0; j < unsatisfied.length; j++) 494 logChildren[j] = new FrameworkLogEntry(symbolicName, FrameworkLogEntry.WARNING, 0, MessageHelper.getResolutionFailureMessage(unsatisfied[j]), 0, null, null); 495 } else { 496 ResolverError[] resolverErrors = state.getResolverErrors(description); 497 if (resolverErrors.length > 0) { 498 logChildren = new FrameworkLogEntry[resolverErrors.length]; 499 for (int j = 0; j < resolverErrors.length; j++) 500 logChildren[j] = new FrameworkLogEntry(symbolicName, FrameworkLogEntry.WARNING, 0, resolverErrors[j].toString(), 0, null, null); 501 } 502 } 503 504 allChildren.add(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.WARNING, 0, generalMessage, 0, null, logChildren)); 505 } 506 if (allChildren.size() > 0) 507 logService.log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.WARNING, 0, EclipseAdaptorMsg.ECLIPSE_STARTUP_ALL_NOT_RESOLVED, 0, null, (FrameworkLogEntry[]) allChildren.toArray(new FrameworkLogEntry[allChildren.size()]))); 508 } 509 510 private static void publishSplashScreen(final Runnable endSplashHandler) { 511 if (endSplashHandler == null) 512 return; 513 try { 515 Method method = endSplashHandler.getClass().getMethod("getOutputStream", new Class [0]); Object outputStream = method.invoke(endSplashHandler, new Object [0]); 517 if (outputStream instanceof OutputStream) { 518 Dictionary osProperties = new Hashtable(); 519 osProperties.put("name", "splashstream"); splashStreamRegistration = context.registerService(OutputStream.class.getName(), outputStream, osProperties); 521 } 522 } catch (Exception ex) { 523 } 525 try { 527 Dictionary monitorProps = new Hashtable(); 528 monitorProps.put(Constants.SERVICE_RANKING, new Integer (Integer.MIN_VALUE)); 529 defaultMonitorRegistration = context.registerService(StartupMonitor.class.getName(), new DefaultStartupMonitor(endSplashHandler), monitorProps); 530 } catch (IllegalStateException e) { 531 } 533 } 534 535 private static URL searchForBundle(String name, String parent) throws MalformedURLException { 536 URL url = null; 537 File fileLocation = null; 538 boolean reference = false; 539 try { 540 new URL(name); url = new URL(new File(parent).toURL(), name); 542 } catch (MalformedURLException e) { 543 File child = new File(name); 548 fileLocation = child.isAbsolute() ? child : new File(parent, name); 549 url = new URL(REFERENCE_PROTOCOL, null, fileLocation.toURL().toExternalForm()); 550 reference = true; 551 } 552 if (!reference) { 554 URL baseURL = url; 555 if (url.getProtocol().equals(REFERENCE_PROTOCOL)) { 557 reference = true; 558 String baseSpec = url.getFile(); 559 if (baseSpec.startsWith(FILE_SCHEME)) { 560 File child = new File(baseSpec.substring(5)); 561 baseURL = child.isAbsolute() ? child.toURL() : new File(parent, child.getPath()).toURL(); 562 } else 563 baseURL = new URL(baseSpec); 564 } 565 566 fileLocation = new File(baseURL.getFile()); 567 if (!fileLocation.isAbsolute()) 569 fileLocation = new File(parent, fileLocation.toString()); 570 } 571 if (reference) { 574 String result = searchFor(fileLocation.getName(), new File(fileLocation.getParent()).getAbsolutePath()); 575 if (result != null) 576 url = new URL(REFERENCE_PROTOCOL, null, FILE_SCHEME + result); 577 else 578 return null; 579 } 580 581 try { 583 URLConnection result = url.openConnection(); 584 result.connect(); 585 return url; 586 } catch (IOException e) { 587 return null; 590 } 591 } 592 593 598 private static Bundle[] loadBasicBundles() throws IOException { 599 long startTime = System.currentTimeMillis(); 600 String osgiBundles = FrameworkProperties.getProperty(PROP_BUNDLES); 601 String osgiExtensions = FrameworkProperties.getProperty(PROP_EXTENSIONS); 602 if (osgiExtensions != null && osgiExtensions.length() > 0) { 603 osgiBundles = osgiExtensions + ',' + osgiBundles; 604 FrameworkProperties.setProperty(PROP_BUNDLES, osgiBundles); 605 } 606 String [] installEntries = getArrayFromList(osgiBundles, ","); InitialBundle[] initialBundles = getInitialBundles(installEntries); 609 Bundle[] curInitBundles = getCurrentBundles(true); 611 612 List toRefresh = new ArrayList(curInitBundles.length); 614 uninstallBundles(curInitBundles, initialBundles, toRefresh); 617 618 ArrayList startBundles = new ArrayList(installEntries.length); 620 ArrayList lazyActivationBundles = new ArrayList(installEntries.length); 621 installBundles(initialBundles, curInitBundles, startBundles, lazyActivationBundles, toRefresh); 622 623 if (!toRefresh.isEmpty() && refreshPackages((Bundle[]) toRefresh.toArray(new Bundle[toRefresh.size()]))) 625 return null; 627 Bundle[] startInitBundles = (Bundle[]) startBundles.toArray(new Bundle[startBundles.size()]); 629 Bundle[] lazyInitBundles = (Bundle[]) lazyActivationBundles.toArray(new Bundle[lazyActivationBundles.size()]); 630 startBundles(startInitBundles, lazyInitBundles); 631 632 if (debug) 633 System.out.println("Time to load bundles: " + (System.currentTimeMillis() - startTime)); return startInitBundles; 635 } 636 637 private static InitialBundle[] getInitialBundles(String [] installEntries) throws MalformedURLException { 638 searchCandidates.clear(); 639 ArrayList result = new ArrayList(installEntries.length); 640 int defaultStartLevel = Integer.parseInt(FrameworkProperties.getProperty(PROP_BUNDLES_STARTLEVEL, DEFAULT_BUNDLES_STARTLEVEL)); 641 String syspath = getSysPath(); 642 try { 644 syspath = new File(syspath).getCanonicalPath(); 645 } catch (IOException ioe) { 646 } 648 for (int i = 0; i < installEntries.length; i++) { 649 String name = installEntries[i]; 650 int level = defaultStartLevel; 651 boolean start = false; 652 int index = name.indexOf('@'); 653 if (index >= 0) { 654 String [] attributes = getArrayFromList(name.substring(index + 1, name.length()), ":"); name = name.substring(0, index); 656 for (int j = 0; j < attributes.length; j++) { 657 String attribute = attributes[j]; 658 if (attribute.equals("start")) start = true; 660 else 661 level = Integer.parseInt(attribute); 662 } 663 } 664 URL location = searchForBundle(name, syspath); 665 if (location == null) { 666 FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_BUNDLE_NOT_FOUND, installEntries[i]), 0, null, null); 667 log.log(entry); 668 continue; 670 } 671 location = makeRelative(LocationManager.getInstallLocation().getURL(), location); 672 String locationString = INITIAL_LOCATION + location.toExternalForm(); 673 result.add(new InitialBundle(locationString, location, level, start)); 674 } 675 return (InitialBundle[]) result.toArray(new InitialBundle[result.size()]); 676 } 677 678 private static boolean refreshPackages(Bundle[] bundles) { 680 ServiceReference packageAdminRef = context.getServiceReference(PackageAdmin.class.getName()); 681 PackageAdmin packageAdmin = null; 682 if (packageAdminRef != null) { 683 packageAdmin = (PackageAdmin) context.getService(packageAdminRef); 684 if (packageAdmin == null) 685 return false; 686 } 687 final Semaphore semaphore = new Semaphore(0); 690 FrameworkListener listener = new FrameworkListener() { 691 public void frameworkEvent(FrameworkEvent event) { 692 if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) 693 semaphore.release(); 694 } 695 }; 696 context.addFrameworkListener(listener); 697 packageAdmin.refreshPackages(bundles); 698 context.ungetService(packageAdminRef); 699 updateSplash(semaphore, listener); 700 if (isForcedRestart()) { 701 Bundle systemBundle = context.getBundle(0); 703 int i = 0; 704 while (i < 5000 && (systemBundle.getState() & (Bundle.ACTIVE | Bundle.STOPPING)) != 0) { 705 i += 200; 706 try { 707 Thread.sleep(200); 708 } catch (InterruptedException e) { 709 break; 710 } 711 } 712 return true; 713 } 714 return false; 715 } 716 717 725 private static void startConsole(OSGi equinox, String [] consoleArgs, String consolePort) { 726 try { 727 String consoleClassName = FrameworkProperties.getProperty(PROP_CONSOLE_CLASS, DEFAULT_CONSOLE_CLASS); 728 Class consoleClass = Class.forName(consoleClassName); 729 Class [] parameterTypes; 730 Object [] parameters; 731 if (consolePort.length() == 0) { 732 parameterTypes = new Class [] {OSGi.class, String [].class}; 733 parameters = new Object [] {equinox, consoleArgs}; 734 } else { 735 parameterTypes = new Class [] {OSGi.class, int.class, String [].class}; 736 parameters = new Object [] {equinox, new Integer (consolePort), consoleArgs}; 737 } 738 Constructor constructor = consoleClass.getConstructor(parameterTypes); 739 console = (Runnable ) constructor.newInstance(parameters); 740 Thread t = new Thread (console, CONSOLE_NAME); 741 t.start(); 742 } catch (NumberFormatException nfe) { 743 System.err.println(NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_INVALID_PORT, consolePort)); 745 } catch (Exception ex) { 746 System.out.println(NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_FAILED_FIND, CONSOLE_NAME)); 747 } 748 749 } 750 751 755 private static void stopConsole() { 756 if (console == null) 757 return; 758 try { 759 Method shutdownMethod = console.getClass().getMethod("shutdown", null); shutdownMethod.invoke(console, null); 761 } catch (Exception ex) { 762 System.err.println(ex.getMessage()); 763 } 764 } 765 766 771 private static FrameworkAdaptor createAdaptor() throws Exception { 772 String adaptorClassName = FrameworkProperties.getProperty(PROP_ADAPTOR, DEFAULT_ADAPTOR_CLASS); 773 Class adaptorClass = Class.forName(adaptorClassName); 774 Class [] constructorArgs = new Class [] {String [].class}; 775 Constructor constructor = adaptorClass.getConstructor(constructorArgs); 776 return (FrameworkAdaptor) constructor.newInstance(new Object [] {new String [0]}); 777 } 778 779 private static String [] processCommandLine(String [] args) throws Exception { 780 EclipseEnvironmentInfo.setAllArgs(args); 781 if (args.length == 0) { 782 EclipseEnvironmentInfo.setFrameworkArgs(args); 783 EclipseEnvironmentInfo.setAllArgs(args); 784 return args; 785 } 786 int[] configArgs = new int[args.length]; 787 configArgs[0] = -1; int configArgIndex = 0; 789 for (int i = 0; i < args.length; i++) { 790 boolean found = false; 791 793 if (args[i].equalsIgnoreCase(DEBUG) && ((i + 1 == args.length) || ((i + 1 < args.length) && (args[i + 1].startsWith("-"))))) { FrameworkProperties.setProperty(PROP_DEBUG, ""); debug = true; 800 found = true; 801 } 802 803 if (args[i].equalsIgnoreCase(DEV) && ((i + 1 == args.length) || ((i + 1 < args.length) && (args[i + 1].startsWith("-"))))) { FrameworkProperties.setProperty(PROP_DEV, ""); found = true; 810 } 811 812 if (args[i].equalsIgnoreCase(INITIALIZE)) { 814 initialize = true; 815 found = true; 816 } 817 818 if (args[i].equalsIgnoreCase(CLEAN)) { 820 FrameworkProperties.setProperty(PROP_CLEAN, "true"); found = true; 822 } 823 824 if (args[i].equalsIgnoreCase(CONSOLE_LOG)) { 826 FrameworkProperties.setProperty(PROP_CONSOLE_LOG, "true"); found = true; 828 } 829 830 if (args[i].equalsIgnoreCase(CONSOLE) && ((i + 1 == args.length) || ((i + 1 < args.length) && (args[i + 1].startsWith("-"))))) { FrameworkProperties.setProperty(PROP_CONSOLE, ""); found = true; 834 } 835 836 if (args[i].equalsIgnoreCase(NOEXIT)) { 837 FrameworkProperties.setProperty(PROP_NOSHUTDOWN, "true"); found = true; 839 } 840 841 if (found) { 842 configArgs[configArgIndex++] = i; 843 continue; 844 } 845 if (i == args.length - 1 || args[i + 1].startsWith("-")) { continue; 849 } 850 String arg = args[++i]; 851 852 if (args[i - 1].equalsIgnoreCase(CONSOLE)) { 854 FrameworkProperties.setProperty(PROP_CONSOLE, arg); 855 found = true; 856 } 857 858 if (args[i - 1].equalsIgnoreCase(CONFIGURATION)) { 860 FrameworkProperties.setProperty(LocationManager.PROP_CONFIG_AREA, arg); 861 found = true; 862 } 863 864 if (args[i - 1].equalsIgnoreCase(DATA)) { 866 FrameworkProperties.setProperty(LocationManager.PROP_INSTANCE_AREA, arg); 867 found = true; 868 } 869 870 if (args[i - 1].equalsIgnoreCase(USER)) { 872 FrameworkProperties.setProperty(LocationManager.PROP_USER_AREA, arg); 873 found = true; 874 } 875 876 if (args[i - 1].equalsIgnoreCase(DEV)) { 878 FrameworkProperties.setProperty(PROP_DEV, arg); 879 found = true; 880 } 881 882 if (args[i - 1].equalsIgnoreCase(DEBUG)) { 884 FrameworkProperties.setProperty(PROP_DEBUG, arg); 885 debug = true; 886 found = true; 887 } 888 889 if (args[i - 1].equalsIgnoreCase(WS)) { 891 FrameworkProperties.setProperty(PROP_WS, arg); 892 found = true; 893 } 894 895 if (args[i - 1].equalsIgnoreCase(OS)) { 897 FrameworkProperties.setProperty(PROP_OS, arg); 898 found = true; 899 } 900 901 if (args[i - 1].equalsIgnoreCase(ARCH)) { 903 FrameworkProperties.setProperty(PROP_ARCH, arg); 904 found = true; 905 } 906 907 if (args[i - 1].equalsIgnoreCase(NL)) { 909 FrameworkProperties.setProperty(PROP_NL, arg); 910 found = true; 911 } 912 if (found) { 914 configArgs[configArgIndex++] = i - 1; 915 configArgs[configArgIndex++] = i; 916 } 917 } 918 919 if (configArgIndex == 0) { 921 EclipseEnvironmentInfo.setFrameworkArgs(new String [0]); 922 EclipseEnvironmentInfo.setAppArgs(args); 923 return args; 924 } 925 String [] appArgs = new String [args.length - configArgIndex]; 926 String [] frameworkArgs = new String [configArgIndex]; 927 configArgIndex = 0; 928 int j = 0; 929 int k = 0; 930 for (int i = 0; i < args.length; i++) { 931 if (i == configArgs[configArgIndex]) { 932 frameworkArgs[k++] = args[i]; 933 configArgIndex++; 934 } else 935 appArgs[j++] = args[i]; 936 } 937 EclipseEnvironmentInfo.setFrameworkArgs(frameworkArgs); 938 EclipseEnvironmentInfo.setAppArgs(appArgs); 939 return appArgs; 940 } 941 942 948 private static String [] getArrayFromList(String prop, String separator) { 949 return ManifestElement.getArrayFromList(prop, separator); 950 } 951 952 protected static String getSysPath() { 953 String result = FrameworkProperties.getProperty(PROP_SYSPATH); 954 if (result != null) 955 return result; 956 result = getSysPathFromURL(FrameworkProperties.getProperty(PROP_FRAMEWORK)); 957 if (result == null) 958 result = getSysPathFromCodeSource(); 959 if (result == null) 960 throw new IllegalStateException ("Can not find the system path."); if (Character.isUpperCase(result.charAt(0))) { 962 char[] chars = result.toCharArray(); 963 chars[0] = Character.toLowerCase(chars[0]); 964 result = new String (chars); 965 } 966 FrameworkProperties.setProperty(PROP_SYSPATH, result); 967 return result; 968 } 969 970 private static String getSysPathFromURL(String urlSpec) { 971 if (urlSpec == null) 972 return null; 973 URL url = null; 974 try { 975 url = new URL(urlSpec); 976 } catch (MalformedURLException e) { 977 return null; 978 } 979 File fwkFile = new File(url.getFile()); 980 fwkFile = new File(fwkFile.getAbsolutePath()); 981 fwkFile = new File(fwkFile.getParent()); 982 return fwkFile.getAbsolutePath(); 983 } 984 985 private static String getSysPathFromCodeSource() { 986 ProtectionDomain pd = EclipseStarter.class.getProtectionDomain(); 987 if (pd == null) 988 return null; 989 CodeSource cs = pd.getCodeSource(); 990 if (cs == null) 991 return null; 992 URL url = cs.getLocation(); 993 if (url == null) 994 return null; 995 String result = url.getFile(); 996 if (result.endsWith(".jar")) { result = result.substring(0, result.lastIndexOf('/')); 998 if ("folder".equals(FrameworkProperties.getProperty(PROP_FRAMEWORK_SHAPE))) result = result.substring(0, result.lastIndexOf('/')); 1000 } else { 1001 if (result.endsWith("/")) result = result.substring(0, result.length() - 1); 1003 result = result.substring(0, result.lastIndexOf('/')); 1004 result = result.substring(0, result.lastIndexOf('/')); 1005 } 1006 return result; 1007 } 1008 1009 private static Bundle[] getCurrentBundles(boolean includeInitial) { 1010 Bundle[] installed = context.getBundles(); 1011 ArrayList initial = new ArrayList(); 1012 for (int i = 0; i < installed.length; i++) { 1013 Bundle bundle = installed[i]; 1014 if (bundle.getLocation().startsWith(INITIAL_LOCATION)) { 1015 if (includeInitial) 1016 initial.add(bundle); 1017 } else if (!includeInitial && bundle.getBundleId() != 0) 1018 initial.add(bundle); 1019 } 1020 return (Bundle[]) initial.toArray(new Bundle[initial.size()]); 1021 } 1022 1023 private static Bundle getBundleByLocation(String location, Bundle[] bundles) { 1024 for (int i = 0; i < bundles.length; i++) { 1025 Bundle bundle = bundles[i]; 1026 if (location.equalsIgnoreCase(bundle.getLocation())) 1027 return bundle; 1028 } 1029 return null; 1030 } 1031 1032 private static void uninstallBundles(Bundle[] curInitBundles, InitialBundle[] newInitBundles, List toRefresh) { 1033 for (int i = 0; i < curInitBundles.length; i++) { 1034 boolean found = false; 1035 for (int j = 0; j < newInitBundles.length; j++) { 1036 if (curInitBundles[i].getLocation().equalsIgnoreCase(newInitBundles[j].locationString)) { 1037 found = true; 1038 break; 1039 } 1040 } 1041 if (!found) 1042 try { 1043 curInitBundles[i].uninstall(); 1044 toRefresh.add(curInitBundles[i]); 1045 } catch (BundleException e) { 1046 FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_FAILED_UNINSTALL, curInitBundles[i].getLocation()), 0, e, null); 1047 log.log(entry); 1048 } 1049 } 1050 } 1051 1052 private static void installBundles(InitialBundle[] initialBundles, Bundle[] curInitBundles, ArrayList startBundles, ArrayList lazyActivationBundles, List toRefresh) { 1053 ServiceReference reference = context.getServiceReference(StartLevel.class.getName()); 1054 StartLevel startService = null; 1055 if (reference != null) 1056 startService = (StartLevel) context.getService(reference); 1057 try { 1058 for (int i = 0; i < initialBundles.length; i++) { 1059 Bundle osgiBundle = getBundleByLocation(initialBundles[i].locationString, curInitBundles); 1060 try { 1061 if (osgiBundle == null) { 1063 InputStream in = initialBundles[i].location.openStream(); 1064 osgiBundle = context.installBundle(initialBundles[i].locationString, in); 1065 if (!initialBundles[i].start && hasLazyActivationPolicy(osgiBundle)) 1067 lazyActivationBundles.add(osgiBundle); 1068 } 1069 if ((osgiBundle.getState() & Bundle.UNINSTALLED) == 0 && initialBundles[i].level >= 0 && startService != null) 1072 startService.setBundleStartLevel(osgiBundle, initialBundles[i].level); 1073 if (initialBundles[i].start) 1075 startBundles.add(osgiBundle); 1076 if ((osgiBundle.getState() & Bundle.INSTALLED) != 0) 1078 toRefresh.add(osgiBundle); 1079 } catch (BundleException e) { 1080 FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_FAILED_INSTALL, initialBundles[i].location), 0, e, null); 1081 log.log(entry); 1082 } catch (IOException e) { 1083 FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_FAILED_INSTALL, initialBundles[i].location), 0, e, null); 1084 log.log(entry); 1085 } 1086 } 1087 } finally { 1088 if (reference != null) 1089 context.ungetService(reference); 1090 } 1091 } 1092 1093 private static boolean hasLazyActivationPolicy(Bundle target) { 1094 Dictionary headers = target.getHeaders(""); String fragmentHost = (String ) headers.get(Constants.FRAGMENT_HOST); 1098 if (fragmentHost != null) 1099 return false; String activationPolicy = (String ) headers.get(Constants.BUNDLE_ACTIVATIONPOLICY); 1102 try { 1103 if (activationPolicy != null) { 1104 ManifestElement[] elements = ManifestElement.parseHeader(Constants.BUNDLE_ACTIVATIONPOLICY, activationPolicy); 1105 if (elements != null && elements.length > 0) { 1106 if (Constants.ACTIVATION_LAZY.equals(elements[0].getValue())) 1108 return true; 1109 } 1110 } else { 1111 String eclipseLazyStart = (String ) headers.get(Constants.ECLIPSE_LAZYSTART); 1113 if (eclipseLazyStart == null) 1114 eclipseLazyStart = (String ) headers.get(Constants.ECLIPSE_AUTOSTART); 1115 ManifestElement[] elements = ManifestElement.parseHeader(Constants.ECLIPSE_LAZYSTART, eclipseLazyStart); 1116 if (elements != null && elements.length > 0) { 1117 if ("true".equals(elements[0].getValue())) return true; 1120 else if (elements[0].getDirective("exceptions") != null) return true; 1123 } 1124 } 1125 } catch (BundleException be) { 1126 } 1128 return false; 1129 } 1130 1131 private static void startBundles(Bundle[] startBundles, Bundle[] lazyBundles) { 1132 for (int i = 0; i < startBundles.length; i++) 1133 startBundle(startBundles[i], 0); 1134 for (int i = 0; i < lazyBundles.length; i++) 1135 startBundle(lazyBundles[i], Bundle.START_ACTIVATION_POLICY); 1136 } 1137 1138 private static void startBundle(Bundle bundle, int options) { 1139 try { 1140 bundle.start(options); 1141 } catch (BundleException e) { 1142 if ((bundle.getState() & Bundle.RESOLVED) != 0) { 1143 FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_FAILED_START, bundle.getLocation()), 0, e, null); 1145 log.log(entry); 1146 } 1147 } 1148 } 1149 1150 private static void loadConfigurationInfo() { 1151 Location configArea = LocationManager.getConfigurationLocation(); 1152 if (configArea == null) 1153 return; 1154 1155 URL location = null; 1156 try { 1157 location = new URL(configArea.getURL().toExternalForm() + LocationManager.CONFIG_FILE); 1158 } catch (MalformedURLException e) { 1159 } 1161 mergeProperties(FrameworkProperties.getProperties(), loadProperties(location)); 1162 } 1163 1164 private static Properties loadProperties(URL location) { 1165 Properties result = new Properties(); 1166 if (location == null) 1167 return result; 1168 try { 1169 InputStream in = location.openStream(); 1170 try { 1171 result.load(in); 1172 } finally { 1173 in.close(); 1174 } 1175 } catch (IOException e) { 1176 } 1179 return result; 1180 } 1181 1182 1187 private static URL makeRelative(URL base, URL location) throws MalformedURLException { 1188 if (base == null) 1189 return location; 1190 if (!"file".equals(base.getProtocol())) return location; 1192 if (!location.getProtocol().equals(REFERENCE_PROTOCOL)) 1193 return location; URL nonReferenceLocation = new URL(location.getPath()); 1195 if (!base.getProtocol().equals(nonReferenceLocation.getProtocol())) 1197 return location; 1198 File locationPath = new File(nonReferenceLocation.getPath()); 1199 if (!locationPath.isAbsolute()) 1201 return location; 1202 File relativePath = makeRelative(new File(base.getPath()), locationPath); 1203 String urlPath = relativePath.getPath(); 1204 if (File.separatorChar != '/') 1205 urlPath = urlPath.replace(File.separatorChar, '/'); 1206 if (nonReferenceLocation.getPath().endsWith("/")) urlPath += '/'; 1209 URL relativeURL = new URL(base.getProtocol(), base.getHost(), base.getPort(), urlPath); 1211 relativeURL = new URL(REFERENCE_SCHEME + relativeURL.toExternalForm()); 1213 return relativeURL; 1214 } 1215 1216 private static File makeRelative(File base, File location) { 1217 if (!location.isAbsolute()) 1218 return location; 1219 File relative = new File(new FilePath(base).makeRelative(new FilePath(location))); 1220 return relative; 1221 } 1222 1223 private static void mergeProperties(Properties destination, Properties source) { 1224 for (Enumeration e = source.keys(); e.hasMoreElements();) { 1225 String key = (String ) e.nextElement(); 1226 String value = source.getProperty(key); 1227 if (destination.getProperty(key) == null) 1228 destination.put(key, value); 1229 } 1230 } 1231 1232 private static void setStartLevel(final int value) { 1233 ServiceReference reference = context.getServiceReference(StartLevel.class.getName()); 1234 final StartLevel startLevel = reference != null ? (StartLevel) context.getService(reference) : null; 1235 if (startLevel == null) 1236 return; 1237 final Semaphore semaphore = new Semaphore(0); 1238 FrameworkListener listener = new FrameworkListener() { 1239 public void frameworkEvent(FrameworkEvent event) { 1240 if (event.getType() == FrameworkEvent.STARTLEVEL_CHANGED && startLevel.getStartLevel() == value) 1241 semaphore.release(); 1242 } 1243 }; 1244 context.addFrameworkListener(listener); 1245 startLevel.setStartLevel(value); 1246 context.ungetService(reference); 1247 updateSplash(semaphore, listener); 1248 } 1249 1250 private static void updateSplash(Semaphore semaphore, FrameworkListener listener) { 1251 ServiceTracker monitorTracker = new ServiceTracker(context, StartupMonitor.class.getName(), null); 1252 monitorTracker.open(); 1253 try { 1254 while (true) { 1255 StartupMonitor monitor = (StartupMonitor) monitorTracker.getService(); 1256 if (monitor != null) { 1257 try { 1258 monitor.update(); 1259 } catch (Throwable e) { 1260 } 1262 } 1263 if (semaphore.acquire(50)) 1265 break; } 1268 } finally { 1269 if (listener != null) 1270 context.removeFrameworkListener(listener); 1271 monitorTracker.close(); 1272 } 1273 } 1274 1275 1283 private static String searchFor(final String target, String start) { 1284 String [] candidates = (String []) searchCandidates.get(start); 1285 if (candidates == null) { 1286 candidates = new File(start).list(); 1287 if (candidates != null) 1288 searchCandidates.put(start, candidates); 1289 } 1290 if (candidates == null) 1291 return null; 1292 String result = null; 1293 Object [] maxVersion = null; 1294 for (int i = 0; i < candidates.length; i++) { 1295 String candidateName = candidates[i]; 1296 if (!candidateName.startsWith(target)) 1297 continue; 1298 boolean simpleJar = false; 1299 if (candidateName.length() > target.length() && candidateName.charAt(target.length()) != '_') { 1300 if (candidateName.length() == 4 + target.length() && candidateName.endsWith(".jar")) simpleJar = true; 1303 else 1304 continue; 1306 } 1307 String version = candidateName.length() > target.length() + 1 && candidateName.charAt(target.length()) == '_' ? candidateName.substring(target.length() + 1) : ""; Object [] currentVersion = getVersionElements(version); 1310 if (currentVersion != null && compareVersion(maxVersion, currentVersion) < 0) { 1311 File candidate = new File(start, candidateName); 1312 if (!simpleJar || candidate.isFile()) { 1314 result = candidate.getAbsolutePath(); 1315 maxVersion = currentVersion; 1316 } 1317 } 1318 } 1319 if (result == null) 1320 return null; 1321 return result.replace(File.separatorChar, '/') + "/"; } 1323 1324 1333 private static Object [] getVersionElements(String version) { 1334 Object [] result = {new Integer (-1), new Integer (-1), new Integer (-1), ""}; StringTokenizer t = new StringTokenizer(version, "."); String token; 1337 for (int i = 0; t.hasMoreTokens() && i < 4; i++) { 1338 token = t.nextToken(); 1339 if (i < 3) { 1340 try { 1342 result[i] = new Integer (token); 1343 } catch (Exception e) { 1344 if (i == 0) 1345 return null; break; 1348 } 1349 } else { 1350 result[i] = token; 1352 } 1353 } 1354 return result; 1355 } 1356 1357 1364 private static int compareVersion(Object [] left, Object [] right) { 1365 if (left == null) 1366 return -1; 1367 int result = ((Integer ) left[0]).compareTo((Integer ) right[0]); if (result != 0) 1369 return result; 1370 1371 result = ((Integer ) left[1]).compareTo((Integer ) right[1]); if (result != 0) 1373 return result; 1374 1375 result = ((Integer ) left[2]).compareTo((Integer ) right[2]); if (result != 0) 1377 return result; 1378 1379 return ((String ) left[3]).compareTo((String ) right[3]); } 1381 1382 private static void initializeProperties() { 1383 if (FrameworkProperties.getProperty(PROP_FRAMEWORK) == null || FrameworkProperties.getProperty(PROP_INSTALL_AREA) == null) { 1385 CodeSource cs = EclipseStarter.class.getProtectionDomain().getCodeSource(); 1386 if (cs == null) 1387 throw new IllegalArgumentException (NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_PROPS_NOT_SET, PROP_FRAMEWORK + ", " + PROP_INSTALL_AREA)); URL url = cs.getLocation(); 1389 if (FrameworkProperties.getProperty(PROP_FRAMEWORK) == null) 1391 FrameworkProperties.setProperty(PROP_FRAMEWORK, url.toExternalForm()); 1392 if (FrameworkProperties.getProperty(PROP_INSTALL_AREA) == null) { 1393 String filePart = url.getFile(); 1394 FrameworkProperties.setProperty(PROP_INSTALL_AREA, filePart.substring(0, filePart.lastIndexOf('/'))); 1395 } 1396 } 1397 FrameworkProperties.setProperty(PROP_FRAMEWORK, decode(FrameworkProperties.getProperty(PROP_FRAMEWORK))); 1399 FrameworkProperties.setProperty(PROP_INSTALL_AREA, decode(FrameworkProperties.getProperty(PROP_INSTALL_AREA))); 1400 } 1401 1402 private static void finalizeProperties() { 1403 if (FrameworkProperties.getProperty(PROP_DEV) != null && FrameworkProperties.getProperty(PROP_CHECK_CONFIG) == null) 1405 FrameworkProperties.setProperty(PROP_CHECK_CONFIG, "true"); } 1407 1408 private static class InitialBundle { 1409 public final String locationString; 1410 public final URL location; 1411 public final int level; 1412 public final boolean start; 1413 1414 InitialBundle(String locationString, URL location, int level, boolean start) { 1415 this.locationString = locationString; 1416 this.location = location; 1417 this.level = level; 1418 this.start = start; 1419 } 1420 } 1421 1422 private static String decode(String urlString) { 1423 try { 1425 Class clazz = URLDecoder.class; 1426 Method method = clazz.getDeclaredMethod("decode", new Class [] {String .class, String .class}); if (urlString.indexOf('+') >= 0) { 1430 int len = urlString.length(); 1431 StringBuffer buf = new StringBuffer (len); 1432 for (int i = 0; i < len; i++) { 1433 char c = urlString.charAt(i); 1434 if (c == '+') 1435 buf.append("%2B"); else 1437 buf.append(c); 1438 } 1439 urlString = buf.toString(); 1440 } 1441 Object result = method.invoke(null, new Object [] {urlString, "UTF-8"}); if (result != null) 1443 return (String ) result; 1444 } catch (Exception e) { 1445 } 1447 boolean replaced = false; 1449 byte[] encodedBytes = urlString.getBytes(); 1450 int encodedLength = encodedBytes.length; 1451 byte[] decodedBytes = new byte[encodedLength]; 1452 int decodedLength = 0; 1453 for (int i = 0; i < encodedLength; i++) { 1454 byte b = encodedBytes[i]; 1455 if (b == '%') { 1456 byte enc1 = encodedBytes[++i]; 1457 byte enc2 = encodedBytes[++i]; 1458 b = (byte) ((hexToByte(enc1) << 4) + hexToByte(enc2)); 1459 replaced = true; 1460 } 1461 decodedBytes[decodedLength++] = b; 1462 } 1463 if (!replaced) 1464 return urlString; 1465 try { 1466 return new String (decodedBytes, 0, decodedLength, "UTF-8"); } catch (UnsupportedEncodingException e) { 1468 return new String (decodedBytes, 0, decodedLength); 1470 } 1471 } 1472 1473 private static int hexToByte(byte b) { 1474 switch (b) { 1475 case '0' : 1476 return 0; 1477 case '1' : 1478 return 1; 1479 case '2' : 1480 return 2; 1481 case '3' : 1482 return 3; 1483 case '4' : 1484 return 4; 1485 case '5' : 1486 return 5; 1487 case '6' : 1488 return 6; 1489 case '7' : 1490 return 7; 1491 case '8' : 1492 return 8; 1493 case '9' : 1494 return 9; 1495 case 'A' : 1496 case 'a' : 1497 return 10; 1498 case 'B' : 1499 case 'b' : 1500 return 11; 1501 case 'C' : 1502 case 'c' : 1503 return 12; 1504 case 'D' : 1505 case 'd' : 1506 return 13; 1507 case 'E' : 1508 case 'e' : 1509 return 14; 1510 case 'F' : 1511 case 'f' : 1512 return 15; 1513 default : 1514 throw new IllegalArgumentException ("Switch error decoding URL"); } 1516 } 1517 1518 1530 public static void setInitialProperties(Map initialProperties) { 1531 if (initialProperties == null || initialProperties.isEmpty()) 1532 return; 1533 for (Iterator it = initialProperties.entrySet().iterator(); it.hasNext();) { 1534 Map.Entry entry = (Map.Entry) it.next(); 1535 if (entry.getValue() != null) 1536 FrameworkProperties.setProperty((String ) entry.getKey(), (String ) entry.getValue()); 1537 else 1538 FrameworkProperties.clearProperty((String ) entry.getKey()); 1539 } 1540 } 1541 1542 1550 public static BundleContext getSystemBundleContext() { 1551 if (context == null || !running) 1552 return null; 1553 return context.getBundle().getBundleContext(); 1554 } 1555 1556 private static boolean isForcedRestart() { 1557 return Boolean.valueOf(FrameworkProperties.getProperty(PROP_FORCED_RESTART)).booleanValue(); 1558 } 1559 1560 1576 static void internalAddFrameworkShutdownHandler(Runnable handler) { 1577 if (running) 1578 throw new IllegalStateException (EclipseAdaptorMsg.ECLIPSE_STARTUP_ALREADY_RUNNING); 1579 1580 if (shutdownHandlers == null) 1581 shutdownHandlers = new ArrayList(); 1582 1583 shutdownHandlers.add(handler); 1584 } 1585 1586 1594 static void internalRemoveFrameworkShutdownHandler(Runnable handler) { 1595 if (running) 1596 throw new IllegalStateException (EclipseAdaptorMsg.ECLIPSE_STARTUP_ALREADY_RUNNING); 1597 1598 if (shutdownHandlers != null) 1599 shutdownHandlers.remove(handler); 1600 } 1601 1602 private static void registerFrameworkShutdownHandlers() { 1603 if (shutdownHandlers == null) 1604 return; 1605 1606 final Bundle systemBundle = context.getBundle(); 1607 for (Iterator it = shutdownHandlers.iterator(); it.hasNext();) { 1608 final Runnable handler = (Runnable ) it.next(); 1609 BundleListener listener = new BundleListener() { 1610 public void bundleChanged(BundleEvent event) { 1611 if (event.getBundle() == systemBundle && event.getType() == BundleEvent.STOPPED) { 1612 handler.run(); 1613 } 1614 } 1615 }; 1616 context.addBundleListener(listener); 1617 } 1618 } 1619} 1620 | Popular Tags |