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
18package libcore.java.net;
19
20import dalvik.annotation.SideEffect;
21import java.io.File;
22import java.io.FileOutputStream;
23import java.io.IOException;
24import java.io.InputStream;
25import java.net.MalformedURLException;
26import java.net.URL;
27import java.net.URLClassLoader;
28import java.security.CodeSource;
29import java.security.Permission;
30import java.security.PermissionCollection;
31import java.security.cert.Certificate;
32import java.util.ArrayList;
33import java.util.Enumeration;
34import java.util.List;
35import java.util.jar.Manifest;
36import org.apache.harmony.security.tests.support.TestCertUtils;
37import tests.support.Support_Configuration;
38import tests.support.Support_TestWebData;
39import tests.support.Support_TestWebServer;
40import tests.support.resource.Support_Resources;
41
42public class OldURLClassLoaderTest extends junit.framework.TestCase {
43
44    URLClassLoader ucl;
45    SecurityManager sm = new SecurityManager() {
46
47        public void checkPermission(Permission perm) {
48        }
49
50        public void checkCreateClassLoader() {
51            throw new SecurityException();
52        }
53    };
54
55    /**
56     * java.net.URLClassLoader#URLClassLoader(java.net.URL[])
57     */
58    public void test_Constructor$Ljava_net_URL() throws MalformedURLException {
59        URL[] u = new URL[0];
60        ucl = new URLClassLoader(u);
61        assertTrue("Failed to set parent", ucl != null
62                && ucl.getParent() == URLClassLoader.getSystemClassLoader());
63
64
65        URL [] urls = {new URL("http://foo.com/foo"),
66                       new URL("jar:file://foo.jar!/foo.c"),
67                       new URL("ftp://foo1/foo2/foo.c")};
68
69        URLClassLoader ucl1 = new URLClassLoader(urls);
70        assertTrue(urls.length == ucl1.getURLs().length);
71
72        try {
73            Class.forName("test", false, ucl);
74            fail("Should throw ClassNotFoundException");
75        } catch (ClassNotFoundException e) {
76            // expected
77        }
78
79        try {
80            new URLClassLoader(new URL[] { null });
81        } catch(Exception e) {
82            fail("Unexpected exception was thrown: " + e.getMessage());
83        }
84    }
85
86    /**
87     * java.net.URLClassLoader#findResources(java.lang.String)
88     */
89    public void test_findResourcesLjava_lang_String() throws Exception {
90        Enumeration<URL> res = null;
91        String[] resValues = { "This is a test resource file.",
92                "This is a resource from a subdir"};
93
94        String tmp = System.getProperty("java.io.tmpdir") + "/";
95
96        File tmpDir = new File(tmp);
97        File test1 = new File(tmp + "test0");
98        test1.deleteOnExit();
99        FileOutputStream out = new FileOutputStream(test1);
100        out.write(resValues[0].getBytes());
101        out.flush();
102        out.close();
103
104        File subDir = new File(tmp + "subdir/");
105        subDir.mkdir();
106        File test2 = new File(tmp + "subdir/test0");
107        test2.deleteOnExit();
108        out = new FileOutputStream(test2);
109        out.write(resValues[1].getBytes());
110        out.flush();
111        out.close();
112
113        URL[] urls = new URL[2];
114        urls[0] = new URL("file://" + tmpDir.getAbsolutePath() + "/");
115        urls[1] = new URL("file://" + subDir.getAbsolutePath() + "/");
116
117        ucl = new URLClassLoader(urls);
118        res = ucl.findResources("test0");
119        assertNotNull("Failed to locate resources", res);
120
121        int i = 0;
122        while (res.hasMoreElements()) {
123            StringBuffer sb = getResContent(res.nextElement());
124            assertEquals("Returned incorrect resource/or in wrong order",
125                    resValues[i++], sb.toString());
126        }
127        assertEquals("Incorrect number of resources returned", 2, i);
128    }
129
130    public void test_addURLLjava_net_URL() throws MalformedURLException {
131        URL[] u = new URL[0];
132
133        URL [] urls = {new URL("http://foo.com/foo"),
134                       new URL("jar:file://foo.jar!/foo.c"),
135                       new URL("ftp://foo1/foo2/foo.c"), null};
136
137        TestURLClassLoader tucl = new TestURLClassLoader(u);
138
139        for(int i = 0; i < urls.length;) {
140            tucl.addURL(urls[i]);
141            i++;
142            URL [] result = tucl.getURLs();
143            assertEquals("Result array length is incorrect: " + i,
144                                                            i, result.length);
145            for(int j = 0; j < result.length; j++) {
146                assertEquals("Result array item is incorrect: " + j,
147                                                            urls[j], result[j]);
148            }
149        }
150    }
151
152    public void test_definePackage() throws MalformedURLException {
153        Manifest manifest = new Manifest();
154        URL[] u = new URL[0];
155        TestURLClassLoader tucl = new TestURLClassLoader(u);
156
157        URL [] urls = {new URL("http://foo.com/foo"),
158                new URL("jar:file://foo.jar!/foo.c"),
159                new URL("ftp://foo1/foo2/foo.c"),
160                new URL("file://new/package/name/"),
161                null};
162
163        String packageName = "new.package.name";
164
165        for(int i = 0; i < urls.length; i++) {
166            Package pack = tucl.definePackage(packageName + i, manifest, urls[i]);
167            assertEquals(packageName + i, pack.getName());
168            assertNull("Implementation Title is not null",
169                    pack.getImplementationTitle());
170            assertNull("Implementation Vendor is not null",
171                    pack.getImplementationVendor());
172            assertNull("Implementation Version is not null.",
173                    pack.getImplementationVersion());
174        }
175
176        try {
177            tucl.definePackage(packageName + "0", manifest, null);
178            fail("IllegalArgumentException was not thrown.");
179        } catch(IllegalArgumentException iae) {
180            //expected
181        }
182    }
183
184    class TestURLClassLoader extends URLClassLoader {
185        public TestURLClassLoader(URL[] urls) {
186            super(urls);
187        }
188
189        public void addURL(URL url) {
190            super.addURL(url);
191        }
192
193        public Package definePackage(String name,
194                                     Manifest man,
195                                     URL url)
196                                     throws IllegalArgumentException {
197            return super.definePackage(name, man, url);
198        }
199
200        public Class<?> findClass(String name)
201                                        throws ClassNotFoundException {
202            return super.findClass(name);
203        }
204
205        protected PermissionCollection getPermissions(CodeSource codesource) {
206            return super.getPermissions(codesource);
207        }
208    }
209
210    @SideEffect("Support_TestWebServer requires isolation.")
211    public void test_findResourceLjava_lang_String() throws Exception {
212        File tmp = File.createTempFile("test", ".txt");
213
214        Support_TestWebServer server = new Support_TestWebServer();
215        try {
216
217            int port = server.initServer(tmp.getAbsolutePath(), "text/html");
218
219            URL[] urls = { new URL("http://localhost:" + port + "/") };
220            ucl = new URLClassLoader(urls);
221            URL res = ucl.findResource("test1");
222            assertNotNull("Failed to locate resource", res);
223
224            StringBuffer sb = getResContent(res);
225            assertEquals("Returned incorrect resource", new String(Support_TestWebData.test1),
226                    sb.toString());
227        } finally {
228            server.close();
229        }
230    }
231
232    /**
233     * Regression for Harmony-2237
234     */
235    @SideEffect("Support_TestWebServer requires isolation.")
236    public void test_findResource_String() throws Exception {
237        File tempFile1 = File.createTempFile("textFile", ".txt");
238        tempFile1.createNewFile();
239        tempFile1.deleteOnExit();
240        File tempFile2 = File.createTempFile("jarFile", ".jar");
241        tempFile2.delete();
242        tempFile2.deleteOnExit();
243
244        Support_TestWebServer server = new Support_TestWebServer();
245        try {
246            int port = server.initServer();
247
248            String tempPath1 = tempFile1.getParentFile().getAbsolutePath() + "/";
249            InputStream is = getClass().getResourceAsStream(
250                    "/tests/resources/hyts_patch.jar");
251            Support_Resources.copyLocalFileto(tempFile2, is);
252            String tempPath2 = tempFile2.getAbsolutePath();
253            String tempPath3 = "http://localhost:" + port + "/";
254            URLClassLoader urlLoader = getURLClassLoader(tempPath1, tempPath2);
255            assertNull("Found inexistant resource",
256                    urlLoader.findResource("XXX"));
257            assertNotNull("Couldn't find resource from directory",
258                    urlLoader.findResource(tempFile1.getName()));
259            assertNotNull("Couldn't find resource from jar",
260                    urlLoader.findResource("Blah.txt"));
261            urlLoader = getURLClassLoader(tempPath1, tempPath2, tempPath3);
262            assertNotNull("Couldn't find resource from web",
263                    urlLoader.findResource("test1"));
264            assertNull("Found inexistant resource from web",
265                    urlLoader.findResource("test3"));
266        } finally {
267            server.close();
268        }
269    }
270
271    private static URLClassLoader getURLClassLoader(String... classPath)
272            throws MalformedURLException {
273        List<URL> urlList = new ArrayList<URL>();
274        for (String path : classPath) {
275            String url;
276            File f = new File(path);
277            if (f.isDirectory()) {
278                url = "file:" + path;
279            } else if (path.startsWith("http")) {
280                url = path;
281            } else {
282                url = "jar:file:" + path + "!/";
283            }
284            urlList.add(new URL(url));
285        }
286        return new URLClassLoader(urlList.toArray(new URL[urlList.size()]));
287    }
288
289    private StringBuffer getResContent(URL res) throws IOException {
290        StringBuffer sb = new StringBuffer();
291        InputStream is = res.openStream();
292
293        int c;
294        while ((c = is.read()) != -1) {
295            sb.append((char) c);
296        }
297        is.close();
298        return sb;
299    }
300}
301