001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.jci.stores;
018:
019: import org.apache.commons.jci.utils.ConversionUtils;
020: import org.apache.commons.logging.Log;
021: import org.apache.commons.logging.LogFactory;
022:
023: /**
024: * A ClassLoader backed by an array of ResourceStores
025: *
026: * @author tcurdt
027: */
028: public final class ResourceStoreClassLoader extends ClassLoader {
029:
030: private final Log log = LogFactory
031: .getLog(ResourceStoreClassLoader.class);
032:
033: private final ResourceStore[] stores;
034:
035: public ResourceStoreClassLoader(final ClassLoader pParent,
036: final ResourceStore[] pStores) {
037: super (pParent);
038: stores = pStores;
039: }
040:
041: private Class fastFindClass(final String name) {
042:
043: if (stores != null) {
044: for (int i = 0; i < stores.length; i++) {
045: final ResourceStore store = stores[i];
046: final byte[] clazzBytes = store.read(ConversionUtils
047: .convertClassToResourcePath(name));
048: if (clazzBytes != null) {
049: log.debug(getId() + " found class: " + name + " ("
050: + clazzBytes.length + " bytes)");
051: return defineClass(name, clazzBytes, 0,
052: clazzBytes.length);
053: }
054: }
055: }
056:
057: return null;
058: }
059:
060: protected synchronized Class loadClass(String name, boolean resolve)
061: throws ClassNotFoundException {
062: // log.debug(getId() + " looking for: " + name);
063: Class clazz = findLoadedClass(name);
064:
065: if (clazz == null) {
066: clazz = fastFindClass(name);
067:
068: if (clazz == null) {
069:
070: final ClassLoader parent = getParent();
071: if (parent != null) {
072: clazz = parent.loadClass(name);
073: // log.debug(getId() + " delegating loading to parent: " + name);
074: } else {
075: throw new ClassNotFoundException(name);
076: }
077:
078: } else {
079: log.debug(getId() + " loaded from store: " + name);
080: }
081: }
082:
083: if (resolve) {
084: resolveClass(clazz);
085: }
086:
087: return clazz;
088: }
089:
090: protected Class findClass(final String name)
091: throws ClassNotFoundException {
092: final Class clazz = fastFindClass(name);
093: if (clazz == null) {
094: throw new ClassNotFoundException(name);
095: }
096: return clazz;
097: }
098:
099: private String getId() {
100: return "" + this + "[" + this .getClass().getClassLoader() + "]";
101: }
102: }
|