📄 genericpeergroup.java
字号:
/* * Copyright (c) 2001-2002 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Sun Microsystems, Inc. for Project JXTA." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact Project JXTA at http://www.jxta.org. * * 5. Products derived from this software may not be called "JXTA", * nor may "JXTA" appear in their name, without prior written * permission of Sun. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL SUN MICROSYSTEMS OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of Project JXTA. For more * information on Project JXTA, please see * <http://www.jxta.org/>. * * This license is based on the BSD license adopted by the Apache Foundation. * * $Id: GenericPeerGroup.java,v 1.119 2006/08/24 19:48:11 bondolo Exp $ */package net.jxta.impl.peergroup;import java.net.URI;import java.net.URL;import java.security.cert.Certificate;import java.util.ArrayList;import java.util.Collections;import java.util.Enumeration;import java.util.Hashtable;import java.util.Iterator;import java.util.List;import java.util.Vector;import java.util.Map;import java.io.IOException;import java.lang.reflect.UndeclaredThrowableException;import java.util.NoSuchElementException;import org.apache.log4j.Level;import org.apache.log4j.Logger;import net.jxta.access.AccessService;import net.jxta.discovery.DiscoveryService;import net.jxta.document.Advertisement;import net.jxta.document.AdvertisementFactory;import net.jxta.document.Element;import net.jxta.document.XMLElement;import net.jxta.endpoint.EndpointService;import net.jxta.id.ID;import net.jxta.id.IDFactory;import net.jxta.membership.MembershipService;import net.jxta.peer.PeerID;import net.jxta.peer.PeerInfoService;import net.jxta.peergroup.PeerGroup;import net.jxta.peergroup.PeerGroupID;import net.jxta.pipe.PipeService;import net.jxta.platform.JxtaLoader;import net.jxta.platform.Module;import net.jxta.platform.ModuleClassID;import net.jxta.platform.ModuleSpecID;import net.jxta.protocol.ModuleImplAdvertisement;import net.jxta.protocol.ConfigParams;import net.jxta.protocol.PeerAdvertisement;import net.jxta.protocol.PeerGroupAdvertisement;import net.jxta.rendezvous.RendezVousService;import net.jxta.resolver.ResolverService;import net.jxta.service.Service;import net.jxta.exception.PeerGroupException;import net.jxta.exception.ProtocolNotSupportedException;import net.jxta.exception.ServiceNotFoundException;import net.jxta.exception.ViolationException;import net.jxta.impl.loader.RefJxtaLoader;import net.jxta.impl.protocol.PlatformConfig;import net.jxta.impl.protocol.PSEConfigAdv;/** * Provides common services for most peer group implementations. **/public abstract class GenericPeerGroup implements PeerGroup { /** * Log4J Logger **/ private static final Logger LOG = Logger.getLogger(GenericPeerGroup.class.getName()); /** * The loader - use the getter and setter for modifying the ClassLoader for * a security manager. * * <p/>This should eventually be group scoped rather than implementation * scoped. We are currently allowing classes to loaded into contexts which * they should not be known. **/ private static JxtaLoader loader = new RefJxtaLoader( new URL[0], new CompatibilityEquater() { public boolean compatible( Element test ) { return StdPeerGroup.isCompatible( test ); } } ); // FIXME 20060217 bondolo We should be loading the class loader with the // net.jxta.impl.config#stdPeerGroupClass moduleImplAdv so that it is used // for peer group instances. /* * Shortcuts to well known services. */ private EndpointService endpoint; private ResolverService resolver; private DiscoveryService discovery; private PipeService pipe; private MembershipService membership; private RendezVousService rendezvous; private PeerInfoService peerinfo; private AccessService access; /** * This peer's advertisement in this group. **/ private final PeerAdvertisement peerAdvertisement; /** * This group's advertisement. **/ private PeerGroupAdvertisement peerGroupAdvertisement = null; /** *This group's implAdvertisement. **/ private ModuleImplAdvertisement implAdvertisement = null; /** * This peer's config advertisement. **/ protected ConfigParams configAdvertisement = null; /** * This service implements a group but, being a Service, it runs inside of * some group. That's its home group. * * <p/>Exception: The platform peer group does not have a parent group. It * has to be entirely self sufficient. **/ protected PeerGroup parentGroup = null; /** * The location of our store **/ protected URI jxtaHome = null; /** * All the plug-ins that do the work. * * <p/><ul> * <li>Keys are {@link net.jxta.platform.ModuleClassID}.</li> * <li>Values are {@link net.jxta.service.Service}.</li> * </ul> **/ private final Hashtable<ModuleClassID,Service> services = new Hashtable<ModuleClassID,Service>(); /** * {@code true} when we have decided to stop this group. **/ private volatile boolean stopping = false; /** * {@code true} when the PG adv has been published. **/ private boolean published = false; // assume it hasn't /** * Counts the number of times an interface to this group has been given out. * This is decremented everytime an interface object is GCed or * its owner calls unref(). * * <p/>When it reaches zero, if it is time to tear-down the group instance; * nomatter what the GC thinks. There are threads that need to be stopped * before the group instance object ever becomes un-reachable. **/ private int masterRefCount = 0; /** * Is true when at least one interface object has been generated AFTER * initComplete has become true. If true, the group stops when its ref * count reaches zero. **/ private boolean stopWhenUnreferenced = false; /** * Is set to true when init is completed enough that it makes sense * to perform ref-counting. **/ private volatile boolean initComplete = false; /** * The thread group in which threads created by this group or services of * this group should live. **/ private ThreadGroup threadGroup = null; /** * {@inheritDoc} **/ public static JxtaLoader getJxtaLoader() { return loader; } /** * Set a modified version of the Jxta ClassLoader **/ public static void setJxtaLoader(JxtaLoader newLoader) { loader = newLoader; } public GenericPeerGroup() { // Start building our peer adv. peerAdvertisement = (PeerAdvertisement) AdvertisementFactory.newAdvertisement(PeerAdvertisement.getAdvertisementType()); } /** * {@inheritDoc} **/ public boolean equals( Object target ) { if( !(target instanceof PeerGroup)) { return false; } PeerGroup targetAsPeerGroup = (PeerGroup) target; // both null or both non-null. if((null == parentGroup) && (null != targetAsPeerGroup.getParentGroup())) { return false; } if((null != parentGroup) && (null == targetAsPeerGroup.getParentGroup())) { return false; } if( (null != parentGroup) && !parentGroup.equals(targetAsPeerGroup.getParentGroup()) ) { return false; } // and same peer ids. return getPeerGroupID().equals(targetAsPeerGroup.getPeerGroupID()); } /** * {@inheritDoc} **/ public int hashCode() { // before init we must fail. if( (null == peerAdvertisement) || (null == getPeerGroupID()) ) { throw new IllegalStateException( "PeerGroup not sufficiently initialized" ); } // XXX 20050907 bondolo including parentGroup would improve the hash. return getPeerGroupID().hashCode(); } /** * {@inheritDoc} * * <p/>An implementation suitable for debugging. <b>Don't try to parse * this string!</b> All of the information is available from other sources. **/ public String toString() { if( null == getPeerGroupID() ) { return super.toString(); } StringBuffer result = new StringBuffer(); result.append( getPeerGroupID().toString() ); String peerGroupName = peerGroupAdvertisement.getName(); if( null != peerGroupName) { result.append( " \"" ); result.append( peerGroupName ); result.append( '\"' ); } if( null != parentGroup ) { result.append( " / " ); result.append( parentGroup.toString() ); } return result.toString(); } /** * Returns the Thread Group in which threads for this peer group will live. * * @return ThreadGroup **/ public ThreadGroup getHomeThreadGroup() { return threadGroup; } // Just a small wrapper around two common idioms that we do use here and // there. private Enumeration discoverSome(int type, String attr, String value, int seconds, Class thisClass) { return discoverSome(discovery, type, attr, value, seconds, thisClass); } private Enumeration discoverSome(DiscoveryService discovery, int type, String attr, String value, int seconds, Class thisClass) { Vector results = new Vector(); try { int count = 0; Enumeration res; do { res = discovery.getLocalAdvertisements(type, attr, value); while (res.hasMoreElements()) { Advertisement a = (Advertisement) res.nextElement(); if (thisClass.isInstance(a)) { results.add(a); } } if (results.size() > 0) { break; } if (count % 30 == 0) { discovery.getRemoteAdvertisements(null, type, attr, value, 20); } Thread.sleep(1000); } while (count++ < seconds); } catch (Exception whatever) { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Failure during discovery : ", whatever); } } return results.elements(); } private Advertisement discoverOne(int type, String attr, String value, int seconds, Class thisClass) { Enumeration res = discoverSome(type, attr, value, seconds, thisClass); if (!res.hasMoreElements()) { return null; } return (Advertisement) res.nextElement(); } /* * Shortcuts to the standard basic services. */ private void setShortCut(ModuleClassID name, Service service) { if (endpointClassID.equals(name)) { endpoint = (EndpointService) service; return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -