Bug 69033 - Please add "platform:/meta" URLConnection support (final touches)
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/Messages.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/Messages.java
index 2fa1f78..f8c841c 100644
--- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/Messages.java
+++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/Messages.java
@@ -175,6 +175,7 @@
public static String url_createConnection;
public static String url_invalidURL;
public static String url_noaccess;
+ public static String url_noOutput;
public static String url_resolveFragment;
public static String url_resolvePlugin;
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/PlatformURLConfigConnection.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/PlatformURLConfigConnection.java
index fe1313e..9ecd117 100644
--- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/PlatformURLConfigConnection.java
+++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/PlatformURLConfigConnection.java
@@ -12,12 +12,15 @@
import java.io.*;
import java.net.URL;
+import java.net.UnknownServiceException;
import org.eclipse.core.internal.boot.PlatformURLConnection;
import org.eclipse.core.internal.boot.PlatformURLHandler;
import org.eclipse.core.runtime.Platform;
+import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.osgi.util.NLS;
public class PlatformURLConfigConnection extends PlatformURLConnection {
+ private static final String FILE_PROTOCOL = "file"; //$NON-NLS-1$
private static boolean isRegistered = false;
public static final String CONFIG = "config"; //$NON-NLS-1$
@@ -35,7 +38,28 @@
if (!spec.startsWith(CONFIG))
throw new IOException(NLS.bind(Messages.url_badVariant, url.toString()));
String path = spec.substring(CONFIG.length() + 1);
- return new URL(Platform.getConfigurationLocation().getURL(), path);
+ // resolution takes parent configuration into account (if it exists)
+ Location localConfig = Platform.getConfigurationLocation();
+ Location parentConfig = localConfig.getParentLocation();
+ // assume we will find the file locally
+ URL localURL = new URL(localConfig.getURL(), path);
+ if (!FILE_PROTOCOL.equals(localURL.getProtocol()) || parentConfig == null)
+ // we only support cascaded file: URLs
+ return localURL;
+ File localFile = new File(localURL.getPath());
+ if (localFile.exists())
+ // file exists in local configuration
+ return localURL;
+ // try to find in the parent configuration
+ URL parentURL = new URL(parentConfig.getURL(), path);
+ if (FILE_PROTOCOL.equals(parentURL.getProtocol())) {
+ // we only support cascaded file: URLs
+ File parentFile = new File(parentURL.getPath());
+ if (parentFile.exists())
+ // parent has the file
+ return parentURL;
+ }
+ return localURL;
}
public static void startup() {
@@ -50,6 +74,8 @@
* @see java.net.URLConnection#getOutputStream()
*/
public OutputStream getOutputStream() throws IOException {
+ if (Platform.getConfigurationLocation().isReadOnly())
+ throw new UnknownServiceException(NLS.bind(Messages.url_noOutput, url));
//This is not optimal but connection is a private ivar in super.
URL resolved = getResolvedURL();
if (resolved != null) {
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/PlatformURLMetaConnection.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/PlatformURLMetaConnection.java
index 2845d5d..8282364 100644
--- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/PlatformURLMetaConnection.java
+++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/PlatformURLMetaConnection.java
@@ -14,7 +14,8 @@
import java.net.URL;
import org.eclipse.core.internal.boot.PlatformURLConnection;
import org.eclipse.core.internal.boot.PlatformURLHandler;
-import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
@@ -41,11 +42,11 @@
String id = getId(ref);
target = InternalPlatform.getDefault().getBundle(id);
if (target == null)
- throw new IOException(NLS.bind(Messages.url_resolvePlugin, url.toString()));
+ throw new IOException(NLS.bind(Messages.url_resolvePlugin, url.toString()));
IPath path = Platform.getStateLocation(target);
if (ix != -1 || (ix + 1) <= spec.length())
path = path.append(spec.substring(ix + 1));
- return new URL("file", null, path.toString()); //$NON-NLS-1$
+ return path.toFile().toURL(); //$NON-NLS-1$
}
public static void startup() {
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/messages.properties b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/messages.properties
index ff2b15d..328839a 100644
--- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/messages.properties
+++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/messages.properties
@@ -167,6 +167,7 @@
url_badVariant=Unsupported \"platform:\" protocol variation \"{0}\".
url_createConnection=Unable to create connection on \"{0}\".
url_invalidURL=Invalid URL \"{0}\".
+url_noOutput=Output is not supported for \"{0}\".
url_noaccess=Unhandled URL protocol \"{0}\".
url_resolveFragment=Unable to resolve fragment \"{0}\".
url_resolvePlugin=Unable to resolve plug-in \"{0}\".
diff --git a/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF b/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF
index dee3a31..a19cf2f 100644
--- a/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF
@@ -17,8 +17,7 @@
org.eclipse.core.tests.runtime.model,
org.eclipse.core.tests.runtime.perf,
org.eclipse.core.tests.runtime.session
-Require-Bundle: org.eclipse.osgi.services,
- org.eclipse.core.runtime.compatibility,
+Require-Bundle: org.eclipse.core.runtime.compatibility,
org.eclipse.core.tests.harness,
org.junit,
org.eclipse.test.performance;resolution:=optional
diff --git a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllTests.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllTests.java
index cfd5da9..4d7ef42 100644
--- a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllTests.java
+++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllTests.java
@@ -35,6 +35,8 @@
suite.addTest(CipherStreamsTest.suite());
suite.addTest(CipherTest.suite());
suite.addTest(LogSerializationTest.suite());
+ suite.addTest(PlatformURLLocalTest.suite());
+ suite.addTest(PlatformURLSessionTest.suite());
return suite;
}
}
diff --git a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/PlatformURLLocalTest.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/PlatformURLLocalTest.java
new file mode 100644
index 0000000..b6cb955
--- /dev/null
+++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/PlatformURLLocalTest.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.core.tests.internal.runtime;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.tests.runtime.RuntimeTest;
+import org.eclipse.core.tests.runtime.RuntimeTestsPlugin;
+
+public class PlatformURLLocalTest extends RuntimeTest {
+
+ public static void assertEquals(String tag, URL expected, URL actual, boolean external) {
+ if (external) {
+ assertEquals(tag, expected, actual);
+ return;
+ }
+ try {
+ assertEquals(tag + ".1", new URL(expected.getProtocol(), expected.getHost(), expected.getPort(), expected.getFile()), new URL(actual.getProtocol(), actual.getHost(), actual.getPort(), actual.getFile()));
+ } catch (MalformedURLException e) {
+ fail(tag + ".2", e);
+ }
+ }
+
+ public static Test suite() {
+ return new TestSuite(PlatformURLLocalTest.class);
+ }
+
+ public PlatformURLLocalTest(String name) {
+ super(name);
+ }
+
+ public void testPlatformURLConfigResolution() {
+ URL platformURL = null;
+ try {
+ // create a fake URL
+ platformURL = new URL("platform:/config/x");
+ } catch (MalformedURLException e) {
+ fail("1.0", e);
+ }
+ URL resolvedURL = null;
+ try {
+ resolvedURL = Platform.resolve(platformURL);
+ } catch (IOException e) {
+ fail("2.0", e);
+ }
+ assertFalse("3.0", platformURL.equals(resolvedURL));
+ URL expected = null;
+ try {
+ expected = new URL(Platform.getConfigurationLocation().getURL(), "x");
+ } catch (MalformedURLException e) {
+ fail("4.0", e);
+ }
+ assertEquals("5.0", expected, resolvedURL, false);
+ }
+
+ public void testPlatformURLMetaResolution() {
+ URL platformURL = null;
+ try {
+ // create a fake URL
+ platformURL = new URL("platform:/meta/" + PI_RUNTIME_TESTS + "/x");
+ } catch (MalformedURLException e) {
+ fail("1.0", e);
+ }
+ URL resolvedURL = null;
+ try {
+ resolvedURL = Platform.resolve(platformURL);
+ } catch (IOException e) {
+ fail("2.0", e);
+ }
+ assertFalse("3.0", platformURL.equals(resolvedURL));
+ URL expected = null;
+ try {
+ expected = new URL(RuntimeTestsPlugin.getPlugin().getStateLocation().toFile().toURL(), "x");
+ } catch (MalformedURLException e) {
+ fail("4.0", e);
+ }
+ assertEquals("5.0", expected, resolvedURL, false);
+ }
+}
diff --git a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/PlatformURLSessionTest.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/PlatformURLSessionTest.java
new file mode 100644
index 0000000..e53a9b7
--- /dev/null
+++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/PlatformURLSessionTest.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.core.tests.internal.runtime;
+
+import java.io.*;
+import java.net.*;
+import junit.framework.Test;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.tests.runtime.RuntimeTest;
+import org.eclipse.core.tests.session.ConfigurationSessionTestSuite;
+import org.eclipse.osgi.service.datalocation.Location;
+
+public class PlatformURLSessionTest extends RuntimeTest {
+
+ private static final String CONFIG_URL = "platform:/config/" + PI_RUNTIME_TESTS + "/";
+ private static final String DATA_CHILD = "child";
+ private static final String DATA_PARENT = "parent";
+ private static final String FILE_BOTH_PARENT_AND_CHILD = "both.txt";
+ private static final String FILE_CHILD_ONLY = "child.txt";
+ private static final String FILE_PARENT_ONLY = "parent.txt";
+
+ public static void assertEquals(String tag, URL expected, URL actual, boolean external) {
+ if (external) {
+ assertEquals(tag, expected, actual);
+ return;
+ }
+ assertEquals(tag + " different protocol", expected.getProtocol(), actual.getProtocol());
+ assertEquals(tag + " different host", expected.getHost(), actual.getHost());
+ assertEquals(tag + " different path", expected.getPath(), actual.getPath());
+ assertEquals(tag + " different port", expected.getPort(), actual.getPort());
+ }
+
+ private static String readContents(String tag, URL url) {
+ URLConnection connection = null;
+ try {
+ connection = url.openConnection();
+ } catch (IOException e) {
+ fail(tag + ".1", e);
+ }
+ InputStream input = null;
+ try {
+ input = connection.getInputStream();
+ } catch (IOException e) {
+ fail(tag + ".2", e);
+ }
+ BufferedReader reader = new BufferedReader(new InputStreamReader(input));
+ String line = null;
+ StringBuffer result = new StringBuffer();
+ try {
+ while ((line = reader.readLine()) != null)
+ result.append(line);
+ return result.toString();
+ } catch (IOException e) {
+ fail(tag + ".99", e);
+ } finally {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ // not interested
+ }
+ }
+ // never happens
+ return null;
+ }
+
+ public static Test suite() {
+ ConfigurationSessionTestSuite suite = new ConfigurationSessionTestSuite(PI_RUNTIME_TESTS, PlatformURLSessionTest.class);
+ suite.setReadOnly(true);
+ suite.setCascaded(true);
+ String[] ids = ConfigurationSessionTestSuite.MINIMAL_BUNDLE_SET;
+ for (int i = 0; i < ids.length; i++)
+ suite.addBundle(ids[i]);
+ suite.addBundle(PI_RUNTIME_TESTS);
+ return suite;
+ }
+
+ public PlatformURLSessionTest(String name) {
+ super(name);
+ }
+
+ /**
+ * Creates test data in both child and parent configurations.
+ */
+ public void test0CreateData() {
+ URL childConfigURL = Platform.getConfigurationLocation().getURL();
+ //tests run with file based configuration
+ assertEquals("0.1", "file", childConfigURL.getProtocol());
+ File childConfigPrivateDir = new File(childConfigURL.getPath(), PI_RUNTIME_TESTS);
+ try {
+ createFileInFileSystem(new File(childConfigPrivateDir, FILE_CHILD_ONLY), getContents(DATA_CHILD));
+ } catch (IOException e) {
+ fail("1.0");
+ }
+ try {
+ createFileInFileSystem(new File(childConfigPrivateDir, FILE_BOTH_PARENT_AND_CHILD), getContents(DATA_CHILD));
+ } catch (IOException e) {
+ fail("2.0");
+ }
+
+ Location parent = Platform.getConfigurationLocation().getParentLocation();
+ //tests run with cascaded configuration
+ assertNotNull("4.0", parent);
+ URL parentConfigURL = parent.getURL();
+ //tests run with file based configuration
+ assertEquals("4.1", "file", parentConfigURL.getProtocol());
+ File parentConfigPrivateDir = new File(parentConfigURL.getPath(), PI_RUNTIME_TESTS);
+ try {
+ createFileInFileSystem(new File(parentConfigPrivateDir, FILE_PARENT_ONLY), getContents(DATA_PARENT));
+ } catch (IOException e) {
+ fail("5.0");
+ }
+ try {
+ createFileInFileSystem(new File(parentConfigPrivateDir, FILE_BOTH_PARENT_AND_CHILD), getContents(DATA_PARENT));
+ } catch (IOException e) {
+ fail("6.0");
+ }
+ }
+
+ public void test1OutputOnReadOnly() {
+ // try to modify a file in the configuration area -should fail
+ URL configURL = null;
+ try {
+ configURL = new URL(CONFIG_URL + "somefile.txt");
+ } catch (MalformedURLException e) {
+ fail("1.0", e);
+ }
+ URLConnection connection = null;
+ try {
+ connection = configURL.openConnection();
+ } catch (IOException e) {
+ fail("2.0", e);
+ }
+ connection.setDoOutput(true);
+ OutputStream output = null;
+ try {
+ output = connection.getOutputStream();
+ fail("3.0 - should have failed");
+ } catch (IOException e) {
+ // that is expected - configuration area is read-only
+ } finally {
+ if (output != null)
+ try {
+ output.close();
+ } catch (IOException e) {
+ // not interested
+ }
+ }
+ }
+
+ public void test2Resolution() {
+ URL parent = null;
+ URL child = null;
+ URL both = null;
+ URL none = null;
+ try {
+ parent = new URL(CONFIG_URL + FILE_PARENT_ONLY);
+ child = new URL(CONFIG_URL + FILE_CHILD_ONLY);
+ both = new URL(CONFIG_URL + FILE_BOTH_PARENT_AND_CHILD);
+ none = new URL(CONFIG_URL + "none.txt");
+ } catch (MalformedURLException e) {
+ fail("0.1", e);
+ }
+ assertEquals("1.0", DATA_PARENT, readContents("1.1", parent));
+ assertEquals("2.0", DATA_CHILD, readContents("2.1", child));
+ assertEquals("3.0", DATA_CHILD, readContents("3.1", both));
+ URL resolvedURL = null;
+ try {
+ resolvedURL = Platform.resolve(none);
+ } catch (IOException e) {
+ fail("4.0", e);
+ }
+ assertFalse("4.1", none.equals(resolvedURL));
+ assertTrue("4.2", resolvedURL.toExternalForm().startsWith(Platform.getConfigurationLocation().getURL().toExternalForm()));
+ }
+
+}
diff --git a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/RuntimeTestsPlugin.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/RuntimeTestsPlugin.java
index 5e3ad41..8973727 100644
--- a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/RuntimeTestsPlugin.java
+++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/RuntimeTestsPlugin.java
@@ -41,4 +41,8 @@
return plugin != null ? plugin.context : null;
}
+ public static Plugin getPlugin() {
+ return plugin;
+ }
+
}