You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2008/09/01 17:08:10 UTC
svn commit: r690991 [7/20] - in /cxf/sandbox/dosgi: ./ discovery/
discovery/local/ discovery/local/src/ discovery/local/src/main/
discovery/local/src/main/java/ discovery/local/src/main/java/org/
discovery/local/src/main/java/org/apache/ discovery/loca...
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,777 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.felix.framework.util.FelixConstants;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.hooks.service.ListenerHook;
+
+
+public class ServiceRegistry
+{
+ private Logger m_logger = null;
+ private long m_currentServiceId = 1L;
+ // Maps bundle to an array of service registrations.
+ private Map m_serviceRegsMap = new HashMap();
+ // Maps registration to thread to keep track when a
+ // registration is in use, which will cause other
+ // threads to wait.
+ private Map m_lockedRegsMap = new HashMap();
+ // Maps bundle to an array of usage counts.
+ private Map m_inUseMap = new HashMap();
+
+ private ServiceListener m_serviceListener = null;
+
+ private List<ListenerHook> listenerHooks =
+ new CopyOnWriteArrayList<ListenerHook>();
+
+ public ServiceRegistry(Logger logger)
+ {
+ m_logger = logger;
+ }
+
+ public synchronized ServiceReference[] getRegisteredServices(Bundle bundle)
+ {
+ ServiceRegistration[] regs = (ServiceRegistration[]) m_serviceRegsMap.get(bundle);
+ if (regs != null)
+ {
+ ServiceReference[] refs = new ServiceReference[regs.length];
+ for (int i = 0; i < refs.length; i++)
+ {
+ refs[i] = regs[i].getReference();
+ }
+ return refs;
+ }
+ return null;
+ }
+
+ public ServiceRegistration registerService(
+ Bundle bundle, String[] classNames, Object svcObj, Dictionary dict)
+ {
+
+ ServiceRegistration reg = null;
+
+ synchronized (this)
+ {
+ registerHooks(classNames, svcObj);
+
+ reg = new ServiceRegistrationImpl(this,
+ bundle,
+ classNames,
+ new Long(m_currentServiceId++),
+ svcObj,
+ dict);
+
+ // Get the bundles current registered services.
+ ServiceRegistration[] regs = (ServiceRegistration[]) m_serviceRegsMap.get(bundle);
+ m_serviceRegsMap.put(bundle, addServiceRegistration(regs, reg));
+ }
+ fireServiceChanged(new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()));
+ return reg;
+ }
+
+ private void registerHooks(String[] classNames, Object svcObj) {
+
+ if (hookRequested(classNames, ListenerHook.class.getName())) {
+ listenerHooks.add((ListenerHook)svcObj);
+ }
+ }
+
+ protected boolean hookRequested(String[] classNames, String hookClass) {
+ for (String name : classNames) {
+ if (name.equals(hookClass)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void unregisterService(Bundle bundle, ServiceRegistration reg)
+ {
+ synchronized (this)
+ {
+ // Note that we don't lock the service registration here using
+ // the m_lockedRegsMap because we want to allow bundles to get
+ // the service during the unregistration process. However, since
+ // we do remove the registration from the service registry, no
+ // new bundles will be able to look up the service.
+
+ // Now remove the registered service.
+ ServiceRegistration[] regs = (ServiceRegistration[]) m_serviceRegsMap.get(bundle);
+ m_serviceRegsMap.put(bundle, removeServiceRegistration(regs, reg));
+ }
+
+ // Fire the service event which gives all client bundles the
+ // opportunity to unget their service object.
+ fireServiceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()));
+
+ // Now forcibly unget the service object for all stubborn clients.
+ synchronized (this)
+ {
+ Bundle[] clients = getUsingBundles(reg.getReference());
+ for (int i = 0; (clients != null) && (i < clients.length); i++)
+ {
+ while (ungetService(clients[i], reg.getReference()))
+ ; // Keep removing until it is no longer possible
+ }
+ ((ServiceRegistrationImpl) reg).invalidate();
+ }
+ }
+
+ /**
+ * This method retrieves all services registrations for the specified
+ * bundle and invokes <tt>ServiceRegistration.unregister()</tt> on each
+ * one. This method is only called be the framework to clean up after
+ * a stopped bundle.
+ * @param bundle the bundle whose services should be unregistered.
+ **/
+ public void unregisterServices(Bundle bundle)
+ {
+ // Simply remove all service registrations for the bundle.
+ ServiceRegistration[] regs = null;
+ synchronized (this)
+ {
+ regs = (ServiceRegistration[]) m_serviceRegsMap.get(bundle);
+ }
+
+ // Note, there is no race condition here with respect to the
+ // bundle registering more services, because its bundle context
+ // has already been invalidated by this point, so it would not
+ // be able to register more services.
+
+ // Unregister each service.
+ for (int i = 0; (regs != null) && (i < regs.length); i++)
+ {
+ regs[i].unregister();
+ }
+
+ // Now remove the bundle itself.
+ synchronized (this)
+ {
+ m_serviceRegsMap.remove(bundle);
+ }
+ }
+
+ public List getServiceReferences(
+ Bundle findingBundle, String className, Filter filter)
+ {
+ // Create a filtered list of service references.
+ List list = new ArrayList();
+
+ // Iterator over all service registrations.
+ for (Iterator i = m_serviceRegsMap.entrySet().iterator(); i.hasNext(); )
+ {
+ Map.Entry entry = (Map.Entry) i.next();
+ ServiceRegistration[] regs = (ServiceRegistration[]) entry.getValue();
+
+ for (int regIdx = 0;
+ (regs != null) && (regIdx < regs.length);
+ regIdx++)
+ {
+ // Determine if the registered services matches
+ // the search criteria.
+ boolean matched = false;
+
+ // If className is null, then look at filter only.
+ if ((className == null) &&
+ ((filter == null) || filter.match(regs[regIdx].getReference())))
+ {
+ matched = true;
+ }
+ // If className is not null, then first match the
+ // objectClass property before looking at the
+ // filter.
+ else if (className != null)
+ {
+ String[] objectClass = (String[])
+ ((ServiceRegistrationImpl) regs[regIdx]).getProperty(FelixConstants.OBJECTCLASS);
+ for (int classIdx = 0;
+ classIdx < objectClass.length;
+ classIdx++)
+ {
+ if (objectClass[classIdx].equals(className) &&
+ ((filter == null) || filter.match(regs[regIdx].getReference())))
+ {
+ matched = true;
+ break;
+ }
+ }
+ }
+
+ // Add reference if it was a match.
+ if (matched)
+ {
+ list.add(regs[regIdx].getReference());
+ }
+ }
+ }
+
+ return list;
+ }
+
+ public synchronized ServiceReference[] getServicesInUse(Bundle bundle)
+ {
+ UsageCount[] usages = (UsageCount[]) m_inUseMap.get(bundle);
+ if (usages != null)
+ {
+ ServiceReference[] refs = new ServiceReference[usages.length];
+ for (int i = 0; i < refs.length; i++)
+ {
+ refs[i] = usages[i].m_ref;
+ }
+ return refs;
+ }
+ return null;
+ }
+
+ public Object getService(Bundle bundle, ServiceReference ref)
+ {
+
+ UsageCount usage = null;
+ Object svcObj = null;
+
+ // Get the service registration.
+ ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();
+
+ synchronized (this)
+ {
+ // First make sure that no existing operation is currently
+ // being performed by another thread on the service registration.
+ for (Object o = m_lockedRegsMap.get(reg); (o != null); o = m_lockedRegsMap.get(reg))
+ {
+ // We don't allow cycles when we call out to the service factory.
+ if (o.equals(Thread.currentThread()))
+ {
+ throw new IllegalStateException(
+ "ServiceFactory.getService() resulted in a cycle.");
+ }
+
+ // Otherwise, wait for it to be freed.
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException ex)
+ {
+ }
+ }
+
+ // Lock the service registration.
+ m_lockedRegsMap.put(reg, Thread.currentThread());
+
+ // Make sure the service registration is still valid.
+ if (!reg.isValid())
+ {
+ // If the service registration is not valid, then this means
+ // that the service provider unregistered the service. The spec
+ // says that calls to get an unregistered service should always
+ // return null (assumption: even if it is currently cached
+ // by the bundle). So in this case, flush the service reference
+ // from the cache and return null.
+ flushUsageCount(bundle, ref);
+
+ // It is not necessary to unget the service object from
+ // the providing bundle, since the associated service is
+ // unregistered and hence not in the list of registered services
+ // of the providing bundle. This is precisely why the service
+ // registration was not found above in the first place.
+ }
+ else
+ {
+ // Get the usage count, if any.
+ usage = getUsageCount(bundle, ref);
+
+ // If the service object is cached, then increase the usage
+ // count and return the cached service object.
+ if (usage != null)
+ {
+ usage.m_count++;
+ svcObj = usage.m_svcObj;
+ }
+ }
+ }
+
+ // If we have a valid registration, but no usage count, that means we
+ // don't have a cached service object, so we need to create one now
+ // without holding the lock, since we will potentially call out to a
+ // service factory.
+ try
+ {
+ if (reg.isValid() && (usage == null))
+ {
+ // Get service object from service registration.
+ svcObj = reg.getService(bundle);
+
+ // Cache the service object.
+ if (svcObj != null)
+ {
+ synchronized (this)
+ {
+ // Unregistration can happen concurrently, so we need
+ // to double-check that we are still valid.
+ if (reg.isValid())
+ {
+ addUsageCount(bundle, ref, svcObj);
+ }
+ else
+ {
+ // The service must have been unregistered in the
+ // middle of our get operation, so null it.
+ svcObj = null;
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ // Finally, unlock the service registration so that any threads
+ // waiting for it can continue.
+ synchronized (this)
+ {
+ m_lockedRegsMap.remove(reg);
+ notifyAll();
+ }
+ }
+
+ return svcObj;
+ }
+
+ public boolean ungetService(Bundle bundle, ServiceReference ref)
+ {
+ UsageCount usage = null;
+ ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();
+
+ synchronized (this)
+ {
+ // First make sure that no existing operation is currently
+ // being performed by another thread on the service registration.
+ for (Object o = m_lockedRegsMap.get(reg); (o != null); o = m_lockedRegsMap.get(reg))
+ {
+ // We don't allow cycles when we call out to the service factory.
+ if (o.equals(Thread.currentThread()))
+ {
+ throw new IllegalStateException(
+ "ServiceFactory.ungetService() resulted in a cycle.");
+ }
+
+ // Otherwise, wait for it to be freed.
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException ex)
+ {
+ }
+ }
+
+ // Get the usage count.
+ usage = getUsageCount(bundle, ref);
+ // If there is no cached services, then just return immediately.
+ if (usage == null)
+ {
+ return false;
+ }
+
+ // Lock the service registration.
+ m_lockedRegsMap.put(reg, Thread.currentThread());
+
+ // Make sure the service registration is still valid.
+ if (!reg.isValid())
+ {
+ // If the service registration is not valid, then this means
+ // that the service provider unregistered the service, so just
+ // flush the usage count and we are done.
+ flushUsageCount(bundle, ref);
+ }
+ else if (reg.isValid())
+ {
+ // Decrement usage count.
+ usage.m_count--;
+ }
+
+ // If the usage count has reached zero, the flush it.
+ if (usage.m_count == 0)
+ {
+ flushUsageCount(bundle, ref);
+ }
+ }
+
+ // If usage count goes to zero, then unget the service
+ // from the registration; we do this outside the lock
+ // since this might call out to the service factory.
+ try
+ {
+ if (usage.m_count == 0)
+ {
+ // Remove reference from usages array.
+ ((ServiceReferenceImpl) ref)
+ .getServiceRegistration().ungetService(bundle, usage.m_svcObj);
+ usage.m_svcObj = null;
+ }
+
+ }
+ finally
+ {
+ // Finally, unlock the service registration so that any threads
+ // waiting for it can continue.
+ synchronized (this)
+ {
+ m_lockedRegsMap.remove(reg);
+ notifyAll();
+ }
+ }
+
+ return (usage.m_count > 0);
+ }
+
+
+ /**
+ * This is a utility method to release all services being
+ * used by the specified bundle.
+ * @param bundle the bundle whose services are to be released.
+ **/
+ public void ungetServices(Bundle bundle)
+ {
+ UsageCount[] usages;
+ synchronized (this)
+ {
+ usages = (UsageCount[]) m_inUseMap.get(bundle);
+ }
+
+ if (usages == null)
+ {
+ return;
+ }
+
+ // Note, there is no race condition here with respect to the
+ // bundle using more services, because its bundle context
+ // has already been invalidated by this point, so it would not
+ // be able to look up more services.
+
+ // Remove each service object from the
+ // service cache.
+ for (int i = 0; i < usages.length; i++)
+ {
+ // Keep ungetting until all usage count is zero.
+ while (ungetService(bundle, usages[i].m_ref))
+ {
+ // Empty loop body.
+ }
+ }
+ }
+
+ public synchronized Bundle[] getUsingBundles(ServiceReference ref)
+ {
+ Bundle[] bundles = null;
+ for (Iterator iter = m_inUseMap.entrySet().iterator(); iter.hasNext(); )
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ Bundle bundle = (Bundle) entry.getKey();
+ UsageCount[] usages = (UsageCount[]) entry.getValue();
+ for (int useIdx = 0; useIdx < usages.length; useIdx++)
+ {
+ if (usages[useIdx].m_ref.equals(ref))
+ {
+ // Add the bundle to the array to be returned.
+ if (bundles == null)
+ {
+ bundles = new Bundle[] { bundle };
+ }
+ else
+ {
+ Bundle[] nbs = new Bundle[bundles.length + 1];
+ System.arraycopy(bundles, 0, nbs, 0, bundles.length);
+ nbs[bundles.length] = bundle;
+ bundles = nbs;
+ }
+ }
+ }
+ }
+ return bundles;
+ }
+
+ public void servicePropertiesModified(ServiceRegistration reg)
+ {
+ fireServiceChanged(new ServiceEvent(ServiceEvent.MODIFIED, reg.getReference()));
+ }
+
+ public Logger getLogger()
+ {
+ return m_logger;
+ }
+
+ private static ServiceRegistration[] addServiceRegistration(
+ ServiceRegistration[] regs, ServiceRegistration reg)
+ {
+ if (regs == null)
+ {
+ regs = new ServiceRegistration[] { reg };
+ }
+ else
+ {
+ ServiceRegistration[] newRegs = new ServiceRegistration[regs.length + 1];
+ System.arraycopy(regs, 0, newRegs, 0, regs.length);
+ newRegs[regs.length] = reg;
+ regs = newRegs;
+ }
+ return regs;
+ }
+
+ private static ServiceRegistration[] removeServiceRegistration(
+ ServiceRegistration[] regs, ServiceRegistration reg)
+ {
+ for (int i = 0; (regs != null) && (i < regs.length); i++)
+ {
+ if (regs[i].equals(reg))
+ {
+ // If this is the only usage, then point to empty list.
+ if ((regs.length - 1) == 0)
+ {
+ regs = new ServiceRegistration[0];
+ }
+ // Otherwise, we need to do some array copying.
+ else
+ {
+ ServiceRegistration[] newRegs = new ServiceRegistration[regs.length - 1];
+ System.arraycopy(regs, 0, newRegs, 0, i);
+ if (i < newRegs.length)
+ {
+ System.arraycopy(
+ regs, i + 1, newRegs, i, newRegs.length - i);
+ }
+ regs = newRegs;
+ }
+ }
+ }
+ return regs;
+ }
+
+ public synchronized void addServiceListener(ServiceListener l)
+ {
+ m_serviceListener = ServiceListenerMulticaster.add(m_serviceListener, l);
+ }
+
+ public synchronized void removeServiceListener(ServiceListener l)
+ {
+ m_serviceListener = ServiceListenerMulticaster.remove(m_serviceListener, l);
+ }
+
+ protected void fireServiceChanged(ServiceEvent event)
+ {
+ // Grab a copy of the listener list.
+ ServiceListener listener;
+ synchronized (this)
+ {
+ listener = m_serviceListener;
+ }
+ // If not null, then dispatch event.
+ if (listener != null)
+ {
+ listener.serviceChanged(event);
+ }
+ }
+
+
+ private static class ServiceListenerMulticaster implements ServiceListener
+ {
+ protected ServiceListener m_a = null, m_b = null;
+
+ protected ServiceListenerMulticaster(ServiceListener a, ServiceListener b)
+ {
+ m_a = a;
+ m_b = b;
+ }
+
+ public void serviceChanged(ServiceEvent e)
+ {
+ m_a.serviceChanged(e);
+ m_b.serviceChanged(e);
+ }
+
+ public static ServiceListener add(ServiceListener a, ServiceListener b)
+ {
+ if (a == null)
+ {
+ return b;
+ }
+ else if (b == null)
+ {
+ return a;
+ }
+ else
+ {
+ return new ServiceListenerMulticaster(a, b);
+ }
+ }
+
+ public static ServiceListener remove(ServiceListener a, ServiceListener b)
+ {
+ if ((a == null) || (a == b))
+ {
+ return null;
+ }
+ else if (a instanceof ServiceListenerMulticaster)
+ {
+ return add(
+ remove(((ServiceListenerMulticaster) a).m_a, b),
+ remove(((ServiceListenerMulticaster) a).m_b, b));
+ }
+ else
+ {
+ return a;
+ }
+ }
+ }
+
+ /**
+ * Utility method to retrieve the specified bundle's usage count for the
+ * specified service reference.
+ * @param bundle The bundle whose usage counts are being searched.
+ * @param ref The service reference to find in the bundle's usage counts.
+ * @return The associated usage count or null if not found.
+ **/
+ private UsageCount getUsageCount(Bundle bundle, ServiceReference ref)
+ {
+ UsageCount[] usages = (UsageCount[]) m_inUseMap.get(bundle);
+ for (int i = 0; (usages != null) && (i < usages.length); i++)
+ {
+ if (usages[i].m_ref.equals(ref))
+ {
+ return usages[i];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Utility method to update the specified bundle's usage count array to
+ * include the specified service. This method should only be called
+ * to add a usage count for a previously unreferenced service. If the
+ * service already has a usage count, then the existing usage count
+ * counter simply needs to be incremented.
+ * @param bundle The bundle acquiring the service.
+ * @param ref The service reference of the acquired service.
+ * @param svcObj The service object of the acquired service.
+ **/
+ private void addUsageCount(Bundle bundle, ServiceReference ref, Object svcObj)
+ {
+ UsageCount[] usages = (UsageCount[]) m_inUseMap.get(bundle);
+
+ UsageCount usage = new UsageCount();
+ usage.m_ref = ref;
+ usage.m_svcObj = svcObj;
+ usage.m_count++;
+
+ if (usages == null)
+ {
+ usages = new UsageCount[] { usage };
+ }
+ else
+ {
+ UsageCount[] newUsages = new UsageCount[usages.length + 1];
+ System.arraycopy(usages, 0, newUsages, 0, usages.length);
+ newUsages[usages.length] = usage;
+ usages = newUsages;
+ }
+
+ m_inUseMap.put(bundle, usages);
+ }
+
+ /**
+ * Utility method to flush the specified bundle's usage count for the
+ * specified service reference. This should be called to completely
+ * remove the associated usage count object for the specified service
+ * reference. If the goal is to simply decrement the usage, then get
+ * the usage count and decrement its counter. This method will also
+ * remove the specified bundle from the "in use" map if it has no more
+ * usage counts after removing the usage count for the specified service
+ * reference.
+ * @param bundle The bundle whose usage count should be removed.
+ * @param ref The service reference whose usage count should be removed.
+ **/
+ private void flushUsageCount(Bundle bundle, ServiceReference ref)
+ {
+ UsageCount[] usages = (UsageCount[]) m_inUseMap.get(bundle);
+ for (int i = 0; (usages != null) && (i < usages.length); i++)
+ {
+ if (usages[i].m_ref.equals(ref))
+ {
+ // If this is the only usage, then point to empty list.
+ if ((usages.length - 1) == 0)
+ {
+ usages = null;
+ }
+ // Otherwise, we need to do some array copying.
+ else
+ {
+ UsageCount[] newUsages = new UsageCount[usages.length - 1];
+ System.arraycopy(usages, 0, newUsages, 0, i);
+ if (i < newUsages.length)
+ {
+ System.arraycopy(
+ usages, i + 1, newUsages, i, newUsages.length - i);
+ }
+ usages = newUsages;
+ }
+ }
+ }
+
+ if (usages != null)
+ {
+ m_inUseMap.put(bundle, usages);
+ }
+ else
+ {
+ m_inUseMap.remove(bundle);
+ }
+ }
+
+ protected List<ListenerHook> getListenerHooks() {
+ return Collections.unmodifiableList(listenerHooks);
+ }
+
+ protected void removeHook(Object svcObj) {
+
+ if (svcObj instanceof ListenerHook) {
+ listenerHooks.remove(svcObj);
+ }
+ }
+
+ private static class UsageCount
+ {
+ public int m_count = 0;
+ public ServiceReference m_ref = null;
+ public Object m_svcObj = null;
+ }
+}
\ No newline at end of file
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import org.osgi.framework.*;
+
+class StartLevelActivator implements BundleActivator
+{
+ private Logger m_logger = null;
+ private Felix m_felix = null;
+ private StartLevelImpl m_startLevel = null;
+ private ServiceRegistration m_reg = null;
+
+ public StartLevelActivator(Logger logger, Felix felix)
+ {
+ m_logger = logger;
+ m_felix = felix;
+ }
+
+ public void start(BundleContext context) throws Exception
+ {
+ m_startLevel = new StartLevelImpl(m_logger, m_felix);
+ m_reg = context.registerService(
+ org.osgi.service.startlevel.StartLevel.class.getName(),
+ m_startLevel, null);
+ }
+
+ public void stop(BundleContext context) throws Exception
+ {
+ m_reg.unregister();
+ m_startLevel.stop();
+ }
+}
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,274 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osgi.framework.AdminPermission;
+import org.osgi.framework.Bundle;
+import org.osgi.service.startlevel.StartLevel;
+
+/**
+ * @author rickhall
+ *
+ * To change the template for this generated type comment go to
+ * Window>Preferences>Java>Code Generation>Code and Comments
+**/
+public class StartLevelImpl implements StartLevel, Runnable
+{
+ private static final int BUNDLE_IDX = 0;
+ private static final int STARTLEVEL_IDX = 1;
+
+ private Logger m_logger = null;
+ private Felix m_felix = null;
+ private List m_requestList = null;
+ private Bundle m_systemBundle = null;
+ private Thread m_thread = null;
+
+ public StartLevelImpl(Logger logger, Felix felix)
+ {
+ m_logger = logger;
+ m_felix = felix;
+ m_requestList = new ArrayList();
+ m_systemBundle = m_felix.getBundle(0);
+ // Start a thread to perform asynchronous package refreshes.
+ m_thread = new Thread(this, "FelixStartLevel");
+ m_thread.setDaemon(true);
+ m_thread.start();
+ }
+
+ /**
+ * Stops the FelixStartLevel thread on system shutdown. Shutting down the
+ * thread explicitly is required in the embedded case, where Felix may be
+ * stopped without the Java VM being stopped. In this case the
+ * FelixStartLevel thread must be stopped explicitly.
+ * <p>
+ * This method is called by the
+ * {@link StartLevelActivator#stop(BundleContext)} method.
+ */
+ void stop()
+ {
+ synchronized (m_requestList)
+ {
+ if (m_thread != null)
+ {
+ // Null thread variable to signal to the thread that
+ // we want it to exit.
+ m_thread = null;
+
+ // Wake up the thread, if it is currently in the wait() state
+ // for more work.
+ m_requestList.notifyAll();
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.startlevel.StartLevel#getStartLevel()
+ **/
+ public int getStartLevel()
+ {
+ return m_felix.getStartLevel();
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.startlevel.StartLevel#setStartLevel(int)
+ **/
+ public void setStartLevel(int startlevel)
+ {
+ Object sm = System.getSecurityManager();
+
+ if (sm != null)
+ {
+ ((SecurityManager) sm).checkPermission(
+ new AdminPermission(m_systemBundle, AdminPermission.STARTLEVEL));
+ }
+
+ if (startlevel <= 0)
+ {
+ throw new IllegalArgumentException(
+ "Start level must be greater than zero.");
+ }
+
+ synchronized (m_requestList)
+ {
+ m_requestList.add(new Integer(startlevel));
+ m_requestList.notifyAll();
+ }
+ }
+
+ /**
+ * This method is currently only called by the by the thread that calls
+ * the Felix.start() method and the shutdown thread when the
+ * framework is shutting down.
+ * @param startlevel
+ **/
+ /* package */ void setStartLevelAndWait(int startlevel)
+ {
+ Object request = new Integer(startlevel);
+ synchronized (request)
+ {
+ synchronized (m_requestList)
+ {
+ m_requestList.add(request);
+ m_requestList.notifyAll();
+ }
+
+ try
+ {
+ request.wait();
+ }
+ catch (InterruptedException ex)
+ {
+ // Log it and ignore since it won't cause much of an issue.
+ m_logger.log(
+ Logger.LOG_WARNING,
+ "Wait for start level change during shutdown interrupted.",
+ ex);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.startlevel.StartLevel#getBundleStartLevel(org.osgi.framework.Bundle)
+ **/
+ public int getBundleStartLevel(Bundle bundle)
+ {
+ return m_felix.getBundleStartLevel(bundle);
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.startlevel.StartLevel#setBundleStartLevel(org.osgi.framework.Bundle, int)
+ **/
+ public void setBundleStartLevel(Bundle bundle, int startlevel)
+ {
+ Object sm = System.getSecurityManager();
+
+ if (sm != null)
+ {
+ ((SecurityManager) sm).checkPermission(
+ new AdminPermission(bundle, AdminPermission.STARTLEVEL));
+ }
+
+ if (bundle.getBundleId() == 0)
+ {
+ throw new IllegalArgumentException(
+ "Cannot change system bundle start level.");
+ }
+ else if (startlevel <= 0)
+ {
+ throw new IllegalArgumentException(
+ "Start level must be greater than zero.");
+ }
+ synchronized (m_requestList)
+ {
+ m_requestList.add(new Object[] { bundle, new Integer(startlevel) });
+ m_requestList.notifyAll();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.startlevel.StartLevel#getInitialBundleStartLevel()
+ **/
+ public int getInitialBundleStartLevel()
+ {
+ return m_felix.getInitialBundleStartLevel();
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.startlevel.StartLevel#setInitialBundleStartLevel(int)
+ **/
+ public void setInitialBundleStartLevel(int startlevel)
+ {
+ Object sm = System.getSecurityManager();
+
+ if (sm != null)
+ {
+ ((SecurityManager) sm).checkPermission(
+ new AdminPermission(m_systemBundle, AdminPermission.STARTLEVEL));
+ }
+ m_felix.setInitialBundleStartLevel(startlevel);
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.startlevel.StartLevel#isBundlePersistentlyStarted(org.osgi.framework.Bundle)
+ **/
+ public boolean isBundlePersistentlyStarted(Bundle bundle)
+ {
+ return m_felix.isBundlePersistentlyStarted(bundle);
+ }
+
+ public void run()
+ {
+ Object request = null;
+
+ // This thread loops forever, thus it should
+ // be a daemon thread.
+ while (true)
+ {
+ synchronized (m_requestList)
+ {
+ // Wait for a request.
+ while (m_requestList.size() == 0)
+ {
+ // Terminate the thread if requested to do so (see stop()).
+ if (m_thread == null)
+ {
+ return;
+ }
+
+ try
+ {
+ m_requestList.wait();
+ }
+ catch (InterruptedException ex)
+ {
+ // Ignore.
+ }
+ }
+
+ // Get the requested start level.
+ request = m_requestList.remove(0);
+ }
+
+ // If the request object is an Integer, then the request
+ // is to set the framework start level. If the request is
+ // an Object array, then the request is to set the start
+ // level for a bundle.
+ if (request instanceof Integer)
+ {
+ // Set the new framework start level.
+ m_felix.setFrameworkStartLevel(((Integer) request).intValue());
+ }
+ else
+ {
+ Bundle bundle = (Bundle) ((Object[]) request)[BUNDLE_IDX];
+ int startlevel = ((Integer) ((Object[]) request)[STARTLEVEL_IDX]).intValue();
+ m_felix.setBundleStartLevel(bundle, startlevel);
+ }
+
+ // Notify any waiting thread that this request is done.
+ synchronized (request)
+ {
+ request.notifyAll();
+ }
+ }
+ }
+}
\ No newline at end of file
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/SystemBundleArchive.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/SystemBundleArchive.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/SystemBundleArchive.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/SystemBundleArchive.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import org.apache.felix.framework.cache.*;
+import java.io.File;
+import java.io.InputStream;
+import java.util.Map;
+
+import org.apache.felix.framework.util.FelixConstants;
+import org.apache.felix.framework.util.StringMap;
+import org.apache.felix.moduleloader.IContent;
+import org.apache.felix.moduleloader.IModule;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+
+/**
+ * <p>
+ * This class represents the bundle archive of the system bundle. It is a
+ * special case that is mostly just an empty implementation, since the system
+ * bundle is not a real archive.
+ * </p>
+**/
+public class SystemBundleArchive extends BundleArchive
+{
+ private BundleCache m_cache;
+ private Map m_headerMap = new StringMap(false);
+ private BundleRevision m_revision;
+
+ public SystemBundleArchive(BundleCache cache)
+ {
+ m_cache = cache;
+
+ try
+ {
+ m_revision = new BundleRevision(null, null, null) {
+
+ public Map getManifestHeader() throws Exception
+ {
+ return m_headerMap;
+ }
+
+ public IContent getContent() throws Exception
+ {
+ return null;
+ }
+
+ public void dispose() throws Exception
+ {
+ }
+ };
+ }
+ catch (Exception ex)
+ {
+ // This should never happen.
+ }
+ }
+
+ public long getId()
+ {
+ return 0;
+ }
+
+ public String getLocation() throws Exception
+ {
+ return FelixConstants.SYSTEM_BUNDLE_LOCATION;
+ }
+
+ public String getCurrentLocation() throws Exception
+ {
+ return null;
+ }
+
+ public void setCurrentLocation(String location) throws Exception
+ {
+ }
+
+ public int getPersistentState() throws Exception
+ {
+ return Bundle.ACTIVE;
+ }
+
+ public void setPersistentState(int state) throws Exception
+ {
+ }
+
+ public int getStartLevel() throws Exception
+ {
+ return FelixConstants.SYSTEMBUNDLE_DEFAULT_STARTLEVEL;
+ }
+
+ public void setStartLevel(int level) throws Exception
+ {
+ }
+
+ public File getDataFile(String fileName) throws Exception
+ {
+ return m_cache.getSystemBundleDataFile(fileName);
+ }
+
+ public BundleActivator getActivator(IModule module)
+ throws Exception
+ {
+ return null;
+ }
+
+ public void setActivator(Object obj) throws Exception
+ {
+ }
+
+ public int getRevisionCount()
+ {
+ return 1;
+ }
+
+ public BundleRevision getRevision(int i)
+ {
+ return m_revision;
+ }
+
+ public void revise(String location, InputStream is)
+ throws Exception
+ {
+ }
+
+ public void purge() throws Exception
+ {
+ }
+
+ public void dispose() throws Exception
+ {
+ }
+
+ public Map getManifestHeader(int revision)
+ {
+ return m_headerMap;
+ }
+
+ public void setManifestHeader(Map headerMap)
+ {
+ m_headerMap = headerMap;
+ }
+}
\ No newline at end of file
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/SystemBundleArchive.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/SystemBundleArchive.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlers.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlers.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlers.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlers.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,638 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import java.io.IOException;
+import java.net.*;
+import java.util.*;
+
+import org.apache.felix.framework.searchpolicy.ContentClassLoader;
+import org.apache.felix.framework.util.*;
+
+/**
+ * <p>
+ * This class is a singleton and implements the stream and content handler
+ * factories for all framework instances executing within the JVM. Any
+ * calls to retrieve stream or content handlers is routed through this class
+ * and it acts as a multiplexer for all framework instances. To achieve this,
+ * all framework instances register with this class when they are created so
+ * that it can maintain a centralized registry of instances.
+ * </p>
+ * <p>
+ * When this class receives a request for a stream or content handler, it
+ * always returns a proxy handler instead of only returning a proxy if a
+ * handler currently exists. This approach is used for three reasons:
+ * </p>
+ * <ol>
+ * <li>Potential caching behavior by the JVM of stream handlers does not give
+ * you a second chance to provide a handler.
+ * </li>
+ * <li>Due to the dynamic nature of OSGi services, handlers may appear at
+ * any time, so always creating a proxy makes sense.
+ * </li>
+ * <li>Since these handler factories service all framework instances,
+ * some instances may have handlers and others may not, so returning
+ * a proxy is the only answer that makes sense.
+ * </li>
+ * </ol>
+ * <p>
+ * It is possible to disable the URL Handlers service by setting the
+ * <tt>framework.service.urlhandlers</tt> configuration property to <tt>false</tt>.
+ * When multiple framework instances are in use, if no framework instances enable
+ * the URL Handlers service, then the singleton stream and content factories will
+ * never be set (i.e., <tt>URL.setURLStreamHandlerFactory()</tt> and
+ * <tt>URLConnection.setContentHandlerFactory()</tt>). However, if one instance
+ * enables URL Handlers service, then the factory methods will be invoked. In
+ * that case, framework instances that disable the URL Handlers service will
+ * simply not provide that services to their contained bundles, while framework
+ * instances with the service enabled will.
+ * </p>
+**/
+class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
+{
+ private static final String STREAM_HANDLER_PACKAGE_PROP = "java.protocol.handler.pkgs";
+ private static final String CONTENT_HANDLER_PACKAGE_PROP = "java.content.handler.pkgs";
+ private static final String DEFAULT_STREAM_HANDLER_PACKAGE = "sun.net.www.protocol|com.ibm.oti.net.www.protocol|gnu.java.net.protocol|wonka.net|com.acunia.wonka.net|org.apache.harmony.luni.internal.net.www.protocol|weblogic.utils|weblogic.net|javax.net.ssl|COM.newmonics.www.protocols";
+ 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";
+
+ private static final SecureAction m_secureAction = new SecureAction();
+
+ private static SecurityManagerEx m_sm = null;
+ private static URLHandlers m_handler = null;
+
+ // This maps classloaders of URLHandlers in other classloaders to lists of
+ // their frameworks.
+ private static Map m_classloaderToFrameworkLists = new HashMap();
+
+ // The list to hold all enabled frameworks registered with this handlers
+ private static final List m_frameworks = new ArrayList();
+
+ private static Map m_contentHandlerCache = null;
+ private static Map m_streamHandlerCache = null;
+ private static URLStreamHandlerFactory m_streamHandlerFactory;
+ private static ContentHandlerFactory m_contentHandlerFactory;
+
+ /**
+ * <p>
+ * Only one instance of this class is created per classloader
+ * and that one instance is registered as the stream and content handler
+ * factories for the JVM. Unless, we already register one from a different
+ * classloader. In this case we attach to this root.
+ * </p>
+ **/
+ private URLHandlers()
+ {
+ synchronized (URL.class)
+ {
+ try
+ {
+ URL.setURLStreamHandlerFactory(this);
+ m_streamHandlerFactory = this;
+ }
+ catch (Error err)
+ {
+ try
+ {
+ // there already is a factory set so try to swap it with ours.
+ m_streamHandlerFactory = (URLStreamHandlerFactory)
+ m_secureAction.swapStaticFieldIfNotClass(URL.class,
+ URLStreamHandlerFactory.class, URLHandlers.class, "streamHandlerLock");
+
+ if (m_streamHandlerFactory == null)
+ {
+ throw err;
+ }
+ if (!m_streamHandlerFactory.getClass().getName().equals(URLHandlers.class.getName()))
+ {
+ URL.setURLStreamHandlerFactory(this);
+ }
+ else if (URLHandlers.class != m_streamHandlerFactory.getClass())
+ {
+ try
+ {
+ m_secureAction.invoke(
+ m_secureAction.getDeclaredMethod(m_streamHandlerFactory.getClass(),
+ "registerFrameworkListsForContextSearch",
+ new Class[]{ClassLoader.class, List.class}),
+ m_streamHandlerFactory, new Object[]{ URLHandlers.class.getClassLoader(),
+ m_frameworks });
+ }
+ catch (Exception ex)
+ {
+ new RuntimeException(ex.getMessage());
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw err;
+ }
+ }
+
+ try
+ {
+ URLConnection.setContentHandlerFactory(this);
+ m_contentHandlerFactory = this;
+ }
+ catch (Error err)
+ {
+ // there already is a factory set so try to swap it with ours.
+ try
+ {
+ m_contentHandlerFactory = (ContentHandlerFactory)
+ m_secureAction.swapStaticFieldIfNotClass(
+ URLConnection.class, ContentHandlerFactory.class,
+ URLHandlers.class, null);
+ if (m_contentHandlerFactory == null)
+ {
+ throw err;
+ }
+ if (!m_contentHandlerFactory.getClass().getName().equals(
+ URLHandlers.class.getName()))
+ {
+ URLConnection.setContentHandlerFactory(this);
+ }
+ }
+ catch (Exception ex)
+ {
+ throw err;
+ }
+ }
+ }
+ // are we not the new root?
+ if ((m_streamHandlerFactory == this) || !URLHandlers.class.getName().equals(
+ m_streamHandlerFactory.getClass().getName()))
+ {
+ // we only need a security manager in the root
+ m_sm = new SecurityManagerEx();
+ }
+ }
+
+ static void registerFrameworkListsForContextSearch(ClassLoader index,
+ List frameworkLists)
+ {
+ synchronized (URL.class)
+ {
+ synchronized (m_classloaderToFrameworkLists)
+ {
+ m_classloaderToFrameworkLists.put(index, frameworkLists);
+ }
+ }
+ }
+
+ static void unregisterFrameworkListsForContextSearch(ClassLoader index)
+ {
+ synchronized (URL.class)
+ {
+ synchronized (m_classloaderToFrameworkLists)
+ {
+ m_classloaderToFrameworkLists.remove(index);
+ if (m_classloaderToFrameworkLists.isEmpty() )
+ {
+ synchronized (m_frameworks)
+ {
+ if (m_frameworks.isEmpty())
+ {
+ try
+ {
+ m_secureAction.swapStaticFieldIfNotClass(URL.class,
+ URLStreamHandlerFactory.class, null, "streamHandlerLock");
+ }
+ catch (Exception ex)
+ {
+ // TODO log this
+ ex.printStackTrace();
+ }
+
+ if (m_streamHandlerFactory.getClass() != URLHandlers.class)
+ {
+ URL.setURLStreamHandlerFactory(m_streamHandlerFactory);
+ }
+ try
+ {
+ m_secureAction.swapStaticFieldIfNotClass(
+ URLConnection.class, ContentHandlerFactory.class,
+ null, null);
+ }
+ catch (Exception ex)
+ {
+ // TODO log this
+ ex.printStackTrace();
+ }
+
+ if (m_contentHandlerFactory.getClass() != URLHandlers.class)
+ {
+ URLConnection.setContentHandlerFactory(m_contentHandlerFactory);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * <p>
+ * This is a method implementation for the <tt>URLStreamHandlerFactory</tt>
+ * interface. It simply creates a stream handler proxy object for the
+ * specified protocol. It caches the returned proxy; therefore, subsequent
+ * requests for the same protocol will receive the same handler proxy.
+ * </p>
+ * @param protocol the protocol for which a stream handler should be returned.
+ * @return a stream handler proxy for the specified protocol.
+ **/
+ public URLStreamHandler createURLStreamHandler(String protocol)
+ {
+ synchronized (this)
+ {
+ // See if there is a cached stream handler.
+ // IMPLEMENTATION NOTE: Caching is not strictly necessary for
+ // stream handlers since the Java runtime caches them. Caching is
+ // performed for code consistency between stream and content
+ // handlers and also because caching behavior may not be guaranteed
+ // across different JRE implementations.
+ URLStreamHandler handler = (URLStreamHandler)
+ ((m_streamHandlerCache != null) ? m_streamHandlerCache.get(protocol) : null);
+
+ if (handler != null)
+ {
+ return handler;
+ }
+ // If this is the framework's "bundle:" protocol, then return
+ // a handler for that immediately, since no one else can be
+ // allowed to deal with it.
+ if (protocol.equals(FelixConstants.BUNDLE_URL_PROTOCOL))
+ {
+ return addToStreamCache(protocol,
+ new URLHandlersBundleStreamHandler(m_secureAction));
+ }
+
+ // If this is the framework's "felix:" extension protocol, then
+ // return the ExtensionManager.m_extensionManager handler for
+ // that immediately - this is a workaround for certain jvms that
+ // do a toString() on the extension url we add to the global
+ // URLClassloader.
+ if (protocol.equals("felix"))
+ {
+ return addToStreamCache(protocol, new URLStreamHandler()
+ {
+ protected URLConnection openConnection(URL url)
+ throws IOException
+ {
+ Object framework = getFrameworkFromContext();
+
+ try
+ {
+ Object handler = m_secureAction.getDeclaredField(
+ framework.getClass(),"m_extensionManager", framework);
+
+ return (URLConnection) m_secureAction.invoke(
+ m_secureAction.getMethod(handler.getClass(),
+ "openConnection", new Class[]{URL.class}), handler,
+ new Object[]{url});
+ }
+ catch (Exception ex)
+ {
+ throw new IOException(ex.getMessage());
+ }
+ }
+ });
+ }
+
+ // If there was a custom factory then try to get the handler form it
+ if (m_streamHandlerFactory != this)
+ {
+ handler =
+ addToStreamCache(protocol, m_streamHandlerFactory.createURLStreamHandler(protocol));
+
+ if (handler != null)
+ {
+ return handler;
+ }
+ }
+ // Check for built-in handlers for the protocol.
+ String pkgs = m_secureAction.getSystemProperty(STREAM_HANDLER_PACKAGE_PROP, "");
+ pkgs = (pkgs.equals(""))
+ ? DEFAULT_STREAM_HANDLER_PACKAGE
+ : pkgs + "|" + DEFAULT_STREAM_HANDLER_PACKAGE;
+
+ // Iterate over built-in packages.
+ StringTokenizer pkgTok = new StringTokenizer(pkgs, "| ");
+ while (pkgTok.hasMoreTokens())
+ {
+ String pkg = pkgTok.nextToken().trim();
+ String className = pkg + "." + protocol + ".Handler";
+ try
+ {
+ // If a built-in handler is found then let the
+ // JRE handle it.
+ if (m_secureAction.forName(className) != null)
+ {
+ return null;
+ }
+ }
+ catch (Exception ex)
+ {
+ // This could be a class not found exception or an
+ // instantiation exception, not much we can do in either
+ // case other than ignore it.
+ }
+ }
+ // If built-in content handler, then create a proxy handler.
+ return addToStreamCache(protocol, new URLHandlersStreamHandlerProxy(protocol, m_secureAction));
+ }
+ }
+
+ /**
+ * <p>
+ * This is a method implementation for the <tt>ContentHandlerFactory</tt>
+ * interface. It simply creates a content handler proxy object for the
+ * specified mime type. It caches the returned proxy; therefore, subsequent
+ * requests for the same content type will receive the same handler proxy.
+ * </p>
+ * @param mimeType the mime type for which a content handler should be returned.
+ * @return a content handler proxy for the specified mime type.
+ **/
+ public ContentHandler createContentHandler(String mimeType)
+ {
+ synchronized (this)
+ {
+ // See if there is a cached stream handler.
+ // IMPLEMENTATION NOTE: Caching is not strictly necessary for
+ // stream handlers since the Java runtime caches them. Caching is
+ // performed for code consistency between stream and content
+ // handlers and also because caching behavior may not be guaranteed
+ // across different JRE implementations.
+ ContentHandler handler = (ContentHandler)
+ ((m_contentHandlerCache != null) ? m_contentHandlerCache.get(mimeType) : null);
+
+ if (handler != null)
+ {
+ return handler;
+ }
+ // If there was a custom factory then try to get the handler form it
+ if (m_contentHandlerFactory != this)
+ {
+ handler = addToContentCache(mimeType,
+ m_contentHandlerFactory.createContentHandler(mimeType));
+
+ if (handler != null)
+ {
+ return handler;
+ }
+ }
+
+ // Check for built-in handlers for the mime type.
+ String pkgs = m_secureAction.getSystemProperty(CONTENT_HANDLER_PACKAGE_PROP, "");
+ pkgs = (pkgs.equals(""))
+ ? DEFAULT_CONTENT_HANDLER_PACKAGE
+ : pkgs + "|" + DEFAULT_CONTENT_HANDLER_PACKAGE;
+
+ // Remove periods, slashes, and dashes from mime type.
+ String fixedType = mimeType.replace('.', '_').replace('/', '.').replace('-', '_');
+
+ // Iterate over built-in packages.
+ StringTokenizer pkgTok = new StringTokenizer(pkgs, "| ");
+ while (pkgTok.hasMoreTokens())
+ {
+ String pkg = pkgTok.nextToken().trim();
+ String className = pkg + "." + fixedType;
+ try
+ {
+ // If a built-in handler is found then let the
+ // JRE handle it.
+ if (m_secureAction.forName(className) != null)
+ {
+ return null;
+ }
+ }
+ catch (Exception ex)
+ {
+ // This could be a class not found exception or an
+ // instantiation exception, not much we can do in either
+ // case other than ignore it.
+ }
+ }
+
+ return addToContentCache(mimeType,
+ new URLHandlersContentHandlerProxy(mimeType, m_secureAction));
+ }
+ }
+
+ private ContentHandler addToContentCache(String mimeType, ContentHandler handler)
+ {
+ if (handler == null)
+ {
+ return null;
+ }
+ if (m_contentHandlerCache == null)
+ {
+ m_contentHandlerCache = new HashMap();
+ m_contentHandlerCache.put(mimeType, handler);
+ }
+ else
+ {
+ ContentHandler result = (ContentHandler)
+ m_contentHandlerCache.get(mimeType);
+
+ if (result == null)
+ {
+ m_contentHandlerCache.put(mimeType, handler);
+ }
+ else
+ {
+ handler = result;
+ }
+ }
+ return handler;
+ }
+
+ private URLStreamHandler addToStreamCache(String protocol, URLStreamHandler handler)
+ {
+ if (handler == null)
+ {
+ return null;
+ }
+
+ if (m_streamHandlerCache == null)
+ {
+ m_streamHandlerCache = new HashMap();
+ m_streamHandlerCache.put(protocol, handler);
+ }
+ else
+ {
+ URLStreamHandler result = (URLStreamHandler)
+ m_streamHandlerCache.get(protocol);
+
+ if (result == null)
+ {
+ m_streamHandlerCache.put(protocol, handler);
+ }
+ else
+ {
+ handler = result;
+ }
+ }
+ return handler;
+ }
+
+ /**
+ * <p>
+ * Static method that adds a framework instance to the centralized
+ * instance registry.
+ * </p>
+ * @param framework the framework instance to be added to the instance
+ * registry.
+ * @param enable a flag indicating whether or not the framework wants to
+ * enable the URL Handlers service.
+ **/
+ public static void registerFrameworkInstance(Object framework, boolean enable)
+ {
+ synchronized (m_frameworks)
+ {
+ // If the URL Handlers service is not going to be enabled,
+ // then return immediately.
+ if (enable)
+ {
+ // We need to create an instance if this is the first
+ // time this method is called, which will set the handler
+ // factories.
+ if (m_handler == null)
+ {
+ m_handler = new URLHandlers();
+ }
+ m_frameworks.add(framework);
+ }
+ }
+ }
+
+ /**
+ * <p>
+ * Static method that removes a framework instance from the centralized
+ * instance registry.
+ * </p>
+ * @param framework the framework instance to be removed from the instance
+ * registry.
+ **/
+ public static void unregisterFrameworkInstance(Object framework)
+ {
+ synchronized (m_frameworks)
+ {
+ if (m_frameworks.remove(framework) && m_frameworks.isEmpty())
+ {
+ if (m_handler.m_streamHandlerFactory.getClass().getName().equals(
+ URLHandlers.class.getName()))
+ {
+ try
+ {
+ m_secureAction.invoke(m_secureAction.getDeclaredMethod(
+ m_handler.m_streamHandlerFactory.getClass(),
+ "unregisterFrameworkListsForContextSearch",
+ new Class[]{ ClassLoader.class}),
+ m_handler.m_streamHandlerFactory,
+ new Object[] {URLHandlers.class.getClassLoader()});
+ }
+ catch (Exception e)
+ {
+ // TODO this should not happen
+ e.printStackTrace();
+ }
+ }
+ m_handler = null;
+ }
+ }
+ }
+
+ /**
+ * <p>
+ * This method returns the system bundle context for the caller.
+ * It determines the appropriate system bundle by retrieving the
+ * class call stack and find the first class that is loaded from
+ * a bundle. It then checks to see which of the registered framework
+ * instances owns the class and returns its system bundle context.
+ * </p>
+ * @return the system bundle context associated with the caller or
+ * <tt>null</tt> if no associated framework was found.
+ **/
+ public static Object getFrameworkFromContext()
+ {
+ // get the current class call stack.
+ Class[] stack = m_sm.getClassContext();
+ // Find the first class that is loaded from a bundle.
+ Class targetClass = null;
+ for (int i = 0; i < stack.length; i++)
+ {
+ if ((stack[i].getClassLoader() != null) &&
+ ContentClassLoader.class.getName().equals(
+ stack[i].getClassLoader().getClass().getName()))
+ {
+ targetClass = stack[i];
+ break;
+ }
+ }
+
+ // If we found a class loaded from a bundle, then iterate
+ // over the framework instances and see which framework owns
+ // the bundle that loaded the class.
+ if (targetClass != null)
+ {
+ synchronized (m_classloaderToFrameworkLists)
+ {
+ ClassLoader index = targetClass.getClassLoader().getClass().getClassLoader();
+
+ List frameworks = (List) m_classloaderToFrameworkLists.get(
+ index);
+
+ if ((frameworks == null) && (index == URLHandlers.class.getClassLoader()))
+ {
+ frameworks = m_frameworks;
+ }
+ if (frameworks != null)
+ {
+ synchronized (frameworks)
+ {
+ // Check the registry of framework instances
+ for (int i = 0; i < frameworks.size(); i++)
+ {
+ Object framework = frameworks.get(i);
+ try
+ {
+ if (m_secureAction.invoke(
+ m_secureAction.getDeclaredMethod(framework.getClass(),
+ "getBundle", new Class[]{Class.class}),
+ framework, new Object[]{targetClass}) != null)
+ {
+ return framework;
+ }
+ }
+ catch (Exception ex)
+ {
+ // This should not happen but if it does there is
+ // not much we can do other then ignore it.
+ // Maybe log this or something.
+ ex.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlers.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlers.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersActivator.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersActivator.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersActivator.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersActivator.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import java.util.Map;
+import org.apache.felix.framework.util.FelixConstants;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * <p>
+ * Simple activator class used by the system bundle to enable the
+ * URL Handlers service. The only purpose of this class is to call
+ * <tt>URLHandlers.registerInstance()</tt> when the framework is
+ * started and <tt>URLHandlers.unregisterInstance()</tt> when the
+ * framework is stopped.
+ *</p>
+**/
+class URLHandlersActivator implements BundleActivator
+{
+ private Map m_configMap = null;
+ private Felix m_framework = null;
+
+ public URLHandlersActivator(Map configMap, Felix framework)
+ {
+ m_configMap = configMap;
+ m_framework = framework;
+ }
+
+ //
+ // Bundle activator methods.
+ //
+
+ public void start(BundleContext context)
+ {
+ // Only register the framework with the URL Handlers service
+ // if the service is enabled.
+ boolean enable = (m_configMap.get(
+ FelixConstants.SERVICE_URLHANDLERS_PROP) == null)
+ ? true
+ : !m_configMap.get(FelixConstants.SERVICE_URLHANDLERS_PROP).equals("false");
+ URLHandlers.registerFrameworkInstance(m_framework, enable);
+ }
+
+ public void stop(BundleContext context)
+ {
+ URLHandlers.unregisterFrameworkInstance(m_framework);
+ }
+}
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersActivator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersActivator.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import java.io.IOException;
+import java.net.*;
+
+import org.apache.felix.framework.util.SecureAction;
+
+class URLHandlersBundleStreamHandler extends URLStreamHandler
+{
+ private final Felix m_framework;
+ private final SecureAction m_action;
+
+ public URLHandlersBundleStreamHandler(Felix framework)
+ {
+ m_framework = framework;
+ m_action = null;
+ }
+
+ public URLHandlersBundleStreamHandler(SecureAction action)
+ {
+ m_framework = null;
+ m_action = action;
+ }
+
+ protected synchronized URLConnection openConnection(URL url) throws IOException
+ {
+ if (m_framework != null)
+ {
+ return new URLHandlersBundleURLConnection(url, m_framework);
+ }
+
+ Object framework = URLHandlers.getFrameworkFromContext();
+
+ if (framework != null)
+ {
+ // TODO: optimize this to not use reflection if not needed
+ try
+ {
+ Class targetClass = framework.getClass().getClassLoader().loadClass(
+ URLHandlersBundleURLConnection.class.getName());
+
+ return (URLConnection) m_action.invoke(m_action.getConstructor(targetClass,
+ new Class[]{URL.class, framework.getClass()}),
+ new Object[]{url, framework});
+ }
+ catch (Exception ex)
+ {
+ throw new IOException(ex.getMessage());
+ }
+ }
+ throw new IOException("No framework context found");
+ }
+}
\ No newline at end of file
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.Permission;
+
+import org.apache.felix.framework.util.Util;
+import org.apache.felix.moduleloader.IModule;
+
+class URLHandlersBundleURLConnection extends URLConnection
+{
+ private Felix m_framework;
+ private IModule m_targetModule;
+ private int m_classPathIdx = -1;
+ private int m_contentLength;
+ private long m_contentTime;
+ private String m_contentType;
+ private InputStream m_is;
+
+ public URLHandlersBundleURLConnection(URL url)
+ {
+ super(url);
+ }
+
+ public URLHandlersBundleURLConnection(URL url, Felix framework)
+ throws IOException
+ {
+ super(url);
+ m_framework = framework;
+
+ // If we don't have a framework instance, try to find
+ // one from the call context.
+ if (m_framework == null)
+ {
+ m_framework = (Felix) URLHandlers.getFrameworkFromContext();
+ }
+
+ // If there is still no framework, then error.
+ if (m_framework == null)
+ {
+ throw new IOException("Unable to find framework for URL: " + url);
+ }
+ // Verify that the resource pointed to by the URL exists.
+ // The URL is constructed like this:
+ // bundle://<module-id>:<bundle-classpath-index>/<resource-path>
+ // Where <module-id> = <bundle-id>.<revision>
+ long bundleId = Util.getBundleIdFromModuleId(url.getHost());
+ FelixBundle bundle = (FelixBundle) m_framework.getBundle(bundleId);
+ if (bundle == null)
+ {
+ throw new IOException("No bundle associated with resource: " + url);
+ }
+ int revision = Util.getModuleRevisionFromModuleId(url.getHost());
+ IModule[] modules = bundle.getInfo().getModules();
+ if ((modules == null) || (revision < 0) || (revision >= modules.length))
+ {
+ throw new IOException("Resource does not exist: " + url);
+ }
+
+ // If the resource cannot be found at the current class path index,
+ // then search them all in order to see if it can be found. This is
+ // necessary since the user might create a resource URL from another
+ // resource URL and not realize they have the wrong class path entry.
+ // Of course, this approach won't work in cases where there are multiple
+ // resources with the same path, since it will always find the first
+ // one on the class path.
+ m_targetModule = modules[revision];
+ m_classPathIdx = url.getPort();
+ if (!modules[revision].getContentLoader().hasInputStream(m_classPathIdx, url.getPath()))
+ {
+ URL newurl = modules[revision].getContentLoader().getResource(url.getPath());
+ if (newurl == null)
+ {
+ throw new IOException("Resource does not exist: " + url);
+ }
+ m_classPathIdx = newurl.getPort();
+ }
+ }
+
+ public synchronized void connect() throws IOException
+ {
+ if (!connected)
+ {
+ if ((m_targetModule == null) || (m_classPathIdx < 0))
+ {
+ throw new IOException("Resource does not exist: " + url);
+ }
+ m_is = m_targetModule.getContentLoader()
+ .getInputStream(m_classPathIdx, url.getPath());
+ m_contentLength = (m_is == null) ? 0 : m_is.available();
+ m_contentTime = 0L;
+ m_contentType = URLConnection.guessContentTypeFromName(url.getFile());
+ connected = true;
+ }
+ }
+
+ public InputStream getInputStream()
+ throws IOException
+ {
+ connect();
+
+ return m_is;
+ }
+
+ public int getContentLength()
+ {
+ try
+ {
+ connect();
+ }
+ catch(IOException ex)
+ {
+ return -1;
+ }
+
+ return m_contentLength;
+ }
+
+ public long getLastModified()
+ {
+ try
+ {
+ connect();
+ }
+ catch(IOException ex)
+ {
+ return 0;
+ }
+
+ if (m_contentTime != -1L)
+ {
+ return m_contentTime;
+ }
+ else
+ {
+ return 0L;
+ }
+ }
+
+ public String getContentType()
+ {
+ try
+ {
+ connect();
+ }
+ catch (IOException ex)
+ {
+ return null;
+ }
+
+ return m_contentType;
+ }
+
+ public Permission getPermission()
+ {
+ // TODO: This should probably return a FilePermission
+ // to access the bundle JAR file, but we don't have the
+ // necessary information here to construct the absolute
+ // path of the JAR file...so it would take some
+ // re-arranging to get this to work.
+ return null;
+ }
+}
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
------------------------------------------------------------------------------
svn:keywords = Rev Date