1/* 2 * Copyright (c) 1999, 2000, 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 26package javax.naming.event; 27 28import 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 */ 73public 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 protected Object changeInfo; 126 127 /** 128 * Contains the type of this event. 129 * @see #OBJECT_ADDED 130 * @see #OBJECT_REMOVED 131 * @see #OBJECT_RENAMED 132 * @see #OBJECT_CHANGED 133 * @serial 134 */ 135 protected int type; 136 137 /** 138 * Contains information about the object before the change. 139 * @serial 140 */ 141 protected Binding oldBinding; 142 143 /** 144 * Contains information about the object after the change. 145 * @serial 146 */ 147 protected Binding newBinding; 148 149 /** 150 * Constructs an instance of {@code NamingEvent}. 151 *<p> 152 * The names in {@code newBd} and {@code oldBd} are to be resolved relative 153 * to the event source {@code source}. 154 * 155 * For an {@code OBJECT_ADDED} event type, {@code newBd} must not be null. 156 * For an {@code OBJECT_REMOVED} event type, {@code oldBd} must not be null. 157 * For an {@code OBJECT_CHANGED} event type, {@code newBd} and 158 * {@code oldBd} must not be null. For an {@code OBJECT_RENAMED} event type, 159 * one of {@code newBd} or {@code oldBd} may be null if the new or old 160 * binding is outside of the scope for which the listener has registered. 161 * 162 * @param source The non-null context that fired this event. 163 * @param type The type of the event. 164 * @param newBd A possibly null binding before the change. See method description. 165 * @param oldBd A possibly null binding after the change. See method description. 166 * @param changeInfo A possibly null object containing information about the change. 167 * @see #OBJECT_ADDED 168 * @see #OBJECT_REMOVED 169 * @see #OBJECT_RENAMED 170 * @see #OBJECT_CHANGED 171 */ 172 public NamingEvent(EventContext source, int type, 173 Binding newBd, Binding oldBd, Object changeInfo) { 174 super(source); 175 this.type = type; 176 oldBinding = oldBd; 177 newBinding = newBd; 178 this.changeInfo = changeInfo; 179 } 180 181 /** 182 * Returns the type of this event. 183 * @return The type of this event. 184 * @see #OBJECT_ADDED 185 * @see #OBJECT_REMOVED 186 * @see #OBJECT_RENAMED 187 * @see #OBJECT_CHANGED 188 */ 189 public int getType() { 190 return type; 191 } 192 193 /** 194 * Retrieves the event source that fired this event. 195 * This returns the same object as {@code EventObject.getSource()}. 196 *<p> 197 * If the result of this method is used to access the 198 * event source, for example, to look up the object or get its attributes, 199 * then it needs to be locked because implementations of {@code Context} 200 * are not guaranteed to be thread-safe 201 * (and {@code EventContext} is a subinterface of {@code Context}). 202 * See the 203 * <a href=package-summary.html#THREADING>package description</a> 204 * for more information on threading issues. 205 * 206 * @return The non-null context that fired this event. 207 */ 208 public EventContext getEventContext() { 209 return (EventContext)getSource(); 210 } 211 212 /** 213 * Retrieves the binding of the object before the change. 214 *<p> 215 * The binding must be nonnull if the object existed before the change 216 * relative to the source context ({@code getEventContext()}). 217 * That is, it must be nonnull for {@code OBJECT_REMOVED} and 218 * {@code OBJECT_CHANGED}. 219 * For {@code OBJECT_RENAMED}, it is null if the object before the rename 220 * is outside of the scope for which the listener has registered interest; 221 * it is nonnull if the object is inside the scope before the rename. 222 *<p> 223 * The name in the binding is to be resolved relative 224 * to the event source {@code getEventContext()}. 225 * The object returned by {@code Binding.getObject()} may be null if 226 * such information is unavailable. 227 * 228 * @return The possibly null binding of the object before the change. 229 */ 230 public Binding getOldBinding() { 231 return oldBinding; 232 } 233 234 /** 235 * Retrieves the binding of the object after the change. 236 *<p> 237 * The binding must be nonnull if the object existed after the change 238 * relative to the source context ({@code getEventContext()}). 239 * That is, it must be nonnull for {@code OBJECT_ADDED} and 240 * {@code OBJECT_CHANGED}. For {@code OBJECT_RENAMED}, 241 * it is null if the object after the rename is outside the scope for 242 * which the listener registered interest; it is nonnull if the object 243 * is inside the scope after the rename. 244 *<p> 245 * The name in the binding is to be resolved relative 246 * to the event source {@code getEventContext()}. 247 * The object returned by {@code Binding.getObject()} may be null if 248 * such information is unavailable. 249 * 250 * @return The possibly null binding of the object after the change. 251 */ 252 public Binding getNewBinding() { 253 return newBinding; 254 } 255 256 /** 257 * Retrieves the change information for this event. 258 * The value of the change information is service-specific. For example, 259 * it could be an ID that identifies the change in a change log on the server. 260 * 261 * @return The possibly null change information of this event. 262 */ 263 public Object getChangeInfo() { 264 return changeInfo; 265 } 266 267 /** 268 * Invokes the appropriate listener method on this event. 269 * The default implementation of 270 * this method handles the following event types: 271 * {@code OBJECT_ADDED, OBJECT_REMOVED, 272 * OBJECT_RENAMED, OBJECT_CHANGED}. 273 *<p> 274 * The listener method is executed in the same thread 275 * as this method. See the 276 * <a href=package-summary.html#THREADING>package description</a> 277 * for more information on threading issues. 278 * @param listener The nonnull listener. 279 */ 280 public void dispatch(NamingListener listener) { 281 switch (type) { 282 case OBJECT_ADDED: 283 ((NamespaceChangeListener)listener).objectAdded(this); 284 break; 285 286 case OBJECT_REMOVED: 287 ((NamespaceChangeListener)listener).objectRemoved(this); 288 break; 289 290 case OBJECT_RENAMED: 291 ((NamespaceChangeListener)listener).objectRenamed(this); 292 break; 293 294 case OBJECT_CHANGED: 295 ((ObjectChangeListener)listener).objectChanged(this); 296 break; 297 } 298 } 299 private static final long serialVersionUID = -7126752885365133499L; 300} 301