1 /*
2 * Copyright 1999-2000 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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 <tt>NamingEvent</tt>'s state consists of
34 * <ul>
35 * <li>The event source: the <tt>EventContext</tt> 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 <tt>EventContext</tt>
45 * <em>instance</em> that the listener has registered with.
46 * Furthermore, the names of the bindings in
47 * the <tt>NamingEvent</tt> 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 * <tt>NamingEvent</tt> (<tt>evt</tt>) 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 * <tt>EventContext</tt> 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 <tt>0</tt>.
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 <tt>1</tt>.
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 <tt>NamingEvent</tt> 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 <tt>2</tt>.
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 <tt>3</tt>.
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 <tt>NamingEvent</tt>.
151 *<p>
152 * The names in <tt>newBd</tt> and <tt>oldBd</tt> are to be resolved relative
153 * to the event source <tt>source</tt>.
154 *
155 * For an <tt>OBJECT_ADDED</tt> event type, <tt>newBd</tt> must not be null.
156 * For an <tt>OBJECT_REMOVED</tt> event type, <tt>oldBd</tt> must not be null.
157 * For an <tt>OBJECT_CHANGED</tt> event type, <tt>newBd</tt> and
158 * <tt>oldBd</tt> must not be null. For an <tt>OBJECT_RENAMED</tt> event type,
159 * one of <tt>newBd</tt> or <tt>oldBd</tt> 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 <tt>EventObject.getSource()</tt>.
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 <tt>Context</tt>
200 * are not guaranteed to be thread-safe
201 * (and <tt>EventContext</tt> is a subinterface of <tt>Context</tt>).
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 (<tt>getEventContext()</tt>).
217 * That is, it must be nonnull for <tt>OBJECT_REMOVED</tt> and
218 * <tt>OBJECT_CHANGED</tt>.
219 * For <tt>OBJECT_RENAMED</tt>, 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 <tt>getEventContext()</tt>.
225 * The object returned by <tt>Binding.getObject()</tt> 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 (<tt>getEventContext()</tt>).
239 * That is, it must be nonnull for <tt>OBJECT_ADDED</tt> and
240 * <tt>OBJECT_CHANGED</tt>. For <tt>OBJECT_RENAMED</tt>,
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 <tt>getEventContext()</tt>.
247 * The object returned by <tt>Binding.getObject()</tt> 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 * <tt>OBJECT_ADDED</TT>, <TT>OBJECT_REMOVED</TT>,
272 * <TT>OBJECT_RENAMED</TT>, <TT>OBJECT_CHANGED</TT>.
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 }