001: /*
002: * JBoss, Home of Professional Open Source
003: * Copyright 2005, JBoss Inc., and individual contributors as indicated
004: * by the @authors tag. See the copyright.txt in the distribution for a
005: * full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jbpm.instantiation;
023:
024: import java.io.ByteArrayInputStream;
025: import java.io.IOException;
026: import java.io.InputStream;
027: import java.net.MalformedURLException;
028: import java.net.URL;
029: import java.net.URLConnection;
030: import java.net.URLStreamHandler;
031:
032: import org.jbpm.JbpmException;
033: import org.jbpm.file.def.FileDefinition;
034: import org.jbpm.graph.def.ProcessDefinition;
035:
036: public class ProcessClassLoader extends ClassLoader {
037:
038: private ProcessDefinition processDefinition = null;
039:
040: public ProcessClassLoader(ClassLoader parent,
041: ProcessDefinition processDefinition) {
042: super (parent);
043: this .processDefinition = processDefinition;
044: }
045:
046: public URL findResource(String name) {
047: URL url = null;
048: FileDefinition fileDefinition = processDefinition
049: .getFileDefinition();
050: if (fileDefinition != null) {
051: // if the name of the resources starts with a /
052: if (name.startsWith("/")) {
053: // then we start searching from the root of the process archive
054:
055: // we know that the leading slashes are removed in the names of the
056: // file definitions, therefor we skip the leading slashes
057: while (name.startsWith("/")) {
058: name = name.substring(1);
059: }
060: } else {
061: // otherwise, (if the resource is relative), we look in the classes
062: // directory in the process archive
063: name = "classes/" + name;
064: }
065:
066: byte[] bytes = null;
067: if (fileDefinition.hasFile(name)) {
068: bytes = fileDefinition.getBytes(name);
069: }
070: if (bytes != null) {
071: try {
072: url = new URL(null, "processresource://"
073: + processDefinition.getName() + "/classes/"
074: + name, new BytesUrlStreamHandler(bytes));
075: } catch (MalformedURLException e) {
076: throw new JbpmException("couldn't create url", e);
077: }
078: }
079: }
080: return url;
081: }
082:
083: public static class BytesUrlStreamHandler extends URLStreamHandler {
084: byte[] bytes;
085:
086: public BytesUrlStreamHandler(byte[] bytes) {
087: this .bytes = bytes;
088: }
089:
090: protected URLConnection openConnection(URL u)
091: throws IOException {
092: return new BytesUrlConnection(bytes, u);
093: }
094: }
095:
096: public static class BytesUrlConnection extends URLConnection {
097: byte[] bytes = null;
098:
099: public BytesUrlConnection(byte[] bytes, URL u) {
100: super (u);
101: this .bytes = bytes;
102: }
103:
104: public void connect() throws IOException {
105: }
106:
107: public InputStream getInputStream() throws IOException {
108: return new ByteArrayInputStream(bytes);
109: }
110: }
111:
112: public Class findClass(String name) throws ClassNotFoundException {
113: Class clazz = null;
114:
115: FileDefinition fileDefinition = processDefinition
116: .getFileDefinition();
117: if (fileDefinition != null) {
118: String fileName = "classes/" + name.replace('.', '/')
119: + ".class";
120: byte[] classBytes;
121: try {
122: classBytes = fileDefinition.getBytes(fileName);
123: clazz = defineClass(name, classBytes, 0,
124: classBytes.length);
125: } catch (JbpmException e) {
126: clazz = null;
127: }
128: }
129:
130: if (clazz == null) {
131: throw new ClassNotFoundException("class '" + name
132: + "' could not be found by the process classloader");
133: }
134:
135: return clazz;
136: }
137: }
|