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