001/* Reference.java --
002   Copyright (C) 2000, 2001, 2005, 2006  Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038
039package javax.naming;
040
041import java.io.Serializable;
042import java.util.Enumeration;
043import 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 */
053public 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}