View Javadoc
1   /*
2    * Copyright (c) 1999, 2011, 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;
27  
28  import java.util.Vector;
29  import java.util.Enumeration;
30  
31  /**
32    * This class represents a reference to an object that is found outside of
33    * the naming/directory system.
34    *<p>
35    * Reference provides a way of recording address information about
36    * objects which themselves are not directly bound to the naming/directory system.
37    *<p>
38    * A Reference consists of an ordered list of addresses and class information
39    * about the object being referenced.
40    * Each address in the list identifies a communications endpoint
41    * for the same conceptual object.  The "communications endpoint"
42    * is information that indicates how to contact the object. It could
43    * be, for example, a network address, a location in memory on the
44    * local machine, another process on the same machine, etc.
45    * The order of the addresses in the list may be of significance
46    * to object factories that interpret the reference.
47    *<p>
48    * Multiple addresses may arise for
49    * various reasons, such as replication or the object offering interfaces
50    * over more than one communication mechanism.  The addresses are indexed
51    * starting with zero.
52    *<p>
53    * A Reference also contains information to assist in creating an instance
54    * of the object to which this Reference refers.  It contains the class name
55    * of that object, and the class name and location of the factory to be used
56    * to create the object.
57    * The class factory location is a space-separated list of URLs representing
58    * the class path used to load the factory.  When the factory class (or
59    * any class or resource upon which it depends) needs to be loaded,
60    * each URL is used (in order) to attempt to load the class.
61    *<p>
62    * A Reference instance is not synchronized against concurrent access by multiple
63    * threads. Threads that need to access a single Reference concurrently should
64    * synchronize amongst themselves and provide the necessary locking.
65    *
66    * @author Rosanna Lee
67    * @author Scott Seligman
68    *
69    * @see RefAddr
70    * @see StringRefAddr
71    * @see BinaryRefAddr
72    * @since 1.3
73    */
74  
75    /*<p>
76    * The serialized form of a Reference object consists of the class
77    * name of the object being referenced (a String), a Vector of the
78    * addresses (each a RefAddr), the name of the class factory (a
79    * String), and the location of the class factory (a String).
80  */
81  
82  
83  public class Reference implements Cloneable, java.io.Serializable {
84      /**
85       * Contains the fully-qualified name of the class of the object to which
86       * this Reference refers.
87       * @serial
88       * @see java.lang.Class#getName
89       */
90      protected String className;
91      /**
92       * Contains the addresses contained in this Reference.
93       * Initialized by constructor.
94       * @serial
95       */
96      protected Vector<RefAddr> addrs = null;
97  
98      /**
99       * Contains the name of the factory class for creating
100      * an instance of the object to which this Reference refers.
101      * Initialized to null.
102      * @serial
103      */
104     protected String classFactory = null;
105 
106     /**
107      * Contains the location of the factory class.
108      * Initialized to null.
109      * @serial
110      */
111     protected String classFactoryLocation = null;
112 
113     /**
114       * Constructs a new reference for an object with class name 'className'.
115       * Class factory and class factory location are set to null.
116       * The newly created reference contains zero addresses.
117       *
118       * @param className The non-null class name of the object to which
119       * this reference refers.
120       */
121     public Reference(String className) {
122         this.className  = className;
123         addrs = new Vector<>();
124     }
125 
126     /**
127       * Constructs a new reference for an object with class name 'className' and
128       * an address.
129       * Class factory and class factory location are set to null.
130       *
131       * @param className The non-null class name of the object to
132       * which this reference refers.
133       * @param addr The non-null address of the object.
134       */
135     public Reference(String className, RefAddr addr) {
136         this.className = className;
137         addrs = new Vector<>();
138         addrs.addElement(addr);
139     }
140 
141     /**
142       * Constructs a new reference for an object with class name 'className',
143       * and the class name and location of the object's factory.
144       *
145       * @param className The non-null class name of the object to which
146       *                         this reference refers.
147       * @param factory  The possibly null class name of the object's factory.
148       * @param factoryLocation
149       *         The possibly null location from which to load
150       *         the factory (e.g. URL)
151       * @see javax.naming.spi.ObjectFactory
152       * @see javax.naming.spi.NamingManager#getObjectInstance
153       */
154     public Reference(String className, String factory, String factoryLocation) {
155         this(className);
156         classFactory = factory;
157         classFactoryLocation = factoryLocation;
158     }
159 
160     /**
161       * Constructs a new reference for an object with class name 'className',
162       * the class name and location of the object's factory, and the address for
163       * the object.
164       *
165       * @param className The non-null class name of the object to
166       *         which this reference refers.
167       * @param factory  The possibly null class name of the object's factory.
168       * @param factoryLocation  The possibly null location from which
169       *                         to load the factory (e.g. URL)
170       * @param addr     The non-null address of the object.
171       * @see javax.naming.spi.ObjectFactory
172       * @see javax.naming.spi.NamingManager#getObjectInstance
173       */
174     public Reference(String className, RefAddr addr,
175                      String factory, String factoryLocation) {
176         this(className, addr);
177         classFactory = factory;
178         classFactoryLocation = factoryLocation;
179     }
180 
181     /**
182       * Retrieves the class name of the object to which this reference refers.
183       *
184       * @return The non-null fully-qualified class name of the object.
185       *         (e.g. "java.lang.String")
186       */
187     public String getClassName() {
188         return className;
189     }
190 
191     /**
192       * Retrieves the class name of the factory of the object
193       * to which this reference refers.
194       *
195       * @return The possibly null fully-qualified class name of the factory.
196       *         (e.g. "java.lang.String")
197       */
198     public String getFactoryClassName() {
199         return classFactory;
200     }
201 
202     /**
203       * Retrieves the location of the factory of the object
204       * to which this reference refers.
205       * If it is a codebase, then it is an ordered list of URLs,
206       * separated by spaces, listing locations from where the factory
207       * class definition should be loaded.
208       *
209       * @return The possibly null string containing the
210       *                 location for loading in the factory's class.
211       */
212     public String getFactoryClassLocation() {
213         return classFactoryLocation;
214     }
215 
216     /**
217       * Retrieves the first address that has the address type 'addrType'.
218       * String.compareTo() is used to test the equality of the address types.
219       *
220       * @param addrType The non-null address type for which to find the address.
221       * @return The address in this reference with address type 'addrType;
222       *         null if no such address exist.
223       */
224     public RefAddr get(String addrType) {
225         int len = addrs.size();
226         RefAddr addr;
227         for (int i = 0; i < len; i++) {
228             addr = addrs.elementAt(i);
229             if (addr.getType().compareTo(addrType) == 0)
230                 return addr;
231         }
232         return null;
233     }
234 
235     /**
236       * Retrieves the address at index posn.
237       * @param posn The index of the address to retrieve.
238       * @return The address at the 0-based index posn. It must be in the
239       *         range [0,getAddressCount()).
240       * @exception ArrayIndexOutOfBoundsException If posn not in the specified
241       *         range.
242       */
243     public RefAddr get(int posn) {
244         return addrs.elementAt(posn);
245     }
246 
247     /**
248       * Retrieves an enumeration of the addresses in this reference.
249       * When addresses are added, changed or removed from this reference,
250       * its effects on this enumeration are undefined.
251       *
252       * @return An non-null enumeration of the addresses
253       *         (<tt>RefAddr</tt>) in this reference.
254       *         If this reference has zero addresses, an enumeration with
255       *         zero elements is returned.
256       */
257     public Enumeration<RefAddr> getAll() {
258         return addrs.elements();
259     }
260 
261     /**
262       * Retrieves the number of addresses in this reference.
263       *
264       * @return The nonnegative number of addresses in this reference.
265       */
266     public int size() {
267         return addrs.size();
268     }
269 
270     /**
271       * Adds an address to the end of the list of addresses.
272       *
273       * @param addr The non-null address to add.
274       */
275     public void add(RefAddr addr) {
276         addrs.addElement(addr);
277     }
278 
279     /**
280       * Adds an address to the list of addresses at index posn.
281       * All addresses at index posn or greater are shifted up
282       * the list by one (away from index 0).
283       *
284       * @param posn The 0-based index of the list to insert addr.
285       * @param addr The non-null address to add.
286       * @exception ArrayIndexOutOfBoundsException If posn not in the specified
287       *         range.
288       */
289     public void add(int posn, RefAddr addr) {
290         addrs.insertElementAt(addr, posn);
291     }
292 
293     /**
294       * Deletes the address at index posn from the list of addresses.
295       * All addresses at index greater than posn are shifted down
296       * the list by one (towards index 0).
297       *
298       * @param posn The 0-based index of in address to delete.
299       * @return The address removed.
300       * @exception ArrayIndexOutOfBoundsException If posn not in the specified
301       *         range.
302       */
303     public Object remove(int posn) {
304         Object r = addrs.elementAt(posn);
305         addrs.removeElementAt(posn);
306         return r;
307     }
308 
309     /**
310       * Deletes all addresses from this reference.
311       */
312     public void clear() {
313         addrs.setSize(0);
314     }
315 
316     /**
317       * Determines whether obj is a reference with the same addresses
318       * (in same order) as this reference.
319       * The addresses are checked using RefAddr.equals().
320       * In addition to having the same addresses, the Reference also needs to
321       * have the same class name as this reference.
322       * The class factory and class factory location are not checked.
323       * If obj is null or not an instance of Reference, null is returned.
324       *
325       * @param obj The possibly null object to check.
326       * @return true if obj is equal to this reference; false otherwise.
327       */
328     public boolean equals(Object obj) {
329         if ((obj != null) && (obj instanceof Reference)) {
330             Reference target = (Reference)obj;
331             // ignore factory information
332             if (target.className.equals(this.className) &&
333                 target.size() ==  this.size()) {
334                 Enumeration<RefAddr> mycomps = getAll();
335                 Enumeration<RefAddr> comps = target.getAll();
336                 while (mycomps.hasMoreElements())
337                     if (!(mycomps.nextElement().equals(comps.nextElement())))
338                         return false;
339                 return true;
340             }
341         }
342         return false;
343     }
344 
345     /**
346       * Computes the hash code of this reference.
347       * The hash code is the sum of the hash code of its addresses.
348       *
349       * @return A hash code of this reference as an int.
350       */
351     public int hashCode() {
352         int hash = className.hashCode();
353         for (Enumeration<RefAddr> e = getAll(); e.hasMoreElements();)
354             hash += e.nextElement().hashCode();
355         return hash;
356     }
357 
358     /**
359       * Generates the string representation of this reference.
360       * The string consists of the class name to which this reference refers,
361       * and the string representation of each of its addresses.
362       * This representation is intended for display only and not to be parsed.
363       *
364       * @return The non-null string representation of this reference.
365       */
366     public String toString() {
367         StringBuffer buf = new StringBuffer("Reference Class Name: " +
368                                             className + "\n");
369         int len = addrs.size();
370         for (int i = 0; i < len; i++)
371             buf.append(get(i).toString());
372 
373         return buf.toString();
374     }
375 
376     /**
377      * Makes a copy of this reference using its class name
378      * list of addresses, class factory name and class factory location.
379      * Changes to the newly created copy does not affect this Reference
380      * and vice versa.
381      */
382     public Object clone() {
383         Reference r = new Reference(className, classFactory, classFactoryLocation);
384         Enumeration<RefAddr> a = getAll();
385         r.addrs = new Vector<>();
386 
387         while (a.hasMoreElements())
388             r.addrs.addElement(a.nextElement());
389         return r;
390     }
391     /**
392      * Use serialVersionUID from JNDI 1.1.1 for interoperability
393      */
394     private static final long serialVersionUID = -1673475790065791735L;
395 };