1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package net.jini.lookup; 20 21 import java.io.IOException; 22 import net.jini.core.lookup.ServiceItem; 23 import org.apache.river.api.io.AtomicSerial; 24 import org.apache.river.api.io.AtomicSerial.GetArg; 25 26 /** 27 * The <code>ServiceDiscoveryEvent</code> class encapsulates the 28 * service discovery information made available by the event mechanism 29 * of the {@link net.jini.lookup.LookupCache LookupCache}. All listeners 30 * that an entity has registered with the cache's event mechanism will 31 * receive an event of type <code>ServiceDiscoveryEvent</code> upon 32 * the discovery, removal, or modification of one of the cache's services. 33 * This class is used by 34 * {@link net.jini.lookup.ServiceDiscoveryManager ServiceDiscoveryManager}. 35 * 36 * @author Sun Microsystems, Inc. 37 * 38 * @see ServiceDiscoveryManager 39 */ 40 @AtomicSerial 41 public class ServiceDiscoveryEvent extends java.util.EventObject { 42 private static final long serialVersionUID = -4654412297235019084L; 43 44 /** Represents the state of the service prior to the event. 45 * 46 * @serial 47 */ 48 private final ServiceItem preEventItem; 49 50 /** Represents the state of the service after the event. 51 * 52 * @serial 53 */ 54 private final ServiceItem postEventItem; 55 56 /** 57 * <p> 58 * The constructor of <code>ServiceDiscoveryEvent</code> takes 59 * three arguments:</p> 60 * <ul> 61 * <li>An instance of <code>Object</code> corresponding to the 62 * instance of <code>LookupCache</code> from which the given event 63 * originated</li> 64 * 65 * <li>A <code>ServiceItem</code> reference representing the state 66 * of the service (associated with the given event) prior to the 67 * occurrence of the event</li> 68 * 69 * <li>A <code>ServiceItem</code> reference representing the state 70 * of the service after the occurrence of the event</li> 71 * </ul> 72 * <p> 73 * If <code>null</code> is passed as the source parameter for the 74 * constructor, a <code>NullPointerException</code> will be thrown. 75 * </p><p> 76 * Depending on the nature of the discovery event, a null reference 77 * may be passed as one or the other of the remaining parameters, but 78 * never both. If <code>null</code> is passed as both the 79 * <code>preEventItem </code>and the <code>postEventItem</code> 80 * parameters, a <code>NullPointerException</code> will be thrown. 81 * </p><p> 82 * Note that the constructor will not modify the contents of either 83 * <code>ServiceItem</code> argument. Doing so can result in 84 * unpredictable and undesirable effects on future processing by the 85 * <code>ServiceDiscoveryManager</code>. That is why the effects of any 86 * such modification to the contents of either input parameter are 87 * undefined.</p> 88 * 89 * @param source an instance of <code>Object</code> corresponding 90 * to the instance of <code>LookupCache</code> from 91 which the given event originated. 92 * 93 * @param preEventItem a <code>ServiceItem</code> reference 94 * representing the state of the service (associated 95 * with the given event) prior to the occurrence of 96 * the event. 97 * 98 * @param postEventItem a <code>ServiceItem</code> reference 99 * representing the state of the service after the 100 * occurrence of the event. 101 * 102 * @throws NullPointerException if <code>null</code> is 103 * passed as the source parameter for the constructor, 104 * or if <code>null</code> is passed as both the 105 * <code>preEventItem </code>and the 106 * <code>postEventItem</code> parameters. 107 */ 108 public ServiceDiscoveryEvent( 109 Object source, 110 ServiceItem preEventItem, 111 ServiceItem postEventItem) 112 { 113 this(source, preEventItem, postEventItem, 114 nullCheck(source, preEventItem, postEventItem)); 115 } 116 117 private static boolean nullCheck( //Prevent finalizer attack. 118 Object source, 119 ServiceItem preEventItem, 120 ServiceItem postEventItem) throws NullPointerException 121 { 122 if((preEventItem == null && postEventItem == null)|| source == null) 123 throw new NullPointerException(); 124 return true; 125 } 126 127 private ServiceDiscoveryEvent( 128 Object source, 129 ServiceItem preEventItem, 130 ServiceItem postEventItem, 131 boolean check) 132 { 133 super(source); 134 if(preEventItem != null) 135 this.preEventItem = preEventItem.clone(); 136 else this.preEventItem = null; 137 if(postEventItem != null) 138 this.postEventItem = postEventItem.clone(); 139 else this.postEventItem = null; 140 } 141 142 /** 143 * AtomicSerial constructor 144 * @param arg 145 * @throws IOException 146 * @throws java.lang.ClassNotFoundException 147 */ 148 public ServiceDiscoveryEvent(GetArg arg) throws IOException, ClassNotFoundException{ 149 // source cannot be null in the constructor, but it is after 150 // deserialization because it is transient. 151 this(Boolean.TRUE, arg.get("preEventItem", null, ServiceItem.class), 152 arg.get("postEventItem", null, ServiceItem.class), false); 153 source = null; 154 } 155 156 /** 157 * Returns an instance of a <code>ServiceItem</code> containing the 158 * service reference corresponding to the given event. The service 159 * state reflected in the returned service item is the state of the 160 * service prior to the occurrence of the event. 161 * <p> 162 * If the event is a discovery event (as opposed to a removal or 163 * modification event), then this method will return <code>null</code> 164 * because the discovered service had no state in the cache prior to 165 * its discovery. 166 * <p> 167 * Because making a copy can be a very expensive process, this 168 * method does not return a copy of the service reference associated 169 * with the given event. Rather, it returns the appropriate service 170 * reference from the cache itself. Due to this cost, listeners that 171 * receive a <code>ServiceDiscoveryEvent</code> must not modify the 172 * contents of the object returned by this method; doing so could 173 * cause the state of the cache to become corrupted or inconsistent 174 * because the objects returned by this method are also members of 175 * the cache. This potential for corruption or inconsistency is why 176 * the effects of modifying the object returned by this accessor 177 * method are undefined. 178 * 179 * @return ServiceItem containing the service reference corresponding 180 * to the given event. 181 */ 182 public ServiceItem getPreEventServiceItem() 183 { 184 return preEventItem.clone(); 185 } 186 187 /** 188 * Returns an instance of a <code>ServiceItem</code> containing the 189 * service reference corresponding to the given event. The service 190 * state reflected in the returned service item is the state of the 191 * service after the occurrence of the event. 192 * <p> 193 * If the event is a removal event, then this method will return 194 * <code>null</code> because the discovered service has no state in 195 * the cache after it is removed from the cache. 196 * <p> 197 * Because making a copy can be a very expensive process, this 198 * method does not return a copy of the service reference associated 199 * with the given event. Rather, it returns the appropriate service 200 * reference from the cache itself. Due to this cost, listeners that 201 * receive a <code>ServiceDiscoveryEvent</code> must not modify the 202 * contents of the object returned by this method; doing so could 203 * cause the state of the cache to become corrupted or inconsistent 204 * because the objects returned by this method are also members of 205 * the cache. This potential for corruption or inconsistency is why 206 * the effects of modifying the object returned by this accessor 207 * method are undefined. 208 * 209 * @return ServiceItem containing the service reference corresponding 210 * to the given event. 211 */ 212 public ServiceItem getPostEventServiceItem() 213 { 214 return postEventItem.clone(); 215 } 216 217 }