blob: 963500af7bca7c94880922853aa215428ada0a60 [file] [log] [blame]
/*
* 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());
}
}