001: /*
002: * Enhydra Java Application Server Project
003: *
004: * The contents of this file are subject to the Enhydra Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License on
007: * the Enhydra web site ( http://www.enhydra.org/ ).
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
011: * the License for the specific terms governing rights and limitations
012: * under the License.
013: *
014: * The Initial Developer of the Enhydra Application Server is Lutris
015: * Technologies, Inc. The Enhydra Application Server and portions created
016: * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
017: * All Rights Reserved.
018: *
019: * Contributor(s):
020: *
021: * $Id: ClassPath.java,v 1.2 2006-06-15 14:07:00 sinisa Exp $
022: */
023:
024: package com.lutris.classloader;
025:
026: // lutris packages
027: import java.io.File;
028: import java.net.URL;
029: import java.util.Enumeration;
030: import java.util.Vector;
031:
032: import com.lutris.logging.LogChannel;
033: import com.lutris.util.FatalExceptionError;
034:
035: /**
036: * <P>A class path that is composed of <CODE>ClassPathEntry</CODE> objects.
037: * This class can be used in conjunction with a class loader to load
038: * classes and resources.
039: *
040: * @author Kristen Pol, Lutris Technologies
041: * @version $Revision : 1.0 $
042: * @see com.lutris.classloader.ClassPathEntry
043: * @see com.lutris.classloader.Resource
044: */
045: class ClassPath {
046:
047: // private data members
048:
049: /** The class path Vector made up of ClassPathEntry objects. */
050: private Vector classPath = null;
051:
052: /** Is logging enabled? */
053: private boolean loggingEnabled = false;
054:
055: /** Log channel to write messages to */
056: // v. strahinja, 23 sep 2002
057: private LogChannel logChannel;
058: // private Logger logger;
059:
060: /** Numeric log level number for LOGLEVEL string */
061: // v. strahinja, 23 sep 2002
062: private int logLevel;
063:
064: // private Level logLevel;
065:
066: // constructors
067:
068: /**
069: * Constructs empty class path with no entries.
070: *
071: * @param loadLogChannel The log channel, maybe null.
072: * @see #set
073: * @see #add
074: */
075: // v. strahinja, 23 sep 2002
076: public ClassPath(LogChannel loadLogChannel) {
077: // v. strahinja, 23 sep 2002
078: this ((Vector) null, loadLogChannel);
079: // public ClassPath(Logger loadLogger) {
080: // this((Vector)null, loadLogger);
081: }
082:
083: /**
084: * Constructs class path with specified class path entries. The
085: * parameter is assumed to be an array of directories, URLs, and/or
086: * zip files.
087: *
088: * @param entries The class path represented by a String array.
089: * @param loadLogChannel The log channel, maybe null.
090: */
091: // v. strahinja, 23 sep 2002
092: public ClassPath(String[] entries, LogChannel loadLogChannel) {
093: // v. strahinja, 23 sep 2002
094: this (convertArrayToVector(entries, loadLogChannel),
095: loadLogChannel);
096: // public ClassPath(String[] entries, Logger loadLogger) {
097: // this(convertArrayToVector(entries, loadLogger), loadLogger);
098: }
099:
100: /**
101: * Constructs class path with specified class path entries. The
102: * parameter is assumed to be an array of zip files and/or directories.
103: *
104: * @param entries The class path represented by a File array.
105: * @param loadLogChannel The log channel, maybe null.
106: */
107: // v. strahinja, 23 sep 2002
108: public ClassPath(File[] entries, LogChannel loadLogChannel) {
109: // v. strahinja, 23 sep 2002
110: this (convertArrayToVector(entries, loadLogChannel),
111: loadLogChannel);
112: // public ClassPath(File[] entries, Logger loadLogger) {
113: // this(convertArrayToVector(entries, loadLogger), loadLogger);
114: }
115:
116: /**
117: * Constructs class path with specified class path entries. The URLs can
118: * represent directories and/or zip files on the local machine and/or
119: * on remote machines.
120: *
121: * @param entries The class path represented by a URL array.
122: * @param loadLogChannel The log channel, maybe null.
123: */
124: // v. strahinja, 23 sep 2002
125: public ClassPath(URL[] entries, LogChannel loadLogChannel) {
126: // v. strahinja, 23 sep 2002
127: this (convertArrayToVector(entries, loadLogChannel),
128: loadLogChannel);
129: // public ClassPath(URL[] entries, Logger loadLogger) {
130: // this(convertArrayToVector(entries, loadLogger), loadLogger);
131: }
132:
133: // private helper constructors
134:
135: /**
136: * Constructs class path with specified class path entries.
137: * Vector entries must be <CODE>ClassPathEntry</CODE> objects.
138: *
139: * @param entries The class path entries.
140: * @param loadLogChannel The log channel, maybe null.
141: * @see ClassPathEntry
142: */
143: // v. strahinja, 23 sep 2002
144: private ClassPath(Vector entries, LogChannel loadLogChannel) {
145: // private ClassPath(Vector entries, Logger loadLogger) {
146: /*
147: * This constructor actually does all the work, because all
148: * other constructors call this one.
149: */
150: classPath = new Vector();
151: set(entries);
152:
153: // v. strahinja, 23 sep 2002
154: logChannel = loadLogChannel;
155: // v. strahinja, 23 sep 2002
156: if (logChannel != null) {
157: // v. strahinja, 23 sep 2002
158: logLevel = logChannel.getLevel(MultiClassLoader.LOG_LEVEL);
159: // v. strahinja, 23 sep 2002
160: loggingEnabled = logChannel.isEnabled(logLevel);
161: // v. strahinja, 23 sep 2002
162: }
163: // logger = loadLogger;
164: // if (logger != null) {
165: //logLevel = logger.getLevel();
166: //if (logLevel == null) {
167: // logLevel = Level.DEBUG;
168: //}
169: // loggingEnabled = logger.isEnabledFor(logLevel);
170: //}
171: }
172:
173: // public methods
174:
175: /**
176: * Sets class path with specified class path entries. The
177: * parameter is assumed to be an array of directories, URLs, and/or
178: * zip files.
179: *
180: * @param entries The class path represented by a String array.
181: */
182: public void set(String[] entries) {
183: // v. strahinja, 23 sep 2002
184: set(convertArrayToVector(entries, logChannel));
185: // set(convertArrayToVector(entries, logger));
186: }
187:
188: /**
189: * Sets class path with specified class path entries. The
190: * parameter is assumed to be an array of zip files and/or directories.
191: *
192: * @param entries The class path represented by a File array.
193: */
194: public void set(File[] entries) {
195: // v. strahinja, 23 sep 2002
196: set(convertArrayToVector(entries, logChannel));
197: // set(convertArrayToVector(entries, logger));
198: }
199:
200: /**
201: * Sets class path with specified class path entries. The URLs can
202: * represent directories and/or zip files on the local machine and/or
203: * on remote machines.
204: *
205: * @param entries The class path represented by a URL array.
206: */
207: public void set(URL[] entries) {
208: // v. strahinja, 23 sep 2002
209: set(convertArrayToVector(entries, logChannel));
210: // set(convertArrayToVector(entries, logger));
211: }
212:
213: /**
214: * Adds specified class path entries to class path. The
215: * parameter is assumed to be an array of directories, URLs, and/or
216: * zip files.
217: *
218: * @param entries The class path entries to add.
219: */
220: public void add(String[] entries) {
221: // v. strahinja, 23 sep 2002
222: add(convertArrayToVector(entries, logChannel));
223: // add(convertArrayToVector(entries, logger));
224: }
225:
226: /**
227: * Adds specified class path entries to class path. The
228: * parameter is assumed to be an array of zip files and/or directories.
229: *
230: * @param entries The class path entries to add.
231: */
232: public void add(File[] entries) {
233: // v. strahinja, 23 sep 2002
234: add(convertArrayToVector(entries, logChannel));
235: // add(convertArrayToVector(entries, logger));
236: }
237:
238: /**
239: * Adds specified class path entries to class path. The URLs can
240: * represent directories and/or zip files on the local machine and/or
241: * on remote machines.
242: *
243: * @param entries The class path entries to add.
244: */
245: public void add(URL[] entries) {
246: // v. strahinja, 23 sep 2002
247: add(convertArrayToVector(entries, logChannel));
248: // add(convertArrayToVector(entries, logger));
249: }
250:
251: /**
252: * Clears class path by removing all entries.
253: *
254: * @see #set
255: * @see #add
256: */
257: public void clear() {
258: for (int i = 0; i < classPath.capacity(); i++) {
259: try {
260: ClassPathEntry cpe = (ClassPathEntry) classPath
261: .elementAt(i);
262: if (cpe.isZipFile()) {
263: cpe.getZipFile().close();
264: }
265: } catch (Exception ex) {
266: }
267: }
268: classPath.removeAllElements();
269: }
270:
271: /**
272: * Get the number of entries in the classpath.
273: *
274: * @return The length ot the class path.
275: */
276: public int getLength() {
277: return classPath.size();
278: }
279:
280: /**
281: * Gets an Enumeration of class path entries.
282: *
283: * @return an Enumeration of ClassPathEntry objects.
284: * @see ClassPathEntry
285: * @see #set
286: */
287: public Enumeration getPath() {
288: return classPath.elements();
289: }
290:
291: /**
292: * Gets resource represented by specified file name. The class path
293: * entries are searched in order to find the desired resource. If the
294: * resource is not found in the class path, null is returned.
295: *
296: * @param name The file name of the resource.
297: * @return the resource associated with the given file name, or null if
298: * it can not be found.
299: * @see Resource
300: */
301: public Resource getResource(String name) {
302:
303: if (name == null) {
304: throw new NullPointerException(
305: "Null resource name passed to "
306: + "getResource() for class path, " + this );
307: }
308: Resource resource = null;
309: for (int i = 0; i < classPath.size(); i++) {
310: ClassPathEntry entry = null;
311: entry = (ClassPathEntry) classPath.elementAt(i);
312:
313: if (loggingEnabled) {
314: // v. strahinja, 23 sep 2002
315: logChannel.write(logLevel, " checking: \""
316: + entry.getName()
317: // logger.log(logLevel, " checking: \"" + entry.getName()
318: + "\"");
319: }
320: resource = entry.getResource(name);
321: if (resource != null) {
322: if (loggingEnabled) {
323: // v. strahinja, 23 sep 2002
324: logChannel.write(logLevel, " found: " + name);
325: // logger.log(logLevel, " found: " + name);
326: }
327: return resource;
328: }
329: }
330: if (loggingEnabled) {
331: // v. strahinja, 23 sep 2002
332: logChannel.write(logLevel, " not found: " + name);
333: // logger.log(logLevel, " not found: " + name);
334: }
335: return null;
336: }
337:
338: // private helper methods
339:
340: /**
341: * Sets class path with specified class path entries.
342: * Vector entries must be <CODE>ClassPathEntry</CODE> objects.
343: * All null and duplicate entries are removed.
344: *
345: * @param entries The class path entries.
346: * @see ClassPathEntry
347: */
348: private void set(Vector entries) {
349: /*
350: * This set method actually does all the work,
351: * since all the other set methods call this one.
352: */
353: classPath.removeAllElements();
354: add(entries);
355: }
356:
357: /**
358: * Adds specified class path entries to class path.
359: * Vector entries must be <CODE>ClassPathEntry</CODE> objects.
360: * All null and duplicate entries are removed.
361: *
362: * @param entries The class path entries.
363: * @see ClassPathEntry
364: */
365: private void add(Vector entries) {
366: /*
367: * This add method actually does all the work,
368: * since all the other add methods call this one.
369: */
370: if (entries != null) {
371: for (int i = 0; i < entries.size(); i++) {
372: classPath.insertElementAt(entries.elementAt(i), i);
373: }
374: }
375: }
376:
377: /**
378: * Converts array of Objects to Vector. Converts all array objects
379: * to ClassPathEntry objects and removes nulls and duplicates.
380: *
381: * @param array The array to convert.
382: * @return the Vector representation of the array.
383: * @see ClassPathEntry
384: */
385: private static Vector convertArrayToVector(Object[] array,
386: // v. strahinja, 23 sep 2002
387: LogChannel loadLogChannel) {
388: // Logger loadLogger) {
389: //FIXME: Is there really a need to support a nul array??
390: if (array != null) {
391: Vector vector = new Vector();
392: for (int i = 0; i < array.length; i++) {
393: Object object = array[i];
394: ClassPathEntry entry = null;
395: if (object instanceof String) {
396: // v. strahinja, 23 sep 2002
397: entry = new ClassPathEntry((String) object,
398: loadLogChannel);
399: // entry = new ClassPathEntry((String)object, loadLogger);
400: } else if (object instanceof File) {
401: // v. strahinja, 23 sep 2002
402: entry = new ClassPathEntry((File) object,
403: loadLogChannel);
404: // entry = new ClassPathEntry((File)object, loadLogger);
405: } else if (object instanceof URL) {
406: // v. strahinja, 23 sep 2002
407: entry = new ClassPathEntry((URL) object,
408: loadLogChannel);
409: // entry = new ClassPathEntry((URL)object, loadLogger);
410: } else {
411: // This should not happen because the only public set
412: // methods are for Strings, Files, and URLs
413: throw new FatalExceptionError(
414: new ClassCastException(
415: "Type, "
416: + object.getClass()
417: + ", is not supported. "
418: + "Expecting a String, File, or URL."));
419: }
420: if (entry != null && !vector.contains(entry)) {
421: vector.addElement(entry);
422: }
423: }
424: return vector;
425: }
426: return null;
427: }
428: }
|