1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 package complex.sdbc; 22 23 import static org.junit.Assert.assertEquals; 24 import static org.junit.Assert.assertTrue; 25 26 import java.net.URL; 27 import java.util.ArrayList; 28 import java.util.List; 29 30 import org.junit.Test; 31 32 import com.sun.star.comp.sdbc.Tools; 33 34 /** 35 * Tests for the {@link Tools} helper class. 36 */ 37 public final class ToolsTest { 38 39 /** Runs each entry through addClassPathURL and returns what was accepted. */ collect(String... entries)40 private static List<URL> collect(String... entries) { 41 List<URL> urls = new ArrayList<URL>(); 42 for (String entry : entries) { 43 Tools.addClassPathURL(urls, entry); 44 } 45 return urls; 46 } 47 48 @Test testAddClassPathURLAddsLocalFileEntry()49 public void testAddClassPathURLAddsLocalFileEntry() { 50 List<URL> urls = collect("file:/opt/a.jar"); 51 assertEquals(1, urls.size()); 52 assertEquals("file", urls.get(0).getProtocol()); 53 } 54 55 @Test testAddClassPathURLTreatsSchemeCaseInsensitively()56 public void testAddClassPathURLTreatsSchemeCaseInsensitively() { 57 assertEquals(1, collect("FILE:/opt/a.jar").size()); 58 } 59 60 @Test testAddClassPathURLSkipsJarWrappedLocalFile()61 public void testAddClassPathURLSkipsJarWrappedLocalFile() { 62 // A JAR file is added by its own file: URL; a jar: URL is never needed. 63 assertTrue(collect("jar:file:/opt/a.jar!/").isEmpty()); 64 } 65 66 @Test testAddClassPathURLSkipsRemoteEntries()67 public void testAddClassPathURLSkipsRemoteEntries() { 68 assertTrue(collect( 69 "http://host/a.jar", 70 "https://host/b.jar", 71 "ftp://host/c.jar").isEmpty()); 72 } 73 74 @Test testAddClassPathURLSkipsJarWrappedRemoteEntry()75 public void testAddClassPathURLSkipsJarWrappedRemoteEntry() { 76 assertTrue(collect("jar:http://host/a.jar!/").isEmpty()); 77 } 78 79 @Test testAddClassPathURLSkipsMalformedEntry()80 public void testAddClassPathURLSkipsMalformedEntry() { 81 assertTrue(collect("::not-a-url::").isEmpty()); 82 } 83 84 @Test testAddClassPathURLSkipsUnknownScheme()85 public void testAddClassPathURLSkipsUnknownScheme() { 86 // A scheme with no registered URL handler cannot be constructed, so the 87 // entry is treated as malformed and skipped. 88 assertTrue(collect( 89 "wibble:/opt/a.jar", 90 "classpath:/opt/b.jar", 91 "foo://host/c.jar").isEmpty()); 92 } 93 94 @Test testAddClassPathURLSkipsJarWrappedUnknownScheme()95 public void testAddClassPathURLSkipsJarWrappedUnknownScheme() { 96 assertTrue(collect("jar:wibble:/opt/a.jar!/").isEmpty()); 97 } 98 99 @Test testAddClassPathURLAddsLocalhostAndEscapedLocalFile()100 public void testAddClassPathURLAddsLocalhostAndEscapedLocalFile() { 101 assertEquals(1, collect("file://localhost/opt/a.jar").size()); 102 assertEquals(1, collect("file:///opt/Program%20Files/a.jar").size()); 103 assertEquals(1, collect("file:///opt/a%2Fb/c.jar").size()); 104 // One level of decoding only: this names a file called "%5C%5Chost". 105 assertEquals(1, collect("file:///opt/%255C%255Chost/a.jar").size()); 106 } 107 108 @Test testAddClassPathURLSkipsFileOnAnotherHost()109 public void testAddClassPathURLSkipsFileOnAnotherHost() { 110 assertTrue(collect( 111 "file://host/share/a.jar", 112 "file://wsl.localhost/distro/a.jar", 113 "jar:file://host/share/b.jar!/").isEmpty()); 114 } 115 116 @Test testAddClassPathURLSkipsPathNamingAnotherHost()117 public void testAddClassPathURLSkipsPathNamingAnotherHost() { 118 assertTrue(collect( 119 "file:////host/share/a.jar", 120 "file://localhost//host/share/b.jar", 121 "jar:file:////host/share/c.jar!/").isEmpty()); 122 } 123 124 @Test testAddClassPathURLSkipsEscapedSeparatorNamingAnotherHost()125 public void testAddClassPathURLSkipsEscapedSeparatorNamingAnotherHost() { 126 // The file: handler decodes the path and, on Windows, turns slashes 127 // into backslashes, so each of these would be opened as \\host\share. 128 assertTrue(collect( 129 "file:///%5C%5Chost/share/a.jar", 130 "file:///%5c%5chost/share/b.jar", 131 "file:///%2F%2Fhost/share/c.jar", 132 "file:/%2Fhost/share/d.jar", 133 "file://localhost/%5C%5Chost/share/e.jar", 134 "jar:file:///%5C%5Chost/share/f.jar!/").isEmpty()); 135 } 136 137 @Test testAddClassPathURLSkipsBackslash()138 public void testAddClassPathURLSkipsBackslash() { 139 assertTrue(collect( 140 "file:\\\\host\\share\\a.jar", 141 "file:///C:%5C..%5Cb.jar").isEmpty()); 142 } 143 144 @Test testAddClassPathURLKeepsOnlyLocalEntriesInOrder()145 public void testAddClassPathURLKeepsOnlyLocalEntriesInOrder() { 146 List<URL> urls = collect( 147 "http://host/a.jar", 148 "file:/opt/b.jar", 149 "jar:http://host/c.jar!/", 150 "file:/opt/d.jar"); 151 assertEquals(2, urls.size()); 152 assertEquals("/opt/b.jar", urls.get(0).getPath()); 153 assertEquals("/opt/d.jar", urls.get(1).getPath()); 154 } 155 156 @Test testAddClassPathURLAddsPathWithPlus()157 public void testAddClassPathURLAddsPathWithPlus() { 158 List<URL> urls = collect("file:/opt/c++/a.jar"); 159 assertEquals(1, urls.size()); 160 assertEquals("/opt/c++/a.jar", urls.get(0).getPath()); 161 } 162 163 @Test testAddClassPathURLSkipsMalformedEscape()164 public void testAddClassPathURLSkipsMalformedEscape() { 165 assertTrue(collect( 166 "file:/opt/%zz.jar", 167 "file:/opt/a.jar%").isEmpty()); 168 } 169 170 @Test testAddClassPathURLSkipsJvmImageSchemes()171 public void testAddClassPathURLSkipsJvmImageSchemes() { 172 // Unsupported schemes fail to parse and are skipped as well. 173 assertTrue(collect( 174 "jrt:/java.base/module-info.class", 175 "jmod:/x").isEmpty()); 176 } 177 } 178