Speed-up URL stream/content handler lookup by using a tracker again. The difference to the previous tracker is that we now create and maintain the trackers inside the framework so don't need to do classloads when using them (FELIX-1138).
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@810183 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index fd29299..14ff7e5 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -307,7 +307,7 @@
{
// This should not throw an exception, but if so, lets convert it to
// a runtime exception.
- throw new RuntimeException(ex);
+ throw new RuntimeException(ex.getMessage());
}
// Read the boot delegation property and parse it.
@@ -4626,4 +4626,21 @@
}
}
}
+
+ private volatile URLHandlersActivator m_urlHandlersActivator;
+
+ void setURLHandlersActivator(URLHandlersActivator urlHandlersActivator)
+ {
+ m_urlHandlersActivator = urlHandlersActivator;
+ }
+
+ Object getStreamHandlerService(String protocol)
+ {
+ return m_urlHandlersActivator.getStreamHandlerService(protocol);
+ }
+
+ Object getContentHandlerService(String mimeType)
+ {
+ return m_urlHandlersActivator.getContentHandlerService(mimeType);
+ }
}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersActivator.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersActivator.java
index 3180aaf..69db16a 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersActivator.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersActivator.java
@@ -18,10 +18,15 @@
*/
package org.apache.felix.framework;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.Map;
+
import org.apache.felix.framework.util.FelixConstants;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
/**
* <p>
@@ -34,8 +39,8 @@
**/
class URLHandlersActivator implements BundleActivator
{
- private Map m_configMap = null;
- private Felix m_framework = null;
+ private final Map m_configMap;
+ private final Felix m_framework;
public URLHandlersActivator(Map configMap, Felix framework)
{
@@ -55,11 +60,71 @@
FelixConstants.SERVICE_URLHANDLERS_PROP) == null)
? true
: !m_configMap.get(FelixConstants.SERVICE_URLHANDLERS_PROP).equals("false");
+
+ if (enable)
+ {
+ m_streamTracker = new ServiceTracker(context, "org.osgi.service.url.URLStreamHandlerService", null);
+ m_contentTracker= new ServiceTracker(context, "java.net.ContentHandler", null);
+ m_streamTracker.open();
+ m_contentTracker.open();
+ m_framework.setURLHandlersActivator(this);
+ }
URLHandlers.registerFrameworkInstance(m_framework, enable);
}
public void stop(BundleContext context)
{
URLHandlers.unregisterFrameworkInstance(m_framework);
+ m_framework.setURLHandlersActivator(null);
+ if (m_streamTracker != null)
+ {
+ m_streamTracker.close();
+ }
+ if (m_contentTracker != null)
+ {
+ m_contentTracker.close();
+ }
+ m_streamTracker = null;
+ m_contentTracker = null;
+ }
+
+ private volatile ServiceTracker m_streamTracker;
+ private volatile ServiceTracker m_contentTracker;
+
+ protected Object getStreamHandlerService(String protocol)
+ {
+ return get(m_streamTracker, "url.handler.protocol", protocol);
+ }
+
+ protected Object getContentHandlerService(String mimeType)
+ {
+ return get(m_contentTracker, "url.content.mimetype", mimeType);
+ }
+
+ private Object get(ServiceTracker tracker, String key, String value)
+ {
+ Object service = null;
+ if (tracker != null)
+ {
+ ServiceReference[] refs = tracker.getServiceReferences();
+
+ if (refs != null)
+ {
+ if (refs.length > 1)
+ {
+ Arrays.sort(refs, Collections.reverseOrder());
+ }
+
+ for (int i = 0;(i < refs.length) && (service == null);i++)
+ {
+ if (value.equals(refs[i].getProperty(key)))
+ {
+ service = tracker.getService(refs[i]);
+ }
+ }
+ }
+ }
+
+ return service;
}
}
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java
index 35b6e15..4d51311 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java
@@ -52,10 +52,7 @@
**/
class URLHandlersContentHandlerProxy extends ContentHandler
{
- private static final Object[] SERVICE_RANKING_PARAMS = new Object[]{"service.ranking"};
- private static final Object[] SERVICE_ID_PARAMS = new Object[]{"service.id"};
private static final Class[] STRING_TYPES = new Class[]{String.class};
- private static final Class[] STRING_STRING_TYPES = new Class[]{String.class, String.class};
private static final String CONTENT_HANDLER_PACKAGE_PROP = "java.content.handler.pkgs";
private static final String DEFAULT_CONTENT_HANDLER_PACKAGE = "sun.net.www.content|com.ibm.oti.net.www.content|gnu.java.net.content|org.apache.harmony.luni.internal.net.www.content|COM.newmonics.www.content";
@@ -75,7 +72,6 @@
private final String m_mimeType;
private final SecureAction m_action;
- private final Object[] m_filter;
public URLHandlersContentHandlerProxy(String mimeType, SecureAction action,
ContentHandlerFactory factory)
@@ -83,10 +79,6 @@
m_mimeType = mimeType;
m_action = action;
m_factory = factory;
- m_filter = new Object[]{"java.net.ContentHandler",
- "(&(objectClass=java.net.ContentHandler)(url.content.mimetype="
- + mimeType
- + "))"};
}
//
@@ -125,63 +117,19 @@
}
try
{
- Object context = m_action.invoke(
- m_action.getMethod(framework.getClass(), "getBundleContext", null),framework, null);
-
- Class contextClass = context.getClass();
-
- Object[] refs = (Object[]) m_action.invoke(
- m_action.getMethod(contextClass, "getServiceReferences", STRING_STRING_TYPES),
- context, m_filter);
-
- Object ref = null;
- int highestRank = -1;
- long currentId = -1;
- if (refs != null)
+ ContentHandler service;
+ if (framework instanceof Felix)
{
- // Loop through all service references and select the reference
- // with the highest ranking and lower service identifier.
- for (int i = 0; (refs != null) && (i < refs.length); i++)
- {
- Class refClass = refs[i].getClass();
- Long idObj = (Long) m_action.invoke(m_action.getMethod(refClass,
- "getProperty", STRING_TYPES), refs[i], SERVICE_ID_PARAMS);
- Integer rankObj = (Integer) m_action.invoke(m_action.getMethod(refClass,
- "getProperty", STRING_TYPES), refs[i], SERVICE_RANKING_PARAMS);
- // Ranking value defaults to zero.
- int rank = (rankObj == null) ? 0 : rankObj.intValue();
- if ((rank > highestRank) ||
- ((rank == highestRank) && (idObj.longValue() < currentId)))
- {
- ref = refs[i];
- highestRank = rank;
- currentId = idObj.longValue();
- }
- }
+ service = (ContentHandler) ((Felix) framework).getContentHandlerService(m_mimeType);
}
- ContentHandler service = null;
- if (ref != null)
+ else
{
- Class serviceRef = null;
- Class[] interfaces = ref.getClass().getInterfaces();
- for (int i = 0;i < interfaces.length; i++)
- {
- if ("org.osgi.framework.ServiceReference".equals(interfaces[i].getName()))
- {
- serviceRef = interfaces[i];
- break;
- }
- }
service = (ContentHandler) m_action.invoke(
- m_action.getMethod(contextClass, "getService", new Class[]{serviceRef}),
- context, new Object[]{ref});
+ m_action.getMethod(framework.getClass(), "getContentHandlerService", STRING_TYPES),
+ framework, new Object[]{m_mimeType});
}
-
- if (service == null)
- {
- service = getBuiltIn();
- }
- return service;
+
+ return (service == null) ? getBuiltIn() : service;
}
catch (Exception ex)
{
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java
index 3cb9751..36708c9 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java
@@ -28,6 +28,8 @@
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
+import java.util.Collections;
+import java.util.Arrays;
import org.apache.felix.framework.util.SecureAction;
import org.osgi.service.url.URLStreamHandlerService;
@@ -59,10 +61,7 @@
implements URLStreamHandlerSetter, InvocationHandler
{
private static final Class[] URL_PROXY_CLASS;
- private static final Object[] SERVICE_RANKING_PARAMS = new Object[]{"service.ranking"};
- private static final Object[] SERVICE_ID_PARAMS = new Object[]{"service.id"};
private static final Class[] STRING_TYPES = new Class[]{String.class};
- private static final Class[] STRING_STRING_TYPES = new Class[]{String.class, String.class};
private static final Method EQUALS;
private static final Method GET_DEFAULT_PORT;
private static final Method GET_HOST_ADDRESS;
@@ -129,28 +128,25 @@
private final SecureAction m_action;
private final URLStreamHandler m_builtIn;
private final URL m_builtInURL;
- private final Object[] m_filter;
+ private final String m_protocol;
public URLHandlersStreamHandlerProxy(String protocol,
SecureAction action, URLStreamHandler builtIn, URL builtInURL)
{
+ m_protocol = protocol;
m_service = null;
m_action = action;
m_builtIn = builtIn;
m_builtInURL = builtInURL;
- m_filter = new Object[]{"org.osgi.service.url.URLStreamHandlerService",
- "(&(objectClass=org.osgi.service.url.URLStreamHandlerService)(url.handler.protocol="
- + protocol
- + "))"};
}
private URLHandlersStreamHandlerProxy(Object service, SecureAction action)
{
+ m_protocol = null;
m_service = service;
m_action = action;
m_builtIn = null;
m_builtInURL = null;
- m_filter = null;
}
//
@@ -535,57 +531,19 @@
{
return m_builtIn;
}
- Object context = m_action.invoke(
- m_action.getMethod(framework.getClass(), "getBundleContext", null),framework, null);
-
- Class contextClass = context.getClass();
-
- Object[] refs = (Object[]) m_action.invoke(
- m_action.getMethod(contextClass, "getServiceReferences", STRING_STRING_TYPES),
- context, m_filter);
-
- Object ref = null;
- int highestRank = -1;
- long currentId = -1;
- if (refs != null)
- {
- // Loop through all service references and select the reference
- // with the highest ranking and lower service identifier.
- for (int i = 0; (refs != null) && (i < refs.length); i++)
- {
- Class refClass = refs[i].getClass();
- Long idObj = (Long) m_action.invoke(m_action.getMethod(refClass,
- "getProperty", STRING_TYPES), refs[i], SERVICE_ID_PARAMS);
- Integer rankObj = (Integer) m_action.invoke(m_action.getMethod(refClass,
- "getProperty", STRING_TYPES), refs[i], SERVICE_RANKING_PARAMS);
- // Ranking value defaults to zero.
- int rank = (rankObj == null) ? 0 : rankObj.intValue();
- if ((rank > highestRank) ||
- ((rank == highestRank) && (idObj.longValue() < currentId)))
- {
- ref = refs[i];
- highestRank = rank;
- currentId = idObj.longValue();
- }
- }
- }
+
Object service = null;
- if (ref != null)
+ if (framework instanceof Felix)
{
- Class serviceRef = null;
- Class[] interfaces = ref.getClass().getInterfaces();
- for (int i = 0;i < interfaces.length; i++)
- {
- if ("org.osgi.framework.ServiceReference".equals(interfaces[i].getName()))
- {
- serviceRef = interfaces[i];
- break;
- }
- }
- service = m_action.invoke(
- m_action.getMethod(contextClass, "getService", new Class[]{serviceRef}),
- context, new Object[]{ref});
+ service = ((Felix) framework).getStreamHandlerService(m_protocol);
}
+ else
+ {
+ m_action.invoke(
+ m_action.getMethod(framework.getClass(), "getStreamHandlerService", STRING_TYPES),
+ framework, new Object[]{m_protocol});
+ }
+
if (service == null)
{
return m_builtIn;