📄 stdpeergroup.java
字号:
moduleAdv = loader.findModuleImplAdvertisement(PeerGroup.refMembershipSpecID); paramAdv.addService(PeerGroup.membershipClassID, moduleAdv); moduleAdv = loader.findModuleImplAdvertisement(PeerGroup.refAccessSpecID); paramAdv.addService(PeerGroup.accessClassID, moduleAdv); // standard services moduleAdv = loader.findModuleImplAdvertisement(PeerGroup.refDiscoverySpecID); paramAdv.addService(PeerGroup.discoveryClassID, moduleAdv); moduleAdv = loader.findModuleImplAdvertisement(PeerGroup.refRendezvousSpecID); paramAdv.addService(PeerGroup.rendezvousClassID, moduleAdv); moduleAdv = loader.findModuleImplAdvertisement(PeerGroup.refPipeSpecID); paramAdv.addService(PeerGroup.pipeClassID, moduleAdv); moduleAdv = loader.findModuleImplAdvertisement(PeerGroup.refPeerinfoSpecID); paramAdv.addService(PeerGroup.peerinfoClassID, moduleAdv); // Applications moduleAdv = loader.findModuleImplAdvertisement(PeerGroup.refShellSpecID); if (null != moduleAdv) { paramAdv.addApp(PeerGroup.applicationClassID, moduleAdv); } // Insert the newParamAdv in implAdv XMLElement paramElement = (XMLElement) paramAdv.getDocument(MimeMediaType.XMLUTF8); implAdv.setParam(paramElement); return implAdv; } /** * constructor */ public StdPeerGroup() { } /** * {@inheritDoc} */ // @Override public boolean compatible(Element compat) { return isCompatible(compat); } /** * Evaluates if the given compatibility statement makes the module that * bears it is loadable by this group. * * @param compat The compatibility statement being tested. * @return {@code true} if we are compatible with the provided statement * otherwise {@code false}. */ static boolean isCompatible(Element compat) { boolean formatOk = false; boolean bindingOk = false; if(!(compat instanceof TextElement)) { return false; } try { Enumeration<TextElement> hisChildren = ((TextElement)compat).getChildren(); int i = 0; while (hisChildren.hasMoreElements()) { // Stop after 2 elements; there shall not be more. if (++i > 2) { return false; } TextElement e = hisChildren.nextElement(); String key = e.getKey(); String val = e.getValue().trim(); if (STD_COMPAT_FORMAT.equals(key)) { Package javaLangPackage = Package.getPackage("java.lang"); boolean specMatches; String version; if (val.startsWith("JDK") || val.startsWith("JRE")) { specMatches = true; version = val.substring(3).trim(); // allow for spaces. } else if (val.startsWith(javaLangPackage.getSpecificationTitle())) { specMatches = true; version = val.substring(javaLangPackage.getSpecificationTitle().length()).trim(); // allow for spaces. } else { specMatches = false; version = null; } formatOk = specMatches && javaLangPackage.isCompatibleWith(version); } else if (STD_COMPAT_BINDING.equals(key) && STD_COMPAT_BINDING_VALUE.equals(val)) { bindingOk = true; } else { if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) { LOG.warning("Bad element in compatibility statement : " + key); } return false; // Might as well stop right now. } } } catch (Exception any) { if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) { LOG.log(Level.WARNING, "Failure handling compatibility statement", any); } return false; } return formatOk && bindingOk; } /** * Builds a table of modules indexed by their class ID. * The values are the loaded modules, the keys are their classId. * This routine interprets the parameter list in the advertisement. * * @param modules The modules to load * @param privileged if true then modules will get a real reference to * the group loading them, otherwise its an interface object. */ protected void loadAllModules(Map<ModuleClassID, Object> modules, boolean privileged) { Iterator<Map.Entry<ModuleClassID, Object>> eachModule = modules.entrySet().iterator(); while (eachModule.hasNext()) { Map.Entry<ModuleClassID, Object> anEntry = eachModule.next(); ModuleClassID classID = anEntry.getKey(); Object value = anEntry.getValue(); // Already loaded. if (value instanceof Module) { continue; } // Try and load it. try { Module theModule = null; if (value instanceof ModuleImplAdvertisement) { // Load module will republish locally but not in the // parent since that adv does not come from there. theModule = loadModule(classID, (ModuleImplAdvertisement) value, privileged); } else if (value instanceof ModuleSpecID) { // loadModule will republish both locally and in the parent // Where the module was fetched. theModule = loadModule(classID, (ModuleSpecID) value, FromParent, privileged); } else { if (Logging.SHOW_SEVERE && LOG.isLoggable(Level.SEVERE)) { LOG.severe("Skipping: " + classID + " Unsupported module descriptor : " + value.getClass().getName()); } eachModule.remove(); continue; } if (theModule == null) { throw new PeerGroupException("Could not find a loadable implementation for : " + classID); } anEntry.setValue(theModule); } catch (Exception e) { if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) { LOG.log(Level.WARNING, "Could not load module for class ID : " + classID, e); if (value instanceof ModuleImplAdvertisement) { LOG.log(Level.WARNING, "Will be missing from peer group : " + ((ModuleImplAdvertisement) value).getDescription()); } else { LOG.log(Level.WARNING, "Will be missing from peer group: " + value); } } eachModule.remove(); } } } /** * The group does not care for start args, and does not come-up * with args to pass to its main app. So, until we decide on something * more useful, the args of the group's startApp are passed-on to the * group's main app. NB: both the apps init and startApp methods are * invoked. * * @return int Status. */ @Override public int startApp(String[] arg) { if (!initComplete) { if (Logging.SHOW_SEVERE && LOG.isLoggable(Level.SEVERE)) { LOG.severe("Group has not been initialized or init failed."); } return -1; } // FIXME: maybe concurrent callers should be blocked until the // end of startApp(). That could mean forever, though. if (started) { return Module.START_OK; } started = true; // Normally does nothing, but we have to. int res = super.startApp(arg); if (Module.START_OK != res) { return res; } loadAllModules(applications, false); // Apps are non-privileged; res = startModules((Map) applications); return res; } /** * {@inheritDoc} */ @Override public void stopApp() { // Shut down the group services and message transports. Collections.reverse(moduleStartOrder); for (ModuleClassID aModule : moduleStartOrder) { try { if (messageTransports.containsKey(aModule)) { Module theMessageTransport = (Module) messageTransports.remove(aModule); theMessageTransport.stopApp(); } else { removeService(aModule); } } catch (Exception any) { if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) { LOG.log(Level.WARNING, "Failed to stop module: " + aModule, any); } } } moduleStartOrder.clear(); if (!messageTransports.isEmpty()) { LOG.warning(messageTransports.size() + " message transports could not be shut down during peer group stop."); } messageTransports.clear(); super.stopApp(); if (cm != null) { cm.stop(); cm = null; } } /** * Given a list of all the modules we need to start attempt to start them. * There is an a-priori order, but we'll iterate over the list until all * where able to complete their start phase or no progress is made. Since we * give modules the opportunity to pretend that they are making progress, we * need to have a safeguard: we will not iterate through the list more than * N^2 + 1 times without at least one module completing; N being the number * of modules still in the list. This should cover the worst case scenario * and still allow the process to eventually fail if it has no chance of * success. * * @param services The services to start. */ private int startModules(Map<ModuleClassID,Module> services) { int iterations = 0; int maxIterations = services.size() * services.size() + iterations + 1; boolean progress = true; while (!services.isEmpty() && (progress || (iterations < maxIterations))) { progress = false; iterations++; if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) { LOG.fine(MessageFormat.format("Service startApp() round {0} of {1}(max)", iterations, maxIterations)); } Iterator<Map.Entry<ModuleClassID, Module>> eachService = services.entrySet().iterator(); while (eachService.hasNext()) { Map.Entry<ModuleClassID, Module> anEntry = eachService.next(); ModuleClassID mcid = anEntry.getKey(); Module aModule = anEntry.getValue(); int res; try { res = aModule.startApp(null); } catch (Throwable all) { if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) { LOG.log(Level.WARNING, "Exception in startApp() : " + aModule, all); } res = -1; } switch (res) { case Module.START_OK: if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) { LOG.fine("Module started : " + aModule); } if (aModule instanceof Service) { addService(mcid, (Service) aModule); } else { messageTransports.put(mcid, aModule); } moduleStartOrder.add(mcid); eachService.remove(); progress = true; break; case Module.START_AGAIN_PROGRESS: if (Logging.SHOW_FINER && LOG.isLoggable(Level.FINER)) { LOG.finer("Service made progress during start : " + aModule); } progress = true; break; case Module.START_AGAIN_STALLED:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -