001: package net.xoetrope.builder.editor;
002:
003: import java.io.File;
004: import java.io.FileInputStream;
005: import java.io.FileNotFoundException;
006: import java.io.IOException;
007: import java.io.InputStream;
008: import java.net.MalformedURLException;
009: import java.net.URL;
010:
011: import net.xoetrope.xui.XProjectManager;
012: import net.xoetrope.optional.resources.XResourceLoader;
013:
014: /**
015: * Used to locate project files. This classloader is used in the XEditorResourceManager and is initialised when
016: * a project is created or opened. It searches for files within the paths
017: * specified in the paths array.
018: * <p>Copyright: Copyright (c) Xoetrope Ltd., 1998-2003</p>
019: * $Revision: 1.7 $
020: */
021: public class XEditorClassLoader extends ClassLoader implements
022: XResourceLoader {
023: protected String[] paths;
024:
025: /**
026: * Create a new class loader. Initially no search path is set.
027: * @param classLoader the super ClassLoader
028: */
029: public XEditorClassLoader(ClassLoader classLoader) {
030: super (classLoader);
031: }
032:
033: /**
034: * Set the paths for loading files
035: * @param projectPaths The String array of paths for inclusion in the search.
036: * @return true to indicate that the sources are setup, false to indicate some failure
037: */
038: public boolean setSources(String[] projectPaths) {
039: paths = projectPaths;
040: return true;
041: }
042:
043: /**
044: * Overrides the Classloader method and searches for the resource file
045: * specifies by the parameter fileName.
046: * @param fileName The name of the file to be found.
047: * @return An InputStream created by from the filename if found or null if not
048: * found.
049: */
050: public InputStream getResourceAsStream(String fileName) {
051: try {
052: for (int i = 0; i < paths.length; i++) {
053: String prefix = (fileName.indexOf("\\") > -1 || fileName
054: .indexOf("/") > -1) ? "" : paths[i]
055: + File.separatorChar;
056: File f = new File(prefix + fileName);
057: if (f.exists()) {
058: FileInputStream is = new FileInputStream(f);
059: if (is != null)
060: return is;
061: }
062: }
063: } catch (FileNotFoundException ex) {
064: ex.printStackTrace();
065: }
066: return null;
067: }
068:
069: /**
070: * Overrides the Classloader method and searches for the resource file
071: * specifies by the parameter fileName.
072: * @param fileName The name of the file to be found.
073: * @return A URL from the filename if found or null if not
074: * found.
075: */
076: public URL findResource(String fileName) {
077: try {
078: for (int i = 0; i < paths.length; i++) {
079: String prefix = (fileName.indexOf("\\") > -1 || fileName
080: .indexOf("/") > -1) ? "" : paths[i]
081: + File.separatorChar;
082: File f = new File(prefix + fileName);
083: if (f.exists()) {
084: return f.toURL();
085: }
086: }
087: } catch (MalformedURLException ex) {
088: } catch (NullPointerException ex) {
089: }
090: return null;
091: }
092:
093: public Class findClass(String className)
094: throws ClassNotFoundException {
095: return (findClass(className, true));
096: }
097:
098: /**
099: * Overrides the method from ClassLoader. This method is called auotmatically
100: * if the system classloader cannot find the class it is looking for. We then
101: * have the chance to find, load and return the class.
102: * @param className The name of the class we are being asked to find
103: * @param resolveIt Simply forward the value passed in
104: * @return The newly created Class
105: * @throws ClassNotFoundException
106: */
107: public synchronized Class findClass(String className,
108: boolean resolveIt) throws ClassNotFoundException {
109: Class result;
110: byte[] classBytes;
111:
112: try {
113: result = super .findSystemClass(className);
114: return result;
115: } catch (ClassNotFoundException e) {
116: }
117:
118: classBytes = loadClassBytes(className);
119: if (classBytes == null) {
120: throw new ClassNotFoundException();
121: }
122: // Define it (parse the class file)
123: result = defineClass(classBytes, 0, classBytes.length);
124: if (result == null) {
125: throw new ClassFormatError();
126: }
127: // Resolve if necessary
128: if (resolveIt)
129: resolveClass(result);
130:
131: // Done
132: return result;
133: }
134:
135: /**
136: * Opens the class file specified by the className. If found it opens the file
137: * and loads it into a byte array. The byte array is then returned.
138: * @param className The name of the class we are being asked to load
139: * @return A byte array created from the class file.
140: */
141: private byte[] loadClassBytes(String className) {
142: byte[] classBytes = new byte[0];
143: InputStream is = getResourceAsStream(className + ".class");
144: try {
145: byte[] b = new byte[1000];
146: int i = is.read(b);
147: while (i != -1) {
148: byte[] tempBytes = classBytes;
149: classBytes = new byte[classBytes.length + i];
150: System.arraycopy(b, 0, classBytes, tempBytes.length, i);
151: b = new byte[1000];
152: i = is.read(b);
153: }
154: } catch (IOException ex) {
155: }
156: return classBytes;
157: }
158: }
|