1c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson/*
2c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson * Copyright (C) 2010 The Android Open Source Project
3c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson *
4c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson * you may not use this file except in compliance with the License.
6c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson * You may obtain a copy of the License at
7c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson *
8c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
9c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson *
10c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson * Unless required by applicable law or agreed to in writing, software
11c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson * See the License for the specific language governing permissions and
14c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson * limitations under the License.
15c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson */
16c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
17c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilsonpackage libcore.java.net;
18c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
19c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilsonimport java.lang.reflect.Field;
20c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilsonimport java.net.URL;
21c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilsonimport java.net.URLConnection;
22c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilsonimport java.net.URLStreamHandler;
23c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilsonimport java.net.URLStreamHandlerFactory;
24c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilsonimport junit.framework.TestCase;
25c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilsonimport libcore.java.net.customstreamhandler.http.Handler;
26c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
27c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilsonpublic final class URLStreamHandlerFactoryTest extends TestCase {
28c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    private URLStreamHandlerFactory oldFactory;
29c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    private Field factoryField;
30c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    private boolean isCreateURLStreamHandlerCalled;
31c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
32c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    public void setUp() throws IllegalAccessException {
33c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        for (Field field : URL.class.getDeclaredFields()) {
34c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            if (URLStreamHandlerFactory.class.equals(field.getType())) {
35c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson                assertNull("URL declares multiple URLStreamHandlerFactory fields", factoryField);
36c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson                factoryField = field;
37c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson                factoryField.setAccessible(true);
38c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson                oldFactory = (URLStreamHandlerFactory) factoryField.get(null);
39c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson                return;
40c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            }
41c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        }
42c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
43c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        fail("URL does not declare a URLStreamHandlerFactory field");
44c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    }
45c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
46c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    public void tearDown() throws IllegalAccessException {
47c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        factoryField.set(null, null);
48c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        URL.setURLStreamHandlerFactory(oldFactory);
49c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    }
50c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
51c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    public void testCreateURLStreamHandler() throws Exception {
52c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        TestURLStreamHandlerFactory shf = new TestURLStreamHandlerFactory();
53c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        assertFalse(isCreateURLStreamHandlerCalled);
54c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
55c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        URL.setURLStreamHandlerFactory(shf);
56c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        URL url = new URL("http://android.com/");
57c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
58c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        URLConnection connection = url.openConnection();
59c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        assertTrue(connection instanceof Handler.HandlerURLConnection);
60c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
61c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        try {
62c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            URL.setURLStreamHandlerFactory(shf);
63c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            fail();
64c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        } catch (Error expected) {
65c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        }
66c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
67c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        try {
68c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            URL.setURLStreamHandlerFactory(null);
69c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            fail();
70c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        } catch (Error expected) {
71c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        }
72c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    }
73c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
74c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    public void testInstallCustomProtocolHandler() throws Exception {
75c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        // clear cached protocol handlers if they exist
76c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        factoryField.set(null, null);
77c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        URL.setURLStreamHandlerFactory(oldFactory);
78c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
79c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        try {
80c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            System.setProperty("java.protocol.handler.pkgs", getHandlerPackageName());
81c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            URLConnection connection = new URL("http://android.com/").openConnection();
82c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            assertTrue(connection instanceof Handler.HandlerURLConnection);
83c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        } finally {
84c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            System.clearProperty("java.protocol.handler.pkgs");
85c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        }
86c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    }
87c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
88c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    public void testFirstUseIsCached() throws Exception {
89c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        // clear cached protocol handlers if they exist
90c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        factoryField.set(null, null);
91c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        URL.setURLStreamHandlerFactory(oldFactory);
92c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
93c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        // creating a connection should use the platform's default stream handler
94c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        URLConnection connection1 = new URL("http://android.com/").openConnection();
95c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        assertFalse(connection1 instanceof Handler.HandlerURLConnection);
96c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
97c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        try {
98c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            // set the property and get another connection. The property should not be honored
99c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            System.setProperty("java.protocol.handler.pkgs", getHandlerPackageName());
100c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            URLConnection connection2 = new URL("http://android.com/").openConnection();
101c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            assertFalse(connection2 instanceof Handler.HandlerURLConnection);
102c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        } finally {
103c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            System.clearProperty("java.protocol.handler.pkgs");
104c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        }
105c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    }
106c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
107c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    private String getHandlerPackageName() {
108c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        String className = Handler.class.getName();
109c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        return className.substring(0, className.indexOf(".http.Handler"));
110c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    }
111c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson
112c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    class TestURLStreamHandlerFactory implements URLStreamHandlerFactory {
113c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        @Override public URLStreamHandler createURLStreamHandler(String protocol) {
114c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            isCreateURLStreamHandlerCalled = true;
115c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson            return new Handler();
116c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson        }
117c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson    }
118c2ebff3511f9df4d8cca2b82630c2d760af9d204Jesse Wilson}
119