diff options
author | Markus Schorn | 2015-06-29 13:54:36 +0000 |
---|---|---|
committer | Uwe Stieber | 2015-06-30 06:39:26 +0000 |
commit | 5e6ee86bef17e7771ba54bdb29b3a4f93909ac4f (patch) | |
tree | 1ec4ce5f3cdc2b04dba9de7914a0798ee24eab98 | |
parent | 06840b04d77e53e61c934b6cf985024ebd01a056 (diff) | |
download | org.eclipse.tcf-5e6ee86bef17e7771ba54bdb29b3a4f93909ac4f.tar.gz org.eclipse.tcf-5e6ee86bef17e7771ba54bdb29b3a4f93909ac4f.tar.xz org.eclipse.tcf-5e6ee86bef17e7771ba54bdb29b3a4f93909ac4f.zip |
Bug 471321: Fix URIs and URLs for the tcf file system.
Change-Id: I3b8b4c5dc0b06f93e432c899aeb836dc1cb8e54f
Signed-off-by: Markus Schorn <markus.schorn@windriver.com>
6 files changed, 25 insertions, 206 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/activator/CorePlugin.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/activator/CorePlugin.java index c0e3b9d86..d718e7ab2 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/activator/CorePlugin.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/activator/CorePlugin.java @@ -13,8 +13,10 @@ import java.util.HashSet; import java.util.Hashtable; import java.util.Set; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.tcf.te.tcf.filesystem.core.internal.url.TcfURLConnection; @@ -100,6 +102,10 @@ public class CorePlugin extends Plugin { return PLUGIN_ID; } + public static void logError(String msg, Throwable cause) { + getDefault().getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, msg, cause)); + } + public boolean addToRevealOnConnect(String location) { if (unsafeGetRevealOnConnect().add(location)) { diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/FSTreeNode.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/FSTreeNode.java index e972ffa47..6d3036703 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/FSTreeNode.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/FSTreeNode.java @@ -272,14 +272,13 @@ public final class FSTreeNode extends FSTreeNodeBase implements IFilterable, org */ @Override public URL getLocationURL() { - try { - String id = getPeerNode().getPeerId(); - String path = getLocation(true); - return new URL(TcfURLConnection.PROTOCOL_SCHEMA, id, path); + try { + URI uri = getLocationURI(); + return uri == null ? null : uri.toURL(); } catch (MalformedURLException e) { - assert false; - return null; + CorePlugin.logError("Cannot create tcf url", e); //$NON-NLS-1$ } + return null; } /** @@ -293,10 +292,9 @@ public final class FSTreeNode extends FSTreeNodeBase implements IFilterable, org try { String id = getPeerNode().getPeerId(); String path = getLocation('/', true); - return new URI(TcfURLConnection.PROTOCOL_SCHEMA, id, path, null); - } - catch (URISyntaxException e) { - assert false; + return new URI(TcfURLConnection.PROTOCOL_SCHEMA, id, "/" + path, null); //$NON-NLS-1$ + } catch (URISyntaxException e) { + CorePlugin.logError("Cannot create tcf uri", e); //$NON-NLS-1$ return null; } } @@ -603,7 +601,7 @@ public final class FSTreeNode extends FSTreeNodeBase implements IFilterable, org public void setAttributes(FileAttrs attrs, boolean notify) { FileAttrs oldAttrs = fAttributes; fAttributes = attrs; - if (attrs.isFile()) + if (attrs != null && attrs.isFile()) fRefreshTime = System.currentTimeMillis(); if (notify) { notifyChange("attributes", oldAttrs, attrs); //$NON-NLS-1$ diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/url/TcfURLConnection.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/url/TcfURLConnection.java index 18e7ce171..b9cfe3e85 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/url/TcfURLConnection.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/url/TcfURLConnection.java @@ -83,16 +83,19 @@ public class TcfURLConnection extends URLConnection { * @param url * The URL of the resource. */ - public TcfURLConnection(final URL url) { + public TcfURLConnection(final URL url) throws IOException { super(url); - // The peerId is stored as the host name in URL. See TcfURLStreamHandlerService#parseURL for details. String peerId = url.getHost(); Assert.isNotNull(peerId); peer = findPeer(peerId); - if(peer == null) { - throw new IllegalArgumentException(NLS.bind(Messages.TcfURLConnection_NoPeerFound, peerId)); + if (peer == null) { + throw new IOException(NLS.bind(Messages.TcfURLConnection_NoPeerFound, peerId)); } - path = url.getPath(); + String p = url.getPath(); + if (!p.startsWith("/")) { //$NON-NLS-1$ + throw new IOException(Messages.TcfURLConnection_relativePath); + } + path = p.substring(1); // Set default timeout. setConnectTimeout(DEFAULT_CONNECT_TIMEOUT); setOpenTimeout(DEFAULT_OPEN_TIMEOUT); diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/url/TcfURLStreamHandlerService.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/url/TcfURLStreamHandlerService.java index be8c0d87a..7399eebee 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/url/TcfURLStreamHandlerService.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/url/TcfURLStreamHandlerService.java @@ -10,207 +10,17 @@ package org.eclipse.tcf.te.tcf.filesystem.core.internal.url; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLConnection; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.StringTokenizer; -import java.util.concurrent.atomic.AtomicReference; -import org.eclipse.core.runtime.ISafeRunnable; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.osgi.util.NLS; -import org.eclipse.tcf.te.tcf.filesystem.core.internal.FSTreeNode; -import org.eclipse.tcf.te.tcf.filesystem.core.nls.Messages; import org.osgi.service.url.AbstractURLStreamHandlerService; /** * The stream handler service used to parse tcf stream protocol. */ public class TcfURLStreamHandlerService extends AbstractURLStreamHandlerService { - // The pattern of a windows path. - private static final String WINPATH_PATTERN = "[A-Za-z]:.*"; //$NON-NLS-1$ - private static final char[] WINPATH_FORBIDDEN_CHARS = {':', '*', '?', '"', '<', '>', '|' }; - - /* - * (non-Javadoc) - * @see org.osgi.service.url.AbstractURLStreamHandlerService#openConnection(java.net.URL) - */ @Override public URLConnection openConnection(URL u) throws IOException { return new TcfURLConnection(u); } - - /** - * Parse the given spec to the specified URL object. The expected format is: - * <p> - * - * <pre> - * TCF_URL = tcf:/<strong>PEER_ID</strong>/(<strong>URL_PATH</strong>)? - * PEER_ID = (.^/)+ - * URL_PATH = <strong>WIN_PATH</strong> | <strong>RELATIVE_PATH</strong> - * WIN_PATH = <strong>DISK_SEG</strong> / (<strong>RELATIVE_PATH</strong>)? - * DISK_SEG = [a-zA-Z]: - * RELATIVE_PATH = <strong>PATH_SEG</strong> | <strong>PATH_SEG</strong>/<strong>RELATIVE_PATH</strong> - * Unix/Linux PATH_SEG = (.^[/])+ - * Windows PATH_SEG = (.^[\/:*?"<>|])+ - * </pre> - */ - @Override - protected void parseURL(URL u, String spec, int start, int limit) { - if (u.getPath() != null) { - String path = u.getPath(); - if (!path.endsWith("/")) { //$NON-NLS-1$ - path += "/"; //$NON-NLS-1$ - } - path += spec; - setURL(u, u.getProtocol(), u.getHost(), u.getPort(), u.getAuthority(), u.getUserInfo(), path, u.getQuery(), u.getRef()); - } - else { - IllegalArgumentException errorFormat = new IllegalArgumentException(Messages.TcfURLStreamHandlerService_ErrorURLFormat); - int end = spec.indexOf("/", start); //$NON-NLS-1$ - if (end == -1) throw errorFormat; - start = end + 1; - end = spec.indexOf("/", start); //$NON-NLS-1$ - if (end == -1) throw errorFormat; - String peerId = spec.substring(start, end); - if (peerId.trim().length() == 0) throw errorFormat; - start = end + 1; - String path = spec.substring(start); - if (path.length() > 0) { - if (path.matches(WINPATH_PATTERN)) { - String pathext = path.substring(2); // Cut the path after ':'. - if (pathext.length() == 0) throw new IllegalArgumentException(Messages.TcfURLStreamHandlerService_OnlyDiskPartError); - pathext = pathext.substring(1); // Cut the path after the disk part. - checkWinPath(pathext); - } - else { - path = "/" + path; //$NON-NLS-1$ - } - } - else { - path = "/"; //$NON-NLS-1$ - } - final String path2decode = path; - final AtomicReference<String> pathRef = new AtomicReference<String>(); - SafeRunner.run(new ISafeRunnable(){ - @Override - public void handleException(Throwable exception) { - // Ignore on purpose - } - @Override - public void run() throws Exception { - pathRef.set(decodeURLPath(path2decode)); - }}); - path = pathRef.get(); - setURL(u, TcfURLConnection.PROTOCOL_SCHEMA, peerId, -1, null, null, path, null, null); - } - } - - /** - * Decode the path from URI compatible path to a - * file system path. - * - * @see FSTreeNode#getURLEncodedPath - * @param path The URL whose path is to be decoded. - * @return The file system path. - * @throws UnsupportedEncodingException - */ - String decodeURLPath(String path) throws UnsupportedEncodingException { - StringTokenizer st = new StringTokenizer(path, "/"); //$NON-NLS-1$ - StringBuilder builder = new StringBuilder(); - while(st.hasMoreTokens()) { - if(builder.length() > 0) { - builder.append("/"); //$NON-NLS-1$ - } - String segment = st.nextToken(); - builder.append(URLDecoder.decode(segment, "UTF-8")); //$NON-NLS-1$ - } - String relative = builder.toString(); - return path.startsWith("/") ? "/" + relative : relative; //$NON-NLS-1$//$NON-NLS-2$ - } - - /** - * Check the format of the specified windows path. - * - * @param path The relative path to a disk part. - */ - private void checkWinPath(String path) { - for (int i = 0; i < path.length(); i++) { - char c = path.charAt(i); - for(int j=0;j<WINPATH_FORBIDDEN_CHARS.length;j++) { - if(c==WINPATH_FORBIDDEN_CHARS[j]) { - throw new IllegalArgumentException(NLS.bind(Messages.TcfURLStreamHandlerService_IllegalCharacter, "'"+c+"'")); //$NON-NLS-1$//$NON-NLS-2$ - } - } - } - } - - /** - * Encode the path from a file system path to - * URI compatible path. - * - * @see FSTreeNode#getURLEncodedPath - * @param path The URL whose path is to be decoded. - * @return The file system path. - * @throws UnsupportedEncodingException - */ - String encodeURLPath(String path) throws UnsupportedEncodingException { - StringTokenizer st = new StringTokenizer(path, "/"); //$NON-NLS-1$ - StringBuilder builder = new StringBuilder(); - while(st.hasMoreTokens()) { - if(builder.length() > 0) { - builder.append("/"); //$NON-NLS-1$ - String segment = st.nextToken(); - builder.append(URLEncoder.encode(segment, "UTF-8")); //$NON-NLS-1$ - } - else { - String segment = st.nextToken(); - if(path.matches(WINPATH_PATTERN)) { - builder.append(segment); - } - else{ - builder.append(URLEncoder.encode(segment, "UTF-8")); //$NON-NLS-1$ - } - } - } - String relative = builder.toString(); - return path.startsWith("/") ? "/" + relative : relative; //$NON-NLS-1$//$NON-NLS-2$ - } - - /* - * (non-Javadoc) - * @see org.osgi.service.url.AbstractURLStreamHandlerService#toExternalForm(java.net.URL) - */ - @Override - public String toExternalForm(final URL u) { - String peerId = u.getHost(); - StringBuilder builder = new StringBuilder(); - builder.append(TcfURLConnection.PROTOCOL_SCHEMA); - builder.append(":/"); //$NON-NLS-1$ - builder.append(peerId); - final AtomicReference<String> pathRef = new AtomicReference<String>(); - SafeRunner.run(new ISafeRunnable(){ - @Override - public void handleException(Throwable exception) { - // Ignore - } - @Override - public void run() throws Exception { - pathRef.set(encodeURLPath(u.getPath())); - }}); - String path = pathRef.get(); - if(path == null) { - builder.append("/"); //$NON-NLS-1$ - } else if(path.length() == 0) { - builder.append("/"); //$NON-NLS-1$ - } else if(path.matches(WINPATH_PATTERN)) { - builder.append("/"); //$NON-NLS-1$ - builder.append(path); - } else { - builder.append(path); - } - return builder.toString(); - } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/nls/Messages.java index 267011aed..7ccc968e2 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/nls/Messages.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/nls/Messages.java @@ -65,6 +65,7 @@ public class Messages extends NLS { public static String TcfURLConnection_NoFileHandleReturned; public static String TcfURLConnection_NoPeerFound; public static String TcfURLConnection_NoSuchTcfAgent; + public static String TcfURLConnection_relativePath; public static String OpDelete_Deleting; public static String OpDelete_error_delete; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/nls/Messages.properties index 1150ba3fb..80a81d094 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/nls/Messages.properties +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/nls/Messages.properties @@ -115,6 +115,7 @@ TcfOutputStream_StreamClosed=Stream is already closed\! TcfURLConnection_NoFileHandleReturned=No file handle returned\! TcfURLConnection_NoPeerFound=Could not find the specified target with the ID {0} TcfURLConnection_NoSuchTcfAgent=TCF agent is already disconnected\! +TcfURLConnection_relativePath=Path must be absolute TcfURLStreamHandlerService_ErrorURLFormat=Error TCF URL format\! TcfURLStreamHandlerService_IllegalCharacter=A Windows path does not permit character {0}. |