| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 org.netbeans.core.startup.layers; |
| |
| import java.io.*; |
| import java.net.URL; |
| import java.text.MessageFormat; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.jar.JarOutputStream; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import java.util.zip.ZipEntry; |
| import org.netbeans.ProxyURLStreamHandlerFactory; |
| import org.netbeans.junit.Log; |
| import org.openide.filesystems.FileObject; |
| import org.openide.filesystems.URLMapper; |
| import org.netbeans.junit.NbTestCase; |
| import org.netbeans.junit.RandomlyFails; |
| import org.openide.filesystems.FileUtil; |
| import org.openide.filesystems.JarFileSystem; |
| import org.openide.util.Utilities; |
| import org.openide.util.test.TestFileUtils; |
| |
| /** |
| * @author tomas zezula |
| */ |
| public class ArchiveURLMapperTest extends NbTestCase { |
| |
| private static final String RESOURCE = "test.txt"; |
| private static final String JAR_FILE = "test.jar"; |
| private Logger LOG; |
| |
| public ArchiveURLMapperTest(String testName) { |
| super(testName); |
| } |
| |
| protected @Override void setUp() throws Exception { |
| super.setUp(); |
| clearWorkDir(); |
| LOG = Logger.getLogger("test." + getName()); |
| } |
| |
| @Override |
| protected Level logLevel() { |
| return Level.FINE; |
| } |
| |
| private URL createJarFile () throws IOException { |
| File workDir = FileUtil.normalizeFile(this.getWorkDir()); |
| File jarFile = new File(workDir,JAR_FILE); |
| JarOutputStream out = new JarOutputStream ( new FileOutputStream (jarFile)); |
| ZipEntry entry = new ZipEntry (RESOURCE); |
| out.putNextEntry(entry); |
| out.write (RESOURCE.getBytes()); |
| out.close(); |
| return Utilities.toURI(jarFile).toURL(); |
| } |
| |
| public void testURLMapper () throws Exception { |
| URL jarFileURL = createJarFile (); |
| assertTrue (jarFileURL != null); |
| URL url = new URL (MessageFormat.format("jar:{0}!/{1}", jarFileURL.toExternalForm(), RESOURCE)); |
| FileObject fo = URLMapper.findFileObject(url); |
| assertNotNull("There is one found file object", fo); |
| assertTrue(fo.getPath().equals(RESOURCE)); |
| URL newUrl = URLMapper.findURL(fo, URLMapper.EXTERNAL); |
| assertEquals(url, newUrl); |
| } |
| |
| public void testArchiveToRootURL () throws Exception { |
| URL jarFileURL = createJarFile (); |
| assertTrue (jarFileURL != null); |
| assertTrue (FileUtil.isArchiveFile(jarFileURL)); |
| URL jarRootURL = FileUtil.getArchiveRoot(jarFileURL); |
| assertTrue ("jar".equals(jarRootURL.getProtocol())); |
| String path = jarRootURL.getPath(); |
| int index = path.lastIndexOf ("!/"); |
| assertTrue (index==path.length()-2); |
| URL innerURL = new URL(path.substring(0,index)); |
| assertTrue (innerURL.equals(jarFileURL)); |
| } |
| |
| public void testArchiveToRootFileObject () throws Exception { |
| URL jarFileURL = createJarFile (); |
| FileObject fo = URLMapper.findFileObject(jarFileURL); |
| assertTrue (fo != null); |
| assertTrue (FileUtil.isArchiveFile(fo)); |
| FileObject rootFo = FileUtil.getArchiveRoot (fo); |
| assertTrue (rootFo!=null); |
| assertTrue ("".equals(rootFo.getPath())); |
| assertTrue (rootFo.getFileSystem() instanceof JarFileSystem); |
| File jarFile = ((JarFileSystem)rootFo.getFileSystem()).getJarFile(); |
| assertTrue (jarFileURL.equals(Utilities.toURI(jarFile).toURL())); |
| } |
| |
| public void testFunnyZipEntryNames() throws Exception { // #181671 |
| doFunnyZipEntryNames("[My Content;hi*();.xml]"); |
| } |
| |
| public void testFunnyZipEntryNames20() throws Exception { // #181671 |
| doFunnyZipEntryNames("[My%20Content;hi*();.xml]"); |
| } |
| |
| public void testFunnyZipEntryNamesQuestion() throws Exception { // #181671 |
| doFunnyZipEntryNames("[My?Content;hi*();.xml]"); |
| } |
| |
| private void doFunnyZipEntryNames(String file) throws Exception { |
| File docx = new File(getWorkDir(), "ms-docx.jar"); |
| JarOutputStream jos = new JarOutputStream(new FileOutputStream(docx)); |
| ZipEntry entry = new ZipEntry(file); |
| jos.putNextEntry(entry); |
| jos.write("content".getBytes()); |
| jos.close(); |
| |
| FileObject docxFO = URLMapper.findFileObject(Utilities.toURI(docx).toURL()); |
| assertNotNull(docxFO); |
| assertTrue(FileUtil.isArchiveFile(docxFO)); |
| |
| FileObject docxRoot = FileUtil.getArchiveRoot(docxFO); |
| assertNotNull("Root found", docxRoot); |
| FileObject content = docxRoot.getFileObject(file); |
| assertNotNull("content.xml found", content); |
| |
| assertEquals("Has right bytes", "content", content.asText()); |
| |
| CharSequence log = Log.enable("", Level.WARNING); |
| URL u = URLMapper.findURL(content, URLMapper.EXTERNAL); |
| InputStream is = u.openStream(); |
| byte[] arr = new byte[30]; |
| int len = is.read(arr); |
| assertEquals("Len is content", "content".length(), len); |
| assertEquals("OK", "content", new String(arr, 0, len)); |
| |
| assertEquals("No warnings:\n" + log, 0, log.length()); |
| assertEquals(u.toString(), content, URLMapper.findFileObject(u)); |
| } |
| |
| @RandomlyFails |
| public void testNestedJars() throws Exception { |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| JarOutputStream jos = new JarOutputStream(baos); |
| ZipEntry entry = new ZipEntry("text"); |
| jos.putNextEntry(entry); |
| jos.write("content".getBytes()); |
| jos.close(); |
| File metaJar = new File(getWorkDir(), "meta.jar"); |
| jos = new JarOutputStream(new FileOutputStream(metaJar)); |
| entry = new ZipEntry("nested.jar"); |
| jos.putNextEntry(entry); |
| jos.write(baos.toByteArray()); |
| jos.close(); |
| FileObject metaJarFO = URLMapper.findFileObject(Utilities.toURI(metaJar).toURL()); |
| assertNotNull(metaJarFO); |
| assertTrue(FileUtil.isArchiveFile(metaJarFO)); |
| FileObject metaRoot = FileUtil.getArchiveRoot(metaJarFO); |
| assertNotNull(metaRoot); |
| FileObject nestedJarFO = metaRoot.getFileObject("nested.jar"); |
| assertNotNull(nestedJarFO); |
| assertTrue(FileUtil.isArchiveFile(nestedJarFO)); |
| FileObject nestedRoot = FileUtil.getArchiveRoot(nestedJarFO); |
| assertNotNull(nestedRoot); |
| FileObject textFO = nestedRoot.getFileObject("text"); |
| assertEquals("content", textFO.asText()); |
| |
| // test refresh of nested jar - #175316 |
| |
| baos = new ByteArrayOutputStream(); |
| jos = new JarOutputStream(baos); |
| // meta.jar/nested.jar/newInNested |
| entry = new ZipEntry("newInNested"); |
| jos.putNextEntry(entry); |
| jos.write("content in newInNested".getBytes()); |
| jos.close(); |
| |
| LOG.log(Level.INFO, "Writing new {0}", metaJar); |
| |
| jos = new JarOutputStream(new FileOutputStream(metaJar)); |
| // meta.jar/nested.jar |
| entry = new ZipEntry("nested.jar"); |
| entry.setTime(System.currentTimeMillis() + 10000); |
| jos.putNextEntry(entry); |
| jos.write(baos.toByteArray()); |
| // meta.jar/newFile |
| entry = new ZipEntry("newFile"); |
| jos.putNextEntry(entry); |
| jos.write("new content".getBytes()); |
| jos.close(); |
| |
| // check meta.jar/newFile |
| FileObject newFO = null; |
| for (int i = 0; i < 10; i++) { |
| TestFileUtils.touch(metaJar, null); // just for sure |
| |
| LOG.info("Before refresh"); |
| metaJarFO.refresh(); |
| LOG.info("After refresh"); |
| |
| newFO = metaRoot.getFileObject("newFile"); |
| if (newFO != null) { |
| break; |
| } |
| Thread.sleep(500); |
| } |
| LOG.log(Level.INFO, "newFile obtained: {0}", newFO); |
| if (newFO == null) { |
| fail("newFile should be found among:\n" + Arrays.toString(metaRoot.getChildren())); |
| } |
| assertEquals("new content", newFO.asText()); |
| // check meta.jar/nested.jar/newInNested |
| nestedRoot = FileUtil.getArchiveRoot(nestedJarFO); |
| FileObject newInNestedFO = nestedRoot.getFileObject("newInNested"); |
| assertNotNull(newInNestedFO); |
| assertEquals("content in newInNested", newInNestedFO.asText()); |
| // check meta.jar/nested.jar/text gone |
| textFO = nestedRoot.getFileObject("text"); |
| assertNull(textFO); |
| } |
| |
| public void test166708() throws Exception { |
| File jar = new File(getWorkDir(), "test.jar"); |
| JarOutputStream jos = new JarOutputStream(new FileOutputStream(jar)); |
| jos.putNextEntry(new ZipEntry("has spaces")); |
| jos.close(); |
| URL source = new URL("jar:" + Utilities.toURI(jar).toURL() + "!/has%20spaces"); |
| source.toURI(); |
| FileObject file = URLMapper.findFileObject(source); |
| assertNotNull(file); |
| assertEquals(source, URLMapper.findURL(file, URLMapper.INTERNAL)); |
| assertEquals(0, source.openConnection().getContentLength()); |
| ProxyURLStreamHandlerFactory.register(); |
| assertEquals(0, new URL("jar:" + Utilities.toURI(jar).toURL() + "!/has%20spaces").openConnection().getContentLength()); |
| } |
| |
| } |