View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.jci.stores;
18  
19  import org.apache.commons.jci.utils.ConversionUtils;
20  import org.apache.commons.logging.Log;
21  import org.apache.commons.logging.LogFactory;
22  
23  
24  /**
25   * A ClassLoader backed by an array of ResourceStores
26   * 
27   * @author tcurdt
28   */
29  public final class ResourceStoreClassLoader extends ClassLoader {
30  
31      private final Log log = LogFactory.getLog(ResourceStoreClassLoader.class);
32  
33      private final ResourceStore[] stores;
34  
35      public ResourceStoreClassLoader( final ClassLoader pParent, final ResourceStore[] pStores ) {
36          super(pParent);
37          stores = pStores;
38      }
39  
40      private Class fastFindClass(final String name) {
41          
42          if (stores != null) {
43              for (int i = 0; i < stores.length; i++) {
44                  final ResourceStore store = stores[i];
45                  final byte[] clazzBytes = store.read(ConversionUtils.convertClassToResourcePath(name));
46                  if (clazzBytes != null) {
47                      log.debug(getId() + " found class: " + name  + " (" + clazzBytes.length + " bytes)");
48                      return defineClass(name, clazzBytes, 0, clazzBytes.length);
49                  }            
50              }
51          }
52          
53          return null;            
54      }
55      
56      protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
57          // log.debug(getId() + " looking for: " + name);
58          Class clazz = findLoadedClass(name);
59  
60          if (clazz == null) {
61              clazz = fastFindClass(name);
62              
63              if (clazz == null) {
64  
65                  final ClassLoader parent = getParent();
66                  if (parent != null) {
67                      clazz = parent.loadClass(name);
68                      // log.debug(getId() + " delegating loading to parent: " + name);
69                  } else {
70                      throw new ClassNotFoundException(name);
71                  }
72                  
73              } else {
74                  log.debug(getId() + " loaded from store: " + name);
75              }
76          }
77  
78          if (resolve) {
79              resolveClass(clazz);
80          }
81  
82          return clazz;
83      }
84  
85      protected Class findClass( final String name ) throws ClassNotFoundException {
86          final Class clazz = fastFindClass(name);
87          if (clazz == null) {
88              throw new ClassNotFoundException(name);
89          }
90          return clazz;
91      }
92      
93      private String getId() {
94          return "" + this + "[" + this.getClass().getClassLoader() + "]";
95      }
96  }