/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.jini.discovery; import net.jini.core.discovery.LookupLocator; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import net.jini.core.lookup.ServiceID; /** * Encapsulate the details of unmarshaling an incoming multicast * announcement packet. * * @author Sun Microsystems, Inc. * * @see OutgoingMulticastAnnouncement */ public class IncomingMulticastAnnouncement { /** * The ServiceID that has been announced. */ protected ServiceID serviceID; /** * The LookupLocator that has been announced. */ protected LookupLocator locator; /** * The groups of which the announcing lookup service is a member. */ protected String[] groups; /** * Current version of the multicast announcement protocol. */ protected final int protoVersion = 1; /** * Construct a new object, initialized by unmarshaling the * contents of a multicast announcement packet. * * @param p the packet to unmarshal * @exception IOException a problem occurred in unmarshaling the * packet */ public IncomingMulticastAnnouncement(DatagramPacket p) throws IOException { ByteArrayInputStream bs = new ByteArrayInputStream(p.getData()); DataInputStream ds = new DataInputStream(bs); int proto = ds.readInt(); if (proto != protoVersion) throw new IOException("unsupported protocol version: " + proto); String host = ds.readUTF(); int port = ds.readInt(); if (port <= 0 || port >= 65536) throw new IOException("port number out of range: " + port); locator = new LookupLocator(host, port); serviceID = new ServiceID(ds); int groupCount = ds.readInt(); // We know that the minimal length of a string written with // DataOutput.writeUTF is two bytes (for the empty string), so // we make some attempt to see if the count can plausibly fit // into this packet. if (groupCount < 0 || groupCount > bs.available() / 2) throw new IOException("group count invalid: " + groupCount); groups = new String[groupCount]; for (int i = 0; i < groups.length; i++) { groups[i] = ds.readUTF(); } } /** * Return the ServiceID of the announcing lookup service. * @return the service ID of the announcing lookup service */ public ServiceID getServiceID() { return serviceID; } /** * Return a LookupLocator for performing unicast discovery of the * announcing lookup service. * @return a <code>LookupLocator</code> for performing unicast * discovery of the announcing lookup service */ public LookupLocator getLocator() { return locator; } /** * Return the groups of which the announcing lookup service is a * member. * @return the groups of which the announcing lookup service is a * member. */ public String[] getGroups() { return groups; } public int hashCode() { return serviceID.hashCode(); } /** * Two announcements are equal if they have the same service ID. */ public boolean equals(Object o) { return o instanceof IncomingMulticastAnnouncement && ((IncomingMulticastAnnouncement) o).serviceID.equals(serviceID); } }