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 */ 147 public ServiceDiscoveryEvent(GetArg arg) throws IOException{ 148 // source cannot be null in the constructor, but it is after 149 // deserialization because it is transient. 150 this(Boolean.TRUE, arg.get("preEventItem", null, ServiceItem.class), 151 arg.get("postEventItem", null, ServiceItem.class), false); 152 source = null; 153 } 154 155 /** 156 * Returns an instance of a <code>ServiceItem</code> containing the 157 * service reference corresponding to the given event. The service 158 * state reflected in the returned service item is the state of the 159 * service prior to the occurrence of the event. 160 * <p> 161 * If the event is a discovery event (as opposed to a removal or 162 * modification event), then this method will return <code>null</code> 163 * because the discovered service had no state in the cache prior to 164 * its discovery. 165 * <p> 166 * Because making a copy can be a very expensive process, this 167 * method does not return a copy of the service reference associated 168 * with the given event. Rather, it returns the appropriate service 169 * reference from the cache itself. Due to this cost, listeners that 170 * receive a <code>ServiceDiscoveryEvent</code> must not modify the 171 * contents of the object returned by this method; doing so could 172 * cause the state of the cache to become corrupted or inconsistent 173 * because the objects returned by this method are also members of 174 * the cache. This potential for corruption or inconsistency is why 175 * the effects of modifying the object returned by this accessor 176 * method are undefined. 177 * 178 * @return ServiceItem containing the service reference corresponding 179 * to the given event. 180 */ 181 public ServiceItem getPreEventServiceItem() 182 { 183 return preEventItem.clone(); 184 } 185 186 /** 187 * Returns an instance of a <code>ServiceItem</code> containing the 188 * service reference corresponding to the given event. The service 189 * state reflected in the returned service item is the state of the 190 * service after the occurrence of the event. 191 * <p> 192 * If the event is a removal event, then this method will return 193 * <code>null</code> because the discovered service has no state in 194 * the cache after it is removed from the cache. 195 * <p> 196 * Because making a copy can be a very expensive process, this 197 * method does not return a copy of the service reference associated 198 * with the given event. Rather, it returns the appropriate service 199 * reference from the cache itself. Due to this cost, listeners that 200 * receive a <code>ServiceDiscoveryEvent</code> must not modify the 201 * contents of the object returned by this method; doing so could 202 * cause the state of the cache to become corrupted or inconsistent 203 * because the objects returned by this method are also members of 204 * the cache. This potential for corruption or inconsistency is why 205 * the effects of modifying the object returned by this accessor 206 * method are undefined. 207 * 208 * @return ServiceItem containing the service reference corresponding 209 * to the given event. 210 */ 211 public ServiceItem getPostEventServiceItem() 212 { 213 return postEventItem.clone(); 214 } 215 216 }