Cleaning up and fixing bugs; new DPOR implementation seems to be correct; need to...
[jpf-core.git] / src / classes / java / lang / ClassLoader.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18 package java.lang;
19
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.net.MalformedURLException;
23 import java.net.URL;
24 import java.nio.ByteBuffer;
25 import java.security.ProtectionDomain;
26 import java.util.Enumeration;
27 import java.util.Vector;
28
29 import sun.misc.CompoundEnumeration;
30
31 /**
32  * @author Nastaran Shafiei <nastaran.shafiei@gmail.com>
33  * 
34  *  Model class for java.lang.ClassLoader
35  */
36 public abstract class ClassLoader {
37   
38   private ClassLoader parent;
39
40   // This is JPF internal identifier which set to the globalId of the classLoader
41   private int nativeId;
42
43   //--- internals
44
45   protected ClassLoader() {
46     // constructed on the native side
47   }
48
49   protected ClassLoader (ClassLoader parent){
50     // constructed on the native side
51   }
52
53   private native String getResource0 (String rname);
54
55   public URL getResource(String name) {
56     URL url = null;
57
58     if(parent == null) {
59       String resourcePath = getSystemClassLoader().getResource0(name);
60       try {
61         url = new URL(resourcePath);
62       } catch (MalformedURLException x){
63         url = null;
64       }
65     } else {
66       url = parent.getResource(name);
67     }
68
69     if (url == null) {
70       url = findResource(name);
71     }
72     return url;
73   }
74
75   /**
76    * Finds the resource with the given name. Class loader implementations
77    * should override this method to specify where to find resources.
78    */
79   protected URL findResource(String name) {
80       return null;
81   }
82
83   private native String[] getResources0 (String rname);
84
85   /**
86    * Returns an array of URL including all resources with the given name 
87    * found in the classpath of this classloader.
88    */
89   private Enumeration<URL> getResourcesURL(String name) {
90     String[] urls = getResources0(name);
91     Vector<URL> list = new Vector<URL>(0);
92     for(String url: urls) {
93       try {
94         list.add(new URL(url));
95       } catch (MalformedURLException x){
96         // process the rest
97       }
98     }
99
100     return list.elements();
101   }
102
103   @SuppressWarnings({"unchecked","rawtypes"})
104   public Enumeration<URL> getResources(String name) throws IOException {
105     Enumeration<URL>[] resEnum = new Enumeration[2];
106
107     if(parent == null) {
108       resEnum[0] = getSystemClassLoader().getResourcesURL(name);
109     } else{
110       resEnum[0] = parent.getResources(name);
111     }
112     resEnum[1] = findResources(name);
113
114     return new CompoundEnumeration<URL>(resEnum);
115   }
116
117   /**
118    * Returns an enumeration representing all the resources with the given 
119    * name. Class loader implementations should override this method to 
120    * specify where to load resources from.
121    */
122   protected Enumeration<URL> findResources(String name) throws IOException {
123       return (new Vector<URL>()).elements();
124   }
125
126   public InputStream getResourceAsStream (String name){
127     URL foundResource = getResource(name);
128     if (foundResource != null) {
129       try {
130         return foundResource.openStream();
131       } catch (IOException e) {
132         System.err.println("cannot open resource " + name);
133       }
134     }
135     return null;
136   }
137
138   public native static ClassLoader getSystemClassLoader ();
139
140   public static URL getSystemResource(String name){
141     return getSystemClassLoader().getResource(name);
142   }
143
144   public static InputStream getSystemResourceAsStream(String name) {
145     return getSystemClassLoader().getResourceAsStream(name);
146   }
147
148   public static Enumeration<URL> getSystemResources(String name) throws IOException {
149     return getSystemClassLoader().getResources(name);
150   }
151
152   public ClassLoader getParent() {
153     return parent;
154   }
155
156   /**
157    * If the class with the given name has been already defined, it is returned. OW, it
158    * returns null.
159    */
160   protected native final Class<?> findLoadedClass(String name);
161
162   protected native final Class<?> findSystemClass(String name) throws ClassNotFoundException;
163
164   public Class<?> loadClass(String name) throws ClassNotFoundException {
165     Class<?> c = findLoadedClass(name);
166
167     if(c == null) {
168       try {
169         if (parent != null && parent != getSystemClassLoader()) {
170           c = parent.loadClass(name, false);
171         } else {
172           c = findSystemClass(name);
173         }
174       } catch (ClassNotFoundException e) {
175         c = findClass(name);
176       }
177     }
178
179     return c;
180   }
181
182   protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
183     return loadClass(name);
184   }
185
186   /**
187    * Finds the class with a given name. This method should be overridden by 
188    * ClassLoader subclasses, and it will be used by loadClass().
189    */
190   protected Class<?> findClass(String name) throws ClassNotFoundException {
191       throw new ClassNotFoundException(name);
192   }
193
194   /**
195    * All the class objects are resolved internally by JPF. So this method
196    * does nothing.
197    */
198   protected final void resolveClass(Class<?> c) {
199   }
200
201   private native Class<?> defineClass0(String name, byte[] b, int off, int len);
202
203   protected final Class<?> defineClass(String name, byte[] b, int off, int len) throws ClassFormatError {
204     return defineClass0(name, b, off, len);
205   }
206
207   protected final Class<?> defineClass(String name, byte[] b, int off, int len, ProtectionDomain protectionDomain) throws ClassFormatError {
208     return defineClass(name, b, off, len);
209   }
210
211   protected String findLibrary(String libname) {
212     return null;
213   }
214
215   protected native Package getPackage(String name);
216
217   protected native Package[] getPackages();
218
219   public native void setDefaultAssertionStatus(boolean enabled);
220
221   public native void setClassAssertionStatus(String className, boolean enabled);
222
223   public native void setPackageAssertionStatus(String packageName, boolean enabled);
224
225   public native void clearAssertionStatus();
226
227   //--- unsupported methods
228
229   protected static boolean registerAsParallelCapable() {
230     return true; // dummy, in prep for jdk7
231   }
232
233   protected Object getClassLoadingLock(String className) {
234     throw new UnsupportedOperationException();
235   }
236
237   protected final Class<?> defineClass(byte[] b, int off, int len) 
238       throws ClassFormatError {
239     throw new UnsupportedOperationException();
240   }
241
242   protected final Class<?> defineClass(String name, ByteBuffer b, ProtectionDomain protectionDomain) 
243       throws ClassFormatError {
244     throw new UnsupportedOperationException();
245   }
246
247   protected final void setSigners(Class<?> c, Object[] signers) {
248     throw new UnsupportedOperationException();
249   }
250
251   protected Package definePackage(String name, String specTitle, String specVersion, 
252                                   String specVendor, String implTitle, String implVersion,
253                                   String implVendor, URL sealBase) 
254                                       throws IllegalArgumentException {
255     throw new UnsupportedOperationException();
256   }
257 }