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