001: /*
002: * Jacareto Copyright (c) 2002-2005
003: * Applied Computer Science Research Group, Darmstadt University of
004: * Technology, Institute of Mathematics & Computer Science,
005: * Ludwigsburg University of Education, and Computer Based
006: * Learning Research Group, Aachen University. All rights reserved.
007: *
008: * Jacareto is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * Jacareto is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public
019: * License along with Jacareto; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: *
022: */
023:
024: package jacareto.toolkit;
025:
026: import jacareto.system.Environment;
027: import jacareto.system.Language;
028:
029: import org.apache.log4j.Logger;
030:
031: import java.net.URL;
032: import java.net.URLClassLoader;
033:
034: import java.util.Hashtable;
035: import java.util.Vector;
036:
037: /**
038: * The system class loader of Jacareto.
039: *
040: * @author <a href="mailto:cspannagel@web.de">Christian Spannagel</a>
041: * @version 1.00
042: */
043: public class JacaretoSystemClassLoader extends URLClassLoader {
044: /** The env. */
045: private Environment env;
046:
047: /** The logger. */
048: private Logger logger;
049:
050: /** The language instance. */
051: private Language language;
052:
053: /** The identifier of the active child. */
054: private String activeIdentifier;
055:
056: /** Hashtable of child vectors. */
057: private Hashtable childVectors;
058:
059: /** Blocked resource name when asking childs. */
060: private String blockedResourceName;
061:
062: /** Blocked class name when asking childs. */
063: private String blockedClassName;
064:
065: /**
066: * Creates a new Jacareto system class loader. The system class loader must be initialized with
067: * the method {@link #init(jacareto.system.Environment)}.
068: *
069: * @param parent the parent class loader
070: */
071: public JacaretoSystemClassLoader(ClassLoader parent) {
072: super (new URL[0], parent);
073: setActiveIdentifier(null);
074: childVectors = new Hashtable();
075: blockedResourceName = null;
076: blockedClassName = null;
077: }
078:
079: /**
080: * Initializes the system class loader.
081: *
082: * @param env the environment
083: */
084: public void init(Environment env) {
085: this .env = env;
086: this .logger = env.getLogger();
087: this .language = env.getLanguage();
088: }
089:
090: /**
091: * Returns a resource When a resource is not known (this occurs when the target applications
092: * circumvents the JacaretoClassLoader by directly accessing the system class loader), the
093: * childs with the active identifier are asked.
094: *
095: * @param name the environment
096: *
097: * @return DOCUMENT ME!
098: */
099: public URL getResource(String name) {
100: // when the name is blocked, return null to
101: // avoid endless recursion, because childs ask
102: // their parent class loaders first
103: if (name.equals(blockedResourceName)) {
104: return null;
105: }
106:
107: URL result = super .getResource(name);
108:
109: if ((result == null)
110: && StringToolkit.isDefined(activeIdentifier)) {
111: Vector childVector = (Vector) childVectors
112: .get(activeIdentifier);
113:
114: if (childVector != null) {
115: int i = childVector.size() - 1;
116: blockedResourceName = name;
117:
118: // ask the latest child with the active identifiert first,
119: // and then the others in reverse order
120: while ((result == null) && (i >= 0)) {
121: JacaretoClassLoader child = (JacaretoClassLoader) childVector
122: .get(i);
123: result = child.getResource(name);
124: i--;
125: }
126:
127: blockedResourceName = null;
128: }
129: }
130:
131: return result;
132: }
133:
134: /*protected Class findClass (String name) throws ClassNotFoundException {
135:
136: // when the name is blocked, return null to
137: // avoid endless recursion, because childs ask
138: // their parent class loaders first
139: if (name.equals (blockedClassName)) {
140: return null;
141: }
142:
143: Class result = null;
144:
145: try {
146: result = super.findClass (name);
147: } catch (ClassNotFoundException cnfe) {
148: System.out.println ("COULD NOT FIND CLASS: " + name);
149:
150: if (result == null && StringToolkit.isDefined(activeIdentifier)) {
151: Vector childVector = (Vector) childVectors.get (activeIdentifier);
152: if (childVector != null) {
153: int i = childVector.size()-1;
154: blockedClassName = name;
155: // ask the latest child with the active identifiert first,
156: // and then the others in reverse order
157: while (result == null && i >= 0) {
158: JacaretoClassLoader child = (JacaretoClassLoader) childVector.get(i);
159: try {
160: result = child.loadClass (name);
161: } catch (ClassNotFoundException cnfe2) {
162: result = null;
163: }
164: i--;
165: }
166: blockedClassName = null;
167: }
168: }
169:
170: if (result == null) {
171: throw (cnfe);
172: }
173: }
174:
175: return result;
176: } */
177:
178: /**
179: * Registers a child class loader.
180: *
181: * @param child the new child
182: */
183: public void registerChild(JacaretoClassLoader child) {
184: String identifier = child.getIdentifier();
185:
186: if (StringToolkit.isDefined(identifier)) {
187: Vector childVector = null;
188:
189: if (childVectors.containsKey(identifier)) {
190: childVector = (Vector) childVectors.get(identifier);
191: } else {
192: childVector = new Vector();
193: childVectors.put(identifier, childVector);
194: }
195:
196: childVector.add(child);
197: }
198: }
199:
200: /**
201: * Removes all children with a given class loader identifier.
202: *
203: * @param identifier the identifier of the children to be removed
204: */
205: public void removeChildren(String identifier) {
206: if (StringToolkit.isDefined(identifier)
207: && childVectors.containsKey(identifier)) {
208: childVectors.remove(identifier);
209: }
210:
211: if (StringToolkit.areEqual(activeIdentifier, identifier)) {
212: setActiveIdentifier(null);
213: }
214: }
215:
216: /**
217: * Sets the identifier of the active child.
218: *
219: * @param activeIdentifier the active identifier
220: */
221: public void setActiveIdentifier(String activeIdentifier) {
222: this.activeIdentifier = activeIdentifier;
223: }
224: }
|