📄 routeadvertisement.java
字号:
/*Copyright (c) 2001-2007 Sun Microsystems, Inc. All rights reserved. * * The Sun Project JXTA(TM) Software License * * 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 Sun Microsystems, Inc. for JXTA(TM) technology." * 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. * * JXTA is a registered trademark of Sun Microsystems, Inc. in the United * States and other countries. * * Please see the license information page at : * <http://www.jxta.org/project/www/license.html> for instructions on use of * the license in source files. * * ==================================================================== * * 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. */package net.jxta.protocol;import net.jxta.document.AdvertisementFactory;import net.jxta.document.ExtendableAdvertisement;import net.jxta.endpoint.EndpointAddress;import net.jxta.id.ID;import net.jxta.id.IDFactory;import net.jxta.peer.PeerID;import net.jxta.peergroup.PeerGroupID;import java.io.ByteArrayInputStream;import java.io.InputStream;import java.util.ArrayList;import java.util.Collection;import java.util.Enumeration;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.ListIterator;import java.util.Set;import java.util.Vector;/** * Advertisement used to represent a route to a peer. Routes are represented in * a generic manner as a sequence of hops to reach the destination. Each hop * represent a potential relay peer in the route: * <p/> * <pre> Dest * hop 1 * hop 2 * hop 3 * .... * hop n * </pre> * <p/> * A route can have as many hops as necessary. Hops are implicitly ordered * starting from the hop with the shortest route to reach the destination. If a * peer cannot reach directly the dest, it should try to reach in descending * order one of the listed hops. Some hops may have the same physical distance * to the destination. Some hops may define alternative routes. * <p/> * The destination and hops are defined using a AccessPointAdvertisements. * * @see net.jxta.protocol.PeerAdvertisement * @see net.jxta.protocol.AccessPointAdvertisement */public abstract class RouteAdvertisement extends ExtendableAdvertisement implements Cloneable { public static final String DEST_PID_TAG = "DstPID"; /** * AccessPointAdvertisement of destination peer. */ private transient AccessPointAdvertisement dest = (AccessPointAdvertisement) AdvertisementFactory.newAdvertisement(AccessPointAdvertisement.getAdvertisementType()); /** * Semi-ordered list of alternative hops to the destination. */ private transient Vector<AccessPointAdvertisement> hops = new Vector<AccessPointAdvertisement>(); /** * Cached value for {@link #getID()} */ private transient ID hashID = null; /** * construct a new route * <p/> * <b>WARNING hops may be MODIFIED.</b> * * @param destPid destination * @param firsthop first hop node ID * @param hops routes * @return the new route */ public static RouteAdvertisement newRoute(PeerID destPid, PeerID firsthop, Vector<AccessPointAdvertisement> hops) { if (destPid == null) { throw new IllegalArgumentException("Missing destination peer id."); } for (AccessPointAdvertisement apa : hops) { if (null == apa) { throw new IllegalArgumentException("Bad route. null APA."); } if (apa.getPeerID() == null) { throw new IllegalArgumentException("Bad route. Incomplete APA."); } } RouteAdvertisement route = (RouteAdvertisement) AdvertisementFactory.newAdvertisement(RouteAdvertisement.getAdvertisementType()); route.setDestPeerID(destPid); // set the route hops route.setHops(hops); // check if the given first hop is already in the route if not add it // (note: we do not expect it to be there, but it is acceptable). if (firsthop != null) { AccessPointAdvertisement ap = route.getFirstHop(); if (ap == null || !ap.getPeerID().equals(firsthop)) { ap = (AccessPointAdvertisement) AdvertisementFactory.newAdvertisement(AccessPointAdvertisement.getAdvertisementType()); ap.setPeerID(firsthop); route.setFirstHop(ap); } } return route; } /** * {@inheritDoc} */ @Override public RouteAdvertisement clone() { try { RouteAdvertisement a = (RouteAdvertisement) super.clone(); a.setDest(getDest()); // deep copy of the hops Vector<AccessPointAdvertisement> clonehops = getVectorHops(); ListIterator<AccessPointAdvertisement> eachHop = clonehops.listIterator(); while (eachHop.hasNext()) { eachHop.set(eachHop.next().clone()); } a.setHops(clonehops); return a; } catch (CloneNotSupportedException impossible) { throw new Error("Object.clone() threw CloneNotSupportedException", impossible); } } /** * makes a copy of a route advertisement * that only contains PID not endpoint addresses * * @return object clone route advertisement */ public RouteAdvertisement cloneOnlyPIDs() { RouteAdvertisement routeAdvertisement; try { routeAdvertisement = (RouteAdvertisement) super.clone(); routeAdvertisement.setDestEndpointAddresses(new Vector<String>()); } catch (CloneNotSupportedException impossible) { throw new Error("Object.clone() threw CloneNotSupportedException", impossible); } // deep copy of the hops Vector<AccessPointAdvertisement> clonehops = routeAdvertisement.getVectorHops(); ListIterator<AccessPointAdvertisement> eachHop = clonehops.listIterator(); while (eachHop.hasNext()) { AccessPointAdvertisement aHop = eachHop.next(); eachHop.set(aHop.clone()); } routeAdvertisement.setHops(clonehops); return routeAdvertisement; } /** * Compare if two routes are equals. Equals means same destination with the * same endpoint addresses and thee same number of hops and the same * endpoint addresses for each hop. * * @param target the route to compare against * @return boolean true if the route is equal to this route otherwise false */ @Override public boolean equals(Object target) { if (this == target) { return true; } if (!(target instanceof RouteAdvertisement)) { return false; } RouteAdvertisement route = (RouteAdvertisement) target; // check the destination if (!dest.equals(route.getDest())) { return false; } // check each of the hops // routes need to have the same size if (hops.size() != route.size()) { return false; } int index = 0; for (AccessPointAdvertisement hop : route.hops) { if (!hop.equals(hops.get(index++))) { return false; } } return true; } /** * {@inheritDoc} */ @Override public int hashCode() { if (null != dest.getPeerID()) { return dest.getPeerID().hashCode(); } else { // force all incomplete advertisements to hash to the same place. return 1; } } /** * Returns the identifying type of this Advertisement. * * @return String the type of advertisement */ public static String getAdvertisementType() { return "jxta:RA"; } /** * {@inheritDoc} */ @Override public final String getBaseAdvType() { return getAdvertisementType(); } /** * {@inheritDoc} */ @Override public synchronized ID getID() { if (null == dest.getPeerID()) { throw new IllegalStateException("Destination peerID not defined. Incomplete RouteAdvertisement"); } if (hashID == null) { try { // We have not yet built it. Do it now byte[] seed = getAdvertisementType().getBytes("UTF-8"); InputStream in = new ByteArrayInputStream(dest.getPeerID().toString().getBytes("UTF-8")); hashID = IDFactory.newCodatID((PeerGroupID) dest.getPeerID().getPeerGroupID(), seed, in); } catch (Exception ez) { return ID.nullID; } } return hashID; } /** * Returns the route destination Peer ID * * @return peerID of the destination of the route */ public PeerID getDestPeerID() { return dest.getPeerID(); } /** * Sets the route destination peer id. * * @param pid route destination peerID */ public void setDestPeerID(PeerID pid) { if ((null != pid) && (null != dest.getPeerID()) && (!pid.equals(dest.getPeerID()))) { throw new IllegalStateException("Changing the peer id of the destination APA." + pid + " != " + dest.getPeerID()); } dest.setPeerID(pid); // recalculate hash. synchronized (this) { hashID = null; } } /** * Returns the destination access point. <b>This does <i>NOT</i> copy * the AccessPointAdvertisement</b>. * * @return AccessPointAdvertisement of the destination peer. * @deprecated Because this method unsafely exposes destination AccessPointAdvertisement it will be removed. */ @Deprecated public AccessPointAdvertisement getDest() { return dest; } /** * Sets the access point of the destination. <b>This does <i>NOT</i> copy * the AccessPointAdvertisement</b>. * * @param ap AccessPointAdvertisement of the destination peer */ public void setDest(AccessPointAdvertisement ap) { PeerID destPid = dest.getPeerID(); this.dest = ap.clone(); if ((null != destPid) && (null != dest.getPeerID()) && (!destPid.equals(dest.getPeerID()))) { throw new IllegalStateException("Changed the peer id of the destination APA." + destPid + " != " + dest.getPeerID()); } if (null != destPid) { dest.setPeerID(destPid); } // recalculate hash. synchronized (this) { hashID = null; } } /** * Add a new list of EndpointAddresses to the Route Destination access * point * * @param addresses vector of endpoint addresses to add to the * destination access point. Warning: The vector of endpoint addresses * is specified as a vector of String. Each string representing * one endpoint address. * @deprecated Use {@link #addDestEndpointAddresses(List<EndpointAddress>)} instead. */ @Deprecated public void addDestEndpointAddresses(Vector<String> addresses) { dest.addEndpointAddresses(addresses); } /** * Clears all endpoint addresses associated with the destination peer. */ public void clearDestEndpointAddresses() { dest.clearEndpointAddresses(); } /** * Add the specified endpoint address to destination peer. * * @param addr EndpointAddress to add. */ public void addDestEndpointAddress(EndpointAddress addr) { dest.addEndpointAddress(addr); } /** * Add all of the specified endpoint addresses to destination peer. * * @param addrs EndpointAddresses to add. */ public void addDestEndpointAddresses(List<EndpointAddress> addrs) { dest.addEndpointAddresses(addrs); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -