T6877206.java revision 2721:f7ce2cfa4cdb
150397Sobrien/* 290075Sobrien * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. 350397Sobrien * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 490075Sobrien * 552284Sobrien * This code is free software; you can redistribute it and/or modify it 690075Sobrien * under the terms of the GNU General Public License version 2 only, as 790075Sobrien * published by the Free Software Foundation. 890075Sobrien * 990075Sobrien * This code is distributed in the hope that it will be useful, but WITHOUT 1052284Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1190075Sobrien * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1290075Sobrien * version 2 for more details (a copy is included in the LICENSE file that 1390075Sobrien * accompanied this code). 1490075Sobrien * 1552284Sobrien * You should have received a copy of the GNU General Public License version 1652284Sobrien * 2 along with this work; if not, write to the Free Software Foundation, 1790075Sobrien * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1890075Sobrien * 1990075Sobrien * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2052284Sobrien * or visit www.oracle.com if you need additional information or have any 2190075Sobrien * questions. 2290075Sobrien */ 2350397Sobrien 2490075Sobrien/* 2590075Sobrien * @test 2690075Sobrien * @bug 6877206 2790075Sobrien * @summary JavaFileObject.toUri returns bogus URI (win) 2850397Sobrien */ 2990075Sobrien 3090075Sobrienimport java.io.*; 3152284Sobrienimport java.net.*; 3290075Sobrienimport java.util.*; 3390075Sobrienimport java.util.jar.*; 3490075Sobrienimport java.util.zip.*; 3590075Sobrienimport javax.tools.*; 3690075Sobrien 3790075Sobrienimport com.sun.tools.javac.file.JavacFileManager; 3890075Sobrienimport com.sun.tools.javac.util.Context; 3990075Sobrienimport com.sun.tools.javac.util.Options; 4090075Sobrien 4190075Sobrien// Test URIs returned from JavacFileManager and its support classes. 4290075Sobrien// For a variety of file objects, verify the validity of FileObject.toUri() 4390075Sobrien// by verifying the URI exists and points to the same contents as the file 4490075Sobrien// object itself 4590075Sobrien 4690075Sobrienpublic class T6877206 { 4790075Sobrien public static void main(String... args) throws Exception { 4890075Sobrien new T6877206().run(); 4950397Sobrien } 5090075Sobrien 5190075Sobrien Set<String> foundClasses = new TreeSet<String>(); 5290075Sobrien Set<String> foundJars = new TreeSet<String>(); 5390075Sobrien 5490075Sobrien void run() throws Exception { 5590075Sobrien // names for entries to be created in directories and jar files 5690075Sobrien String[] entries = { "p/A.class", "p/resources/A-1.jpg" }; 5790075Sobrien 5890075Sobrien // test various combinations of directories and jar files, intended to 5990075Sobrien // cover all sources of URIs within JavacFileManager's support classes 6090075Sobrien 6190075Sobrien test(createFileManager(), createDir("dir", entries), "p", entries.length); 6290075Sobrien test(createFileManager(), createDir("a b/dir", entries), "p", entries.length); 6390075Sobrien 6490075Sobrien for (boolean useOptimizedZip: new boolean[] { false, true }) { 6590075Sobrien test(createFileManager(useOptimizedZip), createJar("jar", entries), "p", entries.length); 6690075Sobrien test(createFileManager(useOptimizedZip), createJar("jar jar", entries), "p", entries.length); 6790075Sobrien } 6890075Sobrien 6990075Sobrien // Verify that we hit the files we intended 7090075Sobrien checkCoverage("classes", foundClasses, 7190075Sobrien "RegularFileObject", "ZipFileIndexFileObject", "ZipFileObject"); 7290075Sobrien 7352284Sobrien // Verify that we hit the jar files we intended 7490075Sobrien checkCoverage("jar files", foundJars, "jar", "jar jar"); 7590075Sobrien } 7652284Sobrien 7790075Sobrien // use a new file manager for each test 7890075Sobrien void test(StandardJavaFileManager fm, File f, String pkg, int expect) throws Exception { 7990075Sobrien JarURLConnection c; 8090075Sobrien System.err.println("Test " + f); 8190075Sobrien try { 8290075Sobrien fm.setLocation(StandardLocation.CLASS_PATH, Collections.singleton(f)); 8352284Sobrien 8490075Sobrien int count = 0; 8550397Sobrien for (JavaFileObject fo: fm.list(StandardLocation.CLASS_PATH, 8690075Sobrien pkg, EnumSet.allOf(JavaFileObject.Kind.class), true)) { 8790075Sobrien System.err.println("checking " + fo); 8890075Sobrien // record the file object class name for coverage checks later 8990075Sobrien foundClasses.add(fo.getClass().getSimpleName()); 9090075Sobrien testFileObject(fo); 9190075Sobrien count++; 9250397Sobrien } 9350397Sobrien 9490075Sobrien if (expect > 0 && count != expect) 9590075Sobrien throw new Exception("wrong number of entries found: " 9650397Sobrien + count + ", expected " + expect); 9790075Sobrien } finally { 9890075Sobrien fm.close(); 9952284Sobrien } 10050397Sobrien } 10152284Sobrien 10290075Sobrien void testFileObject(JavaFileObject fo) throws Exception { 10390075Sobrien // test the validity of the result of toUri() by using URLConnection 10490075Sobrien // and comparing the results of reading from the connection with the 10590075Sobrien // result of reading from the file object directly. 10652284Sobrien URI uri = fo.toUri(); 10752284Sobrien System.err.println("uri: " + uri); 10890075Sobrien 10990075Sobrien URLConnection urlconn = uri.toURL().openConnection(); 11090075Sobrien if (urlconn instanceof JarURLConnection) { 11190075Sobrien JarURLConnection jarconn = (JarURLConnection) urlconn; 11290075Sobrien File f = new File(jarconn.getJarFile().getName()); 11390075Sobrien // record access to the jar file for coverage checks later 11490075Sobrien foundJars.add(f.getName()); 11590075Sobrien } 11690075Sobrien 11790075Sobrien try { 11890075Sobrien byte[] uriData = read(urlconn.getInputStream()); 11990075Sobrien byte[] foData = read(fo.openInputStream()); 12090075Sobrien if (!Arrays.equals(uriData, foData)) { 12190075Sobrien if (uriData.length != foData.length) 12290075Sobrien throw new Exception("data size differs: uri data " 12390075Sobrien + uriData.length + " bytes, fo data " + foData.length+ " bytes"); 12490075Sobrien for (int i = 0; i < uriData.length; i++) { 12590075Sobrien if (uriData[i] != foData[i]) 12690075Sobrien throw new Exception("unexpected data returned at offset " + i 12790075Sobrien + ", uri data " + uriData[i] + ", fo data " + foData[i]); 12890075Sobrien } 12990075Sobrien throw new AssertionError("cannot find difference"); 13090075Sobrien } 13190075Sobrien } finally { 13290075Sobrien // In principle, simply closing the result of urlconn.getInputStream() 13390075Sobrien // should have been sufficient. But the internal JarURLConnection 134 // does not close the JarFile in an expeditious manner, thus preventing 135 // jtreg from deleting the jar file before starting the next test. 136 // Therefore we force access to the JarURLConnection to close the 137 // JarFile when necessary. 138 if (urlconn instanceof JarURLConnection) { 139 JarURLConnection jarconn = (JarURLConnection) urlconn; 140 jarconn.getJarFile().close(); 141 } 142 } 143 } 144 145 void checkCoverage(String label, Set<String> found, String... expect) throws Exception { 146 Set<String> e = new TreeSet<String>(Arrays.asList(expect)); 147 if (!found.equals(e)) { 148 e.removeAll(found); 149 throw new Exception("expected " + label + " not used: " + e); 150 } 151 } 152 153 JavacFileManager createFileManager() { 154 return createFileManager(false, false); 155 } 156 157 JavacFileManager createFileManager(boolean useOptimizedZip) { 158 return createFileManager(useOptimizedZip, false); 159 } 160 161 JavacFileManager createFileManager(boolean useOptimizedZip, boolean useSymbolFile) { 162 Context ctx = new Context(); 163 Options options = Options.instance(ctx); 164 options.put("useOptimizedZip", Boolean.toString(useOptimizedZip)); 165 if (!useSymbolFile) { 166 options.put("ignore.symbol.file", "true"); 167 } 168 return new JavacFileManager(ctx, false, null); 169 } 170 171 File createDir(String name, String... entries) throws Exception { 172 File dir = new File(name); 173 if (!dir.mkdirs()) 174 throw new Exception("cannot create directories " + dir); 175 for (String e: entries) { 176 writeFile(new File(dir, e), e); 177 } 178 return dir; 179 } 180 181 File createJar(String name, String... entries) throws IOException { 182 File jar = new File(name); 183 OutputStream out = new FileOutputStream(jar); 184 try { 185 JarOutputStream jos = new JarOutputStream(out); 186 for (String e: entries) { 187 jos.putNextEntry(new ZipEntry(e)); 188 jos.write(e.getBytes()); 189 } 190 jos.close(); 191 } finally { 192 out.close(); 193 } 194 return jar; 195 } 196 197 byte[] read(InputStream in) throws IOException { 198 byte[] data = new byte[1024]; 199 int offset = 0; 200 try { 201 int n; 202 while ((n = in.read(data, offset, data.length - offset)) != -1) { 203 offset += n; 204 if (offset == data.length) 205 data = Arrays.copyOf(data, 2 * data.length); 206 } 207 } finally { 208 in.close(); 209 } 210 return Arrays.copyOf(data, offset); 211 } 212 213 void writeFile(File f, String s) throws IOException { 214 f.getParentFile().mkdirs(); 215 FileWriter out = new FileWriter(f); 216 try { 217 out.write(s); 218 } finally { 219 out.close(); 220 } 221 } 222} 223