📄 genericpeergroup.java
字号:
// Here's one. // First check that the MSID is realy the one we're // looking for. It could have appeared somewhere else // in the adv than where we're looking, and discovery // doesn't know the difference. if (!found.getModuleSpecID().equals(specID)) { continue; } // Try it. If "found" is not useable it will // trigger an exception and we'll try the next. Module newMod = loadModule(assignedID, found, privileged); if( null != discovery ) { try { discovery.publish(found, DEFAULT_LIFETIME, DEFAULT_EXPIRATION); } catch( IOException nopublish ) { if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("Could not publish module impl adv.", nopublish); } } } // If we reach that point, the module is good. return newMod; } catch (Throwable e) { recentFailure = e; if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("Not a usable impl adv: ", e); } } } // Throw an exception if there was a recent failure. if( null != recentFailure ) { if( recentFailure instanceof Error ) { throw (Error) recentFailure; } else if( recentFailure instanceof RuntimeException ) { throw (RuntimeException) recentFailure; } else { throw new UndeclaredThrowableException( recentFailure ); } } if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("Could not find a loadable implementation of SpecID: " + specID); } return null; } /** * {@inheritDoc} **/ public ConfigParams getConfigAdvertisement() { return configAdvertisement; } /** * {@inheritDoc} **/ protected void setConfigAdvertisement(ConfigParams config) { configAdvertisement = config; } /* * Now comes the implementation of the public API, including the * API mandated by the Service interface. */ /** * {@inheritDoc} * * <p/>It is not recommended to overload this method. Instead, subclassers * should overload either or both of * {@link #initFirst(PeerGroup,ID,Advertisement)} and {@link #initLast()}. * If this method is to be overloaded, the overloading method must * invoke <code>super.init</code>. * * <p/>This method invokes <code>initFirst</code> * with identical parameters. <code>initLast</initLast> does not take * parameters since the relevant information can be obtained from the * group following completion of the <code>initFirst</code> phase. * The resulting values may be different from the parameters to * <code>initFirst</code> since <code>initFirst</code> may * be overLoaded and the overloading method may modify these parameters * when calling <code>super.initFirst</code>. (See * {@link net.jxta.impl.Platform} for an example of such a case). * * <p/>Upon completion, the group object is marked as completely initialized * in all cases. Once a group object is completely initialized, it becomes * sensitive to reference counting. * * <p/>In the future this method may become final. **/ public void init(PeerGroup homeGroup, ID assignedID, Advertisement impl) throws PeerGroupException { try { initFirst(homeGroup, assignedID, impl); initLast(); } finally { // This must be done in all cases. initComplete = true; } } /** * Performs all initialization steps that need to be performed * before any subclass initialization is performed. * * <p/>Classes that override this method should always call * <code>super.initFirst()</code> <strong>before</strong> doing * any of their own work. * * @param homeGroup The group that serves as a parent to this group. * @param assignedID The unique ID assigned to this module. For * group this is the group ID or <code>null</code> if a group ID * has not yet been assigned. If null is passed, GenericPeerGroup * choses a new group ID. * @param impl The ModuleImplAdvertisement which defines this * group's implementation. **/ protected void initFirst(PeerGroup homeGroup, ID assignedID, Advertisement impl) throws PeerGroupException { this.implAdvertisement = (ModuleImplAdvertisement) impl; this.parentGroup = homeGroup; if( null != parentGroup ) { jxtaHome = parentGroup.getStoreHome(); } try { // FIXME 20030919 bondolo@jxta.org This setup doesnt give us any // capability to use seed material or parent group. if (null == assignedID) { if( "cbid".equals( IDFactory.getDefaultIDFormat() ) ) { throw new IllegalStateException( "Cannot generate group id for cbid group" ); } else { assignedID = IDFactory.newPeerGroupID(); } } else { if (parentGroup != null) { DiscoveryService disco = parentGroup.getDiscoveryService(); if( null != disco ) { Enumeration found = disco.getLocalAdvertisements(DiscoveryService.GROUP, "GID", assignedID.toString()); if (found.hasMoreElements()) { peerGroupAdvertisement = (PeerGroupAdvertisement) found.nextElement(); } } } } if (!(assignedID instanceof PeerGroupID)) { throw new PeerGroupException("assignedID must be a peer group ID"); } peerAdvertisement.setPeerGroupID((PeerGroupID) assignedID); // // make sure the parent group is the required group // if (null != peerAdvertisement.getPeerGroupID().getParentPeerGroupID()) { // if (null == parentGroup) { // throw new PeerGroupException("Group requires parent group : " + peerAdvertisement.getPeerGroupID().getParentPeerGroupID()); // } else if (!parentGroup.getPeerGroupID().equals(peerAdvertisement.getPeerGroupID().getParentPeerGroupID())) { // throw new PeerGroupException("Group requires parent group : " + peerAdvertisement.getPeerGroupID().getParentPeerGroupID() + ". Provided parent was : " + parentGroup.getPeerGroupID()); // } // } // Do our part of the PeerAdv construction. // FIXME bondolo 20051011 if ((configAdvertisement != null) && (configAdvertisement instanceof PlatformConfig)) { PlatformConfig platformConfig = (PlatformConfig) configAdvertisement; // Normally there will be a peer ID and a peer name in the config. PeerID configPID = (PeerID) platformConfig.getPeerID(); if( (null == configPID) || (ID.nullID == configPID) ) { if( "cbid".equals( IDFactory.getDefaultIDFormat() ) ) { // Get our peer-defined parameters in the configAdv XMLElement param = (XMLElement) platformConfig.getServiceParam( PeerGroup.membershipClassID ); if( null == param ) { throw new IllegalArgumentException( PSEConfigAdv.getAdvertisementType() +" could not be located" ); } Advertisement paramsAdv = null; try { paramsAdv = AdvertisementFactory.newAdvertisement( (XMLElement) param ); } catch( NoSuchElementException noadv ) {;} if( !(paramsAdv instanceof PSEConfigAdv) ) { throw new IllegalArgumentException( "Provided Advertisement was not a " + PSEConfigAdv.getAdvertisementType() ); } PSEConfigAdv config = (PSEConfigAdv) paramsAdv; Certificate clientRoot = config.getCertificate(); byte [] pub_der = clientRoot.getPublicKey().getEncoded(); platformConfig.setPeerID( IDFactory.newPeerID( (PeerGroupID) assignedID, pub_der ) ); } else { platformConfig.setPeerID( IDFactory.newPeerID( (PeerGroupID) assignedID) ); } } peerAdvertisement.setPeerID(platformConfig.getPeerID()); peerAdvertisement.setName(platformConfig.getName()); peerAdvertisement.setDesc(platformConfig.getDesc()); } else { if (null == parentGroup) { // If we did not get a valid peer id, we'll initialize it here. peerAdvertisement.setPeerID(IDFactory.newPeerID((PeerGroupID) assignedID)); } else { // We're not the platform, which is the authoritative source of these values. peerAdvertisement.setPeerID(parentGroup.getPeerAdvertisement().getPeerID()); peerAdvertisement.setName(parentGroup.getPeerAdvertisement().getName()); peerAdvertisement.setDesc(parentGroup.getPeerAdvertisement().getDesc()); } } if (peerGroupAdvertisement == null) { // No existing gadv. OK then we're creating the group or we're // the platform, it seems. Start a grp adv with the essentials // that we know. peerGroupAdvertisement = (PeerGroupAdvertisement) AdvertisementFactory.newAdvertisement(PeerGroupAdvertisement.getAdvertisementType()); peerGroupAdvertisement.setPeerGroupID((PeerGroupID) assignedID); peerGroupAdvertisement.setModuleSpecID(implAdvertisement.getModuleSpecID()); } else { published = true; } // If we still do not have a config adv, make one with the minimal info in it. // All groups but the Platform and the netPG are in that case. // In theory a plain ConfigParams would be enough for subgroups. But for now // GenericPeerGroup always has a full Platformconfig and there is no other concrete // ConfigParams subclass. if (configAdvertisement == null) { PlatformConfig conf = (PlatformConfig) AdvertisementFactory.newAdvertisement(PlatformConfig.getAdvertisementType()); conf.setPeerID(peerAdvertisement.getPeerID()); conf.setName(peerAdvertisement.getName()); conf.setDesc(peerAdvertisement.getDesc()); configAdvertisement = conf; } // Merge service params with those specified by the group (if any). The only // policy, right now, is to give peer params the precedence over group params. Hashtable grpParams = peerGroupAdvertisement.getServiceParams(); Enumeration keys = grpParams.keys(); while (keys.hasMoreElements()) { ID key = (ID) keys.nextElement(); Element e = (Element) grpParams.get(key); if (configAdvertisement.getServiceParam(key) == null) { configAdvertisement.putServiceParam(key, e); } } /* * Now seems like the right time to attempt to register the group. * The only trouble is that it could cause the group to * be used before all the services are initialized, but on the * other hand, we do not want to let a redundant group go through * it's service initialization because that would cause irreparable * damage to the legitimate instance. There should be a synchro on * on the get<service>() and lookupService() routines. */ if (globalRegistry.registerInstance((PeerGroupID) assignedID, this) == false) { throw new PeerGroupException("Group already instantiated"); } } catch (Throwable any) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error( "Group init failed", any ); } if (any instanceof Error) { throw (Error) any; } else if (any instanceof RuntimeException) { throw (RuntimeException) any; } else if (any instanceof PeerGroupException) { throw (PeerGroupException) any; } throw new PeerGroupException( "Group init failed", any ); } ThreadGroup parentThreadGroup = (null != this.parentGroup) ? parentGroup.getHomeThreadGroup() : Thread.currentThread().getThreadGroup(); threadGroup = new ThreadGroup(parentThreadGroup, "Group " + peerGroupAdvertisement.getPeerGroupID()); /* * The rest of construction and initialization are left to the * group subclass, between here and the begining for initLast. * That should include instanciating and setting the endpoint, and * finally supplying it with endpoint protocols. * That also includes instanciating the appropriate services * and registering them. * For an example, see the StdPeerGroup class. */ } /** * Perform all initialization steps that need to be performed * after any subclass initialization is performed. * * <p/>Classes that override this method should always call super.initLast * <strong>after</strong> doing any of their own work. **/ protected void initLast() throws PeerGroupException { if (LOG.isEnabledFor(Level.INFO)) { StringBuffer configInfo = new StringBuffer("Configuring Group : " + getPeerGroupID()); if (implAdvertisement != null) { configInfo.append("\n\tImplementation :"); configInfo.append("\n\t\tModule Spec ID: " + implAdvertisement.getModuleSpecID()); configInfo.append("\n\t\tImpl Description : " + implAdvertisement.getDescription()); configInfo.append("\n\t\tImpl URI : " + implAdvertisement.getUri()); configInfo.append("\n\t\tImpl Code : " + implAdvertisement.getCode()); } configInfo.append("\n\tGroup Params :"); configInfo.append("\n\t\tModule Spec ID : " + implAdvertisement.getModuleSpecID()); configInfo.append("\n\t\tPeer Group ID : " + getPeerGroupID()); configInfo.append("\n\t\tGroup Name : " + getPeerGroupName()); configInfo.append("\n\t\tPeer ID in Group : " + getPeerID()); configInfo.append("\n\tConfiguration :"); if (null == parentGroup) { configInfo.append("\n\t\tHome Group : (none)"); } else { configInfo.append("\n\t\tHome Group : \"" + parentGroup.getPeerGroupName() + "\" / " + parentGroup.getPeerGroupID()); } configInfo.append("\n\t\tServices :"); Iterator eachService = services.entrySet().iterator(); while (eachService.hasNext()) { Map.Entry anEntry = (Map.Entry) eachService.next(); ModuleClassID aMCID = (ModuleClassID) anEntry.getKey(); ModuleImplAdvertisement anImplAdv = (ModuleImplAdvertisement) ((Service)anEntry.getValue()).getImplAdvertisement(); configInfo.append( "\n\t\t\t" + aMCID + "\t"+ anImplAdv.getDescription() ); } LOG.info(configInfo); } } /** * {@inheritDoc} * * <p/>In practice, it means starting its' main application, but that's for * subclasses. **/ public int startApp(String[] arg) { return 0; } /** * {@inheritDoc} * * <p/>PeerGroupInterface's stopApp() does nothing. Only a real reference * to the group object permits to stop it without going through ref * counting. */ public void stopApp() { globalRegistry.unRegisterInstance(peerGroupAdvertisement.getPeerGroupID(), this); removeAllServicesSync(); // Explicitly unreference our home group in order to allow it // to terminate if this group object was itself the last reference // to it. if (parentGroup != null) { parentGroup.unref(); parentGroup = null; } } /** * May be called by a module which has a direct reference to the group * object and wants to notify its abandoning it. Has no effect on the real * group object. */ public void unref() {} /** * Called every time an interface object that refers to this group * goes away, either by being finalized or by its unref() method being * invoked explicitly. */ protected void decRefCount() { synchronized (this) { --masterRefCount; if (LOG.isEnabledFor(Level.INFO)) { Throwable trace = new Throwable( "Stack Trace" ); StackTraceElement elements[] = trace.getStackTrace(); LOG.info("[" + getPeerGroupID() + "] GROUP REF COUNT DECCREMENTED TO: " + masterRefCount + " by\n\t" + elements[2] ); } if (masterRefCount != 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -