blob: 5443b2f8e73d530b060360ecf285a405cd3ff9b4 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999-2001 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package com.sun.naming.internal;
27
28import java.util.List;
29import javax.naming.NamingException;
30
31/**
32 * The FactoryEnumeration is used for returning factory instances.
33 *
34 * @author Rosanna Lee
35 * @author Scott Seligman
36 */
37
38// no need to implement Enumeration since this is only for internal use
39public final class FactoryEnumeration {
40 private List factories;
41 private int posn = 0;
42 private ClassLoader loader;
43
44 /**
45 * Records the input list and uses it directly to satisfy
46 * hasMore()/next() requests. An alternative would have been to use
47 * an enumeration/iterator from the list, but we want to update the
48 * list so we keep the
49 * original list. The list initially contains Class objects.
50 * As each element is used, the Class object is replaced by an
51 * instance of the Class itself; eventually, the list contains
52 * only a list of factory instances and no more updates are required.
53 *
54 * <p> Both Class objects and factories are wrapped in weak
55 * references so as not to prevent GC of the class loader. Each
56 * weak reference is tagged with the factory's class name so the
57 * class can be reloaded if the reference is cleared.
58
59 * @param factories A non-null list
60 * @param loader The class loader of the list's contents
61 */
62 FactoryEnumeration(List factories, ClassLoader loader) {
63 this.factories = factories;
64 this.loader = loader;
65 }
66
67 public Object next() throws NamingException {
68 synchronized (factories) {
69
70 NamedWeakReference ref = (NamedWeakReference) factories.get(posn++);
71 Object answer = ref.get();
72 if ((answer != null) && !(answer instanceof Class)) {
73 return answer;
74 }
75
76 String className = ref.getName();
77
78 try {
79 if (answer == null) { // reload class if weak ref cleared
80 answer = Class.forName(className, true, loader);
81 }
82 // Instantiate Class to get factory
83 answer = ((Class) answer).newInstance();
84 ref = new NamedWeakReference(answer, className);
85 factories.set(posn-1, ref); // replace Class object or null
86 return answer;
87 } catch (ClassNotFoundException e) {
88 NamingException ne =
89 new NamingException("No longer able to load " + className);
90 ne.setRootCause(e);
91 throw ne;
92 } catch (InstantiationException e) {
93 NamingException ne =
94 new NamingException("Cannot instantiate " + answer);
95 ne.setRootCause(e);
96 throw ne;
97 } catch (IllegalAccessException e) {
98 NamingException ne = new NamingException("Cannot access " + answer);
99 ne.setRootCause(e);
100 throw ne;
101 }
102 }
103 }
104
105 public boolean hasMore() {
106 synchronized (factories) {
107 return posn < factories.size();
108 }
109 }
110}