📄 genericpeergroup.java
字号:
} if (resolverClassID.equals(name)) { resolver = (ResolverService) service; return; } if (discoveryClassID.equals(name)) { discovery = (DiscoveryService) service; return; } if (pipeClassID.equals(name)) { pipe = (PipeService) service; return; } if (membershipClassID.equals(name)) { membership = (MembershipService) service; return; } if (peerinfoClassID.equals(name)) { peerinfo = (PeerInfoService) service; return; } if (rendezvousClassID.equals(name)) { rendezvous = (RendezVousService) service; return; } if (accessClassID.equals(name)) { access = (AccessService) service; return; } } private void clearShortCut(ModuleClassID name) { if (endpointClassID.equals(name)) { endpoint = null; return; } if (resolverClassID.equals(name)) { resolver = null; return; } if (discoveryClassID.equals(name)) { discovery = null; return; } if (pipeClassID.equals(name)) { pipe = null; return; } if (membershipClassID.equals(name)) { membership = null; return; } if (peerinfoClassID.equals(name)) { peerinfo = null; return; } if (rendezvousClassID.equals(name)) { rendezvous = null; return; } if (accessClassID.equals(name)) { access = null; return; } } /** * Adds a service to the set. * Returns any pre-existing one. **/ private synchronized Service addServiceSync(ModuleClassID name, Service service) { if (stopping) { return null; } Service p = (Service) services.remove(name); services.put(name, service); return p; } /** * Adds a service to the set. * * <p/>Removes any pre-existing one with the same name. **/ protected void addService(ModuleClassID name, Service service) { Service oldp = addServiceSync(name, service); setShortCut(name, service); if ((oldp != null) && (oldp != service)) { LOG.warn("Service replaced for " + name); // oldp.stopApp(); maybe ? } } /** * Call a service by name. * * @param name the service name * @return Service, the Service registered by that name **/ synchronized public Service lookupService(ID name) throws ServiceNotFoundException { // Null services are never registered, so we do not need to test that // case. Service p = (Service) services.get(name); if (p == null) { throw new ServiceNotFoundException(name.toString()); } return p.getInterface(); } /** * {@inheritDoc} * Group implementations do not have to support mapping. * it would be nice to separate better Interfaces, so that * Interface Objects can do things that the real service does * not have to implement. */ public Service lookupService(ID name, int roleIndex) throws ServiceNotFoundException { // If the role number is != 0, it can't be honored: we // do not have an explicit map. if (roleIndex != 0) { throw (new ServiceNotFoundException( "" + name + "[" + roleIndex + "]")); } return lookupService(name); } /** * {@inheritDoc} **/ public Iterator getRoleMap(ID name) { // No translation; use the given name in a singleton. return Collections.singletonList(name).iterator(); } /** * check that all required services are registered **/ protected void checkServices() throws ServiceNotFoundException { Service ignored; ignored = lookupService(endpointClassID); ignored = lookupService(resolverClassID); ignored = lookupService(membershipClassID); ignored = lookupService(accessClassID); /** * ignored = lookupService(discoveryClassID); * ignored = lookupService(pipeClassID); * ignored = lookupService(rendezvousClassID); * ignored = lookupService(peerinfoClassID); **/ } /** * We're stopping. Remove all services and stop them. **/ private synchronized void removeAllServicesSync() { stopping = true; // stop everything Iterator allServices = services.entrySet().iterator(); while (allServices.hasNext()) { Map.Entry s = null; try { s = (Map.Entry) allServices.next(); ((Service) s.getValue()).stopApp(); } catch (Throwable e) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("Failed stopping service: " + s, e); } } } // remove everything allServices = services.entrySet().iterator(); while (allServices.hasNext()) { Map.Entry s = null; try { s = (Map.Entry) allServices.next(); clearShortCut(((ModuleClassID) s.getKey())); allServices.remove(); } catch (Throwable e) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("Failed remove service: " + s, e); } } } } /** * Ask a group to unregister and unload a service * * @param service handle to the service to be removed **/ synchronized private void removeServiceSync(ModuleClassID name, Service service) throws ServiceNotFoundException, ViolationException { // Weak check: you need to actually posess a handle to the // service object you're removing, not its name, but // you can fake by doing getService() first. Service p = (Service) services.get(name); if (p == null) { throw new ServiceNotFoundException(name.toString()); } if (p != service) { throw new ViolationException("Service registered for key was did not match provided instance :" + name); } services.remove(name); } /** * Ask a group to unregister and unload a service * * @param service handle to the service to be removed **/ protected void removeService(ModuleClassID name, Service service) throws ServiceNotFoundException, ViolationException { removeServiceSync(name, service); clearShortCut(name); // service.finalize(); FIXME. We probably need a terminate() // method instead. // FIXME: [jice@jxta.org 20011013] to make sure the service is // no-longer referenced, we should always return interfaces, and // have a way to cut the reference to the real service in the // interfaces. One way of doing that would be to have to levels // of indirection: we should keep one and return references to it. // when we want to cut the service loose, we should clear the // reference from the interface that we own before letting it go. // We need to study the consequences of doing that before implementing // it. } /** * {@inheritDoc} **/ abstract public boolean compatible(Element compat); /** * {@inheritDoc} **/ public Module loadModule(ID assigned, Advertisement impl) throws ProtocolNotSupportedException, PeerGroupException { return loadModule(assigned, (ModuleImplAdvertisement) impl, false); } /** * Load a Module from a ModuleImplAdv. * * <p/>Compatibility is checked and load is attempted. If compatible and * loaded successfuly, the resulting Module is initialized and returned. * In most cases the other loadModule() method should be preferred, since * unlike this one, it will seek many compatible implementation * advertisements and try them all until one works. The home group of the new * module (its' parent group if the new Module is a group) will be this group. * * @param assigned Id to be assigned to that module (usually its ClassID). * @param implAdv An implementation advertisement for that module. * @param privileged If {@code true} then the module is provided the true * group obj instead of just an interface to the group object. This is * normally used only for the group's defined services and applications. * @return Module the module loaded and initialized. * @throws ProtocolNotSupportedException The module is a protocol and * is disabled per the peer's configuration. * @throws PeerGroupException The module could not be loaded or initialized **/ protected Module loadModule( ID assigned, ModuleImplAdvertisement implAdv, boolean privileged ) throws ProtocolNotSupportedException, PeerGroupException { Element compat = implAdv.getCompat(); if (null == compat) { throw new IllegalArgumentException("No compatibility statement for : " + assigned); } if (!compatible(compat)) { if (LOG.isEnabledFor(Level.WARN)) { LOG.warn( "Incompatible Module : " + assigned) ; } throw new ProtocolNotSupportedException( "Incompatible Module : " + assigned ); } Module newMod = null; if( (null != implAdv.getCode()) && (null != implAdv.getUri()) ) { try { // Good one. Try it. Class clazz; try { clazz = loader.findClass( implAdv.getModuleSpecID() ); } catch ( ClassNotFoundException notLoaded ) { clazz = loader.defineClass( implAdv ); } if( null == clazz ) { throw new ClassNotFoundException( "Cannot load class (" + implAdv.getCode() + ") : " + assigned ); } newMod = (Module) clazz.newInstance(); newMod.init(privileged ? this : (PeerGroup) getInterface(), assigned, implAdv); if (LOG.isEnabledFor(Level.INFO)) { LOG.info("Loaded" + (privileged ? " privileged" : "") + " module : " + implAdv.getDescription() + " (" + implAdv.getCode() + ")" ); } } catch (Exception ex) { try { newMod.stopApp(); } catch (Throwable ignored) { // If this does not work, nothing needs to be done. ; } throw new PeerGroupException("Could not load module for : " + assigned + " ("+ implAdv.getDescription() + ")", ex ); } } else { throw new PeerGroupException( "Cannot load class for : " + assigned ); } // Publish or renew the lease of this adv since we're using it. try { if (discovery != null) { discovery.publish( implAdv, DEFAULT_LIFETIME, DEFAULT_EXPIRATION ); } } catch (Exception ignored) {;} // If we reached this point we're done. return newMod; } /** * {@inheritDoc} **/ public Module loadModule(ID assigned, ModuleSpecID specID, int where) { return loadModule(assigned, specID, where, false); } /** * Load a module from a ModuleSpecID * * <p/>Advertisement is sought, compatibility is checked on all candidates * and load is attempted. The first one that is compatible and loads * successfuly is initialized and returned. * * @param assignedID Id to be assigned to that module (usually its ClassID). * @param specID The specID of this module. * @param where May be one of: {@code Here}, {@code FromParent}, or {@ Both}, * meaning that the implementation advertisement will be searched in this * group, its parent or both. As a general guideline, the implementation * advertisements of a group should be searched in its propsective parent * (that is Here), the implementation advertisements of a group standard * service should be searched in the same group than where this group's * advertisement was found (that is, FromParent), while applications may be * sought more freely (Both). * @param privileged If {@code true} then the module is provided the true * group obj instead of just an interface to the group object. This is * normally used only for the group's defined services and applications. * @return Module the new module, or {@code null} if no usuable * implementation was found. */ protected Module loadModule(ID assignedID, ModuleSpecID specID, int where, boolean privileged) { boolean fromHere = (where == Here || where == Both); boolean fromParent = (where == FromParent || where == Both); List all = new ArrayList(); if( fromHere && (null != discovery) ) { Enumeration here = discoverSome(DiscoveryService.ADV, "MSID", specID.toString(), 120, ModuleImplAdvertisement.class); all.addAll( Collections.list(here) ); } if( fromParent && (null != getParentGroup()) && (null != parentGroup.getDiscoveryService()) ) { Enumeration parent = discoverSome(parentGroup.getDiscoveryService(), DiscoveryService.ADV, "MSID", specID.toString(), 120, ModuleImplAdvertisement.class); all.addAll( Collections.list(parent) ); } Iterator allModuleImpls = all.iterator(); Throwable recentFailure = null; while (allModuleImpls.hasNext()) { ModuleImplAdvertisement found = null; try { found = (ModuleImplAdvertisement) allModuleImpls.next();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -