diff -r 69ec3771b81c j2ee.common/src/org/netbeans/modules/j2ee/common/project/classpath/ClassPathSupport.java --- a/j2ee.common/src/org/netbeans/modules/j2ee/common/project/classpath/ClassPathSupport.java Mon May 26 11:59:55 2008 +0100 +++ b/j2ee.common/src/org/netbeans/modules/j2ee/common/project/classpath/ClassPathSupport.java Wed May 28 15:26:34 2008 +0200 @@ -157,7 +157,16 @@ AntArtifact artifact = (AntArtifact)ret[0]; URI uri = (URI)ret[1]; File usedFile = antProjectHelper.resolveFile(evaluator.evaluate(pe[i])); - File artifactFile = new File (artifact.getScriptLocation().toURI().resolve(uri).normalize()); + /* Workaround for http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4723726 (URI.normalize() ruins URI built from UNC File) */ + File artifactFile = null; + if(uri.isAbsolute()) { + artifactFile = new File(uri); + } else { + artifactFile = new File(artifact.getScriptLocation().getParent(), uri.getPath()); + } + artifactFile = FileUtil.normalizeFile(artifactFile); + //File artifactFile = new File (artifact.getScriptLocation().toURI().resolve(uri).normalize()); + /* End of UNC workaround */ if (usedFile.equals(artifactFile)) { item = Item.create( artifact, uri, pe[i]); } diff -r 69ec3771b81c j2ee.earproject/src/org/netbeans/modules/j2ee/earproject/EarProject.java --- a/j2ee.earproject/src/org/netbeans/modules/j2ee/earproject/EarProject.java Mon May 26 11:59:55 2008 +0100 +++ b/j2ee.earproject/src/org/netbeans/modules/j2ee/earproject/EarProject.java Wed May 28 15:26:34 2008 +0200 @@ -604,14 +604,8 @@ FileObject metaInfFO = null; try { File prjDirF = FileUtil.toFile(getProjectDirectory()); - File rootF = prjDirF; - while (rootF.getParentFile() != null) { - rootF = rootF.getParentFile(); - } File metaInfF = PropertyUtils.resolveFile(prjDirF, metaInfProp); - String metaInfPropRel = PropertyUtils.relativizeFile(rootF, metaInfF); - assert metaInfPropRel != null; - metaInfFO = FileUtil.createFolder(FileUtil.toFileObject(rootF), metaInfPropRel); + metaInfFO = FileUtil.createFolder(metaInfF); } catch (IOException ex) { assert false : ex; } diff -r 69ec3771b81c masterfs/src/org/netbeans/modules/masterfs/filebasedfs/FileBasedURLMapper.java --- a/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/FileBasedURLMapper.java Mon May 26 11:59:55 2008 +0100 +++ b/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/FileBasedURLMapper.java Wed May 28 15:26:34 2008 +0200 @@ -49,12 +49,9 @@ import java.io.File; import java.net.MalformedURLException; -import java.net.URI; import java.net.URL; import org.netbeans.modules.masterfs.filebasedfs.fileobjects.FileObjectFactory; -import org.netbeans.modules.masterfs.filebasedfs.fileobjects.FolderObj; import org.netbeans.modules.masterfs.filebasedfs.fileobjects.RootObj; -import org.netbeans.modules.masterfs.filebasedfs.utils.FileChangedManager; import org.openide.util.Exceptions; //TODO: JDK problems with URL, URI, File conversion for UNC @@ -110,6 +107,10 @@ public final FileObject[] getFileObjects(final URL url) { if (!"file".equals(url.getProtocol())) return null; //NOI18N + // return null for UNC root + if(url.getPath().equals("//") || url.getPath().equals("////")) { //NOI18N + return null; + } //TODO: review and simplify FileObject retVal = null; File file; @@ -126,7 +127,7 @@ return null; } - retVal = FileBasedFileSystem.getInstance().getFileObject(file, FileObjectFactory.Caller.ToFileObject); + retVal = FileBasedFileSystem.getFileObject(file, FileObjectFactory.Caller.ToFileObject); return new FileObject[]{retVal}; } diff -r 69ec3771b81c masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/BaseFileObj.java --- a/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/BaseFileObj.java Mon May 26 11:59:55 2008 +0100 +++ b/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/BaseFileObj.java Wed May 28 15:26:34 2008 +0200 @@ -60,9 +60,6 @@ import java.util.Enumeration; import java.util.NoSuchElementException; import java.util.Stack; -import java.util.concurrent.Callable; -import java.util.logging.Level; -import java.util.logging.Logger; import org.netbeans.modules.masterfs.filebasedfs.FileBasedFileSystem; import org.netbeans.modules.masterfs.filebasedfs.utils.FileChangedManager; import org.netbeans.modules.masterfs.providers.ProvidedExtensions; @@ -80,8 +77,6 @@ public abstract class BaseFileObj extends FileObject { //constants - private static final char EXTENSION_SEPARATOR = '.'; - private static final char UNC_PREFIX = '\\';//NOI18N private static final String PATH_SEPARATOR = File.separator;//NOI18N private static final char EXT_SEP = '.';//NOI18N private FileChangeListener versioningWeakListener; @@ -111,10 +106,12 @@ } + @Override public final String toString() { return getFileName().toString(); } + @Override public final String getNameExt() { final File file = getFileName().getFile(); final String retVal = BaseFileObj.getNameExt(file); @@ -122,8 +119,20 @@ } + /** Returns true is file is \\ComputerName\sharedFolder. */ + private static boolean isUncRoot(File file) { + File parent = file.getParentFile(); + if(parent != null) { + parent = parent.getParentFile(); + if(parent != null) { + return parent.getPath().equals("\\\\"); // NOI18N + } + } + return false; + } + static String getNameExt(final File file) { - String retVal = (file.getParentFile() == null) ? file.getAbsolutePath() : file.getName(); + String retVal = (file.getParentFile() == null || isUncRoot(file)) ? file.getAbsolutePath() : file.getName(); if (retVal.endsWith(PATH_SEPARATOR)) {//NOI18N final boolean isPermittedToStripSlash = !(file.getParentFile() == null && new FileInfo(file).isUNCFolder()); if (isPermittedToStripSlash) { @@ -133,11 +142,13 @@ return retVal; } + @Override public boolean canRead() { final File file = getFileName().getFile(); return file.canRead(); } + @Override public boolean canWrite() { final File file = getFileName().getFile(); ProvidedExtensions extension = getProvidedExtensions(); @@ -156,10 +167,15 @@ return FileInfo.getExt(getNameExt()); } + @Override public final String getPath() { String prefix = ""; if (Utilities.isWindows()) { prefix = getFactory().getRoot().getFileName().getFile().getPath().replace(File.separatorChar, '/'); + if(prefix.startsWith("//")) { + // UNC root like //computer/sharedFolder + prefix += "/"; + } } return prefix+getRelativePath(getFactory().getRoot().getFileName().getFile(), this.getFileName().getFile());//NOI18N } @@ -190,6 +206,7 @@ return false; } + @Override public final FileObject move(FileLock lock, FileObject target, String name, String ext) throws IOException { if (!checkLock(lock)) { FSException.io("EXC_InvalidLock", lock, getPath()); // NOI18N @@ -803,6 +820,7 @@ } private final class FileChangeListenerForVersioning extends FileChangeAdapter { + @Override public void fileDataCreated(FileEvent fe) { if (fe.getFile() == BaseFileObj.this) { getProvidedExtensions().createSuccess(fe.getFile()); @@ -812,12 +830,14 @@ /** * Implements FileChangeListener.fileFolderCreated(FileEvent fe) */ + @Override public void fileFolderCreated(FileEvent fe) { if (fe.getFile() == BaseFileObj.this) { getProvidedExtensions().createSuccess(fe.getFile()); } } + @Override public void fileDeleted(FileEvent fe) { if (fe.getFile() == BaseFileObj.this) { getProvidedExtensions().deleteSuccess(fe.getFile()); diff -r 69ec3771b81c masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectFactory.java --- a/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectFactory.java Mon May 26 11:59:55 2008 +0100 +++ b/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectFactory.java Wed May 28 15:26:34 2008 +0200 @@ -89,7 +89,8 @@ private FileObjectFactory(final FileInfo fInfo) { final File rootFile = fInfo.getFile(); - assert rootFile.getParentFile() == null; + // can be not null for UNC + // assert rootFile.getParentFile() == null; final BaseFileObj realRoot = create(fInfo); root = realRoot; diff -r 69ec3771b81c masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/RootObj.java --- a/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/RootObj.java Mon May 26 11:59:55 2008 +0100 +++ b/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/RootObj.java Wed May 28 15:26:34 2008 +0200 @@ -58,6 +58,7 @@ import java.util.Map; import org.netbeans.modules.masterfs.filebasedfs.FileBasedFileSystem; import org.netbeans.modules.masterfs.filebasedfs.fileobjects.FileObjectFactory; +import org.netbeans.modules.masterfs.filebasedfs.utils.FileInfo; public final class RootObj extends FileObject { private T realRoot = null; @@ -145,11 +146,8 @@ for (File file : files) { FileObjectFactory factory = roots2Factory.get(file); if (factory == null) { - File tmp = file; - while (tmp.getParentFile() != null) { - tmp = tmp.getParentFile(); - } - factory = roots2Factory.get(tmp); + // UNC - do not use getParentFile to search for root + factory = roots2Factory.get(new FileInfo(file).getRoot().getFile()); } if (factory != null) { List lf = files2Factory.get(factory); diff -r 69ec3771b81c masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/RootObjWindows.java --- a/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/RootObjWindows.java Mon May 26 11:59:55 2008 +0100 +++ b/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/RootObjWindows.java Wed May 28 15:26:34 2008 +0200 @@ -41,6 +41,7 @@ package org.netbeans.modules.masterfs.filebasedfs.fileobjects; +import java.io.File; import org.netbeans.modules.masterfs.filebasedfs.utils.FSException; import org.openide.filesystems.*; @@ -166,10 +167,15 @@ return rootChildren.toArray(new FileObject[rootChildren.size()]); } - public final FileObject getFileObject(final String name, final String ext) { + public final FileObject getFileObject(String name, final String ext) { FileObject[] rootChildren = getChildren(); for (int i = 0; i < rootChildren.length; i++) { FileObject fileObject = rootChildren[i]; + // UNC absolute path + if(name.startsWith("//")) { // NOI18N + // replace '/' by '\' + name = name.replace('/', '\\'); //NOI18N + } if (FileInfo.composeName(name, ext).equals(fileObject.getNameExt())) { return fileObject; } diff -r 69ec3771b81c masterfs/src/org/netbeans/modules/masterfs/filebasedfs/naming/FileName.java --- a/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/naming/FileName.java Mon May 26 11:59:55 2008 +0100 +++ b/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/naming/FileName.java Wed May 28 15:26:34 2008 +0200 @@ -58,12 +58,13 @@ protected FileName(final FileNaming parent, final File file) { this.parent = parent; - this.name = parseName(file); + // UNC change + this.name = parseName(parent, file); id = NamingFactory.createID(file); } - private static String parseName(final File file) { - return (file.getParentFile() == null) ? file.getPath() : file.getName(); + private static String parseName(final FileNaming parent, final File file) { + return parent == null ? file.getPath() : file.getName(); } public boolean rename(String name, ProvidedExtensions.IOHandler handler) { @@ -104,8 +105,8 @@ public File getFile() { - final FileNaming parent = this.getParent(); - return (parent != null) ? new File(parent.getFile(), getName()) : new File(getName()); + final FileNaming myParent = this.getParent(); + return (myParent != null) ? new File(myParent.getFile(), getName()) : new File(getName()); } diff -r 69ec3771b81c masterfs/src/org/netbeans/modules/masterfs/filebasedfs/naming/NamingFactory.java --- a/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/naming/NamingFactory.java Mon May 26 11:59:55 2008 +0100 +++ b/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/naming/NamingFactory.java Wed May 28 15:26:34 2008 +0200 @@ -41,14 +41,11 @@ package org.netbeans.modules.masterfs.filebasedfs.naming; -import org.netbeans.modules.masterfs.filebasedfs.utils.FileInfo; - import java.io.File; import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.util.*; import org.netbeans.modules.masterfs.providers.ProvidedExtensions; -import org.openide.util.Utilities; /** * @author Radek Matous @@ -57,7 +54,7 @@ private static final Map nameMap = new WeakHashMap(); public static synchronized FileNaming fromFile(final File file) { - final LinkedList list = new LinkedList(); + final LinkedList list = new LinkedList(); File current = file; while (current != null) { list.addFirst(current); @@ -66,8 +63,13 @@ FileNaming fileName = null; for (int i = 0; i < list.size(); i++) { - File f = (File) list.get(i); - //TODO: UNC? + File f = list.get(i); + if("\\\\".equals(f.getPath())) { + // UNC file - skip \\, \\computerName + i++; + continue; + } + // returns unknown if last in the list, otherwise directory FileType type = (i == list.size() - 1) ? FileType.unknown : FileType.directory; fileName = NamingFactory.registerInstanceOfFileNaming(fileName, f, type); } @@ -254,26 +256,17 @@ return retVal; } - public static enum FileType {file, directory, unc, unknown} - private static FileNaming createFileNaming(final File f, final FileNaming parentName) { - return createFileNaming(f, parentName, FileType.unknown); - } + public static enum FileType {file, directory, unknown} private static FileNaming createFileNaming(final File f, final FileNaming parentName, FileType type) { FileName retVal = null; //TODO: check all tests for isFile & isDirectory - final FileInfo fInfo = new FileInfo(f); if (type.equals(FileType.unknown)) { if (f.isDirectory()) { type = FileType.directory; } else { //important for resolving named pipes type = FileType.file; - /*else { - if (fInfo.isUNCFolder()) { - type = FileType.unc; - } - }*/ //UNC doesn't work now anyway } } @@ -284,10 +277,6 @@ case directory: retVal = new FolderName(parentName, f); break; - case unc: - retVal = new UNCName(parentName, f); - break; - } return retVal; } diff -r 69ec3771b81c masterfs/src/org/netbeans/modules/masterfs/filebasedfs/utils/FileInfo.java --- a/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/utils/FileInfo.java Mon May 26 11:59:55 2008 +0100 +++ b/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/utils/FileInfo.java Wed May 28 15:26:34 2008 +0200 @@ -47,6 +47,8 @@ import javax.swing.filechooser.FileSystemView; import java.io.File; +import java.util.NoSuchElementException; +import java.util.Scanner; import org.netbeans.modules.masterfs.filebasedfs.naming.FileNaming; import org.openide.filesystems.FileObject; @@ -183,7 +185,7 @@ !WriteLockUtils.hasActiveLockFileSigns(getFile().getAbsolutePath()) && (getFile().getParent() != null || !isWindowsFloppy())) ; } - + public FileInfo getRoot() { if (root == null) { @@ -192,6 +194,18 @@ while (tmp != null) { retVal = tmp; tmp = tmp.getParentFile(); + } + if("\\\\".equals(retVal.getPath())) { + // UNC root + Scanner uncScanner = new Scanner(getFile().getAbsolutePath()).useDelimiter("\\\\"); //NOI18N + uncScanner.skip("\\\\\\\\"); //NOI18N + try { + // return \\computerName\sharedFolder + retVal = new File("\\\\"+uncScanner.next()+"\\"+uncScanner.next()+"\\"); //NOI18N + } catch (NoSuchElementException e) { + // not enough elements to return UNC root (only \\computerName or \\) + // retVal is \\ + } } root = new FileInfo (retVal); diff -r 69ec3771b81c masterfs/test/unit/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectFactoryTest.java --- a/masterfs/test/unit/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectFactoryTest.java Mon May 26 11:59:55 2008 +0100 +++ b/masterfs/test/unit/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectFactoryTest.java Wed May 28 15:26:34 2008 +0200 @@ -46,6 +46,7 @@ import java.lang.ref.Reference; import java.lang.ref.WeakReference; import org.netbeans.junit.NbTestCase; +import org.netbeans.modules.masterfs.filebasedfs.utils.FileInfo; import org.openide.filesystems.FileChangeAdapter; import org.openide.filesystems.FileEvent; import org.openide.filesystems.FileObject; @@ -59,13 +60,13 @@ */ public class FileObjectFactoryTest extends NbTestCase { private File testFile; - private FileObject testFo; public FileObjectFactoryTest(String testName) { super(testName); } + @Override protected void setUp() throws Exception { super.setUp(); clearWorkDir(); @@ -75,7 +76,7 @@ } } - + public void testIssuingFileObject() throws IOException { FileObjectFactory fbs = FileObjectFactory.getInstance(getWorkDir()); @@ -156,10 +157,7 @@ assertTrue(external.createNewFile()); assertNull(foWorkDir.getFileObject(external.getName())); - File root = workDir; - while(root.getParentFile() != null) { - root = root.getParentFile(); - } + File root = new FileInfo(workDir).getRoot().getFile(); fdc.assertDataCreated(0); FileUtil.refreshFor(root); diff -r 69ec3771b81c masterfs/test/unit/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FolderObjTest.java --- a/masterfs/test/unit/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FolderObjTest.java Mon May 26 11:59:55 2008 +0100 +++ b/masterfs/test/unit/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FolderObjTest.java Wed May 28 15:26:34 2008 +0200 @@ -634,8 +634,8 @@ fs.getRoot().getFileObject(f.getAbsolutePath().replace('\\','/')); } assertSame(fo.toString(), fo0, fo); - - if (f.getParentFile() != null) { + + if(!f.getParentFile().equals(FileUtil.toFile(FileObjectFactory.getInstance(f).getRoot()))) { FileObject parent = fo.getParent(); assertNotNull(parent); String nameExt = fo.getNameExt(); @@ -652,11 +652,12 @@ fo = null; fo0 = null; fo2 = null; parent = null;fos = null; list = null; assertGC(msg, ref); } else { - //dsik roots are kept by hard reference + //disk roots are kept by hard reference WeakReference ref = new WeakReference (fo); String msg = fo.toString(); fo = null; fo0 = null; assertNotNull(msg, ref.get()); + break; } f = f.getParentFile(); @@ -710,7 +711,7 @@ FileSystem fs = FileBasedFileSystem.getInstance(); assertNotNull(fs); - while (f != null) { + while (f != null && f.exists()) { FileObject fo = FileBasedFileSystem.getFileObject(f); assertNotNull(f.getAbsolutePath(),fo); assertEquals(f.isFile(), fo.isData()); @@ -730,7 +731,7 @@ FileSystem fs = FileBasedFileSystem.getInstance(); assertNotNull(fs); - while (f != null) { + while (f != null && f.exists()) { FileObject fo = FileBasedFileSystem.getFileObject(f); assertNotNull(f.getAbsolutePath(),fo); if (fo.isFolder() && !fo.isRoot()) { @@ -749,7 +750,7 @@ FileSystem fs = FileBasedFileSystem.getInstance(); assertNotNull(fs); FileObject fo = null; - while (f != null) { + while (f != null && f.exists()) { fo = FileBasedFileSystem.getFileObject(f); assertNotNull(f.getAbsolutePath(),fo); f = f.getParentFile(); @@ -775,7 +776,7 @@ FileSystem fs = FileBasedFileSystem.getInstance(); assertNotNull(fs); - while (f != null) { + while (f != null && f.exists()) { FileObject fo = FileBasedFileSystem.getFileObject(f); assertNotNull(f.getAbsolutePath(),fo); FileObject parent = fo.getParent(); diff -r 69ec3771b81c o.n.bootstrap/src/org/netbeans/ProxyURLStreamHandlerFactory.java --- a/o.n.bootstrap/src/org/netbeans/ProxyURLStreamHandlerFactory.java Mon May 26 11:59:55 2008 +0100 +++ b/o.n.bootstrap/src/org/netbeans/ProxyURLStreamHandlerFactory.java Wed May 28 15:26:34 2008 +0200 @@ -36,20 +36,25 @@ * * Portions Copyrighted 2008 Sun Microsystems, Inc. */ - package org.netbeans; +import java.io.File; +import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.net.Proxy; import java.net.URL; +import java.net.URLConnection; import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; import java.util.Collection; import java.util.logging.Level; import java.util.logging.Logger; +import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.LookupEvent; import org.openide.util.LookupListener; +import org.openide.util.Utilities; /** * A stream handler factory that delegates to others in lookup. @@ -109,6 +114,9 @@ public URLStreamHandler createURLStreamHandler(String protocol) { if (protocol.equals("jar")) { return new JarClassLoader.ResURLStreamHandler(originalJarHandler); + } else if (protocol.equals("file") && Utilities.isWindows() && System.getProperty("java.version").startsWith("1.5")) { // NOI18N + LOG.fine("Registering UNCFileStreamHandler."); // NOI18N + return UNCFileURLStreamHandler.getInstance(); } else if (protocol.equals("file") || protocol.equals("http") || protocol.equals("https") || protocol.equals("resource")) { // NOI18N // Well-known handlers in JRE. Do not try to initialize lookup, etc. return null; @@ -144,5 +152,75 @@ handlers = c.toArray(new URLStreamHandlerFactory[0]); } } + + private static class UNCFileURLStreamHandler extends URLStreamHandler { + private static final URLStreamHandler DELEGATE = getDelegate(); + private static final Method OPEN_CONNECTION_METHOD = getOpenConnectionMethod(); + private static UNCFileURLStreamHandler instance; + + /** Returns null if not possible to get instance of delegate handler. */ + public static UNCFileURLStreamHandler getInstance() { + if(instance == null) { + if(DELEGATE != null && OPEN_CONNECTION_METHOD != null) { + instance = new UNCFileURLStreamHandler(); + } + } + return instance; + } + + private static URLStreamHandler getDelegate() { + try { + Class sunHandlerClass = Class.forName("sun.net.www.protocol.file.Handler"); // NOI18N + return (URLStreamHandler) sunHandlerClass.newInstance(); + } catch (Exception ex) { + // ignore + LOG.log(Level.FINE, "Exception while instantiating sun.net.www.protocol.file.Handler.", ex); // NOI18N + } + return null; + } + + private static Method getOpenConnectionMethod() { + try { + return DELEGATE.getClass().getMethod("openConnection", URL.class, Proxy.class); // NOI18N + } catch (Exception ex) { + LOG.log(Level.FINE, "Exception while getting method sun.net.www.protocol.file.Handler.openConnection.", ex); // NOI18N + } + return null; + } + + @Override + protected void parseURL(URL u, String spec, int start, int limit) { + super.parseURL(u, spec.replace(File.separatorChar, '/'), start, limit); + // Fix UNC URLs - set authority to null and add // before path. + if ((u.getAuthority() != null) && u.getPath().startsWith("//")) { //NOI18N + try { + Field authorityField = URL.class.getDeclaredField("authority"); //NOI18N + authorityField.setAccessible(true); + authorityField.set(u, null); + Field pathField = URL.class.getDeclaredField("path"); //NOI18N + pathField.setAccessible(true); + pathField.set(u, "//" + u.getPath()); //NOI18N + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @Override + protected URLConnection openConnection(URL url) throws IOException { + return openConnection(url, null); + } + + @Override + protected URLConnection openConnection(URL url, Proxy proxy) throws IOException { + try { + return (URLConnection) OPEN_CONNECTION_METHOD.invoke(DELEGATE, url, proxy); + } catch (Exception ex) { + IOException ioe = new IOException("openConnection "+url+" failed."); // NOI18N + ioe.initCause(ex); + throw ioe; + } + } + } } diff -r 69ec3771b81c o.n.bootstrap/test/unit/src/org/netbeans/ProxyURLStreamHandlerFactoryTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/o.n.bootstrap/test/unit/src/org/netbeans/ProxyURLStreamHandlerFactoryTest.java Wed May 28 15:26:34 2008 +0200 @@ -0,0 +1,78 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans; + +import java.io.File; +import java.net.URI; +import java.net.URL; +import org.netbeans.junit.NbTestCase; + +/** + * Tests ProxyURLStreamHandlerFactory. + */ +public class ProxyURLStreamHandlerFactoryTest extends NbTestCase { + + public ProxyURLStreamHandlerFactoryTest(String testName) { + super(testName); + } + + /** Register ProxyURLStreamHandlerFactory. */ + @Override + protected void setUp() throws Exception { + ProxyURLStreamHandlerFactory.register(); + } + + /** Tests UNC path is correctly treated. On JDK1.5 UNCFileStreamHandler should + * be installed in ProxyURLStreamHandlerFactory to workaround JDK bug + * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5086147. + */ + public void testUNCFileURLStreamHandler() throws Exception { + File uncFile = new File("\\\\computerName\\sharedFolder\\a\\b\\c\\d.txt"); + URI uri = uncFile.toURI(); + String expectedURI = "file:////computerName/sharedFolder/a/b/c/d.txt"; + assertEquals("Wrong URI from File.toURI.", expectedURI, uri.toString()); + URL url = uri.toURL(); + assertEquals("Wrong URL from URI.toURL", expectedURI, url.toString()); + assertNull("URL.getAuthority must be null.", url.getAuthority()); + uri = url.toURI(); + assertEquals("Wrong URI from URL.toURI.", expectedURI, uri.toString()); + } +} diff -r 69ec3771b81c openide.filesystems/src/org/openide/filesystems/FileObject.java --- a/openide.filesystems/src/org/openide/filesystems/FileObject.java Mon May 26 11:59:55 2008 +0100 +++ b/openide.filesystems/src/org/openide/filesystems/FileObject.java Wed May 28 15:26:34 2008 +0200 @@ -655,13 +655,17 @@ * @exception IllegalArgumentException if this is not a folder */ public FileObject getFileObject(String relativePath) { - if (relativePath.startsWith("/")) { + if (relativePath.startsWith("/") && !relativePath.startsWith("//")) { relativePath = relativePath.substring(1); } FileObject myObj = this; StringTokenizer st = new StringTokenizer(relativePath, "/"); - + + if(relativePath.startsWith("//")) { + // if UNC absolute path, start with //ComputerName/sharedFolder + myObj = myObj.getFileObject("//"+st.nextToken()+"/"+st.nextToken(), null); + } while ((myObj != null) && st.hasMoreTokens()) { String nameExt = st.nextToken(); myObj = myObj.getFileObject(nameExt, null); diff -r 69ec3771b81c openide.filesystems/src/org/openide/filesystems/FileUtil.java --- a/openide.filesystems/src/org/openide/filesystems/FileUtil.java Mon May 26 11:59:55 2008 +0100 +++ b/openide.filesystems/src/org/openide/filesystems/FileUtil.java Wed May 28 15:26:34 2008 +0200 @@ -641,6 +641,10 @@ * @since 4.29 */ public static FileObject toFileObject(File file) { + // return null for UNC root + if(file.getPath().equals("\\\\")) { + return null; + } boolean asserts = false; assert asserts = true; if (asserts) { @@ -689,7 +693,8 @@ static URL fileToURL(File file) throws MalformedURLException { URL retVal = null; - if (!Utilities.isWindows() || canBeCanonicalizedOnWindows(file)) { + if (!Utilities.isWindows() || canBeCanonicalizedOnWindows(file) || file.getPath().startsWith("\\\\")) { //NOI18N + // all non-Windows files, canonicalizable files on windows, UNC files retVal = file.toURI().toURL(); } else { if (Utilities.isWindows() && file.getParentFile() == null) { @@ -995,7 +1000,7 @@ String result = fo.getPath().substring(folder.getPath().length()); - if (result.startsWith("/")) { + if (result.startsWith("/") && !result.startsWith("//")) { result = result.substring(1); } @@ -1446,13 +1451,13 @@ private static float javaSpecVersion; private static boolean canBeCanonicalizedOnWindows(final File file) { /*#4089199, #95031 - Flopy and empty CD-drives can't be canonicalized*/ - boolean canBeCanonizalized = true; - if (file.getParent() == null && Utilities.isWindows()) {//NOI18N + // UNC path \\computerName can't be canonicalized - parent is "\\\\" and exists() returns false + String parent = file.getParent(); + if ((parent == null || parent.equals("\\\\")) && Utilities.isWindows()) {//NOI18N FileSystemView fsv = getFileSystemView(); - canBeCanonizalized = (fsv != null) ? !fsv.isFloppyDrive(file) && file.exists() : false; + return (fsv != null) ? !fsv.isFloppyDrive(file) && file.exists() : false; } - - return canBeCanonizalized; + return true; } private static boolean is4089199() { @@ -1577,7 +1582,13 @@ if (index >= 0) { try { - return new URL(path.substring(0, index)); + String jarPath = path.substring(0, index); + if (jarPath.indexOf("file://") > -1 && jarPath.indexOf("file:////") == -1) { //NOI18N + /* Replace because JDK application classloader wrongly recognizes UNC paths. */ + jarPath = jarPath.replaceFirst("file://", "file:////"); //NOI18N + } + return new URL(jarPath); + } catch (MalformedURLException mue) { Exceptions.printStackTrace(mue); } diff -r 69ec3771b81c openide.filesystems/test/unit/src/org/openide/filesystems/FileUtilTest.java --- a/openide.filesystems/test/unit/src/org/openide/filesystems/FileUtilTest.java Mon May 26 11:59:55 2008 +0100 +++ b/openide.filesystems/test/unit/src/org/openide/filesystems/FileUtilTest.java Wed May 28 15:26:34 2008 +0200 @@ -143,4 +143,21 @@ FileUtil.archiveOrDirForURL(new URL(urlPrefix + getWorkDir().toURI() + urlSuffix))); } + /** Tests translation from jar resource url to jar archive url. */ + public void testGetArchiveFile() throws Exception { + String urls[][] = { + // resource url, expected jar url + {"jar:file:/a.jar!/META-INF/MANIFEST.MF", "file:/a.jar"}, // unix root + {"jar:file:/a/b/c/a.jar!/META-INF/MANIFEST.MF", "file:/a/b/c/a.jar"}, // unix + {"jar:file:/C:/a.jar!/META-INF/MANIFEST.MF", "file:/C:/a.jar"}, // windows root + {"jar:file:/C:/a/b/c/a.jar!/META-INF/MANIFEST.MF", "file:/C:/a/b/c/a.jar"}, // windows + {"jar:file://computerName/sharedFolder/a.jar!/META-INF/MANIFEST.MF", "file:////computerName/sharedFolder/a.jar"}, // windows UNC root malformed + {"jar:file://computerName/sharedFolder/a/b/c/a.jar!/META-INF/MANIFEST.MF", "file:////computerName/sharedFolder/a/b/c/a.jar"}, // windows UNC malformed + {"jar:file:////computerName/sharedFolder/a.jar!/META-INF/MANIFEST.MF", "file:////computerName/sharedFolder/a.jar"}, // windows UNC root + {"jar:file:////computerName/sharedFolder/a/b/c/a.jar!/META-INF/MANIFEST.MF", "file:////computerName/sharedFolder/a/b/c/a.jar"} // windows UNC + }; + for (int i = 0; i < urls.length; i++) { + assertEquals("FileUtil.getArchiveFile failed.", new URL(urls[i][1]), FileUtil.getArchiveFile(new URL(urls[i][0]))); + } + } }