001    /* Reference.java --
002       Copyright (C) 2000, 2001, 2005, 2006  Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package javax.naming;
040    
041    import java.io.Serializable;
042    import java.util.Enumeration;
043    import java.util.Vector;
044    
045    /**
046     * This class represents a reference to an object that is located outside of the
047     * naming/directory system.
048     * 
049     * @see Referenceable
050     * 
051     * @author Tom Tromey (tromey@redhat.com)
052     */
053    public class Reference implements Cloneable, Serializable
054    {
055      private static final long serialVersionUID = - 1673475790065791735L;
056      
057      /**
058       * The list of addresses, stored in this reference. The object may be 
059       * have by several different addresses.
060       */
061      protected Vector<RefAddr> addrs;
062      
063      /**
064       * The name of the class factory to create an instance of the object,
065       * referenced by this reference.
066       */
067      protected String classFactory;
068      
069      /**
070       * The location, from where the class factory should be loaded.
071       */
072      protected String classFactoryLocation;
073      
074      /**
075       * The name of the class of the object, to that this reference refers.
076       */
077      protected String className;
078      
079      /**
080       * Create a new reference that is referencting to the object of the
081       * specified class.
082       */
083      public Reference (String className)
084      {
085        this.className = className;
086        addrs = new Vector<RefAddr> ();
087      }
088      
089      /**
090       * Create a new reference that is referencing to the object of the
091       * specified class with the given address.
092       */
093      public Reference (String className, RefAddr addr)
094      {
095        this.className = className;
096        addrs = new Vector<RefAddr> ();
097        addrs.add (addr);
098      }
099       
100      /**
101       * Create a new reference that is referencing to the object of the
102       * specified class, specifying the class and location of the factory that
103       * produces these objects.
104       * 
105       * @param className the object class name
106       * @param factoryClassName the object factory class name
107       * @param factoryLocation the object factory location
108       */
109      public Reference (String className, String factoryClassName, 
110                        String factoryLocation)
111      {
112        this.className = className;
113        this.classFactory = factoryClassName;
114        this.classFactoryLocation = factoryLocation;
115        addrs = new Vector<RefAddr> ();
116      }
117    
118      /**
119       * Create a new reference that is referencing to the object of the
120       * specified class, specifying the class and location of the factory that
121       * produces these objects and also the address of this object.
122       * 
123       * @param className the object class name
124       * @param addr the address of the object
125       * @param factoryClassName the object factory class name
126       * @param factoryLocation the object factory location
127       */
128      public Reference (String className, RefAddr addr,
129                        String factoryClassName, String factoryLocation)
130      {
131        this.className = className;
132        this.classFactory = factoryClassName;
133        this.classFactoryLocation = factoryLocation;
134        addrs = new Vector<RefAddr> ();
135        addrs.add (addr);
136      }
137    
138      /**
139       * Add the new address for this object at the given position of the 
140       * address list.
141       */
142      public void add (int posn, RefAddr addr)
143      {
144        addrs.add (posn, addr);
145      }
146      
147      /**
148       * Appends the new object address to the end of the address list.
149       */
150      public void add (RefAddr addr)
151      {
152        addrs.add (addr);
153      }
154      
155      /**
156       * Removes all defined addresses of the object.
157       */
158      public void clear ()
159      {
160        addrs.clear ();
161      }
162    
163      public Object clone ()
164      {
165        Reference r = new Reference (className, classFactory,
166                                     classFactoryLocation);
167        r.addrs = (Vector<RefAddr>) addrs.clone ();
168        return r;
169      }
170    
171      // Convenience function.
172      private boolean equals (String a, String b)
173      {
174        return (a == null) ? (b == null) : a.equals (b);
175      }
176      
177      /**
178       * Compares two addresses for equality, by value.
179       */
180      public boolean equals (Object obj)
181      {
182        if (! (obj instanceof Reference))
183          return false;
184        Reference r = (Reference) obj;
185        return (equals (classFactory, r.classFactory)
186                && equals (classFactoryLocation, r.classFactoryLocation)
187                && equals (className, r.className)
188                && addrs.equals (r.addrs));
189      }
190      
191      /**
192       * Get the address of this object at the given position.
193       */
194      public RefAddr get (int posn)
195      {
196        return addrs.get (posn);
197      }
198      
199      /**
200       * Get the given type of address for this object.
201       * 
202       * @param addrType the needed type of address
203       * 
204       * @return the address of this object, having the specified type. If there
205       *           is no address of such type, null is returned.
206       */
207      public RefAddr get (String addrType)
208      {
209        for (int i = 0; i < addrs.size (); ++i)
210          {
211            RefAddr r = addrs.get (i);
212            if (addrType.equals (r.getType ()))
213              return r;
214          }
215        return null;
216      }
217      
218      /**
219       * Get the enumeration over all defined addresses of the object.
220       */
221      public Enumeration<RefAddr> getAll ()
222      {
223        return addrs.elements ();
224      }
225      
226      /**
227       * Get the name of the class of the referenced object.
228       * 
229       * @see #className
230       */
231      public String getClassName ()
232      {
233        return className;
234      }
235      
236      /**
237       * Get the location of the factory class of the referenced object.
238       * 
239       * @see #classFactoryLocation
240       */
241      public String getFactoryClassLocation ()
242      {
243        return classFactoryLocation;
244      }
245    
246      /**
247       * Get the name of the factory class of the referenced object
248       * 
249       * @see #classFactory
250       */
251      public String getFactoryClassName ()
252      {
253        return classFactory;
254      }
255      
256      /**
257       * Get the hashcode of this reference. 
258       * 
259       * @return the sum of the hash codes of the addresses.  
260       */
261      public int hashCode ()
262      {
263        // The spec says the hash code is the sum of the hash codes of the
264        // addresses.  It does not mention the other fields.
265        int h = 0;
266        for (int i = 0; i < addrs.size (); ++i)
267          h += addrs.get (i).hashCode ();
268        return h;
269      }
270      
271      /**
272       * Remove the address at the given position.
273       * 
274       * @param posn the position of the address to remove
275       * 
276       * @return the removed address
277       */
278      public Object remove (int posn)
279      {
280        return addrs.remove (posn);
281      }
282      
283      /**
284       * Return the number of the defined addresses.
285       */
286      public int size ()
287      {
288        return addrs.size ();
289      }
290      
291      /**
292       * Return the string representation.
293       */
294      public String toString ()
295      {
296        String x = getClass ().toString () + "[";
297        for (int i = 0; i < addrs.size (); ++i)
298          {
299            if (i > 0)
300              x += ",";
301            x += addrs.get (i).toString ();
302          }
303        return x + "]";
304      }
305    
306    }