From 55d2d367e5667c584dd2c0c5513c5dbc4294b44c Mon Sep 17 00:00:00 2001 From: Jeff McAffer Date: Mon, 13 Feb 2006 23:16:00 +0000 Subject: Bug 125549 - Adding helpers for URL converter --- .../eclipse/core/internal/runtime/Activator.java | 56 +++++++- .../src/org/eclipse/core/runtime/BundleFinder.java | 31 +++-- .../src/org/eclipse/core/runtime/FileLocator.java | 147 +++++++++++++++++++++ .../internal/preferences/DefaultPreferences.java | 4 +- 4 files changed, 221 insertions(+), 17 deletions(-) create mode 100644 bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/FileLocator.java diff --git a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/internal/runtime/Activator.java b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/internal/runtime/Activator.java index 324f169fc..95908bd4a 100644 --- a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/internal/runtime/Activator.java +++ b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/internal/runtime/Activator.java @@ -10,8 +10,11 @@ *******************************************************************************/ package org.eclipse.core.internal.runtime; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; +import java.net.URL; +import java.util.*; +import org.eclipse.osgi.service.urlconversion.URLConverter; +import org.osgi.framework.*; +import org.osgi.util.tracker.ServiceTracker; /** * The Common runtime plugin class. @@ -20,6 +23,11 @@ import org.osgi.framework.BundleContext; */ public class Activator implements BundleActivator { + /** + * Table to keep track of all the URL converter services. + */ + private static Map urlTrackers = new HashMap(); + /** * The bundle context associated this plug-in */ @@ -37,10 +45,54 @@ public class Activator implements BundleActivator { */ public void stop(BundleContext context) throws Exception { CommonOSGiUtils.getDefault().closeServices(); + closeURLTrackerServices(); bundleContext = null; } static BundleContext getContext() { return bundleContext; } + + /* + * Let go of all the services that we aquired and kept track of. + */ + private static void closeURLTrackerServices() { + synchronized (urlTrackers) { + if (!urlTrackers.isEmpty()) { + for (Iterator iter = urlTrackers.keySet().iterator(); iter.hasNext();) { + String key = (String) iter.next(); + ServiceTracker tracker = (ServiceTracker) urlTrackers.get(key); + tracker.close(); + } + urlTrackers = new HashMap(); + } + } + } + + /* + * Return the URL Converter for the given URL. Return null if we can't + * find one. + */ + public static URLConverter getURLConverter(URL url) { + String protocol = url.getProtocol(); + synchronized (urlTrackers) { + ServiceTracker tracker = (ServiceTracker) urlTrackers.get(protocol); + if (tracker == null) { + // get the right service based on the protocol + String FILTER_PREFIX = "(&(objectClass=" + URLConverter.class.getName() + ")(protocol="; //$NON-NLS-1$ //$NON-NLS-2$ + String FILTER_POSTFIX = "))"; //$NON-NLS-1$ + Filter filter = null; + try { + filter = getContext().createFilter(FILTER_PREFIX + protocol + FILTER_POSTFIX); + } catch (InvalidSyntaxException e) { + return null; + } + tracker = new ServiceTracker(getContext(), filter, null); + tracker.open(); + // cache it in the registry + urlTrackers.put(protocol, tracker); + } + return (URLConverter) tracker.getService(); + } + } } diff --git a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/BundleFinder.java b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/BundleFinder.java index e0652d00e..5adf9c7fe 100644 --- a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/BundleFinder.java +++ b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/BundleFinder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005 IBM Corporation and others. + * Copyright (c) 2005, 2006 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 @@ -14,7 +14,6 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Map; -import org.eclipse.core.internal.runtime.FindSupport; import org.osgi.framework.Bundle; /** @@ -23,9 +22,8 @@ import org.osgi.framework.Bundle; * * The class is not intended to be subclassed or instantiated by clients. * - * @since org.eclipse.equinox.common 1.0 - * XXX bundle finder renamed and it aggregates URLCOnverter. - * This is not a service! just statics. + * @since 3.2 + * @deprecated clients should use {@link FileLocator} instead */ public final class BundleFinder { @@ -38,9 +36,10 @@ public final class BundleFinder { * @return a URL for the given path or null. The actual form * of the returned URL is not specified. * @see #find(Bundle, IPath, Map) + * @deprecated use {@link FileLocator#find(Bundle, IPath)} */ public static URL find(Bundle bundle, IPath path) { - return FindSupport.find(bundle, path, null); + return FileLocator.find(bundle, path, null); } /** @@ -77,7 +76,8 @@ public final class BundleFinder { * *

* The current environment variable values can be overridden using - * the override map argument. + * the override map argument or null can be specified + * if this is not desired. *

* * @param bundle the bundle in which to search @@ -90,9 +90,10 @@ public final class BundleFinder { * is used. * @return a URL for the given path or null. The actual form * of the returned URL is not specified. + * @deprecated use {@link FileLocator#find(Bundle, IPath, Map)} */ public static URL find(Bundle bundle, IPath path, Map override) { - return FindSupport.find(bundle, path, override); + return FileLocator.find(bundle, path, override); } /** @@ -113,9 +114,10 @@ public final class BundleFinder { * as specified * @return an input stream * @exception IOException if the given path cannot be found in this plug-in + * @deprecated use {@link FileLocator#openStream(Bundle, IPath, boolean)} */ - public static final InputStream openStream(Bundle bundle, IPath file, boolean localized) throws IOException { - return FindSupport.openStream(bundle, file, localized); + public static InputStream openStream(Bundle bundle, IPath file, boolean localized) throws IOException { + return FileLocator.openStream(bundle, file, localized); } /** @@ -128,9 +130,10 @@ public final class BundleFinder { * @exception IOException if the given path cannot be found in this plug-in * * @see #openStream(Bundle,IPath,boolean) + * @deprecated use {@link FileLocator#openStream(Bundle, IPath)} */ public static final InputStream openStream(Bundle bundle, IPath file) throws IOException { - return FindSupport.openStream(bundle, file, false); + return FileLocator.openStream(bundle, file, false); } /** @@ -145,9 +148,10 @@ public final class BundleFinder { * @return the converted file URL or the original URL passed in if it is * not recognized by this converter * @throws IOException if an error occurs during the conversion + * @deprecated use {@link FileLocator#toFileURL(URL)} */ public static URL toFileURL(URL url) throws IOException { - return null; //TODO get the code from internalplatform + return FileLocator.toFileURL(url); } /** @@ -166,8 +170,9 @@ public final class BundleFinder { * @return the resolved URL or the original if the protocol is unknown to this converter * @exception IOException if unable to resolve URL * @throws IOException if an error occurs during the resolution + * @deprecated use {@link FileLocator#resolve(URL)} */ public static URL resolve(URL url) throws IOException { - return null; //TODO get the code from internalplatform + return FileLocator.resolve(url); } } diff --git a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/FileLocator.java b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/FileLocator.java new file mode 100644 index 000000000..de658405b --- /dev/null +++ b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/FileLocator.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2006 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.runtime; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Map; +import org.eclipse.core.internal.runtime.*; +import org.eclipse.osgi.service.urlconversion.URLConverter; +import org.osgi.framework.Bundle; + +/** + * This class contains collection of helper methods aimed at finding files in bundles. + * This class can only be used if OSGi plugin is available. + *

+ * The class is not intended to be subclassed or instantiated by clients. + *

+ * @since 3.2 + */ +public final class FileLocator { + + /** + * Returns a URL for the given path in the given bundle. Returns null if the URL + * could not be computed or created. + *

+ * find looks for this path in given bundle and any attached fragments. + * null is returned if no such entry is found. Note that + * there is no specific order to the fragments. + *

+ * The following arguments may also be used + *

+	 *     $nl$ - for language specific information
+	 *     $os$ - for operating system specific information
+	 *     $ws$ - for windowing system specific information
+	 * 
+ *

+ * A path of $nl$/about.properties in an environment with a default + * locale of en_CA will return a URL corresponding to the first place + * about.properties is found according to the following order: + *

+	 *     plugin root/nl/en/CA/about.properties
+	 *     fragment1 root/nl/en/CA/about.properties
+	 *     fragment2 root/nl/en/CA/about.properties
+	 *     ...
+	 *     plugin root/nl/en/about.properties
+	 *     fragment1 root/nl/en/about.properties
+	 *     fragment2 root/nl/en/about.properties
+	 *     ...
+	 *     plugin root/about.properties
+	 *     fragment1 root/about.properties
+	 *     fragment2 root/about.properties
+	 *     ...
+	 * 
+ *

+ * The current environment variable values can be overridden using + * the override map argument or null can be specified + * if this is not desired. + *

+ * + * @param bundle the bundle in which to search + * @param path file path relative to plug-in installation location + * @param override map of override substitution arguments to be used for + * any $arg$ path elements. The map keys correspond to the substitution + * arguments (eg. "$nl$" or "$os$"). The resulting + * values must be of type java.lang.String. If the map is null, + * or does not contain the required substitution argument, the default + * is used. + * @return a URL for the given path or null. The actual form + * of the returned URL is not specified. + */ + public static URL find(Bundle bundle, IPath path, Map override) { + return FindSupport.find(bundle, path, override); + } + + /** + * Returns an input stream for the specified file. The file path + * must be specified relative to this plug-in's installation location. + * Optionally, the platform searches for the correct localized version + * of the specified file using the users current locale, and Java + * naming convention for localized resource files (locale suffix appended + * to the specified file extension). + *

+ * The caller must close the returned stream when done. + *

+ * + * @param bundle the bundle in which to search + * @param file path relative to plug-in installation location + * @param localized true for the localized version + * of the file, and false for the file exactly + * as specified + * @return an input stream + * @exception IOException if the given path cannot be found in this plug-in + */ + public static InputStream openStream(Bundle bundle, IPath file, boolean localized) throws IOException { + return FindSupport.openStream(bundle, file, localized); + } + + /** + * Converts a URL that uses a user-defined protocol into a URL that uses the file + * protocol. The contents of the URL may be extracted into a cache on the file-system + * in order to get a file URL. + *

+ * If the protocol for the given URL is not recognized by this converter, the original + * URL is returned as-is. + *

+ * @param url the original URL + * @return the converted file URL or the original URL passed in if it is + * not recognized by this converter + * @throws IOException if an error occurs during the conversion + */ + public static URL toFileURL(URL url) throws IOException { + URLConverter converter = Activator.getURLConverter(url); + return converter == null ? url : converter.toFileURL(url); + } + + /** + * Converts a URL that uses a client-defined protocol into a URL that uses a + * protocol which is native to the Java class library (file, jar, http, etc). + *

+ * Note however that users of this API should not assume too much about the + * results of this method. While it may consistently return a file: URL in certain + * installation configurations, others may result in jar: or http: URLs. + *

+ *

+ * If the protocol is not reconized by this converter, then the original URL is + * returned as-is. + *

+ * @param url the original URL + * @return the resolved URL or the original if the protocol is unknown to this converter + * @exception IOException if unable to resolve URL + * @throws IOException if an error occurs during the resolution + */ + public static URL resolve(URL url) throws IOException { + URLConverter converter = Activator.getURLConverter(url); + return converter == null ? url : converter.resolve(url); + } + +} diff --git a/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/DefaultPreferences.java b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/DefaultPreferences.java index bb7bffec7..a2f2b447f 100644 --- a/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/DefaultPreferences.java +++ b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/DefaultPreferences.java @@ -86,13 +86,13 @@ public class DefaultPreferences extends EclipsePreferences { Bundle bundle = PreferencesOSGiUtils.getDefault().getBundle(name()); if (bundle == null) return; - URL url = BundleFinder.find(bundle, new Path(IPreferencesConstants.PREFERENCES_DEFAULT_OVERRIDE_FILE_NAME)); + URL url = FileLocator.find(bundle, new Path(IPreferencesConstants.PREFERENCES_DEFAULT_OVERRIDE_FILE_NAME), null); if (url == null) { if (EclipsePreferences.DEBUG_PREFERENCE_GENERAL) PrefsMessages.message("Preference default override file not found for bundle: " + bundle.getSymbolicName()); //$NON-NLS-1$ return; } - URL transURL = BundleFinder.find(bundle, NL_DIR.append(IPreferencesConstants.PREFERENCES_DEFAULT_OVERRIDE_BASE_NAME).addFileExtension(PROPERTIES_FILE_EXTENSION)); + URL transURL = FileLocator.find(bundle, NL_DIR.append(IPreferencesConstants.PREFERENCES_DEFAULT_OVERRIDE_BASE_NAME).addFileExtension(PROPERTIES_FILE_EXTENSION), null); if (transURL == null && EclipsePreferences.DEBUG_PREFERENCE_GENERAL) PrefsMessages.message("Preference translation file not found for bundle: " + bundle.getSymbolicName()); //$NON-NLS-1$ applyDefaults(name(), loadProperties(url), loadProperties(transURL)); -- cgit v1.2.3