1 /* 2 * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.naming.event; 27 28 import javax.naming.Binding; 29 30 /** 31 * This class represents an event fired by a naming/directory service. 32 *<p> 33 * The {@code NamingEvent}'s state consists of 34 * <ul> 35 * <li>The event source: the {@code EventContext} which fired this event. 36 * <li>The event type. 37 * <li>The new binding: information about the object after the change. 38 * <li>The old binding: information about the object before the change. 39 * <li>Change information: information about the change 40 * that triggered this event; usually service provider-specific or server-specific 41 * information. 42 * </ul> 43 * <p> 44 * Note that the event source is always the same {@code EventContext} 45 * <em>instance</em> that the listener has registered with. 46 * Furthermore, the names of the bindings in 47 * the {@code NamingEvent} are always relative to that instance. 48 * For example, suppose a listener makes the following registration: 49 *<blockquote><pre> 50 * NamespaceChangeListener listener = ...; 51 * src.addNamingListener("x", SUBTREE_SCOPE, listener); 52 *</pre></blockquote> 53 * When an object named "x/y" is subsequently deleted, the corresponding 54 * {@code NamingEvent} ({@code evt}) must contain: 55 *<blockquote><pre> 56 * evt.getEventContext() == src 57 * evt.getOldBinding().getName().equals("x/y") 58 *</pre></blockquote> 59 * 60 * Care must be taken when multiple threads are accessing the same 61 * {@code EventContext} concurrently. 62 * See the 63 * <a href=package-summary.html#THREADING>package description</a> 64 * for more information on threading issues. 65 * 66 * @author Rosanna Lee 67 * @author Scott Seligman 68 * 69 * @see NamingListener 70 * @see EventContext 71 * @since 1.3 72 */ 73 public class NamingEvent extends java.util.EventObject { 74 /** 75 * Naming event type for indicating that a new object has been added. 76 * The value of this constant is {@code 0}. 77 */ 78 public static final int OBJECT_ADDED = 0; 79 80 /** 81 * Naming event type for indicating that an object has been removed. 82 * The value of this constant is {@code 1}. 83 */ 84 public static final int OBJECT_REMOVED = 1; 85 86 /** 87 * Naming event type for indicating that an object has been renamed. 88 * Note that some services might fire multiple events for a single 89 * logical rename operation. For example, the rename operation might 90 * be implemented by adding a binding with the new name and removing 91 * the old binding. 92 *<p> 93 * The old/new binding in {@code NamingEvent} may be null if the old 94 * name or new name is outside of the scope for which the listener 95 * has registered. 96 *<p> 97 * When an interior node in the namespace tree has been renamed, the 98 * topmost node which is part of the listener's scope should used to generate 99 * a rename event. The extent to which this can be supported is 100 * provider-specific. For example, a service might generate rename 101 * notifications for all descendants of the changed interior node and the 102 * corresponding provider might not be able to prevent those 103 * notifications from being propagated to the listeners. 104 *<p> 105 * The value of this constant is {@code 2}. 106 */ 107 public static final int OBJECT_RENAMED = 2; 108 109 /** 110 * Naming event type for indicating that an object has been changed. 111 * The changes might include the object's attributes, or the object itself. 112 * Note that some services might fire multiple events for a single 113 * modification. For example, the modification might 114 * be implemented by first removing the old binding and adding 115 * a new binding containing the same name but a different object. 116 *<p> 117 * The value of this constant is {@code 3}. 118 */ 119 public static final int OBJECT_CHANGED = 3; 120 121 /** 122 * Contains information about the change that generated this event. 123 * @serial 124 */ 125 @SuppressWarnings("serial") // Not statically typed as Serializable 126 protected Object changeInfo; 127 128 /** 129 * Contains the type of this event. 130 * @see #OBJECT_ADDED 131 * @see #OBJECT_REMOVED 132 * @see #OBJECT_RENAMED 133 * @see #OBJECT_CHANGED 134 * @serial 135 */ 136 protected int type; 137 138 /** 139 * Contains information about the object before the change. 140 * @serial 141 */ 142 protected Binding oldBinding; 143 144 /** 145 * Contains information about the object after the change. 146 * @serial 147 */ 148 protected Binding newBinding; 149 150 /** 151 * Constructs an instance of {@code NamingEvent}. 152 *<p> 153 * The names in {@code newBd} and {@code oldBd} are to be resolved relative 154 * to the event source {@code source}. 155 * 156 * For an {@code OBJECT_ADDED} event type, {@code newBd} must not be null. 157 * For an {@code OBJECT_REMOVED} event type, {@code oldBd} must not be null. 158 * For an {@code OBJECT_CHANGED} event type, {@code newBd} and 159 * {@code oldBd} must not be null. For an {@code OBJECT_RENAMED} event type, 160 * one of {@code newBd} or {@code oldBd} may be null if the new or old 161 * binding is outside of the scope for which the listener has registered. 162 * 163 * @param source The non-null context that fired this event. 164 * @param type The type of the event. 165 * @param newBd A possibly null binding before the change. See method description. 166 * @param oldBd A possibly null binding after the change. See method description. 167 * @param changeInfo A possibly null object containing information about the change. 168 * @see #OBJECT_ADDED 169 * @see #OBJECT_REMOVED 170 * @see #OBJECT_RENAMED 171 * @see #OBJECT_CHANGED 172 */ 173 public NamingEvent(EventContext source, int type, 174 Binding newBd, Binding oldBd, Object changeInfo) { 175 super(source); 176 this.type = type; 177 oldBinding = oldBd; 178 newBinding = newBd; 179 this.changeInfo = changeInfo; 180 } 181 182 /** 183 * Returns the type of this event. 184 * @return The type of this event. 185 * @see #OBJECT_ADDED 186 * @see #OBJECT_REMOVED 187 * @see #OBJECT_RENAMED 188 * @see #OBJECT_CHANGED 189 */ 190 public int getType() { 191 return type; 192 } 193 194 /** 195 * Retrieves the event source that fired this event. 196 * This returns the same object as {@code EventObject.getSource()}. 197 *<p> 198 * If the result of this method is used to access the 199 * event source, for example, to look up the object or get its attributes, 200 * then it needs to be locked because implementations of {@code Context} 201 * are not guaranteed to be thread-safe 202 * (and {@code EventContext} is a subinterface of {@code Context}). 203 * See the 204 * <a href=package-summary.html#THREADING>package description</a> 205 * for more information on threading issues. 206 * 207 * @return The non-null context that fired this event. 208 */ 209 public EventContext getEventContext() { 210 return (EventContext)getSource(); 211 } 212 213 /** 214 * Retrieves the binding of the object before the change. 215 *<p> 216 * The binding must be nonnull if the object existed before the change 217 * relative to the source context ({@code getEventContext()}). 218 * That is, it must be nonnull for {@code OBJECT_REMOVED} and 219 * {@code OBJECT_CHANGED}. 220 * For {@code OBJECT_RENAMED}, it is null if the object before the rename 221 * is outside of the scope for which the listener has registered interest; 222 * it is nonnull if the object is inside the scope before the rename. 223 *<p> 224 * The name in the binding is to be resolved relative 225 * to the event source {@code getEventContext()}. 226 * The object returned by {@code Binding.getObject()} may be null if 227 * such information is unavailable. 228 * 229 * @return The possibly null binding of the object before the change. 230 */ 231 public Binding getOldBinding() { 232 return oldBinding; 233 } 234 235 /** 236 * Retrieves the binding of the object after the change. 237 *<p> 238 * The binding must be nonnull if the object existed after the change 239 * relative to the source context ({@code getEventContext()}). 240 * That is, it must be nonnull for {@code OBJECT_ADDED} and 241 * {@code OBJECT_CHANGED}. For {@code OBJECT_RENAMED}, 242 * it is null if the object after the rename is outside the scope for 243 * which the listener registered interest; it is nonnull if the object 244 * is inside the scope after the rename. 245 *<p> 246 * The name in the binding is to be resolved relative 247 * to the event source {@code getEventContext()}. 248 * The object returned by {@code Binding.getObject()} may be null if 249 * such information is unavailable. 250 * 251 * @return The possibly null binding of the object after the change. 252 */ 253 public Binding getNewBinding() { 254 return newBinding; 255 } 256 257 /** 258 * Retrieves the change information for this event. 259 * The value of the change information is service-specific. For example, 260 * it could be an ID that identifies the change in a change log on the server. 261 * 262 * @return The possibly null change information of this event. 263 */ 264 public Object getChangeInfo() { 265 return changeInfo; 266 } 267 268 /** 269 * Invokes the appropriate listener method on this event. 270 * The default implementation of 271 * this method handles the following event types: 272 * {@code OBJECT_ADDED, OBJECT_REMOVED, 273 * OBJECT_RENAMED, OBJECT_CHANGED}. 274 *<p> 275 * The listener method is executed in the same thread 276 * as this method. See the 277 * <a href=package-summary.html#THREADING>package description</a> 278 * for more information on threading issues. 279 * @param listener The nonnull listener. 280 */ 281 public void dispatch(NamingListener listener) { 282 switch (type) { 283 case OBJECT_ADDED: 284 ((NamespaceChangeListener)listener).objectAdded(this); 285 break; 286 287 case OBJECT_REMOVED: 288 ((NamespaceChangeListener)listener).objectRemoved(this); 289 break; 290 291 case OBJECT_RENAMED: 292 ((NamespaceChangeListener)listener).objectRenamed(this); 293 break; 294 295 case OBJECT_CHANGED: 296 ((ObjectChangeListener)listener).objectChanged(this); 297 break; 298 } 299 } 300 private static final long serialVersionUID = -7126752885365133499L; 301 }