| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package libcore.io; |
| |
| import junit.framework.TestCase; |
| |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.net.JarURLConnection; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.net.URLConnection; |
| import java.net.URLStreamHandler; |
| import java.net.UnknownServiceException; |
| import java.util.Arrays; |
| |
| import tests.support.resource.Support_Resources; |
| |
| public class ClassPathURLStreamHandlerTest extends TestCase { |
| |
| // A well formed jar file with 6 entries. |
| private static final String JAR = "ClassPathURLStreamHandlerTest.jar"; |
| private static final String ENTRY_IN_ROOT = "root.txt"; |
| private static final String DIR_ENTRY_WITHOUT_SLASH = "foo"; |
| private static final String DIR_ENTRY_WITH_SLASH = DIR_ENTRY_WITHOUT_SLASH + "/"; |
| private static final String ENTRY_IN_SUBDIR = "foo/bar/baz.txt"; |
| private static final String ENTRY_STORED = "stored_file.txt"; |
| private static final String ENTRY_WITH_SPACES_ENCODED = "file%20with%20spaces.txt"; |
| private static final String ENTRY_WITH_SPACES_UNENCODED = "file with spaces.txt"; |
| private static final String ENTRY_THAT_NEEDS_ESCAPING = "file_with_percent20_%20.txt"; |
| private static final String ENTRY_THAT_NEEDS_ESCAPING_ENCODED = "file_with_percent20_%2520.txt"; |
| private static final String ENTRY_WITH_RELATIVE_PATH = "foo/../foo/bar/baz.txt"; |
| private static final String MISSING_ENTRY = "Wrong.resource"; |
| |
| private File jarFile; |
| |
| @Override |
| protected void setUp() throws Exception { |
| File resources = Support_Resources.createTempFolder().getCanonicalFile(); |
| Support_Resources.copyFile(resources, null, JAR); |
| jarFile = new File(resources, JAR); |
| } |
| |
| public void testConstructor() throws Exception { |
| try { |
| ClassPathURLStreamHandler streamHandler = new ClassPathURLStreamHandler("Missing.file"); |
| fail("Should throw IOException"); |
| } catch (IOException expected) { |
| } |
| |
| String fileName = jarFile.getPath(); |
| ClassPathURLStreamHandler streamHandler = new ClassPathURLStreamHandler(fileName); |
| streamHandler.close(); |
| } |
| |
| public void testGetEntryOrNull() throws Exception { |
| String fileName = jarFile.getPath(); |
| ClassPathURLStreamHandler streamHandler = new ClassPathURLStreamHandler(fileName); |
| |
| checkGetEntryUrlOrNull(streamHandler, ENTRY_IN_ROOT, ENTRY_IN_ROOT); |
| checkGetEntryUrlOrNull(streamHandler, ENTRY_IN_SUBDIR, ENTRY_IN_SUBDIR); |
| checkGetEntryUrlOrNull(streamHandler, ENTRY_WITH_SPACES_UNENCODED, |
| ENTRY_WITH_SPACES_ENCODED); |
| checkGetEntryUrlOrNull(streamHandler, ENTRY_THAT_NEEDS_ESCAPING, |
| ENTRY_THAT_NEEDS_ESCAPING_ENCODED); |
| |
| // getEntryOrNull() performs a lookup with and without trailing slash to handle directories. |
| // http://b/22527772 |
| checkGetEntryUrlOrNull(streamHandler, DIR_ENTRY_WITHOUT_SLASH, |
| DIR_ENTRY_WITHOUT_SLASH); |
| checkGetEntryUrlOrNull(streamHandler, DIR_ENTRY_WITH_SLASH, DIR_ENTRY_WITH_SLASH); |
| |
| assertNull(streamHandler.getEntryUrlOrNull(MISSING_ENTRY)); |
| assertNull(streamHandler.getEntryUrlOrNull("/" + ENTRY_IN_ROOT)); |
| assertNull(streamHandler.getEntryUrlOrNull("/" + ENTRY_IN_SUBDIR)); |
| assertNull(streamHandler.getEntryUrlOrNull(ENTRY_WITH_SPACES_ENCODED)); |
| assertNull(streamHandler.getEntryUrlOrNull(ENTRY_WITH_RELATIVE_PATH)); |
| assertNull(streamHandler.getEntryUrlOrNull("/" + DIR_ENTRY_WITHOUT_SLASH)); |
| assertNull(streamHandler.getEntryUrlOrNull("/" + DIR_ENTRY_WITH_SLASH)); |
| streamHandler.close(); |
| } |
| |
| /** |
| * Check that the call to {@link ClassPathURLStreamHandler#getEntryUrlOrNull(String)} works as |
| * expected. |
| */ |
| private void checkGetEntryUrlOrNull(ClassPathURLStreamHandler streamHandler, |
| String entryName, String expectedJarRelativeURI) throws IOException { |
| |
| String fileName = jarFile.getPath(); |
| URL urlOrNull = streamHandler.getEntryUrlOrNull(entryName); |
| assertNotNull("URL was unexpectedly null for " + entryName, urlOrNull); |
| assertEquals("jar:file:" + fileName + "!/" + expectedJarRelativeURI, |
| urlOrNull.toExternalForm()); |
| |
| // Make sure that the resource could be opened and the correct contents returned, i.e. the |
| // same as those read from the jar file directly. |
| assertOpenConnectionOk(jarFile, expectedJarRelativeURI, streamHandler); |
| } |
| |
| public void testIsEntryStored() throws IOException { |
| String fileName = jarFile.getPath(); |
| ClassPathURLStreamHandler streamHandler = new ClassPathURLStreamHandler(fileName); |
| |
| assertFalse(streamHandler.isEntryStored("this/file/does/not/exist.txt")); |
| // This one is compressed |
| assertFalse(streamHandler.isEntryStored(ENTRY_IN_SUBDIR)); |
| assertTrue(streamHandler.isEntryStored(ENTRY_STORED)); |
| |
| assertTrue(streamHandler.isEntryStored(DIR_ENTRY_WITHOUT_SLASH)); |
| |
| // Directory entries are just stored, empty entries with "/" on the end of the name, so |
| // "true". |
| assertTrue(streamHandler.isEntryStored(DIR_ENTRY_WITH_SLASH)); |
| } |
| |
| public void testOpenConnection() throws Exception { |
| String fileName = jarFile.getPath(); |
| ClassPathURLStreamHandler streamHandler = new ClassPathURLStreamHandler(fileName); |
| |
| assertOpenConnectionOk(jarFile, ENTRY_IN_ROOT, streamHandler); |
| assertOpenConnectionOk(jarFile, ENTRY_IN_SUBDIR, streamHandler); |
| assertOpenConnectionOk(jarFile, ENTRY_WITH_SPACES_ENCODED, streamHandler); |
| assertOpenConnectionOk(jarFile, ENTRY_WITH_SPACES_UNENCODED, streamHandler); |
| assertOpenConnectionOk(jarFile, DIR_ENTRY_WITH_SLASH, streamHandler); |
| assertOpenConnectionOk(jarFile, DIR_ENTRY_WITHOUT_SLASH, streamHandler); |
| |
| assertOpenConnectionConnectFails(jarFile, ENTRY_WITH_RELATIVE_PATH, streamHandler); |
| assertOpenConnectionConnectFails(jarFile, MISSING_ENTRY, streamHandler); |
| assertOpenConnectionConnectFails(jarFile, ENTRY_THAT_NEEDS_ESCAPING, streamHandler); |
| |
| streamHandler.close(); |
| } |
| |
| private void assertOpenConnectionConnectFails( |
| File jarFile, String entryName, URLStreamHandler streamHandler) throws IOException { |
| |
| URL standardUrl = createJarUrl(jarFile, entryName, null /* use default stream handler */); |
| try { |
| standardUrl.openConnection().connect(); |
| fail(); |
| } catch (FileNotFoundException expected) { |
| } |
| |
| URL actualUrl = createJarUrl(jarFile, entryName, streamHandler); |
| try { |
| actualUrl.openConnection().connect(); |
| fail(); |
| } catch (FileNotFoundException expected) { |
| } |
| } |
| |
| private static void assertOpenConnectionOk(File jarFile, String entryName, |
| ClassPathURLStreamHandler streamHandler) throws IOException { |
| URL standardUrl = createJarUrl(jarFile, entryName, null /* use default stream handler */); |
| URLConnection standardUrlConnection = standardUrl.openConnection(); |
| assertNotNull(standardUrlConnection); |
| |
| URL actualUrl = createJarUrl(jarFile, entryName, streamHandler); |
| URLConnection actualUrlConnection = actualUrl.openConnection(); |
| assertNotNull(actualUrlConnection); |
| assertBehaviorSame(standardUrlConnection, actualUrlConnection); |
| } |
| |
| private static void assertBehaviorSame(URLConnection standardURLConnection, |
| URLConnection actualUrlConnection) throws IOException { |
| |
| JarURLConnection standardJarUrlConnection = (JarURLConnection) standardURLConnection; |
| JarURLConnection actualJarUrlConnection = (JarURLConnection) actualUrlConnection; |
| |
| byte[] actualBytes = Streams.readFully(actualJarUrlConnection.getInputStream()); |
| byte[] standardBytes = Streams.readFully(standardJarUrlConnection.getInputStream()); |
| assertEquals(Arrays.toString(standardBytes), Arrays.toString(actualBytes)); |
| |
| try { |
| actualJarUrlConnection.getOutputStream(); |
| fail(); |
| } catch (UnknownServiceException expected) { |
| } |
| |
| assertEquals( |
| standardJarUrlConnection.getJarFile().getName(), |
| actualJarUrlConnection.getJarFile().getName()); |
| |
| assertEquals( |
| standardJarUrlConnection.getJarEntry().getName(), |
| actualJarUrlConnection.getJarEntry().getName()); |
| |
| assertEquals( |
| standardJarUrlConnection.getJarFileURL(), |
| actualJarUrlConnection.getJarFileURL()); |
| |
| assertEquals( |
| standardJarUrlConnection.getContentType(), |
| actualJarUrlConnection.getContentType()); |
| |
| assertEquals( |
| standardJarUrlConnection.getContentLength(), |
| actualJarUrlConnection.getContentLength()); |
| } |
| |
| private static URL createJarUrl(File jarFile, String entryName, URLStreamHandler streamHandler) |
| throws MalformedURLException { |
| return new URL("jar", null, -1, jarFile.toURI() + "!/" + entryName, streamHandler); |
| } |
| |
| } |