1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package java.lang;
18
19import java.net.MalformedURLException;
20import java.net.URL;
21import java.security.ProtectionDomain;
22import java.util.ArrayList;
23import java.util.Enumeration;
24import java.util.NoSuchElementException;
25
26class VMClassLoader {
27
28    /**
29     * Get a resource from a file in the bootstrap class path.
30     *
31     * It would be simpler to just walk through the class path elements
32     * ourselves, but that would require reopening Jar files.
33     *
34     * We assume that the bootclasspath can't change once the VM has
35     * started.  This assumption seems to be supported by the spec.
36     */
37    static URL getResource(String name) {
38        int numEntries = getBootClassPathSize();
39        int i;
40
41        for (i = 0; i < numEntries; i++) {
42            String urlStr = getBootClassPathResource(name, i);
43            if (urlStr != null) {
44                try {
45                    return new URL(urlStr);
46                }
47                catch (MalformedURLException mue) {
48                    mue.printStackTrace();
49                    // unexpected; keep going
50                }
51            }
52        }
53
54        return null;
55    }
56
57    /*
58     * Get an enumeration with all matching resources.
59     */
60    static Enumeration<URL> getResources(String name) {
61        ArrayList<URL> list = null;
62        int numEntries = getBootClassPathSize();
63        int i;
64
65        for (i = 0; i < numEntries; i++) {
66            String urlStr = getBootClassPathResource(name, i);
67            if (urlStr != null) {
68                if (list == null)
69                    list = new ArrayList<URL>();
70
71                try {
72                    list.add(new URL(urlStr));
73                }
74                catch (MalformedURLException mue) {
75                    mue.printStackTrace();
76                    // unexpected; keep going
77                }
78            }
79        }
80
81        if (list == null)
82            return null;
83        else
84            return new EnumerateListArray<URL>(list);
85    }
86
87    /**
88     * Load class with bootstrap class loader.
89     */
90    native static Class loadClass(String name, boolean resolve)
91        throws ClassNotFoundException;
92
93    native static Class getPrimitiveClass(char type);
94
95    /*
96     * TODO(Google) Ticket 156: Native implementation does nothing, just throws
97     * OperationNotSupportedException.
98     */
99    native static Class defineClass(ClassLoader cl, String name,
100        byte[] data, int offset, int len, ProtectionDomain pd)
101        throws ClassFormatError;
102
103    /*
104     * TODO(Google) Ticket 156: Native implementation does nothing, just throws
105     * OperationNotSupportedException.
106     */
107    native static Class defineClass(ClassLoader cl,
108            byte[] data, int offset, int len, ProtectionDomain pd)
109            throws ClassFormatError;
110
111    native static Class findLoadedClass(ClassLoader cl, String name);
112
113    /**
114     * Boot class path manipulation, for getResources().
115     */
116    native private static int getBootClassPathSize();
117    native private static String getBootClassPathResource(String name,
118            int index);
119
120    /*
121     * Create an Enumeration for an ArrayList.
122     */
123    private static class EnumerateListArray<T> implements Enumeration<T> {
124        private final ArrayList mList;
125        private int i = 0;
126
127        EnumerateListArray(ArrayList list) {
128            mList = list;
129        }
130
131        public boolean hasMoreElements() {
132            return i < mList.size();
133        }
134
135        public T nextElement() {
136            if (i >= mList.size())
137                throw new NoSuchElementException();
138            return (T) mList.get(i++);
139        }
140    };
141}
142
143