Rollback after failed release.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1103918 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/pom.xml b/framework/pom.xml
index e2bc4b8..5cbdb1f 100644
--- a/framework/pom.xml
+++ b/framework/pom.xml
@@ -55,7 +55,7 @@
<Bundle-Name>Apache Felix Framework</Bundle-Name>
<Bundle-Description>OSGi R4 framework implementation.</Bundle-Description>
<Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
- <Export-Package>org.osgi.framework.*;-split-package:=merge-first,org.osgi.service.packageadmin,org.osgi.service.url,org.osgi.service.startlevel,org.osgi.util.tracker</Export-Package>
+ <Export-Package>org.osgi.framework;-split-package:=merge-first,org.osgi.framework.launch,org.osgi.framework.hooks.service,org.osgi.service.packageadmin,org.osgi.service.url,org.osgi.service.startlevel,org.osgi.util.tracker</Export-Package>
<Private-Package>org.apache.felix.framework.*</Private-Package>
<Import-Package>!*</Import-Package>
<Include-Resource>META-INF/LICENSE=LICENSE,META-INF/NOTICE=NOTICE,META-INF/DEPENDENCIES=DEPENDENCIES,{src/main/resources/}</Include-Resource>
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
index 7aa4bcf..e425c91 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
@@ -20,23 +20,10 @@
import java.io.File;
import java.io.InputStream;
-import java.util.Collection;
import java.util.Dictionary;
import org.apache.felix.framework.ext.FelixBundleContext;
-import org.osgi.framework.AdminPermission;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.BundleListener;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.FrameworkListener;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServicePermission;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.framework.*;
class BundleContextImpl implements FelixBundleContext
{
@@ -178,18 +165,6 @@
return m_felix.getBundle(id);
}
- public Bundle getBundle(String location)
- {
- checkValidity();
-
- // CONCURRENCY NOTE: This is a check-then-act situation,
- // but we ignore it since the time window is small and
- // the result is the same as if the calling thread had
- // won the race condition.
-
- return m_felix.getBundle(location);
- }
-
public Bundle[] getBundles()
{
checkValidity();
@@ -306,14 +281,14 @@
m_felix.removeFrameworkListener(m_bundle, l);
}
- public ServiceRegistration<?> registerService(
- String clazz, Object svcObj, Dictionary<String, ? > dict)
+ public ServiceRegistration registerService(
+ String clazz, Object svcObj, Dictionary dict)
{
return registerService(new String[] { clazz }, svcObj, dict);
}
- public ServiceRegistration<?> registerService(
- String[] clazzes, Object svcObj, Dictionary<String, ? > dict)
+ public ServiceRegistration registerService(
+ String[] clazzes, Object svcObj, Dictionary dict)
{
checkValidity();
@@ -338,13 +313,7 @@
return m_felix.registerService(m_bundle, clazzes, svcObj, dict);
}
- public <S> ServiceRegistration<S> registerService(
- Class<S> clazz, S svcObj, Dictionary<String, ? > dict)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public ServiceReference<?> getServiceReference(String clazz)
+ public ServiceReference getServiceReference(String clazz)
{
checkValidity();
@@ -365,11 +334,6 @@
return null;
}
- public <S> ServiceReference<S> getServiceReference(Class<S> clazz)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
private ServiceReference getBestServiceReference(ServiceReference[] refs)
{
if (refs == null)
@@ -396,8 +360,7 @@
return bestRef;
}
- public ServiceReference<?>[] getAllServiceReferences(String clazz, String filter)
- throws InvalidSyntaxException
+ public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException
{
checkValidity();
@@ -410,7 +373,7 @@
}
- public ServiceReference<?>[] getServiceReferences(String clazz, String filter)
+ public ServiceReference[] getServiceReferences(String clazz, String filter)
throws InvalidSyntaxException
{
checkValidity();
@@ -424,14 +387,7 @@
}
- public <S> Collection<ServiceReference<S>> getServiceReferences(
- Class<S> clazz, String filter)
- throws InvalidSyntaxException
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public <S> S getService(ServiceReference<S> ref)
+ public Object getService(ServiceReference ref)
{
checkValidity();
@@ -455,7 +411,7 @@
return m_felix.getService(m_bundle, ref);
}
- public boolean ungetService(ServiceReference<?> ref)
+ public boolean ungetService(ServiceReference ref)
{
checkValidity();
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
index 6609b42..1c6e6f5 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -18,7 +18,6 @@
*/
package org.apache.felix.framework;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@@ -26,20 +25,12 @@
import java.util.*;
import org.apache.felix.framework.cache.BundleArchive;
+import org.apache.felix.framework.resolver.Module;
import org.apache.felix.framework.ext.SecurityProvider;
+import org.apache.felix.framework.resolver.Wire;
import org.apache.felix.framework.util.StringMap;
import org.apache.felix.framework.util.Util;
-import org.osgi.framework.AdminPermission;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServicePermission;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Version;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.*;
class BundleImpl implements Bundle
{
@@ -47,7 +38,7 @@
private final Felix __m_felix;
private final BundleArchive m_archive;
- private final List<BundleRevision> m_revisions = new ArrayList<BundleRevision>(0);
+ private final List<Module> m_modules = new ArrayList<Module>(0);
private volatile int m_state;
private boolean m_useDeclaredActivationPolicy;
private BundleActivator m_activator = null;
@@ -87,8 +78,8 @@
m_activator = null;
m_context = null;
- BundleRevision revision = createRevision();
- addRevision(revision);
+ Module module = createModule();
+ addModule(module);
}
// This method exists because the system bundle extends BundleImpl
@@ -105,10 +96,9 @@
return m_archive;
}
-// Only called when the framework is stopping. Don't need to clean up dependencies.
synchronized void close()
{
- closeRevisions();
+ closeModules();
try
{
m_archive.close();
@@ -122,35 +112,45 @@
}
}
-// Called when install fails, when stopping framework with uninstalled bundles,
-// and when refreshing an uninstalled bundle. Only need to clear up dependencies
-// for last case.
synchronized void closeAndDelete() throws Exception
{
// Mark the bundle as stale, since it is being deleted.
m_stale = true;
- // Close all revisions.
- closeRevisions();
+ // Close all modules.
+ closeModules();
// Delete bundle archive, which will close revisions.
m_archive.closeAndDelete();
}
-// Called from BundleImpl.close(), BundleImpl.closeAndDelete(), and BundleImpl.refresh()
- private void closeRevisions()
+ private void closeModules()
{
- // Remove the bundle's associated revisions from the resolver state
+ // Remove the bundle's associated modules from the resolver state
// and close them.
- for (BundleRevision br : m_revisions)
+ for (Module m : m_modules)
{
- // Remove the revision from the resolver state.
- getFramework().getResolver().removeRevision(br);
+ // Remove the module from the resolver state.
+ getFramework().getResolver().removeModule(m);
- // Close the revision's content.
- ((BundleRevisionImpl) br).close();
+ // Set fragments to null, which will remove the module from all
+ // of its dependent fragment modules.
+ try
+ {
+ ((ModuleImpl) m).attachFragments(null);
+ }
+ catch (Exception ex)
+ {
+ getFramework().getLogger().log(
+ m.getBundle(), Logger.LOG_ERROR, "Error detaching fragments.", ex);
+ }
+ // Set wires to null, which will remove the module from all
+ // of its dependent modules.
+ ((ModuleImpl) m).setWires(null);
+
+ // Close the module's content.
+ ((ModuleImpl) m).close();
}
}
-// Called when refreshing a bundle. Must clean up dependencies beforehand.
synchronized void refresh() throws Exception
{
if (isExtension() && (getFramework().getState() != Bundle.STOPPING))
@@ -160,17 +160,17 @@
}
else
{
- // Dispose of the current revisions.
- closeRevisions();
+ // Dispose of the current modules.
+ closeModules();
// Now we will purge all old revisions, only keeping the newest one.
m_archive.purge();
// Lastly, we want to reset our bundle be reinitializing our state
- // and recreating a revision object for the newest revision.
- m_revisions.clear();
- final BundleRevision br = createRevision();
- addRevision(br);
+ // and recreating a module for the newest revision.
+ m_modules.clear();
+ final Module module = createModule();
+ addModule(module);
m_state = Bundle.INSTALLED;
m_stale = false;
m_cachedHeaders.clear();
@@ -323,8 +323,7 @@
// Spec says empty local returns raw headers.
if (locale.length() == 0)
{
- result = new StringMap(
- ((BundleRevisionImpl) getCurrentRevision()).getHeaders(), false);
+ result = new StringMap(getCurrentModule().getHeaders(), false);
}
// If we have no result, try to get it from the cached headers.
@@ -360,8 +359,7 @@
if (result == null)
{
// Get a modifiable copy of the raw headers.
- Map headers = new StringMap(
- ((BundleRevisionImpl) getCurrentRevision()).getHeaders(), false);
+ Map headers = new StringMap(getCurrentModule().getHeaders(), false);
// Assume for now that this will be the result.
result = headers;
@@ -390,22 +388,23 @@
basename = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
}
- // Create ordered list of revisions to search for localization
+ // Create ordered list of modules to search for localization
// property resources.
- List<BundleRevision> revisionList = createLocalizationRevisionList(
- (BundleRevisionImpl) getCurrentRevision());
+ List moduleList = createLocalizationModuleList(
+ (ModuleImpl) getCurrentModule());
// Create ordered list of files to load properties from
- List<String> resourceList = createLocalizationResourceList(basename, locale);
+ List resourceList = createLocalizationResourceList(basename, locale);
// Create a merged props file with all available props for this locale
boolean found = false;
Properties mergedProperties = new Properties();
- for (BundleRevision br : revisionList)
+ for (int modIdx = 0; modIdx < moduleList.size(); modIdx++)
{
- for (String res : resourceList)
+ for (Iterator it = resourceList.iterator(); it.hasNext(); )
{
- URL temp = ((BundleRevisionImpl) br).getEntry(res + ".properties");
+ URL temp = ((Module) moduleList.get(modIdx)).getEntry(
+ it.next() + ".properties");
if (temp != null)
{
found = true;
@@ -467,39 +466,36 @@
}
}
- private static List<BundleRevision> createLocalizationRevisionList(BundleRevision br)
+ private static List createLocalizationModuleList(ModuleImpl module)
{
- // If the revision is a fragment, then we actually need
+ // If the module is a fragment, then we actually need
// to search its host and associated fragments for its
// localization information. So, check to see if there
// are any hosts and then use the one with the highest
// version instead of the fragment itself. If there are
- // no hosts, but the revision is a fragment, then just
- // search the revision itself.
- if (Util.isFragment(br))
+ // no hosts, but the module is a fragment, then just
+ // search the module itself.
+ if (Util.isFragment(module))
{
- if (br.getWiring() != null)
+ List<Wire> hostWires = module.getWires();
+ if ((hostWires != null) && (hostWires.size() > 0))
{
- List<BundleWire> hostWires = br.getWiring().getRequiredWires(null);
- if ((hostWires != null) && (hostWires.size() > 0))
+ module = (ModuleImpl) hostWires.get(0).getExporter();
+ for (int hostIdx = 1; hostIdx < hostWires.size(); hostIdx++)
{
- br = hostWires.get(0).getProviderWiring().getRevision();
- for (int hostIdx = 1; hostIdx < hostWires.size(); hostIdx++)
+ if (module.getVersion().compareTo(
+ hostWires.get(hostIdx).getExporter().getVersion()) < 0)
{
- if (br.getVersion().compareTo(
- hostWires.get(hostIdx).getProviderWiring().getRevision().getVersion()) < 0)
- {
- br = hostWires.get(hostIdx).getProviderWiring().getRevision();
- }
+ module = (ModuleImpl) hostWires.get(hostIdx).getExporter();
}
}
}
}
- // Create a list of the revision and any attached fragment revisions.
- List<BundleRevision> result = new ArrayList<BundleRevision>();
- result.add(br);
- List<BundleRevision> fragments = ((BundleWiringImpl) br.getWiring()).getFragments();
+ // Create a list of the module and any attached fragments.
+ List result = new ArrayList();
+ result.add(module);
+ List<Module> fragments = module.getFragments();
if (fragments != null)
{
result.addAll(fragments);
@@ -507,9 +503,9 @@
return result;
}
- private static List<String> createLocalizationResourceList(String basename, String locale)
+ private static List createLocalizationResourceList(String basename, String locale)
{
- List<String> result = new ArrayList(4);
+ List result = new ArrayList(4);
StringTokenizer tokens;
StringBuffer tempLocale = new StringBuffer(basename);
@@ -857,9 +853,9 @@
synchronized boolean isExtension()
{
- for (int i = (m_revisions.size() - 1); i > -1; i--)
+ for (int i = (m_modules.size() - 1); i > -1; i--)
{
- if (((BundleRevisionImpl) m_revisions.get(i)).isExtension())
+ if (m_modules.get(i).isExtension())
{
return true;
}
@@ -869,12 +865,12 @@
public String getSymbolicName()
{
- return getCurrentRevision().getSymbolicName();
+ return getCurrentModule().getSymbolicName();
}
public Version getVersion()
{
- return getCurrentRevision().getVersion();
+ return getCurrentModule().getVersion();
}
public boolean hasPermission(Object obj)
@@ -999,24 +995,9 @@
getFramework().uninstallBundle(this);
}
- public <A> A adapt(Class<A> type)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public File getDataFile(String filename)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public int compareTo(Bundle t)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
public String toString()
{
- String sym = getCurrentRevision().getSymbolicName();
+ String sym = getCurrentModule().getSymbolicName();
if (sym != null)
{
return sym + " [" + getBundleId() +"]";
@@ -1026,11 +1007,11 @@
synchronized boolean isRemovalPending()
{
- return (m_state == Bundle.UNINSTALLED) || (m_revisions.size() > 1) || m_stale;
+ return (m_state == Bundle.UNINSTALLED) || (m_modules.size() > 1) || m_stale;
}
//
- // Revision management.
+ // Module management.
//
/**
@@ -1045,22 +1026,22 @@
* no limit on the potential number of bundle JAR file revisions.
* @return array of modules corresponding to the bundle JAR file revisions.
**/
- synchronized List<BundleRevision> getRevisions()
+ synchronized List<Module> getModules()
{
- return m_revisions;
+ return m_modules;
}
/**
* Determines if the specified module is associated with this bundle.
- * @param revision the module to determine if it is associate with this bundle.
+ * @param module the module to determine if it is associate with this bundle.
* @return <tt>true</tt> if the specified module is in the array of modules
* associated with this bundle, <tt>false</tt> otherwise.
**/
- synchronized boolean hasRevision(BundleRevision revision)
+ synchronized boolean hasModule(Module module)
{
- for (int i = 0; i < m_revisions.size(); i++)
+ for (int i = 0; i < m_modules.size(); i++)
{
- if (m_revisions.get(i) == revision)
+ if (m_modules.get(i) == module)
{
return true;
}
@@ -1073,9 +1054,34 @@
* in the module array.
* @return the newest module.
**/
- synchronized BundleRevision getCurrentRevision()
+ synchronized Module getCurrentModule()
{
- return m_revisions.get(m_revisions.size() - 1);
+ return m_modules.get(m_modules.size() - 1);
+ }
+
+ synchronized boolean isUsed()
+ {
+ boolean unresolved = true;
+ for (int i = 0; unresolved && (i < m_modules.size()); i++)
+ {
+ if (m_modules.get(i).isResolved())
+ {
+ unresolved = false;
+ }
+ }
+ boolean used = false;
+ for (int i = 0; !unresolved && !used && (i < m_modules.size()); i++)
+ {
+ List<Module> dependents = ((ModuleImpl) m_modules.get(i)).getDependents();
+ for (int j = 0; (dependents != null) && (j < dependents.size()) && !used; j++)
+ {
+ if (dependents.get(j) != m_modules.get(i))
+ {
+ used = true;
+ }
+ }
+ }
+ return used;
}
synchronized void revise(String location, InputStream is)
@@ -1085,8 +1091,8 @@
m_archive.revise(location, is);
try
{
- BundleRevision revision = createRevision();
- addRevision(revision);
+ Module module = createModule();
+ addModule(module);
}
catch (Exception ex)
{
@@ -1098,27 +1104,27 @@
synchronized boolean rollbackRevise() throws Exception
{
boolean isExtension = isExtension();
- BundleRevision br = m_revisions.remove(m_revisions.size() - 1);
+ Module m = m_modules.remove(m_modules.size() - 1);
if (!isExtension)
{
- // Since revising a bundle adds a revision to the global
+ // Since revising a module adds the module to the global
// state, we must remove it from the global state on rollback.
- getFramework().getResolver().removeRevision(br);
+ getFramework().getResolver().removeModule(m);
}
return m_archive.rollbackRevise();
}
// This method should be private, but is visible because the
- // system bundle needs to add its revision directly to the bundle,
- // since it doesn't have an archive from which it will be created,
- // which is the normal case.
- synchronized void addRevision(BundleRevision revision) throws Exception
+ // system bundle needs to add its module directly to the bundle,
+ // since it doesn't have an archive from which the module will
+ // be created, which is the normal case.
+ synchronized void addModule(Module module) throws Exception
{
- m_revisions.add(revision);
+ m_modules.add(module);
- // Set protection domain after adding the revision to the bundle,
- // since this requires that the bundle has a revision.
- ((BundleRevisionImpl) revision).setSecurityContext(
+ // Set protection domain after adding the module to the bundle,
+ // since this requires that the bundle has a module.
+ ((ModuleImpl) module).setSecurityContext(
new BundleProtectionDomain(getFramework(), this));
SecurityProvider sp = getFramework().getSecurityProvider();
@@ -1130,29 +1136,30 @@
}
catch (Exception ex)
{
- m_revisions.remove(m_revisions.size() - 1);
+ m_modules.remove(m_modules.size() - 1);
throw ex;
}
}
- // TODO: REFACTOR - consider nulling capabilities for extension bundles
- // so we don't need this check anymore.
+ // TODO: REFACTOR - consider moving ModuleImpl into the framework package
+ // so we can null module capabilities for extension bundles so we don't
+ // need this check anymore.
if (!isExtension())
{
- // Now that the revision is added to the bundle, we can update
- // the resolver's state to be aware of any new capabilities.
- getFramework().getResolver().addRevision(revision);
+ // Now that the module is added to the bundle, we can update
+ // the resolver's module state.
+ getFramework().getResolver().addModule(module);
}
}
- private BundleRevision createRevision() throws Exception
+ private Module createModule() throws Exception
{
- // Get and parse the manifest from the most recent revision and
- // create an associated revision object for it.
+ // Get and parse the manifest from the most recent revision to
+ // create an associated module for it.
Map headerMap = m_archive.getCurrentRevision().getManifestHeader();
- // Create the bundle revision instance.
- BundleRevisionImpl revision = new BundleRevisionImpl(
+ // Create the module instance.
+ ModuleImpl module = new ModuleImpl(
getFramework().getLogger(),
getFramework().getConfig(),
getFramework().getResolver(),
@@ -1166,11 +1173,11 @@
getFramework().getBootPackageWildcards());
// Verify that the bundle symbolic name + version is unique.
- if (revision.getManifestVersion().equals("2"))
+ if (module.getManifestVersion().equals("2"))
{
- Version bundleVersion = revision.getVersion();
+ Version bundleVersion = module.getVersion();
bundleVersion = (bundleVersion == null) ? Version.emptyVersion : bundleVersion;
- String symName = revision.getSymbolicName();
+ String symName = module.getSymbolicName();
Bundle[] bundles = getFramework().getBundles();
for (int i = 0; (bundles != null) && (i < bundles.length); i++)
@@ -1179,8 +1186,8 @@
if (id != getBundleId())
{
String sym = bundles[i].getSymbolicName();
- Version ver = ((BundleRevisionImpl)
- ((BundleImpl) bundles[i]).getCurrentRevision()).getVersion();
+ Version ver = ((ModuleImpl)
+ ((BundleImpl) bundles[i]).getCurrentModule()).getVersion();
if ((symName != null) && (sym != null) && symName.equals(sym) && bundleVersion.equals(ver))
{
throw new BundleException(
@@ -1191,17 +1198,16 @@
}
}
- return revision;
+ return module;
}
synchronized ProtectionDomain getProtectionDomain()
{
ProtectionDomain pd = null;
- for (int i = m_revisions.size() - 1; (i >= 0) && (pd == null); i--)
+ for (int i = m_modules.size() - 1; (i >= 0) && (pd == null); i--)
{
- pd = (ProtectionDomain)
- ((BundleRevisionImpl) m_revisions.get(i)).getSecurityContext();
+ pd = (ProtectionDomain) m_modules.get(i).getSecurityContext();
}
return pd;
@@ -1252,4 +1258,4 @@
{
return m_context;
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java b/framework/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java
index 8e424ee..2ba8f92 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java
@@ -25,7 +25,7 @@
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
-import org.osgi.framework.wiring.BundleRevision;
+import org.apache.felix.framework.resolver.Module;
public class BundleProtectionDomain extends ProtectionDomain
{
@@ -33,9 +33,9 @@
private final WeakReference m_bundle;
private final int m_hashCode;
private final String m_toString;
- private final WeakReference m_revision;
+ private final WeakReference m_module;
- // TODO: SECURITY - This should probably take a revision, not a bundle.
+ // TODO: SECURITY - This should probably take a module, not a bundle.
BundleProtectionDomain(Felix felix, BundleImpl bundle)
throws MalformedURLException
{
@@ -50,14 +50,14 @@
null);
m_felix = new WeakReference(felix);
m_bundle = new WeakReference(bundle);
- m_revision = new WeakReference(bundle.getCurrentRevision());
+ m_module = new WeakReference(bundle.getCurrentModule());
m_hashCode = bundle.hashCode();
m_toString = "[" + bundle + "]";
}
- BundleRevision getRevision()
+ Module getModule()
{
- return (BundleRevision) m_revision.get();
+ return (Module) m_module.get();
}
public boolean implies(Permission permission)
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleRevisionDependencies.java b/framework/src/main/java/org/apache/felix/framework/BundleRevisionDependencies.java
deleted file mode 100644
index 72c28ad..0000000
--- a/framework/src/main/java/org/apache/felix/framework/BundleRevisionDependencies.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * 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.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
-
-class BundleRevisionDependencies
-{
- private final Map<BundleRevision, Map<BundleCapability, Set<BundleRevision>>>
- m_dependentsMap = new HashMap<BundleRevision, Map<BundleCapability, Set<BundleRevision>>>();
-
- public synchronized void addDependent(BundleRevision provider, BundleCapability cap, BundleRevision requirer)
- {
- Map<BundleCapability, Set<BundleRevision>> caps = m_dependentsMap.get(provider);
- if (caps == null)
- {
- caps = new HashMap<BundleCapability, Set<BundleRevision>>();
- m_dependentsMap.put(provider, caps);
- }
- Set<BundleRevision> dependents = caps.get(cap);
- if (dependents == null)
- {
- dependents = new HashSet<BundleRevision>();
- caps.put(cap, dependents);
- }
- dependents.add(requirer);
- }
-
- public synchronized void removeDependent(
- BundleRevision provider, BundleCapability cap, BundleRevision requirer)
- {
- Map<BundleCapability, Set<BundleRevision>> caps = m_dependentsMap.get(provider);
- if (caps != null)
- {
- Set<BundleRevision> dependents = caps.get(cap);
- if (dependents == null)
- {
- dependents.remove(requirer);
- if (dependents.isEmpty())
- {
- caps.remove(cap);
- if (caps.isEmpty())
- {
- m_dependentsMap.remove(provider);
- }
- }
- }
- }
- }
-
- public synchronized void removeDependents(BundleRevision provider)
- {
- m_dependentsMap.remove(provider);
- }
-
- public synchronized Map<BundleCapability, Set<BundleRevision>>
- getDependents(BundleRevision provider)
- {
- return m_dependentsMap.get(provider);
- }
-
- public synchronized boolean hasDependents(BundleImpl bundle)
- {
- List<BundleRevision> revisions = bundle.getRevisions();
- for (BundleRevision revision : revisions)
- {
- if (m_dependentsMap.containsKey(revision))
- {
- return true;
- }
- }
- return false;
- }
-
- public synchronized Set<Bundle> getDependentBundles(BundleImpl bundle)
- {
- Set<Bundle> result = new HashSet<Bundle>();
-
- List<BundleRevision> revisions = bundle.getRevisions();
- for (BundleRevision revision : revisions)
- {
-// TODO: OSGi R4.3 - This is sort of a hack. We need to special case fragments,
-// since their dependents are their hosts.
- if (Util.isFragment(revision))
- {
- if (revision.getWiring() != null)
- {
- for (BundleWire wire : revision.getWiring().getRequiredWires(null))
- {
- result.add(wire.getProviderWiring().getBundle());
- }
- }
- }
- else
- {
- Map<BundleCapability, Set<BundleRevision>> caps =
- m_dependentsMap.get(revision);
- if (caps != null)
- {
- for (Entry<BundleCapability, Set<BundleRevision>> entry : caps.entrySet())
- {
- for (BundleRevision rev : entry.getValue())
- {
- result.add(rev.getBundle());
- }
- }
- }
- }
- }
-
- return result;
- }
-
- public synchronized Set<Bundle> getImportingBundles(
- BundleImpl exporter, BundleCapability exportCap)
- {
- // Create set for storing importing bundles.
- Set<Bundle> result = new HashSet<Bundle>();
-
- // Get exported package name.
- String pkgName = (String)
- exportCap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
-
- // Get all importers and requirers for all revisions of the bundle.
- // The spec says that require-bundle should be returned with importers.
- for (BundleRevision revision : exporter.getRevisions())
- {
- Map<BundleCapability, Set<BundleRevision>>
- caps = m_dependentsMap.get(revision);
- if (caps != null)
- {
- for (Entry<BundleCapability, Set<BundleRevision>> entry : caps.entrySet())
- {
- BundleCapability cap = entry.getKey();
- if ((cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
- && cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)
- .equals(pkgName))
- || cap.getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
- {
- for (BundleRevision dependent : entry.getValue())
- {
- result.add(dependent.getBundle());
- }
- }
- }
- }
- }
-
- // Return the results.
- return result;
- }
-
- public synchronized Set<Bundle> getRequiringBundles(BundleImpl bundle)
- {
- // Create set for storing requiring bundles.
- Set<Bundle> result = new HashSet<Bundle>();
-
- // Get all requirers for all revisions of the bundle.
- for (BundleRevision revision : bundle.getRevisions())
- {
- Map<BundleCapability, Set<BundleRevision>>
- caps = m_dependentsMap.get(revision);
- if (caps != null)
- {
- for (Entry<BundleCapability, Set<BundleRevision>> entry : caps.entrySet())
- {
- if (entry.getKey().getNamespace()
- .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
- {
- for (BundleRevision dependent : entry.getValue())
- {
- result.add(dependent.getBundle());
- }
- }
- }
- }
- }
-
- // Return the results.
- return result;
- }
-
- public synchronized void removeDependencies(BundleImpl bundle)
- {
- List<BundleRevision> revs = bundle.getRevisions();
- for (BundleRevision rev : revs)
- {
- BundleWiring wiring = rev.getWiring();
- if (wiring != null)
- {
- for (BundleWire wire : wiring.getRequiredWires(null))
- {
- // The provider wiring may already be null if the framework
- // is shutting down, so don't worry about updating dependencies
- // in that case.
- if (wire.getProviderWiring() != null)
- {
- Map<BundleCapability, Set<BundleRevision>> caps =
- m_dependentsMap.get(wire.getProviderWiring().getRevision());
- if (caps != null)
- {
- List<BundleCapability> gc = new ArrayList<BundleCapability>();
- for (Entry<BundleCapability, Set<BundleRevision>> entry
- : caps.entrySet())
- {
- entry.getValue().remove(rev);
- if (entry.getValue().isEmpty())
- {
- gc.add(entry.getKey());
- }
- }
- for (BundleCapability cap : gc)
- {
- caps.remove(cap);
- }
- if (caps.isEmpty())
- {
- m_dependentsMap.remove(wire.getProviderWiring().getRevision());
- }
- }
- }
- }
- }
- }
- }
-
- public synchronized void dump()
- {
-/*
-System.out.println("DEPENDENTS:");
- for (Entry<BundleRevision, Map<BundleCapability, Set<BundleRevision>>> entry
- : m_dependentsMap.entrySet())
- {
- System.out.println("Revision " + entry.getKey() + " DEPS:");
- for (Entry<BundleCapability, Set<BundleRevision>> capEntry : entry.getValue().entrySet())
- {
- System.out.println(" " + capEntry.getKey() + " <-- " + capEntry.getValue());
- }
- }
-*/
- }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
deleted file mode 100644
index a390407..0000000
--- a/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * 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.MalformedURLException;
-import java.net.URL;
-import java.net.URLStreamHandler;
-import java.security.ProtectionDomain;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-import org.apache.felix.framework.Felix.StatefulResolver;
-import org.apache.felix.framework.cache.Content;
-import org.apache.felix.framework.util.FelixConstants;
-import org.apache.felix.framework.util.SecureAction;
-import org.apache.felix.framework.util.manifestparser.ManifestParser;
-import org.apache.felix.framework.util.manifestparser.R4Library;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWiring;
-
-public class BundleRevisionImpl implements BundleRevision
-{
- public final static int EAGER_ACTIVATION = 0;
- public final static int LAZY_ACTIVATION = 1;
-
- private final Logger m_logger;
- private final Map m_configMap;
- private final StatefulResolver m_resolver;
- private final String m_id;
- private final Content m_content;
- private final Map m_headerMap;
- private final URLStreamHandler m_streamHandler;
-
- private final String m_manifestVersion;
- private final boolean m_isExtension;
- private final String m_symbolicName;
- private final Version m_version;
-
- private final List<BundleCapability> m_declaredCaps;
- private final List<BundleRequirement> m_declaredReqs;
- private final List<R4Library> m_declaredNativeLibs;
- private final int m_declaredActivationPolicy;
- private final List<String> m_activationIncludes;
- private final List<String> m_activationExcludes;
-
- private final Bundle m_bundle;
-
- private List<Content> m_contentPath;
- private boolean m_isActivationTriggered = false;
- private ProtectionDomain m_protectionDomain = null;
- private final static SecureAction m_secureAction = new SecureAction();
-
- // Bundle wiring when resolved.
- private volatile BundleWiringImpl m_wiring = null;
-
- // Boot delegation packages.
- private final String[] m_bootPkgs;
- private final boolean[] m_bootPkgWildcards;
-
- /**
- * This constructor is used by the extension manager, since it needs
- * a constructor that does not throw an exception.
- * @param logger
- * @param bundle
- * @param id
- * @param bootPkgs
- * @param bootPkgWildcards
- * @throws org.osgi.framework.BundleException
- */
- public BundleRevisionImpl(
- Logger logger, Map configMap, Bundle bundle, String id,
- String[] bootPkgs, boolean[] bootPkgWildcards)
- {
- m_logger = logger;
- m_configMap = configMap;
- m_resolver = null;
- m_bundle = bundle;
- m_id = id;
- m_headerMap = null;
- m_content = null;
- m_streamHandler = null;
- m_bootPkgs = bootPkgs;
- m_bootPkgWildcards = bootPkgWildcards;
- m_manifestVersion = null;
- m_symbolicName = null;
- m_isExtension = false;
- m_version = null;
- m_declaredCaps = Collections.EMPTY_LIST;
- m_declaredReqs = Collections.EMPTY_LIST;
- m_declaredNativeLibs = null;
- m_declaredActivationPolicy = EAGER_ACTIVATION;
- m_activationExcludes = null;
- m_activationIncludes = null;
- }
-
- BundleRevisionImpl(
- Logger logger, Map configMap, StatefulResolver resolver,
- Bundle bundle, String id, Map headerMap, Content content,
- URLStreamHandler streamHandler, String[] bootPkgs,
- boolean[] bootPkgWildcards)
- throws BundleException
- {
- m_logger = logger;
- m_configMap = configMap;
- m_resolver = resolver;
- m_bundle = bundle;
- m_id = id;
- m_headerMap = headerMap;
- m_content = content;
- m_streamHandler = streamHandler;
- m_bootPkgs = bootPkgs;
- m_bootPkgWildcards = bootPkgWildcards;
-
- ManifestParser mp = new ManifestParser(m_logger, m_configMap, this, m_headerMap);
-
- // Record some of the parsed metadata. Note, if this is an extension
- // bundle it's exports are removed, since they will be added to the
- // system bundle directly later on.
- m_manifestVersion = mp.getManifestVersion();
- m_version = mp.getBundleVersion();
- m_declaredCaps = mp.isExtension() ? null : mp.getCapabilities();
- m_declaredReqs = mp.getRequirements();
- m_declaredNativeLibs = mp.getLibraries();
- m_declaredActivationPolicy = mp.getActivationPolicy();
- m_activationExcludes = (mp.getActivationExcludeDirective() == null)
- ? null
- : ManifestParser.parseDelimitedString(mp.getActivationExcludeDirective(), ",");
- m_activationIncludes = (mp.getActivationIncludeDirective() == null)
- ? null
- : ManifestParser.parseDelimitedString(mp.getActivationIncludeDirective(), ",");
- m_symbolicName = mp.getSymbolicName();
- m_isExtension = mp.isExtension();
- }
-
- int getDeclaredActivationPolicy()
- {
- return m_declaredActivationPolicy;
- }
-
- List<String> getActivationExcludes()
- {
- return m_activationExcludes;
- }
-
- List<String> getActivationIncludes()
- {
- return m_activationIncludes;
- }
-
- URLStreamHandler getURLStreamHandler()
- {
- return m_streamHandler;
- }
-
- // TODO: OSGi R4.3 - Figure out how to handle this. Here we provide access
- // needed for BundleWiringImpl, but for implicit boot delegation property
- // we store it in BundleWiringImpl.
- String[] getBootDelegationPackages()
- {
- return m_bootPkgs;
- }
-
- // TODO: OSGi R4.3 - Figure out how to handle this. Here we provide access
- // needed for BundleWiringImpl, but for implicit boot delegation property
- // we store it in BundleWiringImpl.
- boolean[] getBootDelegationPackageWildcards()
- {
- return m_bootPkgWildcards;
- }
-
- //
- // BundleRevision methods.
- //
-
- public String getSymbolicName()
- {
- return m_symbolicName;
- }
-
- public Version getVersion()
- {
- return m_version;
- }
-
- public List<BundleCapability> getDeclaredCapabilities(String namespace)
- {
- List<BundleCapability> result = m_declaredCaps;
- if (namespace != null)
- {
- result = new ArrayList<BundleCapability>();
- for (BundleCapability cap : m_declaredCaps)
- {
- if (cap.getNamespace().equals(namespace))
- {
- result.add(cap);
- }
- }
- }
- return result;
- }
-
- public List<BundleRequirement> getDeclaredRequirements(String namespace)
- {
- List<BundleRequirement> result = m_declaredReqs;
- if (namespace != null)
- {
- result = new ArrayList<BundleRequirement>();
- for (BundleRequirement req : m_declaredReqs)
- {
- if (req.getNamespace().equals(namespace))
- {
- result.add(req);
- }
- }
- }
- return result;
- }
-
- public int getTypes()
- {
- if (getHeaders().containsKey(Constants.FRAGMENT_HOST))
- {
- return BundleRevision.TYPE_FRAGMENT;
- }
- return 0;
- }
-
- public BundleWiring getWiring()
- {
- return m_wiring;
- }
-
- public Bundle getBundle()
- {
- return m_bundle;
- }
-
- //
- // Implementating details.
- //
-
- public Map getHeaders()
- {
- return m_headerMap;
- }
-
- public boolean isExtension()
- {
- return m_isExtension;
- }
-
- public String getManifestVersion()
- {
- return m_manifestVersion;
- }
-
- public List<R4Library> getDeclaredNativeLibraries()
- {
- return m_declaredNativeLibs;
- }
-
- synchronized boolean isActivationTriggered()
- {
- return m_isActivationTriggered;
- }
-
- boolean isActivationTrigger(String pkgName)
- {
- if ((m_activationIncludes == null) && (m_activationExcludes == null))
- {
- return true;
- }
-
- // If there are no include filters then all classes are included
- // by default, otherwise try to find one match.
- boolean included = (m_activationIncludes == null);
- for (int i = 0;
- (!included) && (m_activationIncludes != null) && (i < m_activationIncludes.size());
- i++)
- {
- included = m_activationIncludes.get(i).equals(pkgName);
- }
-
- // If there are no exclude filters then no classes are excluded
- // by default, otherwise try to find one match.
- boolean excluded = false;
- for (int i = 0;
- (!excluded) && (m_activationExcludes != null) && (i < m_activationExcludes.size());
- i++)
- {
- excluded = m_activationExcludes.get(i).equals(pkgName);
- }
- return included && !excluded;
- }
-
- public String getId()
- {
- return m_id;
- }
-
- public synchronized void resolve(BundleWiringImpl wiring)
- {
- if (m_wiring != null)
- {
- m_wiring.dispose();
- m_wiring = null;
- }
-
- if (wiring != null)
- {
- // If the wiring has fragments, then close the old content path,
- // since it'll need to be recalculated to include fragments.
- if (wiring.getFragments() != null)
- {
- for (int i = 0; (m_contentPath != null) && (i < m_contentPath.size()); i++)
- {
- // Don't close this module's content, if it is on the content path.
- if (m_content != m_contentPath.get(i))
- {
- m_contentPath.get(i).close();
- }
- }
- m_contentPath = null;
- }
-
- m_wiring = wiring;
- }
- }
-
- public synchronized void setSecurityContext(Object securityContext)
- {
- m_protectionDomain = (ProtectionDomain) securityContext;
- }
-
- public synchronized Object getSecurityContext()
- {
- return m_protectionDomain;
- }
-
- // TODO: FRAGMENT RESOLVER - Technically, this is only necessary for fragments.
- // When we refactoring for the new R4.3 framework API, we'll have to see
- // if this is still necessary, since the new BundleWirings API will give
- // us another way to detect it.
- public boolean isRemovalPending()
- {
- return (m_bundle.getState() == Bundle.UNINSTALLED)
- || (this != ((BundleImpl) m_bundle).getCurrentRevision());
- }
-
- //
- // Content access methods.
- //
-
- public Content getContent()
- {
- return m_content;
- }
-
- synchronized List<Content> getContentPath()
- {
- if (m_contentPath == null)
- {
- try
- {
- m_contentPath = initializeContentPath();
- }
- catch (Exception ex)
- {
- m_logger.log(
- m_bundle, Logger.LOG_ERROR, "Unable to get module class path.", ex);
- }
- }
- return m_contentPath;
- }
-
- private List<Content> initializeContentPath() throws Exception
- {
- List<Content> contentList = new ArrayList();
- calculateContentPath(this, getContent(), contentList, true);
-
- List<BundleRevision> fragments = null;
- List<Content> fragmentContents = null;
- if (m_wiring != null)
- {
- fragments = m_wiring.getFragments();
- fragmentContents = m_wiring.getFragmentContents();
- }
- if (fragments != null)
- {
- for (int i = 0; i < fragments.size(); i++)
- {
- calculateContentPath(
- fragments.get(i), fragmentContents.get(i), contentList, false);
- }
- }
- return contentList;
- }
-
- private List calculateContentPath(
- BundleRevision revision, Content content, List<Content> contentList,
- boolean searchFragments)
- throws Exception
- {
- // Creating the content path entails examining the bundle's
- // class path to determine whether the bundle JAR file itself
- // is on the bundle's class path and then creating content
- // objects for everything on the class path.
-
- // Create a list to contain the content path for the specified content.
- List localContentList = new ArrayList();
-
- // Find class path meta-data.
- String classPath = (String) ((BundleRevisionImpl) revision)
- .getHeaders().get(FelixConstants.BUNDLE_CLASSPATH);
- // Parse the class path into strings.
- List<String> classPathStrings = ManifestParser.parseDelimitedString(
- classPath, FelixConstants.CLASS_PATH_SEPARATOR);
-
- if (classPathStrings == null)
- {
- classPathStrings = new ArrayList<String>(0);
- }
-
- // Create the bundles class path.
- for (int i = 0; i < classPathStrings.size(); i++)
- {
- // Remove any leading slash, since all bundle class path
- // entries are relative to the root of the bundle.
- classPathStrings.set(i, (classPathStrings.get(i).startsWith("/"))
- ? classPathStrings.get(i).substring(1)
- : classPathStrings.get(i));
-
- // Check for the bundle itself on the class path.
- if (classPathStrings.get(i).equals(FelixConstants.CLASS_PATH_DOT))
- {
- localContentList.add(content);
- }
- else
- {
- // Try to find the embedded class path entry in the current
- // content.
- Content embeddedContent = content.getEntryAsContent(classPathStrings.get(i));
- // If the embedded class path entry was not found, it might be
- // in one of the fragments if the current content is the bundle,
- // so try to search the fragments if necessary.
- List<Content> fragmentContents = (m_wiring == null)
- ? null : m_wiring.getFragmentContents();
- for (int fragIdx = 0;
- searchFragments && (embeddedContent == null)
- && (fragmentContents != null) && (fragIdx < fragmentContents.size());
- fragIdx++)
- {
- embeddedContent =
- fragmentContents.get(fragIdx).getEntryAsContent(classPathStrings.get(i));
- }
- // If we found the embedded content, then add it to the
- // class path content list.
- if (embeddedContent != null)
- {
- localContentList.add(embeddedContent);
- }
- else
- {
-// TODO: FRAMEWORK - Per the spec, this should fire a FrameworkEvent.INFO event;
-// need to create an "Eventer" class like "Logger" perhaps.
- m_logger.log(getBundle(), Logger.LOG_INFO,
- "Class path entry not found: "
- + classPathStrings.get(i));
- }
- }
- }
-
- // If there is nothing on the class path, then include
- // "." by default, as per the spec.
- if (localContentList.isEmpty())
- {
- localContentList.add(content);
- }
-
- // Now add the local contents to the global content list and return it.
- contentList.addAll(localContentList);
- return contentList;
- }
-
- URL getResourceLocal(String name)
- {
- URL url = null;
-
- // Remove leading slash, if present, but special case
- // "/" so that it returns a root URL...this isn't very
- // clean or meaninful, but the Spring guys want it.
- if (name.equals("/"))
- {
- // Just pick a class path index since it doesn't really matter.
- url = createURL(1, name);
- }
- else if (name.startsWith("/"))
- {
- name = name.substring(1);
- }
-
- // Check the module class path.
- List<Content> contentPath = getContentPath();
- for (int i = 0;
- (url == null) &&
- (i < contentPath.size()); i++)
- {
- if (contentPath.get(i).hasEntry(name))
- {
- url = createURL(i + 1, name);
- }
- }
-
- return url;
- }
-
- Enumeration getResourcesLocal(String name)
- {
- List l = new ArrayList();
-
- // Special case "/" so that it returns a root URLs for
- // each bundle class path entry...this isn't very
- // clean or meaningful, but the Spring guys want it.
- final List<Content> contentPath = getContentPath();
- if (name.equals("/"))
- {
- for (int i = 0; i < contentPath.size(); i++)
- {
- l.add(createURL(i + 1, name));
- }
- }
- else
- {
- // Remove leading slash, if present.
- if (name.startsWith("/"))
- {
- name = name.substring(1);
- }
-
- // Check the module class path.
- for (int i = 0; i < contentPath.size(); i++)
- {
- if (contentPath.get(i).hasEntry(name))
- {
- // Use the class path index + 1 for creating the path so
- // that we can differentiate between module content URLs
- // (where the path will start with 0) and module class
- // path URLs.
- l.add(createURL(i + 1, name));
- }
- }
- }
-
- return Collections.enumeration(l);
- }
-
- // TODO: API: Investigate how to handle this better, perhaps we need
- // multiple URL policies, one for content -- one for class path.
- public URL getEntry(String name)
- {
- URL url = null;
-
- // Check for the special case of "/", which represents
- // the root of the bundle according to the spec.
- if (name.equals("/"))
- {
- url = createURL(0, "/");
- }
-
- if (url == null)
- {
- // Remove leading slash, if present.
- if (name.startsWith("/"))
- {
- name = name.substring(1);
- }
-
- // Check the module content.
- if (getContent().hasEntry(name))
- {
- // Module content URLs start with 0, whereas module
- // class path URLs start with the index into the class
- // path + 1.
- url = createURL(0, name);
- }
- }
-
- return url;
- }
-
- public boolean hasInputStream(int index, String urlPath)
- {
- if (urlPath.startsWith("/"))
- {
- urlPath = urlPath.substring(1);
- }
- if (index == 0)
- {
- return m_content.hasEntry(urlPath);
- }
- return getContentPath().get(index - 1).hasEntry(urlPath);
- }
-
- public InputStream getInputStream(int index, String urlPath)
- throws IOException
- {
- if (urlPath.startsWith("/"))
- {
- urlPath = urlPath.substring(1);
- }
- if (index == 0)
- {
- return m_content.getEntryAsStream(urlPath);
- }
- return getContentPath().get(index - 1).getEntryAsStream(urlPath);
- }
-
- public URL getLocalURL(int index, String urlPath)
- {
- if (urlPath.startsWith("/"))
- {
- urlPath = urlPath.substring(1);
- }
- if (index == 0)
- {
- return m_content.getEntryAsURL(urlPath);
- }
- return getContentPath().get(index - 1).getEntryAsURL(urlPath);
- }
-
- private URL createURL(int port, String path)
- {
- // Add a slash if there is one already, otherwise
- // the is no slash separating the host from the file
- // in the resulting URL.
- if (!path.startsWith("/"))
- {
- path = "/" + path;
- }
-
- try
- {
- return m_secureAction.createURL(null,
- FelixConstants.BUNDLE_URL_PROTOCOL + "://" +
- m_id + ":" + port + path, m_streamHandler);
- }
- catch (MalformedURLException ex)
- {
- m_logger.log(m_bundle,
- Logger.LOG_ERROR,
- "Unable to create resource URL.",
- ex);
- }
- return null;
- }
-
- synchronized void close()
- {
- try
- {
- resolve(null);
- }
- catch (Exception ex)
- {
- m_logger.log(Logger.LOG_ERROR, "Error releasing revision: " + ex.getMessage(), ex);
- }
- m_content.close();
- for (int i = 0; (m_contentPath != null) && (i < m_contentPath.size()); i++)
- {
- m_contentPath.get(i).close();
- }
- m_contentPath = null;
- }
-
- @Override
- public String toString()
- {
- return m_id;
- }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/EntryFilterEnumeration.java b/framework/src/main/java/org/apache/felix/framework/EntryFilterEnumeration.java
index 5fee892..fcf8e39 100644
--- a/framework/src/main/java/org/apache/felix/framework/EntryFilterEnumeration.java
+++ b/framework/src/main/java/org/apache/felix/framework/EntryFilterEnumeration.java
@@ -22,14 +22,14 @@
import java.net.URL;
import java.util.*;
import org.apache.felix.framework.capabilityset.SimpleFilter;
-import org.osgi.framework.wiring.BundleRevision;
+import org.apache.felix.framework.resolver.Module;
class EntryFilterEnumeration implements Enumeration
{
private final BundleImpl m_bundle;
private final List<Enumeration> m_enumerations;
- private final List<BundleRevision> m_revisions;
- private int m_revisionIndex = 0;
+ private final List<Module> m_modules;
+ private int m_moduleIndex = 0;
private final String m_path;
private final List<String> m_filePattern;
private final boolean m_recurse;
@@ -42,25 +42,23 @@
String filePattern, boolean recurse, boolean isURLValues)
{
m_bundle = bundle;
- BundleRevision br = m_bundle.getCurrentRevision();
- if (includeFragments
- && (br.getWiring() != null)
- && (((BundleWiringImpl) br.getWiring()).getFragments() != null))
+ Module bundleModule = m_bundle.getCurrentModule();
+ List<Module> fragmentModules = ((ModuleImpl) bundleModule).getFragments();
+ if (includeFragments && (fragmentModules != null))
{
- m_revisions = new ArrayList(
- ((BundleWiringImpl) br.getWiring()).getFragments().size() + 1);
- m_revisions.addAll(((BundleWiringImpl) br.getWiring()).getFragments());
+ m_modules = new ArrayList(fragmentModules.size() + 1);
+ m_modules.addAll(fragmentModules);
}
else
{
- m_revisions = new ArrayList(1);
+ m_modules = new ArrayList(1);
}
- m_revisions.add(0, br);
- m_enumerations = new ArrayList(m_revisions.size());
- for (int i = 0; i < m_revisions.size(); i++)
+ m_modules.add(0, bundleModule);
+ m_enumerations = new ArrayList(m_modules.size());
+ for (int i = 0; i < m_modules.size(); i++)
{
- m_enumerations.add(((BundleRevisionImpl) m_revisions.get(i)).getContent() != null ?
- ((BundleRevisionImpl) m_revisions.get(i)).getContent().getEntries() : null);
+ m_enumerations.add(m_modules.get(i).getContent() != null ?
+ m_modules.get(i).getContent().getEntries() : null);
}
m_recurse = recurse;
m_isURLValues = isURLValues;
@@ -116,19 +114,19 @@
{
return;
}
- while ((m_revisionIndex < m_enumerations.size()) && m_nextEntries.isEmpty())
+ while ((m_moduleIndex < m_enumerations.size()) && m_nextEntries.isEmpty())
{
- while (m_enumerations.get(m_revisionIndex) != null
- && m_enumerations.get(m_revisionIndex).hasMoreElements()
+ while (m_enumerations.get(m_moduleIndex) != null
+ && m_enumerations.get(m_moduleIndex).hasMoreElements()
&& m_nextEntries.isEmpty())
{
// Get the current entry to determine if it should be filtered or not.
- String entryName = (String) m_enumerations.get(m_revisionIndex).nextElement();
+ String entryName = (String) m_enumerations.get(m_moduleIndex).nextElement();
// Check to see if the current entry is a descendent of the specified path.
if (!entryName.equals(m_path) && entryName.startsWith(m_path))
{
// Cached entry URL. If we are returning URLs, we use this
- // cached URL to avoid doing multiple URL lookups from a revision
+ // cached URL to avoid doing multiple URL lookups from a module
// when synthesizing directory URLs.
URL entryURL = null;
@@ -172,14 +170,11 @@
if (m_isURLValues)
{
entryURL = (entryURL == null)
- ? ((BundleRevisionImpl)
- m_revisions.get(m_revisionIndex))
- .getEntry(entryName)
+ ? m_modules.get(m_moduleIndex).getEntry(entryName)
: entryURL;
try
{
- m_nextEntries.add(
- new URL(entryURL, "/" + dir));
+ m_nextEntries.add(new URL(entryURL, "/" + dir));
}
catch (MalformedURLException ex)
{
@@ -214,8 +209,7 @@
if (m_isURLValues)
{
entryURL = (entryURL == null)
- ? ((BundleRevisionImpl)
- m_revisions.get(m_revisionIndex)).getEntry(entryName)
+ ? m_modules.get(m_moduleIndex).getEntry(entryName)
: entryURL;
m_nextEntries.add(entryURL);
}
@@ -229,7 +223,7 @@
}
if (m_nextEntries.isEmpty())
{
- m_revisionIndex++;
+ m_moduleIndex++;
}
}
}
@@ -244,4 +238,4 @@
: entryName.lastIndexOf('/', endIdx) + 1;
return entryName.substring(startIdx, endIdx);
}
-}
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java b/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
index 01fab7a..abb4fed 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
@@ -18,34 +18,33 @@
*/
package org.apache.felix.framework;
-import java.util.Set;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import java.util.List;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.resolver.Module;
import org.osgi.framework.Bundle;
import org.osgi.framework.Version;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
import org.osgi.service.packageadmin.ExportedPackage;
class ExportedPackageImpl implements ExportedPackage
{
private final Felix m_felix;
private final BundleImpl m_exportingBundle;
- private final BundleRevision m_exportingRevision;
- private final BundleCapability m_export;
+ private final Module m_exportingModule;
+ private final Capability m_export;
private final String m_pkgName;
private final Version m_version;
public ExportedPackageImpl(
- Felix felix, BundleImpl exporter, BundleRevision revision, BundleCapability export)
+ Felix felix, BundleImpl exporter, Module module, Capability export)
{
m_felix = felix;
m_exportingBundle = exporter;
- m_exportingRevision = revision;
+ m_exportingModule = module;
m_export = export;
- m_pkgName = (String) m_export.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
- m_version = (!m_export.getAttributes().containsKey(BundleCapabilityImpl.VERSION_ATTR))
+ m_pkgName = (String) m_export.getAttribute(Capability.PACKAGE_ATTR).getValue();
+ m_version = (m_export.getAttribute(Capability.VERSION_ATTR) == null)
? Version.emptyVersion
- : (Version) m_export.getAttributes().get(BundleCapabilityImpl.VERSION_ATTR);
+ : (Version) m_export.getAttribute(Capability.VERSION_ATTR).getValue();
}
public Bundle getExportingBundle()
@@ -65,8 +64,8 @@
{
return null;
}
- Set<Bundle> set = m_felix.getImportingBundles(m_exportingBundle, m_export);
- return set.toArray(new Bundle[set.size()]);
+ List<Bundle> list = m_felix.getImportingBundles(this);
+ return list.toArray(new Bundle[list.size()]);
}
public String getName()
diff --git a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
index b30a70b..46c83a3 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -27,26 +27,26 @@
import java.security.AccessControlException;
import java.security.AllPermission;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Set;
-import org.apache.felix.framework.Felix.StatefulResolver;
-import org.apache.felix.framework.resolver.ResolverWire;
+import org.apache.felix.framework.Felix.StatefulResolver;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.resolver.Module;
import org.apache.felix.framework.util.FelixConstants;
import org.apache.felix.framework.util.StringMap;
import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.util.manifestparser.CapabilityImpl;
import org.apache.felix.framework.util.manifestparser.ManifestParser;
-import org.apache.felix.framework.cache.Content;
-import org.apache.felix.framework.util.manifestparser.R4Library;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.resolver.Content;
import org.osgi.framework.AdminPermission;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
@@ -54,10 +54,6 @@
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
/**
* The ExtensionManager class is used in several ways.
@@ -120,10 +116,9 @@
}
private final Logger m_logger;
- private final Map m_configMap;
private final Map m_headerMap = new StringMap(false);
- private final BundleRevision m_systemBundleRevision;
- private List<BundleCapability> m_capabilities = null;
+ private final Module m_systemBundleModule;
+ private List<Capability> m_capabilities = null;
private Set m_exportNames = null;
private Object m_securityContext = null;
private final List m_extensions;
@@ -136,8 +131,7 @@
private ExtensionManager()
{
m_logger = null;
- m_configMap = null;
- m_systemBundleRevision = null;
+ m_systemBundleModule = null;
m_extensions = new ArrayList();
m_extensionsCache = new Bundle[0];
m_names = new HashSet();
@@ -155,20 +149,19 @@
* @param config the configuration to read properties from.
* @param systemBundleInfo the info to change if we need to add exports.
*/
- ExtensionManager(Logger logger, Map configMap, Felix felix)
+ ExtensionManager(Logger logger, Felix felix)
{
- m_logger = logger;
- m_configMap = configMap;
- m_systemBundleRevision = new ExtensionManagerRevision(felix);
+ m_systemBundleModule = new ExtensionManagerModule(felix);
m_extensions = null;
m_extensionsCache = null;
m_names = null;
m_sourceToExtensions = null;
+ m_logger = logger;
// TODO: FRAMEWORK - Not all of this stuff really belongs here, probably only exports.
// Populate system bundle header map.
m_headerMap.put(FelixConstants.BUNDLE_VERSION,
- m_configMap.get(FelixConstants.FELIX_VERSION_PROPERTY));
+ felix.getConfig().get(FelixConstants.FELIX_VERSION_PROPERTY));
m_headerMap.put(FelixConstants.BUNDLE_SYMBOLICNAME,
FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME);
m_headerMap.put(FelixConstants.BUNDLE_NAME, "System Bundle");
@@ -184,27 +177,27 @@
// We must construct the system bundle's export metadata.
// Get configuration property that specifies which class path
// packages should be exported by the system bundle.
- String syspkgs = (String) m_configMap.get(FelixConstants.FRAMEWORK_SYSTEMPACKAGES);
+ String syspkgs = (String) felix.getConfig().get(FelixConstants.FRAMEWORK_SYSTEMPACKAGES);
// If no system packages were specified, load our default value.
syspkgs = (syspkgs == null)
? Util.getDefaultProperty(logger, Constants.FRAMEWORK_SYSTEMPACKAGES)
: syspkgs;
syspkgs = (syspkgs == null) ? "" : syspkgs;
// If any extra packages are specified, then append them.
- String extra = (String) m_configMap.get(FelixConstants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
+ String extra = (String) felix.getConfig().get(FelixConstants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
syspkgs = (extra == null) ? syspkgs : syspkgs + "," + extra;
m_headerMap.put(FelixConstants.BUNDLE_MANIFESTVERSION, "2");
m_headerMap.put(FelixConstants.EXPORT_PACKAGE, syspkgs);
try
{
ManifestParser mp = new ManifestParser(
- m_logger, m_configMap, m_systemBundleRevision, m_headerMap);
- List<BundleCapability> caps = aliasSymbolicName(mp.getCapabilities());
+ m_logger, felix.getConfig(), m_systemBundleModule, m_headerMap);
+ List<Capability> caps = aliasSymbolicName(mp.getCapabilities());
setCapabilities(caps);
}
catch (Exception ex)
{
- m_capabilities = new ArrayList<BundleCapability>(0);
+ m_capabilities = new ArrayList<Capability>(0);
m_logger.log(
Logger.LOG_ERROR,
"Error parsing system bundle export statement: "
@@ -212,36 +205,36 @@
}
}
- private static List<BundleCapability> aliasSymbolicName(List<BundleCapability> caps)
+ private static List<Capability> aliasSymbolicName(List<Capability> caps)
{
if (caps == null)
{
- return new ArrayList<BundleCapability>(0);
+ return new ArrayList<Capability>(0);
}
- List<BundleCapability> aliasCaps = new ArrayList<BundleCapability>(caps);
+ List<Capability> aliasCaps = new ArrayList<Capability>(caps);
for (int capIdx = 0; capIdx < aliasCaps.size(); capIdx++)
{
// Get the attributes and search for bundle symbolic name.
- for (Entry<String, Object> entry : aliasCaps.get(capIdx).getAttributes().entrySet())
+ List<Attribute> attrs = aliasCaps.get(capIdx).getAttributes();
+ for (int i = 0; i < attrs.size(); i++)
{
// If there is a bundle symbolic name attribute, add the
// standard alias as a value.
- if (entry.getKey().equalsIgnoreCase(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
+ if (attrs.get(i).getName().equalsIgnoreCase(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
{
// Make a copy of the attribute array.
- Map<String, Object> aliasAttrs =
- new HashMap<String, Object>(aliasCaps.get(capIdx).getAttributes());
+ List<Attribute> aliasAttrs = new ArrayList<Attribute>(attrs);
// Add the aliased value.
- aliasAttrs.put(
+ aliasAttrs.set(i, new Attribute(
Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE,
new String[] {
- (String) entry.getValue(),
- Constants.SYSTEM_BUNDLE_SYMBOLICNAME});
+ (String) attrs.get(i).getValue(), Constants.SYSTEM_BUNDLE_SYMBOLICNAME},
+ false));
// Create the aliased capability to replace the old capability.
- aliasCaps.set(capIdx, new BundleCapabilityImpl(
- caps.get(capIdx).getRevision(),
+ aliasCaps.set(capIdx, new CapabilityImpl(
+ caps.get(capIdx).getModule(),
caps.get(capIdx).getNamespace(),
caps.get(capIdx).getDirectives(),
aliasAttrs));
@@ -254,9 +247,9 @@
return aliasCaps;
}
- public BundleRevision getRevision()
+ public Module getModule()
{
- return m_systemBundleRevision;
+ return m_systemBundleModule;
}
public synchronized Object getSecurityContext()
@@ -306,29 +299,27 @@
throw new SecurityException("Extension Bundles must have AllPermission");
}
- String directive = ManifestParser.parseExtensionBundleHeader((String)
- ((BundleRevisionImpl) bundle.getCurrentRevision())
- .getHeaders().get(Constants.FRAGMENT_HOST));
+ Directive dir = ManifestParser.parseExtensionBundleHeader((String)
+ bundle.getCurrentModule().getHeaders().get(Constants.FRAGMENT_HOST));
// We only support classpath extensions (not bootclasspath).
- if (!Constants.EXTENSION_FRAMEWORK.equals(directive))
+ if (!Constants.EXTENSION_FRAMEWORK.equals(dir.getValue()))
{
throw new BundleException("Unsupported Extension Bundle type: " +
- directive, new UnsupportedOperationException(
+ dir.getValue(), new UnsupportedOperationException(
"Unsupported Extension Bundle type!"));
}
try
{
// Merge the exported packages with the exported packages of the systembundle.
- List<BundleCapability> exports = null;
+ List<Capability> exports = null;
try
{
exports = ManifestParser.parseExportHeader(
- m_logger, m_systemBundleRevision,
- (String) ((BundleRevisionImpl) bundle.getCurrentRevision())
- .getHeaders().get(Constants.EXPORT_PACKAGE),
- m_systemBundleRevision.getSymbolicName(), m_systemBundleRevision.getVersion());
+ m_logger, m_systemBundleModule,
+ (String) bundle.getCurrentModule().getHeaders().get(Constants.EXPORT_PACKAGE),
+ m_systemBundleModule.getSymbolicName(), m_systemBundleModule.getVersion());
exports = aliasSymbolicName(exports);
}
catch (Exception ex)
@@ -337,8 +328,7 @@
bundle,
Logger.LOG_ERROR,
"Error parsing extension bundle export statement: "
- + ((BundleRevisionImpl) bundle.getCurrentRevision())
- .getHeaders().get(Constants.EXPORT_PACKAGE), ex);
+ + bundle.getCurrentModule().getHeaders().get(Constants.EXPORT_PACKAGE), ex);
return;
}
@@ -356,8 +346,7 @@
throw new UnsupportedOperationException(
"Unable to add extension bundle to FrameworkClassLoader - Maybe not an URLClassLoader?");
}
- List<BundleCapability> temp =
- new ArrayList<BundleCapability>(m_capabilities.size() + exports.size());
+ List<Capability> temp = new ArrayList<Capability>(m_capabilities.size() + exports.size());
temp.addAll(m_capabilities);
temp.addAll(exports);
setCapabilities(temp);
@@ -380,8 +369,8 @@
void startExtensionBundle(Felix felix, BundleImpl bundle)
{
String activatorClass = (String)
- ((BundleRevisionImpl) bundle.getCurrentRevision())
- .getHeaders().get(FelixConstants.FELIX_EXTENSION_ACTIVATOR);
+ bundle.getCurrentModule().getHeaders().get(
+ FelixConstants.FELIX_EXTENSION_ACTIVATOR);
if (activatorClass != null)
{
@@ -427,7 +416,7 @@
}
}
- private void setCapabilities(List<BundleCapability> capabilities)
+ private void setCapabilities(List<Capability> capabilities)
{
m_capabilities = capabilities;
m_headerMap.put(Constants.EXPORT_PACKAGE, convertCapabilitiesToHeaders(m_headerMap));
@@ -440,7 +429,7 @@
for (int i = 0; (m_capabilities != null) && (i < m_capabilities.size()); i++)
{
- if (m_capabilities.get(i).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ if (m_capabilities.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
// Add a comma separate if there is an existing package.
if (exportSB.length() > 0)
@@ -449,35 +438,31 @@
}
// Append exported package information.
- exportSB.append(m_capabilities.get(i)
- .getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
- for (Entry<String, String> entry
- : m_capabilities.get(i).getDirectives().entrySet())
+ exportSB.append(m_capabilities.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue());
+ for (Directive dir : m_capabilities.get(i).getDirectives())
{
exportSB.append("; ");
- exportSB.append(entry.getKey());
+ exportSB.append(dir.getName());
exportSB.append(":=\"");
- exportSB.append(entry.getValue());
+ exportSB.append(dir.getValue());
exportSB.append("\"");
}
- for (Entry<String, Object> entry
- : m_capabilities.get(i).getAttributes().entrySet())
+ for (Attribute attr : m_capabilities.get(i).getAttributes())
{
- if (!entry.getKey().equals(BundleCapabilityImpl.PACKAGE_ATTR)
- && !entry.getKey().equals(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)
- && !entry.getKey().equals(Constants.BUNDLE_VERSION_ATTRIBUTE))
+ if (!attr.getName().equals(Capability.PACKAGE_ATTR)
+ && !attr.getName().equals(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)
+ && !attr.getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE))
{
exportSB.append("; ");
- exportSB.append(entry.getKey());
+ exportSB.append(attr.getName());
exportSB.append("=\"");
- exportSB.append(entry.getValue());
+ exportSB.append(attr.getValue());
exportSB.append("\"");
}
}
// Remember exported packages.
- exportNames.add(m_capabilities.get(i)
- .getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
+ exportNames.add(m_capabilities.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue());
}
}
@@ -509,8 +494,7 @@
{
try
{
- result = ((BundleRevisionImpl) ((BundleImpl)
- extBundle).getCurrentRevision()).getResourceLocal(path);
+ result = ((ModuleImpl) ((BundleImpl) extBundle).getCurrentModule()).getResourceLocal(path);
}
catch (Exception ex)
{
@@ -640,20 +624,17 @@
// Utility methods.
//
- class ExtensionManagerRevision extends BundleRevisionImpl
+ class ExtensionManagerModule extends ModuleImpl
{
private final Version m_version;
- private volatile BundleWiring m_wiring;
-
- ExtensionManagerRevision(Felix felix)
+ ExtensionManagerModule(Felix felix)
{
- super(m_logger, m_configMap, felix, "0",
+ super(m_logger, felix.getConfig(), felix, "0",
felix.getBootPackages(), felix.getBootPackageWildcards());
m_version = new Version((String)
- m_configMap.get(FelixConstants.FELIX_VERSION_PROPERTY));
+ felix.getConfig().get(FelixConstants.FELIX_VERSION_PROPERTY));
}
- @Override
public Map getHeaders()
{
synchronized (ExtensionManager.this)
@@ -662,8 +643,7 @@
}
}
- @Override
- public List<BundleCapability> getDeclaredCapabilities(String namespace)
+ public List<Capability> getCapabilities()
{
synchronized (ExtensionManager.this)
{
@@ -671,102 +651,16 @@
}
}
- @Override
public String getSymbolicName()
{
return FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME;
}
- @Override
public Version getVersion()
{
return m_version;
}
- @Override
- public void close()
- {
- // Nothing needed here.
- }
-
- @Override
- public Content getContent()
- {
- return ExtensionManager.this;
- }
-
- @Override
- public URL getEntry(String name)
- {
- // There is no content for the system bundle, so return null.
- return null;
- }
-
- @Override
- public boolean hasInputStream(int index, String urlPath)
- {
- return (getClass().getClassLoader().getResource(urlPath) != null);
- }
-
- @Override
- public InputStream getInputStream(int index, String urlPath)
- {
- return getClass().getClassLoader().getResourceAsStream(urlPath);
- }
-
- @Override
- public URL getLocalURL(int index, String urlPath)
- {
- return getClass().getClassLoader().getResource(urlPath);
- }
-
- @Override
- public void resolve(BundleWiringImpl wire)
- {
- try
- {
- m_wiring = new ExtensionManagerWiring(
- m_logger, m_configMap, this);
- }
- catch (Exception ex)
- {
- // This should never happen.
- }
- }
-
- @Override
- public BundleWiring getWiring()
- {
- return m_wiring;
- }
- }
-
- class ExtensionManagerWiring extends BundleWiringImpl
- {
- ExtensionManagerWiring(
- Logger logger, Map configMap, BundleRevisionImpl revision)
- throws Exception
- {
- super(logger, configMap, null, revision,
- null, Collections.EMPTY_LIST, null, null);
- }
-
- @Override
- public List<BundleCapability> getCapabilities(String namespace)
- {
- synchronized (ExtensionManager.this)
- {
- return m_capabilities;
- }
- }
-
- @Override
- public List<R4Library> getNativeLibraries()
- {
- return Collections.EMPTY_LIST;
- }
-
- @Override
public Class getClassByDelegation(String name) throws ClassNotFoundException
{
Class clazz = null;
@@ -810,13 +704,11 @@
return clazz;
}
- @Override
public URL getResourceByDelegation(String name)
{
return getClass().getClassLoader().getResource(name);
}
- @Override
public Enumeration getResourcesByDelegation(String name)
{
try
@@ -829,10 +721,56 @@
}
}
- @Override
- public void dispose()
+ public Logger getLogger()
+ {
+ return m_logger;
+ }
+
+ public Map getConfig()
+ {
+ return null;
+ }
+
+ public StatefulResolver getResolver()
+ {
+ return null;
+ }
+
+ public void attachFragmentContents(Content[] fragmentContents)
+ throws Exception
+ {
+ throw new UnsupportedOperationException("Should not be used!");
+ }
+
+ public void close()
{
// Nothing needed here.
}
+
+ public Content getContent()
+ {
+ return ExtensionManager.this;
+ }
+
+ public URL getEntry(String name)
+ {
+ // There is no content for the system bundle, so return null.
+ return null;
+ }
+
+ public boolean hasInputStream(int index, String urlPath)
+ {
+ return (getClass().getClassLoader().getResource(urlPath) != null);
+ }
+
+ public InputStream getInputStream(int index, String urlPath)
+ {
+ return getClass().getClassLoader().getResourceAsStream(urlPath);
+ }
+
+ public URL getLocalURL(int index, String urlPath)
+ {
+ return getClass().getClassLoader().getResource(urlPath);
+ }
}
-}
\ No newline at end of file
+}
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 397b0ed..d5b8610 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -27,9 +27,14 @@
import org.apache.felix.framework.ServiceRegistry.ServiceRegistryCallbacks;
import org.apache.felix.framework.cache.BundleArchive;
import org.apache.felix.framework.cache.BundleCache;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Capability;
import org.apache.felix.framework.capabilityset.CapabilitySet;
+import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.resolver.Module;
+import org.apache.felix.framework.capabilityset.Requirement;
import org.apache.felix.framework.capabilityset.SimpleFilter;
-import org.apache.felix.framework.resolver.ResolverWire;
+import org.apache.felix.framework.resolver.Wire;
import org.apache.felix.framework.ext.SecurityProvider;
import org.apache.felix.framework.resolver.ResolveException;
import org.apache.felix.framework.resolver.Resolver;
@@ -44,9 +49,7 @@
import org.apache.felix.framework.util.ThreadGate;
import org.apache.felix.framework.util.Util;
import org.apache.felix.framework.util.manifestparser.R4LibraryClause;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.apache.felix.framework.wiring.BundleWireImpl;
+import org.apache.felix.framework.util.manifestparser.RequirementImpl;
import org.osgi.framework.AdminPermission;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
@@ -70,10 +73,6 @@
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.hooks.service.FindHook;
import org.osgi.framework.hooks.service.ListenerHook;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.startlevel.StartLevel;
@@ -126,9 +125,6 @@
// CONCURRENCY: Access guarded by the global lock for writes,
// but no lock for reads since it is copy on write.
private volatile List<BundleImpl> m_uninstalledBundles;
- // Object to keep track of dependencies among bundle revisions.
- private final BundleRevisionDependencies m_dependencies =
- new BundleRevisionDependencies();
// Framework's active start level.
private volatile int m_activeStartLevel = FelixConstants.FRAMEWORK_INACTIVE_STARTLEVEL;
@@ -371,12 +367,12 @@
m_logger,
(String) m_configMap.get(Constants.FRAMEWORK_EXECUTIONENVIRONMENT)));
- // Create the extension manager, which we will use as the
- // revision for the system bundle.
- m_extensionManager = new ExtensionManager(m_logger, m_configMap, this);
+ // Create the extension manager, which we will use as the module
+ // definition for creating the system bundle module.
+ m_extensionManager = new ExtensionManager(m_logger, this);
try
{
- addRevision(m_extensionManager.getRevision());
+ addModule(m_extensionManager.getModule());
}
catch (Exception ex)
{
@@ -644,7 +640,7 @@
// state to be set to RESOLVED.
try
{
- m_resolver.resolve(getCurrentRevision());
+ m_resolver.resolve(getCurrentModule());
}
catch (ResolveException ex)
{
@@ -876,27 +872,24 @@
AdminPermission.EXECUTE));
}
- if ((getState() & (Bundle.INSTALLED | Bundle.RESOLVED)) == 0)
- {
- // Spec says stop() on SystemBundle should return immediately and
- // shutdown framework on another thread.
- new Thread(new Runnable() {
- public void run()
+ // Spec says stop() on SystemBundle should return immediately and
+ // shutdown framework on another thread.
+ new Thread(new Runnable() {
+ public void run()
+ {
+ try
{
- try
- {
- stopBundle(Felix.this, true);
- }
- catch (BundleException ex)
- {
- m_logger.log(
- Logger.LOG_ERROR,
- "Exception trying to stop framework.",
- ex);
- }
+ stopBundle(Felix.this, true);
}
- }, "FelixShutdown").start();
- }
+ catch (BundleException ex)
+ {
+ m_logger.log(
+ Logger.LOG_ERROR,
+ "Exception trying to stop framework.",
+ ex);
+ }
+ }
+ }, "FelixShutdown").start();
}
public void stop(int options) throws BundleException
@@ -1479,25 +1472,11 @@
{
throw new IllegalStateException("The bundle is uninstalled.");
}
- else if (Util.isFragment(bundle.getCurrentRevision()))
+ else if (Util.isFragment(bundle.getCurrentModule()))
{
return null;
}
-// TODO: OSGi R4.3 - Currently, we try to resolve resource requests in
-// findClassOrResourceByDelegation() and fall back to local resource
-// searching if it fails. Perhaps we should attempt the resolve here
-// and do the local searching here. This means we could get rid of
-// resolve attempts in findClassOrResourceByDelegation().
- if (bundle.getCurrentRevision().getWiring() == null)
- {
- return ((BundleRevisionImpl) bundle.getCurrentRevision())
- .getResourceLocal(name);
- }
- else
- {
- return ((BundleWiringImpl) bundle.getCurrentRevision().getWiring())
- .getResourceByDelegation(name);
- }
+ return bundle.getCurrentModule().getResourceByDelegation(name);
}
/**
@@ -1509,25 +1488,11 @@
{
throw new IllegalStateException("The bundle is uninstalled.");
}
- else if (Util.isFragment(bundle.getCurrentRevision()))
+ else if (Util.isFragment(bundle.getCurrentModule()))
{
return null;
}
-// TODO: OSGi R4.3 - Currently, we try to resolve resource requests in
-// findResourcesByDelegation() and fall back to local resource
-// searching if it fails. Perhaps we should attempt the resolve here
-// and do the local searching here. This means we could get rid of
-// resolve attempts in findResourcesByDelegation().
- if (bundle.getCurrentRevision().getWiring() == null)
- {
- return ((BundleRevisionImpl) bundle.getCurrentRevision())
- .getResourcesLocal(name);
- }
- else
- {
- return ((BundleWiringImpl) bundle.getCurrentRevision().getWiring())
- .getResourcesByDelegation(name);
- }
+ return bundle.getCurrentModule().getResourcesByDelegation(name);
}
/**
@@ -1540,7 +1505,7 @@
throw new IllegalStateException("The bundle is uninstalled.");
}
- URL url = ((BundleRevisionImpl) bundle.getCurrentRevision()).getEntry(name);
+ URL url = bundle.getCurrentModule().getEntry(name);
// Some JAR files do not contain directory entries, so if
// the entry wasn't found and is a directory, scan the entries
@@ -1579,7 +1544,7 @@
throw new IllegalStateException("The bundle is uninstalled.");
}
- // Get the entry enumeration from the revision content and
+ // Get the entry enumeration from the module content and
// create a wrapper enumeration to filter it.
Enumeration enumeration =
new EntryFilterEnumeration(bundle, false, path, "*", false, false);
@@ -1597,7 +1562,7 @@
// Try to resolve the bundle per the spec.
resolveBundles(new Bundle[] { bundle });
- // Get the entry enumeration from the revision content and
+ // Get the entry enumeration from the module content and
// create a wrapper enumeration to filter it.
Enumeration enumeration =
new EntryFilterEnumeration(bundle, true, path, filePattern, recurse, true);
@@ -1668,7 +1633,7 @@
{
throw new IllegalStateException("Bundle is uninstalled");
}
- else if (Util.isFragment(bundle.getCurrentRevision()))
+ else if (Util.isFragment(bundle.getCurrentModule()))
{
throw new ClassNotFoundException("Fragments cannot load classes.");
}
@@ -1686,8 +1651,7 @@
throw new ClassNotFoundException(name, ex);
}
}
- return ((BundleWiringImpl)
- bundle.getCurrentRevision().getWiring()).getClassByDelegation(name);
+ return bundle.getCurrentModule().getClassByDelegation(name);
}
/**
@@ -1726,8 +1690,7 @@
// Record whether the bundle is using its declared activation policy.
boolean wasDeferred = bundle.isDeclaredActivationPolicyUsed()
- && (((BundleRevisionImpl) bundle.getCurrentRevision())
- .getDeclaredActivationPolicy() == BundleRevisionImpl.LAZY_ACTIVATION);
+ && (bundle.getCurrentModule().getDeclaredActivationPolicy() == Module.LAZY_ACTIVATION);
bundle.setDeclaredActivationPolicyUsed(
(options & Bundle.START_ACTIVATION_POLICY) != 0);
@@ -1743,7 +1706,7 @@
// As per the OSGi spec, fragment bundles can not be started and must
// throw a BundleException when there is an attempt to start one.
- if (Util.isFragment(bundle.getCurrentRevision()))
+ if (Util.isFragment(bundle.getCurrentModule()))
{
throw new BundleException("Fragment bundles can not be started.");
}
@@ -1848,9 +1811,8 @@
// If the bundle's activation policy is eager or activation has already
// been triggered, then activate the bundle immediately.
if (!bundle.isDeclaredActivationPolicyUsed()
- || (((BundleRevisionImpl) bundle.getCurrentRevision())
- .getDeclaredActivationPolicy() != BundleRevisionImpl.LAZY_ACTIVATION)
- || ((BundleRevisionImpl) bundle.getCurrentRevision()).isActivationTriggered())
+ || (bundle.getCurrentModule().getDeclaredActivationPolicy() != Module.LAZY_ACTIVATION)
+ || ((ModuleImpl) bundle.getCurrentModule()).isActivationTriggered())
{
// Record the event type for the final event and activate.
eventType = BundleEvent.STARTED;
@@ -2039,8 +2001,8 @@
// First get the update-URL from our header.
String updateLocation = (String)
- ((BundleRevisionImpl) bundle.getCurrentRevision())
- .getHeaders().get(Constants.BUNDLE_UPDATELOCATION);
+ bundle.getCurrentModule().getHeaders().get(
+ Constants.BUNDLE_UPDATELOCATION);
// If no update location specified, use original location.
if (updateLocation == null)
@@ -2057,7 +2019,7 @@
try
{
- // Revising the bundle creates a new revision, which modifies
+ // Revising the bundle creates a new module, which modifies
// the global state, so we need to acquire the global lock
// before revising.
boolean locked = acquireGlobalLock();
@@ -2089,7 +2051,7 @@
{
m_extensionManager.addExtensionBundle(this, bundle);
// TODO: REFACTOR - Perhaps we could move this into extension manager.
- m_resolver.addRevision(m_extensionManager.getRevision());
+ m_resolver.addModule(m_extensionManager.getModule());
// TODO: REFACTOR - Not clear why this is here. We should look at all of these steps more closely.
setBundleStateAndNotify(bundle, Bundle.RESOLVED);
}
@@ -2153,8 +2115,7 @@
{
try
{
- if (!m_dependencies.hasDependents(bundle)
- && !bundle.isExtension())
+ if (!bundle.isUsed() && !bundle.isExtension())
{
try
{
@@ -2176,9 +2137,9 @@
}
}
- // If the old state was active, but the new revision is a fragment,
+ // If the old state was active, but the new module is a fragment,
// then mark the persistent state to inactive.
- if ((oldState == Bundle.ACTIVE) && Util.isFragment(bundle.getCurrentRevision()))
+ if ((oldState == Bundle.ACTIVE) && Util.isFragment(bundle.getCurrentModule()))
{
bundle.setPersistentStateInactive();
m_logger.log(bundle, Logger.LOG_WARNING,
@@ -2271,7 +2232,7 @@
// As per the OSGi spec, fragment bundles can not be stopped and must
// throw a BundleException when there is an attempt to stop one.
- if (Util.isFragment(bundle.getCurrentRevision()))
+ if (Util.isFragment(bundle.getCurrentModule()))
{
throw new BundleException("Fragment bundles can not be stopped: " + bundle);
}
@@ -2283,8 +2244,7 @@
throw new IllegalStateException("Cannot stop an uninstalled bundle.");
case Bundle.STARTING:
if (bundle.isDeclaredActivationPolicyUsed()
- && ((BundleRevisionImpl) bundle.getCurrentRevision())
- .getDeclaredActivationPolicy() != BundleRevisionImpl.LAZY_ACTIVATION)
+ && bundle.getCurrentModule().getDeclaredActivationPolicy() != Module.LAZY_ACTIVATION)
{
throw new BundleException(
"Stopping a starting or stopping bundle is currently not supported.");
@@ -2494,7 +2454,7 @@
{
// If the bundle is not used by anyone, then garbage
// collect it now.
- if (!m_dependencies.hasDependents(bundle))
+ if (!bundle.isUsed())
{
try
{
@@ -2650,7 +2610,7 @@
else
{
m_extensionManager.addExtensionBundle(this, bundle);
- m_resolver.addRevision(m_extensionManager.getRevision());
+ m_resolver.addModule(m_extensionManager.getModule());
}
}
catch (Throwable ex)
@@ -3172,11 +3132,11 @@
}
- <S> S getService(Bundle bundle, ServiceReference<S> ref)
+ Object getService(Bundle bundle, ServiceReference ref)
{
try
{
- return (S) m_registry.getService(bundle, ref);
+ return m_registry.getService(bundle, ref);
}
catch (ServiceException ex)
{
@@ -3253,8 +3213,8 @@
Class sbClass = null;
try
{
- sbClass = ((BundleWiringImpl) m_extensionManager
- .getRevision().getWiring()).getClassByDelegation(clazz.getName());
+ sbClass = m_extensionManager
+ .getModule().getClassByDelegation(clazz.getName());
}
catch (ClassNotFoundException ex)
{
@@ -3289,19 +3249,16 @@
ExportedPackage[] getExportedPackages(String pkgName)
{
// First, get all exporters of the package.
- Map<String, Object> attrs = new HashMap<String, Object>(1);
- attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
- BundleRequirementImpl req = new BundleRequirementImpl(
- null,
- BundleCapabilityImpl.PACKAGE_NAMESPACE,
- Collections.EMPTY_MAP,
- attrs);
- Set<BundleCapability> exports = m_resolver.getCandidates(req, false);
+ List<Directive> dirs = new ArrayList<Directive>(0);
+ List<Attribute> attrs = new ArrayList<Attribute>(1);
+ attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
+ Requirement req = new RequirementImpl(null, Capability.PACKAGE_NAMESPACE, dirs, attrs);
+ Set<Capability> exports = m_resolver.getCandidates(req, false);
// We only want resolved capabilities.
- for (Iterator<BundleCapability> it = exports.iterator(); it.hasNext(); )
+ for (Iterator<Capability> it = exports.iterator(); it.hasNext(); )
{
- if (it.next().getRevision().getWiring() == null)
+ if (!it.next().getModule().isResolved())
{
it.remove();
}
@@ -3311,41 +3268,39 @@
{
List pkgs = new ArrayList();
- for (Iterator<BundleCapability> it = exports.iterator(); it.hasNext(); )
+ for (Iterator<Capability> it = exports.iterator(); it.hasNext(); )
{
- // Get the bundle associated with the current exporting revision.
- BundleImpl bundle = (BundleImpl) it.next().getRevision().getBundle();
+ // Get the bundle associated with the current exporting module.
+ BundleImpl bundle = (BundleImpl) it.next().getModule().getBundle();
// We need to find the version of the exported package, but this
// is tricky since there may be multiple versions of the package
// offered by a given bundle, since multiple revisions of the
// bundle JAR file may exist if the bundle was updated without
// refreshing the framework. In this case, each revision of the
- // bundle JAR file is represented as a revision ordered from
- // oldest to newest. We assume that the first revision found to
- // be exporting the package is the provider of the package,
- // which makes sense since it must have been resolved first.
- for (BundleRevision br : bundle.getRevisions())
+ // bundle JAR file is represented as a module in the BundleInfo
+ // module array, which is ordered from oldest to newest. We assume
+ // that the first module found to be exporting the package is the
+ // provider of the package, which makes sense since it must have
+ // been resolved first.
+ List<Module> modules = bundle.getModules();
+ for (int modIdx = 0; modIdx < modules.size(); modIdx++)
{
- List<BundleCapability> caps = (br.getWiring() == null)
- ? br.getDeclaredCapabilities(null)
- : br.getWiring().getCapabilities(null);
- for (BundleCapability cap : caps)
+ List<Capability> ec = modules.get(modIdx).getCapabilities();
+ for (int i = 0; (ec != null) && (i < ec.size()); i++)
{
- if (cap.getNamespace().equals(req.getNamespace())
- && CapabilitySet.matches(cap, req.getFilter()))
+ if (ec.get(i).getNamespace().equals(req.getNamespace())
+ && CapabilitySet.matches(ec.get(i), req.getFilter()))
{
pkgs.add(
new ExportedPackageImpl(
- this, bundle, br, cap));
+ this, bundle, modules.get(modIdx), ec.get(i)));
}
}
}
}
- return (pkgs.isEmpty())
- ? null
- : (ExportedPackage[]) pkgs.toArray(new ExportedPackage[pkgs.size()]);
+ return (pkgs.isEmpty()) ? null : (ExportedPackage[]) pkgs.toArray(new ExportedPackage[pkgs.size()]);
}
return null;
@@ -3423,45 +3378,46 @@
**/
private void getExportedPackages(BundleImpl bundle, List list)
{
- // Since a bundle may have many revisions associated with it,
- // one for each revision in the cache, search each revision
- // to get all exports.
- for (BundleRevision br : bundle.getRevisions())
+ // Since a bundle may have many modules associated with it,
+ // one for each revision in the cache, search each module
+ // for each revision to get all exports.
+ List<Module> modules = bundle.getModules();
+ for (int modIdx = 0; modIdx < modules.size(); modIdx++)
{
- List<BundleCapability> caps = (br.getWiring() == null)
- ? br.getDeclaredCapabilities(null)
- : br.getWiring().getCapabilities(null);
+ List<Capability> caps = modules.get(modIdx).getCapabilities();
if ((caps != null) && (caps.size() > 0))
{
- for (BundleCapability cap : caps)
+ for (int capIdx = 0; capIdx < caps.size(); capIdx++)
{
- // See if the target bundle's revisions is one of the
+ // See if the target bundle's module is one of the
// resolved exporters of the package.
- if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
String pkgName = (String)
- cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
- Map<String, Object> attrs = new HashMap<String, Object>(1);
- attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
- BundleRequirementImpl req =
- new BundleRequirementImpl(
- null,
- BundleCapabilityImpl.PACKAGE_NAMESPACE,
- Collections.EMPTY_MAP,
- attrs);
- Set<BundleCapability> providers = m_resolver.getCandidates(req, false);
-
- // Search through the current providers to find the target revision.
+ caps.get(capIdx).getAttribute(Capability.PACKAGE_ATTR).getValue();
+ List<Directive> dirs = new ArrayList<Directive>(0);
+ List<Attribute> attrs = new ArrayList<Attribute>(1);
+ attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
+ Requirement req =
+ new RequirementImpl(null, Capability.PACKAGE_NAMESPACE, dirs, attrs);
+ Set<Capability> exports = m_resolver.getCandidates(req, false);
// We only want resolved capabilities.
- if (providers != null)
+ for (Iterator<Capability> it = exports.iterator(); it.hasNext(); )
{
- for (BundleCapability provider : providers)
+ if (!it.next().getModule().isResolved())
{
- if ((provider.getRevision().getWiring() != null)
- && (provider == cap))
- {
- list.add(new ExportedPackageImpl(this, bundle, br, cap));
- }
+ it.remove();
+ }
+ }
+
+
+ // Search through the current providers to find the target module.
+ for (Capability cap : exports)
+ {
+ if (cap == caps.get(capIdx))
+ {
+ list.add(new ExportedPackageImpl(
+ this, bundle, modules.get(modIdx), caps.get(capIdx)));
}
}
}
@@ -3470,16 +3426,64 @@
}
}
- // Needed by ExportedPackageImpl.
- Set<Bundle> getImportingBundles(BundleImpl exporter, BundleCapability cap)
+ List<Bundle> getDependentBundles(BundleImpl exporter)
{
- return m_dependencies.getImportingBundles(exporter, cap);
+ // Create list for storing importing bundles.
+ List<Bundle> list = new ArrayList();
+
+ // Get all dependent modules from all exporter module revisions.
+ List<Module> modules = exporter.getModules();
+ for (int modIdx = 0; modIdx < modules.size(); modIdx++)
+ {
+ List<Module> dependents = ((ModuleImpl) modules.get(modIdx)).getDependents();
+ for (int depIdx = 0;
+ (dependents != null) && (depIdx < dependents.size());
+ depIdx++)
+ {
+ list.add(dependents.get(depIdx).getBundle());
+ }
+ }
+
+ return list;
}
- // Needed by RequiredBundleImpl.
- Set<Bundle> getRequiringBundles(BundleImpl bundle)
+ List<Bundle> getImportingBundles(ExportedPackage ep)
{
- return m_dependencies.getRequiringBundles(bundle);
+ // Create list for storing importing bundles.
+ List<Bundle> list = new ArrayList();
+
+ // Get exporting bundle information.
+ BundleImpl exporter = (BundleImpl) ep.getExportingBundle();
+
+ // Get all importers and requirers for all revisions of the bundle.
+ // The spec says that require-bundle should be returned with importers.
+ List<Module> expModules = exporter.getModules();
+ for (int expIdx = 0; (expModules != null) && (expIdx < expModules.size()); expIdx++)
+ {
+ // Include any importers that have wires to the specific
+ // exported package.
+ List<Module> dependents = ((ModuleImpl) expModules.get(expIdx)).getDependentImporters();
+ for (int depIdx = 0; (dependents != null) && (depIdx < dependents.size()); depIdx++)
+ {
+ List<Wire> wires = dependents.get(depIdx).getWires();
+ for (int wireIdx = 0; (wires != null) && (wireIdx < wires.size()); wireIdx++)
+ {
+ if ((wires.get(wireIdx).getExporter() == expModules.get(expIdx))
+ && (wires.get(wireIdx).hasPackage(ep.getName())))
+ {
+ list.add(dependents.get(depIdx).getBundle());
+ }
+ }
+ }
+ dependents = ((ModuleImpl) expModules.get(expIdx)).getDependentRequirers();
+ for (int depIdx = 0; (dependents != null) && (depIdx < dependents.size()); depIdx++)
+ {
+ list.add(dependents.get(depIdx).getBundle());
+ }
+ }
+
+ // Return the results.
+ return list;
}
boolean resolveBundles(Bundle[] targets)
@@ -3550,13 +3554,13 @@
{
try
{
- m_resolver.resolve(bundle.getCurrentRevision());
+ m_resolver.resolve(bundle.getCurrentModule());
}
catch (ResolveException ex)
{
- if (ex.getRevision() != null)
+ if (ex.getModule() != null)
{
- Bundle b = ex.getRevision().getBundle();
+ Bundle b = ex.getModule().getBundle();
throw new BundleException(
"Unresolved constraint in bundle "
+ b + ": " + ex.getMessage());
@@ -3623,18 +3627,18 @@
{
// Create map of bundles that import the packages
// from the target bundles.
- Set<Bundle> set = new HashSet<Bundle>();
+ Map map = new HashMap();
for (int targetIdx = 0; targetIdx < newTargets.length; targetIdx++)
{
// Add the current target bundle to the map of
// bundles to be refreshed.
BundleImpl target = (BundleImpl) newTargets[targetIdx];
- set.add(target);
+ map.put(target, target);
// Add all importing bundles to map.
- populateDependentGraph(target, set);
+ populateDependentGraph(target, map);
}
- bundles = (BundleImpl[]) set.toArray(new BundleImpl[set.size()]);
+ bundles = (BundleImpl[]) map.values().toArray(new BundleImpl[map.size()]);
}
// Now refresh each bundle.
@@ -3728,23 +3732,23 @@
fireFrameworkEvent(FrameworkEvent.PACKAGES_REFRESHED, this, null);
}
- private void populateDependentGraph(BundleImpl exporter, Set<Bundle> set)
+ private void populateDependentGraph(BundleImpl exporter, Map map)
{
// Get all dependent bundles of this bundle.
- Set<Bundle> dependents = m_dependencies.getDependentBundles(exporter);
+ List<Bundle> dependents = getDependentBundles(exporter);
- if (dependents != null)
+ for (int depIdx = 0;
+ (dependents != null) && (depIdx < dependents.size());
+ depIdx++)
{
- for (Bundle b : dependents)
+ // Avoid cycles if the bundle is already in map.
+ if (!map.containsKey(dependents.get(depIdx)))
{
- // Avoid cycles if the bundle is already in set.
- if (!set.contains(b))
- {
- // Add each dependent bundle to set.
- set.add(b);
- // Now recurse into each bundle to get its dependents.
- populateDependentGraph((BundleImpl) b, set);
- }
+ // Add each importing bundle to map.
+ map.put(dependents.get(depIdx), dependents.get(depIdx));
+ // Now recurse into each bundle to get its importers.
+ populateDependentGraph(
+ (BundleImpl) dependents.get(depIdx), map);
}
}
}
@@ -3792,7 +3796,7 @@
// Get the activator class from the header map.
BundleActivator activator = null;
- Map headerMap = ((BundleRevisionImpl) impl.getCurrentRevision()).getHeaders();
+ Map headerMap = impl.getCurrentModule().getHeaders();
String className = (String) headerMap.get(Constants.BUNDLE_ACTIVATOR);
// Try to instantiate activator class if present.
if (className != null)
@@ -3801,8 +3805,7 @@
Class clazz;
try
{
- clazz = ((BundleWiringImpl)
- impl.getCurrentRevision().getWiring()).getClassByDelegation(className);
+ clazz = impl.getCurrentModule().getClassByDelegation(className);
}
catch (ClassNotFoundException ex)
{
@@ -3831,8 +3834,6 @@
{
// See if we need to fire UNRESOLVED event.
boolean fire = (bundle.getState() != Bundle.INSTALLED);
- // Remove dependencies.
- m_dependencies.removeDependencies(bundle);
// Reset the bundle object.
((BundleImpl) bundle).refresh();
// Fire UNRESOLVED event if necessary
@@ -4102,44 +4103,42 @@
m_resolverState = resolverState;
}
- void addRevision(BundleRevision br)
+ void addModule(Module m)
{
- m_resolverState.addRevision(br);
+ m_resolverState.addModule(m);
}
- void removeRevision(BundleRevision br)
+ void removeModule(Module m)
{
- m_resolverState.removeRevision(br);
+ m_resolverState.removeModule(m);
}
- Set<BundleCapability> getCandidates(BundleRequirementImpl req, boolean obeyMandatory)
+ Set<Capability> getCandidates(Requirement req, boolean obeyMandatory)
{
return m_resolverState.getCandidates(req, obeyMandatory);
}
- void resolve(BundleRevision rootRevision) throws ResolveException
+ void resolve(Module rootModule) throws ResolveException
{
// Although there is a race condition to check the bundle state
// then lock it, we do this because we don't want to acquire the
- // a lock just to check if the revision is resolved, which itself
- // is a safe read. If the revision isn't resolved, we end up double
+ // a lock just to check if the module is resolved, which itself
+ // is a safe read. If the module isn't resolved, we end up double
// check the resolved status later.
-// TODO: OSGi R4.3 - This locking strategy here depends on how we ultimately
-// implement getWiring(), which may change.
- if (rootRevision.getWiring() == null)
+ if (!rootModule.isResolved())
{
// Acquire global lock.
boolean locked = acquireGlobalLock();
if (!locked)
{
throw new ResolveException(
- "Unable to acquire global lock for resolve.", rootRevision, null);
+ "Unable to acquire global lock for resolve.", rootModule, null);
}
- Map<BundleRevision, List<ResolverWire>> wireMap = null;
+ Map<Module, List<Wire>> wireMap = null;
try
{
- BundleImpl bundle = (BundleImpl) rootRevision.getBundle();
+ BundleImpl bundle = (BundleImpl) rootModule.getBundle();
// Extensions are resolved differently.
if (bundle.isExtension())
@@ -4147,12 +4146,12 @@
return;
}
- // Resolve the revision.
+ // Resolve the module.
wireMap = m_resolver.resolve(
- m_resolverState, rootRevision, m_resolverState.getFragments());
+ m_resolverState, rootModule, m_resolverState.getFragments());
- // Mark all revisions as resolved.
- markResolvedRevisions(wireMap);
+ // Mark all modules as resolved.
+ markResolvedModules(wireMap);
}
finally
{
@@ -4164,72 +4163,61 @@
}
}
- BundleRevision resolve(BundleRevision revision, String pkgName)
- throws ResolveException
+ Wire resolve(Module module, String pkgName) throws ResolveException
{
- BundleRevision provider = null;
-
- // We cannot dynamically import if the revision is not already resolved
+ Wire candidateWire = null;
+ // We cannot dynamically import if the module is not already resolved
// or if it is not allowed, so check that first. Note: We check if the
// dynamic import is allowed without holding any locks, but this is
// okay since the resolver will double check later after we have
// acquired the global lock below.
- if ((revision.getWiring() != null) && isAllowedDynamicImport(revision, pkgName))
+ if (module.isResolved() && isAllowedDynamicImport(module, pkgName))
{
// Acquire global lock.
boolean locked = acquireGlobalLock();
if (!locked)
{
throw new ResolveException(
- "Unable to acquire global lock for resolve.", revision, null);
+ "Unable to acquire global lock for resolve.", module, null);
}
- Map<BundleRevision, List<ResolverWire>> wireMap = null;
+ Map<Module, List<Wire>> wireMap = null;
try
{
// Double check to make sure that someone hasn't beaten us to
// dynamically importing the package, which can happen if two
// threads are racing to do so. If we have an existing wire,
// then just return it instead.
- provider = ((BundleWiringImpl) revision.getWiring())
- .getImportedPackageSource(pkgName);
- if (provider == null)
+ List<Wire> wires = module.getWires();
+ for (int i = 0; (wires != null) && (i < wires.size()); i++)
{
- wireMap = m_resolver.resolve(
- m_resolverState, revision, pkgName,
- m_resolverState.getFragments());
-
- if ((wireMap != null) && wireMap.containsKey(revision))
+ if (wires.get(i).hasPackage(pkgName))
{
- List<ResolverWire> dynamicWires = wireMap.remove(revision);
- ResolverWire dynamicWire = dynamicWires.get(0);
+ return wires.get(i);
+ }
+ }
- // Mark all revisions as resolved.
- markResolvedRevisions(wireMap);
+ wireMap = m_resolver.resolve(
+ m_resolverState, module, pkgName, m_resolverState.getFragments());
- // Dynamically add new wire to importing revision.
- if (dynamicWire != null)
- {
- m_dependencies.addDependent(
- dynamicWire.getProvider(),
- dynamicWire.getCapability(),
- revision);
+ if ((wireMap != null) && wireMap.containsKey(module))
+ {
+ List<Wire> dynamicWires = wireMap.remove(module);
+ candidateWire = dynamicWires.get(0);
- ((BundleWiringImpl) revision.getWiring())
- .addDynamicWire(
- new BundleWireImpl(
- dynamicWire.getRequirer(),
- dynamicWire.getRequirement(),
- dynamicWire.getProvider(),
- dynamicWire.getCapability()));
+ // Mark all modules as resolved.
+ markResolvedModules(wireMap);
- m_logger.log(
- Logger.LOG_DEBUG,
- "DYNAMIC WIRE: " + dynamicWire);
-
- provider = ((BundleWiringImpl) revision.getWiring())
- .getImportedPackageSource(pkgName);
- }
+ // Dynamically add new wire to importing module.
+ if (candidateWire != null)
+ {
+ wires = new ArrayList(wires.size() + 1);
+ wires.addAll(module.getWires());
+ wires.add(candidateWire);
+ ((ModuleImpl) module).setWires(wires);
+ m_logger.log(
+ Logger.LOG_DEBUG,
+ "DYNAMIC WIRE: " + wires.get(wires.size() - 1));
}
}
}
@@ -4242,63 +4230,64 @@
fireResolvedEvents(wireMap);
}
- return provider;
+ return candidateWire;
}
// This method duplicates a lot of logic from:
// ResolverImpl.getDynamicImportCandidates()
- boolean isAllowedDynamicImport(BundleRevision revision, String pkgName)
+ boolean isAllowedDynamicImport(Module module, String pkgName)
{
- // Unresolved revisions cannot dynamically import, nor can the default
+ // Unresolved modules cannot dynamically import, nor can the default
// package be dynamically imported.
- if ((revision.getWiring() == null) || pkgName.length() == 0)
+ if (!module.isResolved() || pkgName.length() == 0)
{
return false;
}
- // If the revision doesn't have dynamic imports, then just return
+ // If the module doesn't have dynamic imports, then just return
// immediately.
- List<BundleRequirement> dynamics =
- Util.getDynamicRequirements(revision.getWiring().getRequirements(null));
+ List<Requirement> dynamics = module.getDynamicRequirements();
if ((dynamics == null) || dynamics.isEmpty())
{
return false;
}
- // If the revision exports this package, then we cannot
+ // If any of the module exports this package, then we cannot
// attempt to dynamically import it.
- for (BundleCapability cap : revision.getWiring().getCapabilities(null))
+ List<Capability> caps = module.getCapabilities();
+ for (int i = 0; (caps != null) && (i < caps.size()); i++)
{
- if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
- && cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
+ if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+ && caps.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+ {
+ return false;
+ }
+ }
+ // If any of our wires have this package, then we cannot
+ // attempt to dynamically import it.
+ List<Wire> wires = module.getWires();
+ for (int i = 0; (wires != null) && (i < wires.size()); i++)
+ {
+ if (wires.get(i).hasPackage(pkgName))
{
return false;
}
}
- // If this revision already imports or requires this package, then
- // we cannot dynamically import it.
- if (((BundleWiringImpl) revision.getWiring()).hasPackageSource(pkgName))
- {
- return false;
- }
-
// Loop through the importer's dynamic requirements to determine if
// there is a matching one for the package from which we want to
// load a class.
- Map<String, Object> attrs = new HashMap(1);
- attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
- BundleRequirementImpl req = new BundleRequirementImpl(
- revision,
- BundleCapabilityImpl.PACKAGE_NAMESPACE,
- Collections.EMPTY_MAP,
- attrs);
- Set<BundleCapability> candidates = m_resolverState.getCandidates(req, false);
+ List<Directive> dirs = Collections.EMPTY_LIST;
+ List<Attribute> attrs = new ArrayList(1);
+ attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
+ Requirement req = new RequirementImpl(
+ module, Capability.PACKAGE_NAMESPACE, dirs, attrs);
+ Set<Capability> candidates = m_resolverState.getCandidates(req, false);
return !candidates.isEmpty();
}
- private void markResolvedRevisions(Map<BundleRevision, List<ResolverWire>> wireMap)
+ private void markResolvedModules(Map<Module, List<Wire>> wireMap)
throws ResolveException
{
// DO THIS IN THREE PASSES:
@@ -4310,194 +4299,145 @@
{
// First pass: Loop through the wire map to find the host wires
// for any fragments and map a host to all of its fragments.
- Map<BundleRevision, List<BundleRevision>> hosts =
- new HashMap<BundleRevision, List<BundleRevision>>();
- for (Entry<BundleRevision, List<ResolverWire>> entry : wireMap.entrySet())
+ Map<Module, List<Module>> hosts = new HashMap<Module, List<Module>>();
+ for (Entry<Module, List<Wire>> entry : wireMap.entrySet())
{
- BundleRevision revision = entry.getKey();
- List<ResolverWire> wires = entry.getValue();
+ Module module = entry.getKey();
+ List<Wire> wires = entry.getValue();
- if (Util.isFragment(revision))
+ if (Util.isFragment(module))
{
- for (Iterator<ResolverWire> itWires = wires.iterator();
- itWires.hasNext(); )
+ for (Iterator<Wire> itWires = wires.iterator(); itWires.hasNext(); )
{
- ResolverWire w = itWires.next();
- List<BundleRevision> fragments = hosts.get(w.getProvider());
+ Wire w = itWires.next();
+ List<Module> fragments = hosts.get(w.getExporter());
if (fragments == null)
{
- fragments = new ArrayList<BundleRevision>();
- hosts.put(w.getProvider(), fragments);
+ fragments = new ArrayList<Module>();
+ hosts.put(w.getExporter(), fragments);
}
- fragments.add(w.getRequirer());
+ fragments.add(w.getImporter());
}
}
}
- // Second pass: Loop through the wire map to do three things:
- // 1) convert resolver wires to bundle wires 2) create wiring
- // objects for revisions and 3) record dependencies among
- // revisions. We don't actually set the wirings here because
- // that indicates that a revision is resolved and we don't want
- // to mark anything as resolved unless we succussfully create
- // all wirings.
- Map<BundleRevision, BundleWiringImpl> wirings =
- new HashMap<BundleRevision, BundleWiringImpl>(wireMap.size());
- for (Entry<BundleRevision, List<ResolverWire>> entry : wireMap.entrySet())
+ // Second pass: Loop through the wire map to set wires and attach
+ // fragments, if any.
+ for (Entry<Module, List<Wire>> entry : wireMap.entrySet())
{
- BundleRevision revision = entry.getKey();
- List<ResolverWire> resolverWires = entry.getValue();
+ Module module = entry.getKey();
+ List<Wire> wires = entry.getValue();
- List<BundleWire> bundleWires =
- new ArrayList<BundleWire>(resolverWires.size());
-
- // Loop through resolver wires to calculate the package
- // space implied by the wires as well as to record the
- // dependencies.
- Map<String, BundleRevision> importedPkgs =
- new HashMap<String, BundleRevision>();
- Map<String, List<BundleRevision>> requiredPkgs =
- new HashMap<String, List<BundleRevision>>();
- for (ResolverWire rw : resolverWires)
+// TODO: FRAGMENT RESOLVER - Better way to handle log level?
+ for (Iterator<Wire> itWires = wires.iterator(); itWires.hasNext(); )
{
- bundleWires.add(
- new BundleWireImpl(
- rw.getRequirer(),
- rw.getRequirement(),
- rw.getProvider(),
- rw.getCapability()));
-
- m_dependencies.addDependent(
- rw.getProvider(), rw.getCapability(), rw.getRequirer());
-
- if (Util.isFragment(revision))
+ Wire w = itWires.next();
+ if (!Util.isFragment(module))
+ {
+ m_logger.log(Logger.LOG_DEBUG, "WIRE: " + w);
+ }
+ else
{
m_logger.log(
Logger.LOG_DEBUG,
"FRAGMENT WIRE: "
- + this + " -> hosted by -> " + rw.getProvider());
+ + module + " -> hosted by -> " + w.getExporter());
}
- else
- {
- m_logger.log(Logger.LOG_DEBUG, "WIRE: " + rw);
+ }
- if (rw.getCapability().getNamespace()
- .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ // Set the module's wires. If the module is a resolved
+ // fragment, then we must actually append any new host
+ // wires to the existing ones.
+ if (Util.isFragment(module) && module.isResolved())
+ {
+ wires.addAll(module.getWires());
+ }
+ ((ModuleImpl) module).setWires(wires);
+
+ // Attach fragments, if any.
+ List<Module> fragments = hosts.get(module);
+ if (fragments != null)
+ {
+ try
+ {
+ ((ModuleImpl) module).attachFragments(fragments);
+ }
+ catch (Exception ex)
+ {
+ // This is a fatal error, so undo everything and
+ // throw an exception.
+ for (Entry<Module, List<Wire>> reentry : wireMap.entrySet())
{
- importedPkgs.put(
- (String) rw.getCapability().getAttributes()
- .get(BundleCapabilityImpl.PACKAGE_ATTR),
- rw.getProvider());
- }
- else if (rw.getCapability().getNamespace()
- .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
- {
- Set<String> pkgs = calculateExportedAndReexportedPackages(
- rw.getProvider(),
- wireMap,
- new HashSet<String>(),
- new HashSet<BundleRevision>());
- for (String pkg : pkgs)
+ module = reentry.getKey();
+
+ // Undo wires.
+ ((ModuleImpl) module).setWires(null);
+
+ fragments = hosts.get(module);
+ if (fragments != null)
{
- List<BundleRevision> revs = requiredPkgs.get(pkg);
- if (revs == null)
+ try
{
- revs = new ArrayList<BundleRevision>();
- requiredPkgs.put(pkg, revs);
+ // Undo fragments.
+ ((ModuleImpl) module).attachFragments(null);
}
- revs.add(rw.getProvider());
+ catch (Exception ex2)
+ {
+ // We are in big trouble.
+ RuntimeException rte = new RuntimeException(
+ "Unable to clean up resolver failure.", ex2);
+ m_logger.log(
+ Logger.LOG_ERROR,
+ rte.getMessage(), ex2);
+ throw rte;
+ }
+
+ // Reindex host with no fragments.
+ m_resolverState.addModule(module);
}
}
- }
- }
- List<BundleRevision> fragments = hosts.get(revision);
- try
- {
- wirings.put(
- revision,
- new BundleWiringImpl(
- m_logger,
- m_configMap,
- this,
- (BundleRevisionImpl) revision,
- fragments,
- bundleWires,
- importedPkgs,
- requiredPkgs));
- }
- catch (Exception ex)
- {
- // This is a fatal error, so undo everything and
- // throw an exception.
- for (Entry<BundleRevision, BundleWiringImpl> wiringEntry
- : wirings.entrySet())
- {
- // Dispose of wiring.
- try
- {
- wiringEntry.getValue().dispose();
- }
- catch (Exception ex2)
- {
- // We are in big trouble.
- RuntimeException rte = new RuntimeException(
- "Unable to clean up resolver failure.", ex2);
- m_logger.log(
- Logger.LOG_ERROR,
- rte.getMessage(), ex2);
- throw rte;
- }
-
- // Reindex host with no fragments.
- m_resolverState.addRevision(revision);
+ ResolveException re = new ResolveException(
+ "Unable to attach fragments to " + module,
+ module, null);
+ re.initCause(ex);
+ m_logger.log(
+ Logger.LOG_ERROR,
+ re.getMessage(), ex);
+ throw re;
}
- ResolveException re = new ResolveException(
- "Unable to resolve " + revision,
- revision, null);
- re.initCause(ex);
- m_logger.log(
- Logger.LOG_ERROR,
- re.getMessage(), ex);
- throw re;
+ // Reindex host with attached fragments.
+ m_resolverState.addModule(module);
}
}
- // Third pass: Loop through the wire map to mark revision as resolved
+ // Third pass: Loop through the wire map to mark modules as resolved
// and update the resolver state.
- for (Entry<BundleRevision, BundleWiringImpl> entry : wirings.entrySet())
+ for (Entry<Module, List<Wire>> entry : wireMap.entrySet())
{
- BundleRevisionImpl revision = (BundleRevisionImpl) entry.getKey();
-
- // Mark revision as resolved.
- revision.resolve(entry.getValue());
-
+ Module module = entry.getKey();
+ // Mark module as resolved.
+ ((ModuleImpl) module).setResolved();
// Update resolver state to remove substituted capabilities.
- if (!Util.isFragment(revision))
+ if (!Util.isFragment(module))
{
- // Update resolver state by reindexing host with attached
- // fragments and removing any substituted exports.
-// TODO: OSGi R4.3 - We could avoid reindexing for fragments if we check it
-// the revision has fragments or not.
- m_resolverState.addRevision(revision);
- m_resolverState.removeSubstitutedCapabilities(revision);
+ m_resolverState.removeSubstitutedCapabilities(module);
}
-
- // Update the state of the revision's bundle to resolved as well.
- markBundleResolved(revision);
+ // Update the state of the module's bundle to resolved as well.
+ markBundleResolved(module);
}
}
}
- private void markBundleResolved(BundleRevision revision)
+ private void markBundleResolved(Module module)
{
// Update the bundle's state to resolved when the
- // current revision is resolved; just ignore resolve
+ // current module is resolved; just ignore resolve
// events for older revisions since this only occurs
// when an update is done on an unresolved bundle
// and there was no refresh performed.
- BundleImpl bundle = (BundleImpl) revision.getBundle();
+ BundleImpl bundle = (BundleImpl) module.getBundle();
// Lock the bundle first.
try
@@ -4511,7 +4451,7 @@
{
// There is nothing we can do.
}
- if (bundle.getCurrentRevision() == revision)
+ if (bundle.getCurrentModule() == module)
{
if (bundle.getState() != Bundle.INSTALLED)
{
@@ -4531,97 +4471,29 @@
}
}
- private void fireResolvedEvents(Map<BundleRevision, List<ResolverWire>> wireMap)
+ private void fireResolvedEvents(Map<Module, List<Wire>> wireMap)
{
if (wireMap != null)
{
- Iterator<Entry<BundleRevision, List<ResolverWire>>> iter = wireMap.entrySet().iterator();
+ Iterator<Entry<Module, List<Wire>>> iter = wireMap.entrySet().iterator();
// Iterate over the map to fire necessary RESOLVED events.
while (iter.hasNext())
{
- Entry<BundleRevision, List<ResolverWire>> entry = iter.next();
- BundleRevision revision = entry.getKey();
+ Entry<Module, List<Wire>> entry = iter.next();
+ Module module = entry.getKey();
// Fire RESOLVED events for all fragments.
- List<BundleRevision> fragments =
- ((BundleWiringImpl) revision.getWiring()).getFragments();
+ List<Module> fragments = ((ModuleImpl) module).getFragments();
for (int i = 0; (fragments != null) && (i < fragments.size()); i++)
{
fireBundleEvent(BundleEvent.RESOLVED, fragments.get(i).getBundle());
}
- fireBundleEvent(BundleEvent.RESOLVED, revision.getBundle());
+ fireBundleEvent(BundleEvent.RESOLVED, module.getBundle());
}
}
}
}
- private static Set<String> calculateExportedAndReexportedPackages(
- BundleRevision br,
- Map<BundleRevision, List<ResolverWire>> wireMap,
- Set<String> pkgs,
- Set<BundleRevision> cycles)
- {
- if (!cycles.contains(br))
- {
- cycles.add(br);
-
- // Add all exported packages.
- for (BundleCapability cap : br.getDeclaredCapabilities(null))
- {
- if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
- {
- pkgs.add((String)
- cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
- }
- }
-
- // Now check to see if any required bundles are required with reexport
- // visibility, since we need to include those packages too.
- if (br.getWiring() == null)
- {
- for (ResolverWire rw : wireMap.get(br))
- {
- if (rw.getCapability().getNamespace().equals(
- BundleCapabilityImpl.BUNDLE_NAMESPACE))
- {
- String dir = rw.getRequirement()
- .getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
- if ((dir != null) && (dir.equals(Constants.VISIBILITY_REEXPORT)))
- {
- calculateExportedAndReexportedPackages(
- rw.getProvider(),
- wireMap,
- pkgs,
- cycles);
- }
- }
- }
- }
- else
- {
- for (BundleWire bw : br.getWiring().getRequiredWires(null))
- {
- if (bw.getCapability().getNamespace().equals(
- BundleCapabilityImpl.BUNDLE_NAMESPACE))
- {
- String dir = bw.getRequirement()
- .getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
- if ((dir != null) && (dir.equals(Constants.VISIBILITY_REEXPORT)))
- {
- calculateExportedAndReexportedPackages(
- bw.getProviderWiring().getRevision(),
- wireMap,
- pkgs,
- cycles);
- }
- }
- }
- }
- }
-
- return pkgs;
- }
-
class SystemBundleActivator implements BundleActivator
{
public void start(BundleContext context) throws Exception
@@ -4810,16 +4682,14 @@
// current state.
if (m_bundle.getState() == Bundle.UNINSTALLED)
{
- // Remove dependencies.
- m_dependencies.removeDependencies(m_bundle);
m_bundle.closeAndDelete();
m_bundle = null;
}
else
{
- // This removes all old bundle revisions from memory and
- // from disk. It only maintains the newest revision in the
- // bundle cache.
+ // This removes all old bundle modules from memory and
+ // all old revisions from disk. It only maintains the
+ // newest version in the bundle cache.
refreshBundle(m_bundle);
}
}
diff --git a/framework/src/main/java/org/apache/felix/framework/FilterImpl.java b/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
index a64ba1f..e245b3a 100644
--- a/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
@@ -18,23 +18,20 @@
*/
package org.apache.felix.framework;
-import java.util.Collection;
-import java.util.Collections;
+import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import org.apache.felix.framework.ServiceRegistrationImpl.ServiceReferenceImpl;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Capability;
import org.apache.felix.framework.capabilityset.CapabilitySet;
+import org.apache.felix.framework.capabilityset.Directive;
import org.apache.felix.framework.capabilityset.SimpleFilter;
+import org.apache.felix.framework.resolver.Module;
import org.apache.felix.framework.util.StringMap;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
-import org.osgi.framework.wiring.BundleRevision;
public class FilterImpl implements Filter
{
@@ -54,24 +51,19 @@
public boolean match(ServiceReference sr)
{
- return CapabilitySet.matches((ServiceReferenceImpl) sr, m_filter);
+ return CapabilitySet.matches(new ServiceReferenceCapability(sr), m_filter);
}
- public boolean match(Dictionary<String, ? > dctnr)
+ public boolean match(Dictionary dctnr)
{
return CapabilitySet.matches(new DictionaryCapability(dctnr, false), m_filter);
}
- public boolean matchCase(Dictionary<String, ? > dctnr)
+ public boolean matchCase(Dictionary dctnr)
{
return CapabilitySet.matches(new DictionaryCapability(dctnr, true), m_filter);
}
- public boolean matches(Map<String, ?> map)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
public boolean equals(Object o)
{
return toString().equals(o.toString());
@@ -87,53 +79,12 @@
return m_filter.toString();
}
- static class DictionaryCapability extends BundleCapabilityImpl
- {
- private final Map m_map;
-
- public DictionaryCapability(Dictionary dict, boolean caseSensitive)
- {
- super(null, null, Collections.EMPTY_MAP, Collections.EMPTY_MAP);
- m_map = new DictionaryMap(dict, caseSensitive);
- }
-
- @Override
- public BundleRevision getRevision()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public String getNamespace()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public Map<String, String> getDirectives()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public Map<String, Object> getAttributes()
- {
- return m_map;
- }
-
- @Override
- public List<String> getUses()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
- }
-
- private static class DictionaryMap implements Map
+ static class DictionaryCapability implements Capability
{
private final StringMap m_map;
private final Dictionary m_dict;
- public DictionaryMap(Dictionary dict, boolean caseSensitive)
+ public DictionaryCapability(Dictionary dict, boolean caseSensitive)
{
m_dict = dict;
if (!caseSensitive)
@@ -163,29 +114,29 @@
}
}
- public int size()
+ public Module getModule()
{
throw new UnsupportedOperationException("Not supported yet.");
}
- public boolean isEmpty()
+ public String getNamespace()
{
throw new UnsupportedOperationException("Not supported yet.");
}
- public boolean containsKey(Object o)
+ public Directive getDirective(String name)
{
throw new UnsupportedOperationException("Not supported yet.");
}
- public boolean containsValue(Object o)
+ public List<Directive> getDirectives()
{
throw new UnsupportedOperationException("Not supported yet.");
}
- public Object get(Object o)
+ public Attribute getAttribute(String name)
{
- String key = (String) o;
+ String key = name;
Object value = null;
if (m_dict != null)
{
@@ -194,7 +145,7 @@
// the key.
if (m_map != null)
{
- key = (String) m_map.get(o);
+ key = (String) m_map.get(name);
}
// If the key could not be found in the case insensitive
// key map, then avoid doing the dictionary lookup on it.
@@ -203,42 +154,63 @@
value = m_dict.get(key);
}
}
- return value;
+ return (value == null) ? null : new Attribute(key, value, false);
}
- public Object put(Object k, Object v)
+ public List<Attribute> getAttributes()
+ {
+ return new ArrayList();
+ }
+
+ public List<String> getUses()
{
throw new UnsupportedOperationException("Not supported yet.");
}
-
- public Object remove(Object o)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void putAll(Map map)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void clear()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public Set<Object> keySet()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public Collection<Object> values()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public Set<Entry<Object, Object>> entrySet()
- {
- return Collections.EMPTY_SET;
- }
}
-}
\ No newline at end of file
+
+ static class ServiceReferenceCapability implements Capability
+ {
+ private final ServiceReference m_sr;
+
+ public ServiceReferenceCapability(ServiceReference sr)
+ {
+ m_sr = sr;
+ }
+
+ public Module getModule()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public String getNamespace()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public Directive getDirective(String name)
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public List<Directive> getDirectives()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public Attribute getAttribute(String name)
+ {
+ Object value = m_sr.getProperty(name);
+ return (value == null) ? null : new Attribute(name, value, false);
+ }
+
+ public List<Attribute> getAttributes()
+ {
+ return new ArrayList();
+ }
+
+ public List<String> getUses()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ }
+}
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
similarity index 60%
rename from framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
rename to framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
index 00e1fd7..0ee825a 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
@@ -6,9 +6,9 @@
* 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
@@ -19,70 +19,93 @@
package org.apache.felix.framework;
import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
+import java.net.URLStreamHandler;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
import java.security.SecureClassLoader;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
+
import org.apache.felix.framework.Felix.StatefulResolver;
import org.apache.felix.framework.cache.JarContent;
-import org.apache.felix.framework.cache.Content;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.resolver.Content;
import org.apache.felix.framework.resolver.HostedCapability;
import org.apache.felix.framework.resolver.HostedRequirement;
+import org.apache.felix.framework.resolver.Module;
import org.apache.felix.framework.resolver.ResolveException;
import org.apache.felix.framework.resolver.ResourceNotFoundException;
+import org.apache.felix.framework.resolver.Wire;
import org.apache.felix.framework.util.CompoundEnumeration;
import org.apache.felix.framework.util.FelixConstants;
import org.apache.felix.framework.util.SecureAction;
import org.apache.felix.framework.util.SecurityManagerEx;
import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.util.manifestparser.ManifestParser;
import org.apache.felix.framework.util.manifestparser.R4Library;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
+import org.apache.felix.framework.util.manifestparser.RequirementImpl;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.BundleReference;
import org.osgi.framework.Constants;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.framework.Version;
-public class BundleWiringImpl implements BundleWiring
+public class ModuleImpl implements Module
{
- public final static int EAGER_ACTIVATION = 0;
- public final static int LAZY_ACTIVATION = 1;
-
private final Logger m_logger;
private final Map m_configMap;
private final StatefulResolver m_resolver;
- private final BundleRevisionImpl m_revision;
- private final List<BundleRevision> m_fragments;
- private final List<BundleWire> m_wires;
- private final Map<String, BundleRevision> m_importedPkgs;
- private final Map<String, List<BundleRevision>> m_requiredPkgs;
- private final List<BundleCapability> m_resolvedCaps;
- private final List<BundleRequirement> m_resolvedReqs;
- private final List<R4Library> m_resolvedNativeLibs;
- private final List<Content> m_fragmentContents;
+ private final String m_id;
+ private final Content m_content;
+ private final Map m_headerMap;
+ private final URLStreamHandler m_streamHandler;
- private BundleClassLoader m_classLoader;
+ private final String m_manifestVersion;
+ private final boolean m_isExtension;
+ private final String m_symbolicName;
+ private final Version m_version;
+
+ private final List<Capability> m_capabilities;
+ private List<Capability> m_cachedCapabilities = null;
+ private final List<Requirement> m_requirements;
+ private List<Requirement> m_cachedRequirements = null;
+ private final List<Requirement> m_dynamicRequirements;
+ private List<Requirement> m_cachedDynamicRequirements = null;
+ private final List<R4Library> m_nativeLibraries;
+ private final int m_declaredActivationPolicy;
+ private final List<String> m_activationIncludes;
+ private final List<String> m_activationExcludes;
+
+ private final Bundle m_bundle;
+
+ private List<Module> m_fragments = null;
+ private List<Wire> m_wires = null;
+ private List<Module> m_dependentImporters = new ArrayList<Module>(0);
+ private List<Module> m_dependentRequirers = new ArrayList<Module>(0);
+ private volatile boolean m_isResolved = false;
+
+ private Content[] m_contentPath;
+ private Content[] m_fragmentContents = null;
+ private ModuleClassLoader m_classLoader;
private boolean m_isActivationTriggered = false;
private ProtectionDomain m_protectionDomain = null;
private final static SecureAction m_secureAction = new SecureAction();
@@ -114,6 +137,10 @@
m_defBootClassLoader = cl;
}
+ // Boot delegation packages.
+ private final String[] m_bootPkgs;
+ private final boolean[] m_bootPkgWildcards;
+
// Boolean flag to enable/disable implicit boot delegation.
private final boolean m_implicitBootDelegation;
// Boolean flag to enable/disable local URLs.
@@ -131,139 +158,65 @@
// Flag indicating whether we are on an old JVM or not.
private volatile static boolean m_isPreJava5 = false;
- BundleWiringImpl(
+ /**
+ * This constructor is used by the extension manager, since it needs
+ * a constructor that does not throw an exception.
+ * @param logger
+ * @param bundle
+ * @param id
+ * @param bootPkgs
+ * @param bootPkgWildcards
+ * @throws org.osgi.framework.BundleException
+ */
+ public ModuleImpl(
+ Logger logger, Map configMap, Bundle bundle, String id,
+ String[] bootPkgs, boolean[] bootPkgWildcards)
+ {
+ m_logger = logger;
+ m_configMap = configMap;
+ m_resolver = null;
+ m_bundle = bundle;
+ m_id = id;
+ m_headerMap = null;
+ m_content = null;
+ m_streamHandler = null;
+ m_bootPkgs = bootPkgs;
+ m_bootPkgWildcards = bootPkgWildcards;
+ m_manifestVersion = null;
+ m_symbolicName = null;
+ m_isExtension = false;
+ m_version = null;
+ m_capabilities = null;
+ m_requirements = null;
+ m_dynamicRequirements = null;
+ m_nativeLibraries = null;
+ m_declaredActivationPolicy = EAGER_ACTIVATION;
+ m_activationExcludes = null;
+ m_activationIncludes = null;
+ m_implicitBootDelegation = false;
+ m_useLocalURLs =
+ (m_configMap.get(FelixConstants.USE_LOCALURLS_PROP) == null)
+ ? false : true;
+ m_bootClassLoader = m_defBootClassLoader;
+ }
+
+ ModuleImpl(
Logger logger, Map configMap, StatefulResolver resolver,
- BundleRevisionImpl revision, List<BundleRevision> fragments,
- List<BundleWire> wires,
- Map<String, BundleRevision> importedPkgs,
- Map<String, List<BundleRevision>> requiredPkgs)
- throws Exception
+ Bundle bundle, String id, Map headerMap, Content content,
+ URLStreamHandler streamHandler, String[] bootPkgs,
+ boolean[] bootPkgWildcards)
+ throws BundleException
{
m_logger = logger;
m_configMap = configMap;
m_resolver = resolver;
- m_revision = revision;
- m_importedPkgs = importedPkgs;
- m_requiredPkgs = requiredPkgs;
- m_wires = wires;
-
- // We need to sort the fragments and add ourself as a dependent of each one.
- // We also need to create an array of fragment contents to attach to our
- // content path.
- List<Content> fragmentContents = null;
- if (fragments != null)
- {
- // Sort fragments according to ID order, if necessary.
- // Note that this sort order isn't 100% correct since
- // it uses a string, but it is likely close enough and
- // avoids having to create more objects.
- if (fragments.size() > 1)
- {
- SortedMap<String, BundleRevision> sorted = new TreeMap<String, BundleRevision>();
- for (BundleRevision f : fragments)
- {
- sorted.put(((BundleRevisionImpl) f).getId(), f);
- }
- fragments = new ArrayList(sorted.values());
- }
- fragmentContents = new ArrayList<Content>(fragments.size());
- for (int i = 0; (fragments != null) && (i < fragments.size()); i++)
- {
- fragmentContents.add(
- ((BundleRevisionImpl) fragments.get(i)).getContent()
- .getEntryAsContent(FelixConstants.CLASS_PATH_DOT));
- }
- }
- m_fragments = fragments;
- m_fragmentContents = fragmentContents;
-
- List<BundleCapability> capList = (m_revision.getDeclaredCapabilities(null) == null)
- ? new ArrayList<BundleCapability>()
- : new ArrayList<BundleCapability>(m_revision.getDeclaredCapabilities(null));
- for (int fragIdx = 0;
- (m_fragments != null) && (fragIdx < m_fragments.size());
- fragIdx++)
- {
- List<BundleCapability> caps =
- m_fragments.get(fragIdx).getDeclaredCapabilities(null);
- for (int capIdx = 0;
- (caps != null) && (capIdx < caps.size());
- capIdx++)
- {
- if (caps.get(capIdx).getNamespace().equals(
- BundleCapabilityImpl.PACKAGE_NAMESPACE))
- {
- capList.add(
- new HostedCapability(
- m_revision, (BundleCapabilityImpl) caps.get(capIdx)));
- }
- }
- }
- m_resolvedCaps = Collections.unmodifiableList(capList);
-
- List<BundleRequirement> reqList = (m_revision.getDeclaredRequirements(null) == null)
- ? new ArrayList() : new ArrayList(m_revision.getDeclaredRequirements(null));
- for (int fragIdx = 0;
- (m_fragments != null) && (fragIdx < m_fragments.size());
- fragIdx++)
- {
- List<BundleRequirement> reqs =
- m_fragments.get(fragIdx).getDeclaredRequirements(null);
- for (int reqIdx = 0;
- (reqs != null) && (reqIdx < reqs.size());
- reqIdx++)
- {
- if (reqs.get(reqIdx).getNamespace().equals(
- BundleCapabilityImpl.PACKAGE_NAMESPACE)
- || reqs.get(reqIdx).getNamespace().equals(
- BundleCapabilityImpl.BUNDLE_NAMESPACE))
- {
- reqList.add(
- new HostedRequirement(
- m_revision, (BundleRequirementImpl) reqs.get(reqIdx)));
- }
- }
- }
- m_resolvedReqs = Collections.unmodifiableList(reqList);
-
- List<R4Library> libList = (m_revision.getDeclaredNativeLibraries() == null)
- ? new ArrayList<R4Library>()
- : new ArrayList<R4Library>(m_revision.getDeclaredNativeLibraries());
- for (int fragIdx = 0;
- (m_fragments != null) && (fragIdx < m_fragments.size());
- fragIdx++)
- {
- List<R4Library> libs =
- ((BundleRevisionImpl) m_fragments.get(fragIdx))
- .getDeclaredNativeLibraries();
- for (int reqIdx = 0;
- (libs != null) && (reqIdx < libs.size());
- reqIdx++)
- {
- libList.add(libs.get(reqIdx));
- }
- }
- // We need to return null here if we don't have any libraries, since a
- // zero-length array is used to indicate that matching native libraries
- // could not be found when resolving the bundle.
- m_resolvedNativeLibs = (libList.isEmpty())
- ? null
- : Collections.unmodifiableList(libList);
-
- ClassLoader bootLoader = m_defBootClassLoader;
- if (revision.getBundle().getBundleId() != 0)
- {
- Object map = m_configMap.get(FelixConstants.BOOT_CLASSLOADERS_PROP);
- if (map instanceof Map)
- {
- Object l = ((Map) map).get(m_revision.getBundle());
- if (l instanceof ClassLoader)
- {
- bootLoader = (ClassLoader) l;
- }
- }
- }
- m_bootClassLoader = bootLoader;
+ m_bundle = bundle;
+ m_id = id;
+ m_headerMap = headerMap;
+ m_content = content;
+ m_streamHandler = streamHandler;
+ m_bootPkgs = bootPkgs;
+ m_bootPkgWildcards = bootPkgWildcards;
m_implicitBootDelegation =
(m_configMap.get(FelixConstants.IMPLICIT_BOOT_DELEGATION_PROP) == null)
@@ -274,485 +227,435 @@
m_useLocalURLs =
(m_configMap.get(FelixConstants.USE_LOCALURLS_PROP) == null)
? false : true;
- }
- public void dispose()
- {
- if (m_fragmentContents != null)
+ ClassLoader bootLoader = m_defBootClassLoader;
+ Object map = m_configMap.get(FelixConstants.BOOT_CLASSLOADERS_PROP);
+ if (map instanceof Map)
{
- for (Content content : m_fragmentContents)
+ Object l = ((Map) map).get(bundle);
+ if (l instanceof ClassLoader)
{
- content.close();
+ bootLoader = (ClassLoader) l;
}
}
- m_classLoader = null;
- }
+ m_bootClassLoader = bootLoader;
-// TODO: OSGi R4.3 - This really shouldn't be public, but it is needed by the
-// resolver to determine if a bundle can dynamically import.
- public synchronized boolean hasPackageSource(String pkgName)
- {
- return (m_importedPkgs.containsKey(pkgName) || m_requiredPkgs.containsKey(pkgName));
- }
+ ManifestParser mp = new ManifestParser(m_logger, m_configMap, this, m_headerMap);
-// TODO: OSGi R4.3 - This really shouldn't be public, but it is needed by the
-// to implement dynamic imports.
- public synchronized BundleRevision getImportedPackageSource(String pkgName)
- {
- return m_importedPkgs.get(pkgName);
- }
-
- List<BundleRevision> getFragments()
- {
- return m_fragments;
- }
-
- List<Content> getFragmentContents()
- {
- return m_fragmentContents;
- }
-
- public boolean isCurrent()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public boolean isInUse()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public List<BundleCapability> getCapabilities(String namespace)
- {
- List<BundleCapability> result = m_resolvedCaps;
- if (namespace != null)
- {
- result = new ArrayList<BundleCapability>();
- for (BundleCapability cap : m_resolvedCaps)
- {
- if (cap.getNamespace().equals(namespace))
- {
- result.add(cap);
- }
- }
- }
- return result;
- }
-
- public List<BundleRequirement> getRequirements(String namespace)
- {
-
- List<BundleRequirement> result = m_resolvedReqs;
- if (namespace != null)
- {
- result = new ArrayList<BundleRequirement>();
- for (BundleRequirement req : m_resolvedReqs)
- {
- if (req.getNamespace().equals(namespace))
- {
- result.add(req);
- }
- }
- }
- return result;
- }
-
- public List<R4Library> getNativeLibraries()
- {
- return m_resolvedNativeLibs;
- }
-
- public List<BundleWire> getProvidedWires(String namespace)
- {
-// TODO: OSGI R4.3 - IMPLEMENT THIS!!
- return Collections.EMPTY_LIST;
- }
-
- public List<BundleWire> getRequiredWires(String namespace)
- {
- return m_wires;
- }
-
- public synchronized void addDynamicWire(BundleWire wire)
- {
- m_wires.add(wire);
- m_importedPkgs.put(
- (String) wire.getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR),
- wire.getProviderWiring().getRevision());
- }
-
- public BundleRevision getRevision()
- {
- return m_revision;
- }
-
- public synchronized ClassLoader getClassLoader()
- {
- if (m_classLoader == null)
- {
- // Determine which class loader to use based on which
- // Java platform we are running on.
- Class clazz;
- if (m_isPreJava5)
- {
- clazz = BundleClassLoader.class;
- }
- else
- {
- try
- {
- clazz = BundleClassLoaderJava5.class;
- }
- catch (Throwable th)
- {
- // If we are on pre-Java5 then we will get a verify error
- // here since we try to override a getResources() which is
- // a final method in pre-Java5.
- m_isPreJava5 = true;
- clazz = BundleClassLoader.class;
- }
- }
-
- // Use SecureAction to create the class loader if security is
- // enabled; otherwise, create it directly.
- try
- {
- Constructor ctor = (Constructor) m_secureAction.getConstructor(
- clazz, new Class[] { BundleWiringImpl.class, ClassLoader.class });
- m_classLoader = (BundleClassLoader)
- m_secureAction.invoke(ctor,
- new Object[] { this, determineParentClassLoader() });
- }
- catch (Exception ex)
- {
- throw new RuntimeException("Unable to create module class loader: "
- + ex.getMessage() + " [" + ex.getClass().getName() + "]");
- }
- }
- return m_classLoader;
- }
-
- public List<URL> findEntries(String path, String filePattern, int options)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public Collection<String> listResources(String path, String filePattern, int options)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public Bundle getBundle()
- {
- return m_revision.getBundle();
+ // Record some of the parsed metadata. Note, if this is an extension
+ // bundle it's exports are removed, since they will be added to the
+ // system bundle directly later on.
+ m_manifestVersion = mp.getManifestVersion();
+ m_version = mp.getBundleVersion();
+ m_capabilities = mp.isExtension() ? null : mp.getCapabilities();
+ m_requirements = mp.getRequirements();
+ m_dynamicRequirements = mp.getDynamicRequirements();
+ m_nativeLibraries = mp.getLibraries();
+ m_declaredActivationPolicy = mp.getActivationPolicy();
+ m_activationExcludes = (mp.getActivationExcludeDirective() == null)
+ ? null
+ : ManifestParser.parseDelimitedString(mp.getActivationExcludeDirective(), ",");
+ m_activationIncludes = (mp.getActivationIncludeDirective() == null)
+ ? null
+ : ManifestParser.parseDelimitedString(mp.getActivationIncludeDirective(), ",");
+ m_symbolicName = mp.getSymbolicName();
+ m_isExtension = mp.isExtension();
}
//
- // Class loader implementation methods.
+ // Metadata access methods.
//
- private URL createURL(int port, String path)
+ public Map getHeaders()
{
- // Add a slash if there is one already, otherwise
- // the is no slash separating the host from the file
- // in the resulting URL.
- if (!path.startsWith("/"))
- {
- path = "/" + path;
- }
-
- try
- {
- return m_secureAction.createURL(null,
- FelixConstants.BUNDLE_URL_PROTOCOL + "://" +
- m_revision.getId() + ":" + port + path, m_revision.getURLStreamHandler());
- }
- catch (MalformedURLException ex)
- {
- m_logger.log(m_revision.getBundle(),
- Logger.LOG_ERROR,
- "Unable to create resource URL.",
- ex);
- }
- return null;
+ return m_headerMap;
}
- public Enumeration getResourcesByDelegation(String name)
+ public boolean isExtension()
{
- Set requestSet = (Set) m_cycleCheck.get();
- if (requestSet == null)
- {
- requestSet = new HashSet();
- m_cycleCheck.set(requestSet);
- }
- if (!requestSet.contains(name))
- {
- requestSet.add(name);
- try
- {
- return findResourcesByDelegation(name);
- }
- finally
- {
- requestSet.remove(name);
- }
- }
-
- return null;
+ return m_isExtension;
}
- private Enumeration findResourcesByDelegation(String name)
+ public String getSymbolicName()
{
- Enumeration urls = null;
- List completeUrlList = new ArrayList();
+ return m_symbolicName;
+ }
- // First, try to resolve the originating module.
- try
+ public String getManifestVersion()
+ {
+ return m_manifestVersion;
+ }
+
+ public Version getVersion()
+ {
+ return m_version;
+ }
+
+ public synchronized List<Capability> getCapabilities()
+ {
+ if (m_cachedCapabilities == null)
{
- m_resolver.resolve(m_revision);
- }
- catch (ResolveException ex)
- {
- // The spec states that if the bundle cannot be resolved, then
- // only the local bundle's resources should be searched. So we
- // will ask the module's own class path.
- return m_revision.getResourcesLocal(name);
- }
-
- // Get the package of the target class/resource.
- String pkgName = Util.getResourcePackage(name);
-
- // Delegate any packages listed in the boot delegation
- // property to the parent class loader.
- if (shouldBootDelegate(pkgName))
- {
- try
+ List capList = (m_capabilities == null)
+ ? new ArrayList<Capability>()
+ : new ArrayList<Capability>(m_capabilities);
+ for (int fragIdx = 0;
+ (m_fragments != null) && (fragIdx < m_fragments.size());
+ fragIdx++)
{
- // Get the appropriate class loader for delegation.
- ClassLoader bdcl = getBootDelegationClassLoader();
- urls = bdcl.getResources(name);
- }
- catch (IOException ex)
- {
- // This shouldn't happen and even if it does, there
- // is nothing we can do, so just ignore it.
- }
- // If this is a java.* package, then always terminate the
- // search; otherwise, continue to look locally.
- if (pkgName.startsWith("java."))
- {
- return urls;
- }
-
- completeUrlList.add(urls);
- }
-
- // Look in the revisions's imported packages. If the package is
- // imported, then we stop searching no matter the result since
- // imported packages cannot be split.
- BundleRevision provider = m_importedPkgs.get(pkgName);
- if (provider != null)
- {
- // Delegate to the provider revision.
- urls = ((BundleWiringImpl) provider.getWiring()).getResourcesByDelegation(name);
-
- // If we find any resources, then add them.
- if ((urls != null) && (urls.hasMoreElements()))
- {
- completeUrlList.add(urls);
- }
-
- // Always return here since imported packages cannot be split
- // across required bundles or the revision's content.
- return new CompoundEnumeration((Enumeration[])
- completeUrlList.toArray(new Enumeration[completeUrlList.size()]));
- }
-
- // See whether we can get the resource from the required bundles and
- // regardless of whether or not this is the case continue to the next
- // step potentially passing on the result of this search (if any).
- List<BundleRevision> providers = m_requiredPkgs.get(pkgName);
- if (providers != null)
- {
- for (BundleRevision p : providers)
- {
- // Delegate to the provider revision.
- urls = ((BundleWiringImpl) p.getWiring()).getResourcesByDelegation(name);
-
- // If we find any resources, then add them.
- if ((urls != null) && (urls.hasMoreElements()))
+ List<Capability> caps = m_fragments.get(fragIdx).getCapabilities();
+ for (int capIdx = 0;
+ (caps != null) && (capIdx < caps.size());
+ capIdx++)
{
- completeUrlList.add(urls);
+ if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+ {
+ capList.add(
+ new HostedCapability(this, caps.get(capIdx)));
+ }
}
-
- // Do not return here, since required packages can be split
- // across the revision's content.
}
+ m_cachedCapabilities = Collections.unmodifiableList(capList);
}
+ return m_cachedCapabilities;
+ }
- // Try the module's own class path. If we can find the resource then
- // return it together with the results from the other searches else
- // try to look into the dynamic imports.
- urls = m_revision.getResourcesLocal(name);
- if ((urls != null) && (urls.hasMoreElements()))
+ public synchronized List<Requirement> getRequirements()
+ {
+ if (m_cachedRequirements == null)
{
- completeUrlList.add(urls);
+ List<Requirement> reqList = (m_requirements == null)
+ ? new ArrayList() : new ArrayList(m_requirements);
+ for (int fragIdx = 0;
+ (m_fragments != null) && (fragIdx < m_fragments.size());
+ fragIdx++)
+ {
+ List<Requirement> reqs = m_fragments.get(fragIdx).getRequirements();
+ for (int reqIdx = 0;
+ (reqs != null) && (reqIdx < reqs.size());
+ reqIdx++)
+ {
+ if (reqs.get(reqIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+ || reqs.get(reqIdx).getNamespace().equals(Capability.MODULE_NAMESPACE))
+ {
+ reqList.add(
+ new HostedRequirement(this, reqs.get(reqIdx)));
+ }
+ }
+ }
+ m_cachedRequirements = Collections.unmodifiableList(reqList);
+ }
+ return m_cachedRequirements;
+ }
+
+ public synchronized List<Requirement> getDynamicRequirements()
+ {
+ if (m_cachedDynamicRequirements == null)
+ {
+ List<Requirement> reqList = (m_dynamicRequirements == null)
+ ? new ArrayList() : new ArrayList(m_dynamicRequirements);
+ for (int fragIdx = 0;
+ (m_fragments != null) && (fragIdx < m_fragments.size());
+ fragIdx++)
+ {
+ List<Requirement> reqs = m_fragments.get(fragIdx).getDynamicRequirements();
+ for (int reqIdx = 0;
+ (reqs != null) && (reqIdx < reqs.size());
+ reqIdx++)
+ {
+ if (reqs.get(reqIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+ {
+ reqList.add(reqs.get(reqIdx));
+ }
+ }
+ }
+ m_cachedDynamicRequirements = Collections.unmodifiableList(reqList);
+ }
+ return m_cachedDynamicRequirements;
+ }
+
+ public synchronized List<R4Library> getNativeLibraries()
+ {
+ List<R4Library> result = null;
+ if (m_isResolved)
+ {
+ List<R4Library> nativeList = (m_nativeLibraries == null)
+ ? new ArrayList() : new ArrayList(m_nativeLibraries);
+ for (int fragIdx = 0;
+ (m_fragments != null) && (fragIdx < m_fragments.size());
+ fragIdx++)
+ {
+ List<R4Library> libs = m_fragments.get(fragIdx).getNativeLibraries();
+ for (int reqIdx = 0;
+ (libs != null) && (reqIdx < libs.size());
+ reqIdx++)
+ {
+ nativeList.add(libs.get(reqIdx));
+ }
+ }
+
+ // We need to return null here if we don't have any libraries, since a
+ // zero-length array is used to indicate that matching native libraries
+ // could not be found when resolving the bundle.
+ result = (nativeList.isEmpty())
+ ? null
+ : Collections.unmodifiableList(nativeList);
}
else
{
- // If not found, then try the module's dynamic imports.
- // At this point, the module's imports were searched and so was the
- // the module's content. Now we make an attempt to load the
- // class/resource via a dynamic import, if possible.
- try
- {
- provider = m_resolver.resolve(m_revision, pkgName);
- }
- catch (ResolveException ex)
- {
- // Ignore this since it is likely normal.
- }
- if (provider != null)
- {
- // Delegate to the provider revision.
- urls = ((BundleWiringImpl) provider.getWiring()).getResourcesByDelegation(name);
-
- // If we find any resources, then add them.
- if ((urls != null) && (urls.hasMoreElements()))
- {
- completeUrlList.add(urls);
- }
- }
+ result = m_nativeLibraries;
}
- return new CompoundEnumeration((Enumeration[])
- completeUrlList.toArray(new Enumeration[completeUrlList.size()]));
+ return result;
}
- private ClassLoader determineParentClassLoader()
+ public int getDeclaredActivationPolicy()
{
- // Determine the class loader's parent based on the
- // configuration property; use boot class loader by
- // default.
- String cfg = (String) m_configMap.get(Constants.FRAMEWORK_BUNDLE_PARENT);
- cfg = (cfg == null) ? Constants.FRAMEWORK_BUNDLE_PARENT_BOOT : cfg;
- final ClassLoader parent;
- if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_APP))
- {
- parent = m_secureAction.getSystemClassLoader();
- }
- else if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_EXT))
- {
- parent = m_secureAction.getParentClassLoader(m_secureAction.getSystemClassLoader());
- }
- else if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK))
- {
- parent = m_secureAction.getClassLoader(BundleRevisionImpl.class);
- }
- // On Android we cannot set the parent class loader to be null, so
- // we special case that situation here and set it to the system
- // class loader by default instead, which is not really spec.
- else if (m_bootClassLoader == null)
- {
- parent = m_secureAction.getSystemClassLoader();
- }
- else
- {
- parent = null;
- }
- return parent;
+ return m_declaredActivationPolicy;
}
- boolean shouldBootDelegate(String pkgName)
+ synchronized boolean isActivationTriggered()
{
- // Always boot delegate if the bundle has a configured
- // boot class loader.
- if (m_bootClassLoader != m_defBootClassLoader)
+ return m_isActivationTriggered;
+ }
+
+ boolean isActivationTrigger(String pkgName)
+ {
+ if ((m_activationIncludes == null) && (m_activationExcludes == null))
{
return true;
}
- boolean result = false;
-
- // Only consider delegation if we have a package name, since
- // we don't want to promote the default package. The spec does
- // not take a stand on this issue.
- if (pkgName.length() > 0)
+ // If there are no include filters then all classes are included
+ // by default, otherwise try to find one match.
+ boolean included = (m_activationIncludes == null);
+ for (int i = 0;
+ (!included) && (m_activationIncludes != null) && (i < m_activationIncludes.size());
+ i++)
{
- for (int i = 0; !result && (i < m_revision.getBootDelegationPackages().length); i++)
+ included = m_activationIncludes.get(i).equals(pkgName);
+ }
+
+ // If there are no exclude filters then no classes are excluded
+ // by default, otherwise try to find one match.
+ boolean excluded = false;
+ for (int i = 0;
+ (!excluded) && (m_activationExcludes != null) && (i < m_activationExcludes.size());
+ i++)
+ {
+ excluded = m_activationExcludes.get(i).equals(pkgName);
+ }
+ return included && !excluded;
+ }
+
+ //
+ // Run-time data access.
+ //
+
+ public Bundle getBundle()
+ {
+ return m_bundle;
+ }
+
+ public String getId()
+ {
+ return m_id;
+ }
+
+ public synchronized List<Wire> getWires()
+ {
+ return m_wires;
+ }
+
+ public synchronized void setWires(List<Wire> wires)
+ {
+ // This not only sets the wires for the module, but it also records
+ // the dependencies this module has on other modules (i.e., the provider
+ // end of the wire) to simplify bookkeeping.
+
+ // For fragments we don't need to capture any additional dependency
+ // information, since the wires are sufficient, so just record the
+ // new wires. The wires are to the hosts to which the fragment is attached.
+ boolean isFragment = Util.isFragment(this);
+
+ // Remove module from old wire modules' dependencies,
+ // since we are no longer dependent on any the moduels
+ // from the old wires.
+ for (int i = 0; !isFragment && (m_wires != null) && (i < m_wires.size()); i++)
+ {
+ if (m_wires.get(i).getCapability().getNamespace().equals(Capability.MODULE_NAMESPACE))
{
- // Check if the boot package is wildcarded.
- // A wildcarded boot package will be in the form "foo.",
- // so a matching subpackage will start with "foo.", e.g.,
- // "foo.bar".
- if (m_revision.getBootDelegationPackageWildcards()[i]
- && pkgName.startsWith(m_revision.getBootDelegationPackages()[i]))
+ ((ModuleImpl) m_wires.get(i).getExporter()).removeDependentRequirer(this);
+ }
+ else if (m_wires.get(i).getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+ {
+ ((ModuleImpl) m_wires.get(i).getExporter()).removeDependentImporter(this);
+ }
+ }
+
+ m_wires = wires;
+
+ // Add ourself as a dependent to the new wires' modules.
+ for (int i = 0; !isFragment && (m_wires != null) && (i < m_wires.size()); i++)
+ {
+ if (m_wires.get(i).getCapability().getNamespace().equals(Capability.MODULE_NAMESPACE))
+ {
+ ((ModuleImpl) m_wires.get(i).getExporter()).addDependentRequirer(this);
+ }
+ else if (m_wires.get(i).getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+ {
+ ((ModuleImpl) m_wires.get(i).getExporter()).addDependentImporter(this);
+ }
+ }
+ }
+
+ public boolean isResolved()
+ {
+ return m_isResolved;
+ }
+
+ public void setResolved()
+ {
+ m_isResolved = true;
+ }
+
+
+ public synchronized void setSecurityContext(Object securityContext)
+ {
+ m_protectionDomain = (ProtectionDomain) securityContext;
+ }
+
+ public synchronized Object getSecurityContext()
+ {
+ return m_protectionDomain;
+ }
+
+ // TODO: FRAGMENT RESOLVER - Technically, this is only necessary for fragments.
+ // When we refactoring for the new R4.3 framework API, we'll have to see
+ // if this is still necessary, since the new BundleWirings API will give
+ // us another way to detect it.
+ public boolean isRemovalPending()
+ {
+ return (m_bundle.getState() == Bundle.UNINSTALLED)
+ || (this != ((BundleImpl) m_bundle).getCurrentModule());
+ }
+
+ //
+ // Content access methods.
+ //
+
+ public Content getContent()
+ {
+ return m_content;
+ }
+
+ private synchronized Content[] getContentPath()
+ {
+ if (m_contentPath == null)
+ {
+ try
+ {
+ m_contentPath = initializeContentPath();
+ }
+ catch (Exception ex)
+ {
+ m_logger.log(
+ m_bundle, Logger.LOG_ERROR, "Unable to get module class path.", ex);
+ }
+ }
+ return m_contentPath;
+ }
+
+ private Content[] initializeContentPath() throws Exception
+ {
+ List contentList = new ArrayList();
+ calculateContentPath(this, m_content, contentList, true);
+ for (int i = 0; (m_fragmentContents != null) && (i < m_fragmentContents.length); i++)
+ {
+ calculateContentPath(m_fragments.get(i), m_fragmentContents[i], contentList, false);
+ }
+ return (Content[]) contentList.toArray(new Content[contentList.size()]);
+ }
+
+ private List calculateContentPath(
+ Module module, Content content, List contentList, boolean searchFragments)
+ throws Exception
+ {
+ // Creating the content path entails examining the bundle's
+ // class path to determine whether the bundle JAR file itself
+ // is on the bundle's class path and then creating content
+ // objects for everything on the class path.
+
+ // Create a list to contain the content path for the specified content.
+ List localContentList = new ArrayList();
+
+ // Find class path meta-data.
+ String classPath = (String) module.getHeaders().get(FelixConstants.BUNDLE_CLASSPATH);
+ // Parse the class path into strings.
+ List<String> classPathStrings = ManifestParser.parseDelimitedString(
+ classPath, FelixConstants.CLASS_PATH_SEPARATOR);
+
+ if (classPathStrings == null)
+ {
+ classPathStrings = new ArrayList<String>(0);
+ }
+
+ // Create the bundles class path.
+ for (int i = 0; i < classPathStrings.size(); i++)
+ {
+ // Remove any leading slash, since all bundle class path
+ // entries are relative to the root of the bundle.
+ classPathStrings.set(i, (classPathStrings.get(i).startsWith("/"))
+ ? classPathStrings.get(i).substring(1)
+ : classPathStrings.get(i));
+
+ // Check for the bundle itself on the class path.
+ if (classPathStrings.get(i).equals(FelixConstants.CLASS_PATH_DOT))
+ {
+ localContentList.add(content);
+ }
+ else
+ {
+ // Try to find the embedded class path entry in the current
+ // content.
+ Content embeddedContent = content.getEntryAsContent(classPathStrings.get(i));
+ // If the embedded class path entry was not found, it might be
+ // in one of the fragments if the current content is the bundle,
+ // so try to search the fragments if necessary.
+ for (int fragIdx = 0;
+ searchFragments && (embeddedContent == null)
+ && (m_fragmentContents != null) && (fragIdx < m_fragmentContents.length);
+ fragIdx++)
{
- return true;
+ embeddedContent =
+ m_fragmentContents[fragIdx].getEntryAsContent(classPathStrings.get(i));
}
- // If not wildcarded, then check for an exact match.
- else if (m_revision.getBootDelegationPackages()[i].equals(pkgName))
+ // If we found the embedded content, then add it to the
+ // class path content list.
+ if (embeddedContent != null)
{
- return true;
+ localContentList.add(embeddedContent);
+ }
+ else
+ {
+// TODO: FRAMEWORK - Per the spec, this should fire a FrameworkEvent.INFO event;
+// need to create an "Eventer" class like "Logger" perhaps.
+ m_logger.log(m_bundle, Logger.LOG_INFO,
+ "Class path entry not found: "
+ + classPathStrings.get(i));
}
}
}
- return result;
- }
-
- ClassLoader getBootDelegationClassLoader()
- {
- // Get the appropriate class loader for delegation.
- ClassLoader parent = (m_classLoader == null)
- ? determineParentClassLoader() : m_classLoader.getParent();
- return (parent == null) ? m_bootClassLoader : parent;
- }
-
- private static final Constructor m_dexFileClassConstructor;
- private static final Method m_dexFileClassLoadDex;
- private static final Method m_dexFileClassLoadClass;
-
- static
- {
- Constructor dexFileClassConstructor = null;
- Method dexFileClassLoadDex = null;
- Method dexFileClassLoadClass = null;
- try
+ // If there is nothing on the class path, then include
+ // "." by default, as per the spec.
+ if (localContentList.isEmpty())
{
- Class dexFileClass;
- try
- {
- dexFileClass = Class.forName("dalvik.system.DexFile");
- }
- catch (Exception ex)
- {
- dexFileClass = Class.forName("android.dalvik.DexFile");
- }
+ localContentList.add(content);
+ }
- try
- {
- dexFileClassLoadDex = dexFileClass.getMethod("loadDex",
- new Class[]{String.class, String.class, Integer.TYPE});
- }
- catch (Exception ex)
- {
- // Nothing we need to do
- }
- dexFileClassConstructor = dexFileClass.getConstructor(
- new Class[] { java.io.File.class });
- dexFileClassLoadClass = dexFileClass.getMethod("loadClass",
- new Class[] { String.class, ClassLoader.class });
- }
- catch (Throwable ex)
- {
- dexFileClassConstructor = null;
- dexFileClassLoadDex = null;
- dexFileClassLoadClass = null;
- }
- m_dexFileClassConstructor = dexFileClassConstructor;
- m_dexFileClassLoadDex= dexFileClassLoadDex;
- m_dexFileClassLoadClass = dexFileClassLoadClass;
+ // Now add the local contents to the global content list and return it.
+ contentList.addAll(localContentList);
+ return contentList;
}
public Class getClassByDelegation(String name) throws ClassNotFoundException
@@ -779,7 +682,7 @@
}
catch (ResourceNotFoundException ex)
{
- m_logger.log(m_revision.getBundle(),
+ m_logger.log(m_bundle,
Logger.LOG_DEBUG,
ex.getMessage());
}
@@ -801,8 +704,8 @@
{
try
{
- // First, try to resolve the originating revision.
- m_resolver.resolve(m_revision);
+ // First, try to resolve the originating module.
+ m_resolver.resolve(this);
// Get the package of the target class/resource.
String pkgName = (isClass)
@@ -838,22 +741,22 @@
}
}
- // Look in the revision's imports. Note that the search may
+ // Look in the module's imports. Note that the search may
// be aborted if this method throws an exception, otherwise
// it continues if a null is returned.
- result = searchImports(pkgName, name, isClass);
+ result = searchImports(name, isClass);
- // If not found, try the revision's own class path.
+ // If not found, try the module's own class path.
if (result == null)
{
result = (isClass)
- ? (Object) ((BundleClassLoader) getClassLoader()).findClass(name)
- : (Object) m_revision.getResourceLocal(name);
+ ? (Object) getClassLoader().findClass(name)
+ : (Object) getResourceLocal(name);
- // If still not found, then try the revision's dynamic imports.
+ // If still not found, then try the module's dynamic imports.
if (result == null)
{
- result = searchDynamicImports(pkgName, name, isClass);
+ result = searchDynamicImports(name, pkgName, isClass);
}
}
}
@@ -875,7 +778,7 @@
// The spec states that if the bundle cannot be resolved, then
// only the local bundle's resources should be searched. So we
// will ask the module's own class path.
- URL url = m_revision.getResourceLocal(name);
+ URL url = getResourceLocal(name);
if (url != null)
{
return url;
@@ -919,69 +822,630 @@
return result;
}
- private Object searchImports(String pkgName, String name, boolean isClass)
+ URL getResourceLocal(String name)
+ {
+ URL url = null;
+
+ // Remove leading slash, if present, but special case
+ // "/" so that it returns a root URL...this isn't very
+ // clean or meaninful, but the Spring guys want it.
+ if (name.equals("/"))
+ {
+ // Just pick a class path index since it doesn't really matter.
+ url = createURL(1, name);
+ }
+ else if (name.startsWith("/"))
+ {
+ name = name.substring(1);
+ }
+
+ // Check the module class path.
+ Content[] contentPath = getContentPath();
+ for (int i = 0;
+ (url == null) &&
+ (i < contentPath.length); i++)
+ {
+ if (contentPath[i].hasEntry(name))
+ {
+ url = createURL(i + 1, name);
+ }
+ }
+
+ return url;
+ }
+
+ public Enumeration getResourcesByDelegation(String name)
+ {
+ Set requestSet = (Set) m_cycleCheck.get();
+ if (requestSet == null)
+ {
+ requestSet = new HashSet();
+ m_cycleCheck.set(requestSet);
+ }
+ if (!requestSet.contains(name))
+ {
+ requestSet.add(name);
+ try
+ {
+ return findResourcesByDelegation(name);
+ }
+ finally
+ {
+ requestSet.remove(name);
+ }
+ }
+
+ return null;
+ }
+
+ private Enumeration findResourcesByDelegation(String name)
+ {
+ Enumeration urls = null;
+ List completeUrlList = new ArrayList();
+
+ // First, try to resolve the originating module.
+ try
+ {
+ m_resolver.resolve(this);
+ }
+ catch (ResolveException ex)
+ {
+ // The spec states that if the bundle cannot be resolved, then
+ // only the local bundle's resources should be searched. So we
+ // will ask the module's own class path.
+ return getResourcesLocal(name);
+ }
+
+ // Get the package of the target class/resource.
+ String pkgName = Util.getResourcePackage(name);
+
+ // Delegate any packages listed in the boot delegation
+ // property to the parent class loader.
+ if (shouldBootDelegate(pkgName))
+ {
+ try
+ {
+ // Get the appropriate class loader for delegation.
+ ClassLoader bdcl = getBootDelegationClassLoader();
+ urls = bdcl.getResources(name);
+ }
+ catch (IOException ex)
+ {
+ // This shouldn't happen and even if it does, there
+ // is nothing we can do, so just ignore it.
+ }
+ // If this is a java.* package, then always terminate the
+ // search; otherwise, continue to look locally.
+ if (pkgName.startsWith("java."))
+ {
+ return urls;
+ }
+
+ completeUrlList.add(urls);
+ }
+
+ // Look in the module's imports.
+ // We delegate to the module's wires for the resources.
+ // If any resources are found, this means that the package of these
+ // resources is imported, we must not keep looking since we do not
+ // support split-packages.
+
+ // Note that the search may be aborted if this method throws an
+ // exception, otherwise it continues if a null is returned.
+ List<Wire> wires = getWires();
+ for (int i = 0; (wires != null) && (i < wires.size()); i++)
+ {
+ if (wires.get(i).getRequirement().getNamespace()
+ .equals(Capability.PACKAGE_NAMESPACE))
+ {
+ try
+ {
+ // If we find the class or resource, then return it.
+ urls = wires.get(i).getResources(name);
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ urls = null;
+ }
+ if (urls != null)
+ {
+ completeUrlList.add(urls);
+ return new CompoundEnumeration((Enumeration[])
+ completeUrlList.toArray(new Enumeration[completeUrlList.size()]));
+ }
+ }
+ }
+
+ // See whether we can get the resource from the required bundles and
+ // regardless of whether or not this is the case continue to the next
+ // step potentially passing on the result of this search (if any).
+ for (int i = 0; (wires != null) && (i < wires.size()); i++)
+ {
+ if (wires.get(i).getRequirement().getNamespace()
+ .equals(Capability.MODULE_NAMESPACE))
+ {
+ try
+ {
+ // If we find the class or resource, then add it.
+ urls = wires.get(i).getResources(name);
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ urls = null;
+ }
+ if (urls != null)
+ {
+ completeUrlList.add(urls);
+ }
+ }
+ }
+
+ // Try the module's own class path. If we can find the resource then
+ // return it together with the results from the other searches else
+ // try to look into the dynamic imports.
+ urls = getResourcesLocal(name);
+ if ((urls != null) && (urls.hasMoreElements()))
+ {
+ completeUrlList.add(urls);
+ }
+ else
+ {
+ // If not found, then try the module's dynamic imports.
+ // At this point, the module's imports were searched and so was the
+ // the module's content. Now we make an attempt to load the
+ // class/resource via a dynamic import, if possible.
+ Wire wire = null;
+ try
+ {
+ wire = m_resolver.resolve(this, pkgName);
+ }
+ catch (ResolveException ex)
+ {
+ // Ignore this since it is likely normal.
+ }
+ if (wire != null)
+ {
+ try
+ {
+ urls = wire.getResources(name);
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ urls = null;
+ }
+ if (urls != null)
+ {
+ completeUrlList.add(urls);
+ }
+ }
+ }
+
+ return new CompoundEnumeration((Enumeration[])
+ completeUrlList.toArray(new Enumeration[completeUrlList.size()]));
+ }
+
+ private Enumeration getResourcesLocal(String name)
+ {
+ List l = new ArrayList();
+
+ // Special case "/" so that it returns a root URLs for
+ // each bundle class path entry...this isn't very
+ // clean or meaningful, but the Spring guys want it.
+ final Content[] contentPath = getContentPath();
+ if (name.equals("/"))
+ {
+ for (int i = 0; i < contentPath.length; i++)
+ {
+ l.add(createURL(i + 1, name));
+ }
+ }
+ else
+ {
+ // Remove leading slash, if present.
+ if (name.startsWith("/"))
+ {
+ name = name.substring(1);
+ }
+
+ // Check the module class path.
+ for (int i = 0; i < contentPath.length; i++)
+ {
+ if (contentPath[i].hasEntry(name))
+ {
+ // Use the class path index + 1 for creating the path so
+ // that we can differentiate between module content URLs
+ // (where the path will start with 0) and module class
+ // path URLs.
+ l.add(createURL(i + 1, name));
+ }
+ }
+ }
+
+ return Collections.enumeration(l);
+ }
+
+ // TODO: API: Investigate how to handle this better, perhaps we need
+ // multiple URL policies, one for content -- one for class path.
+ public URL getEntry(String name)
+ {
+ URL url = null;
+
+ // Check for the special case of "/", which represents
+ // the root of the bundle according to the spec.
+ if (name.equals("/"))
+ {
+ url = createURL(0, "/");
+ }
+
+ if (url == null)
+ {
+ // Remove leading slash, if present.
+ if (name.startsWith("/"))
+ {
+ name = name.substring(1);
+ }
+
+ // Check the module content.
+ if (getContent().hasEntry(name))
+ {
+ // Module content URLs start with 0, whereas module
+ // class path URLs start with the index into the class
+ // path + 1.
+ url = createURL(0, name);
+ }
+ }
+
+ return url;
+ }
+
+ public boolean hasInputStream(int index, String urlPath)
+ {
+ if (urlPath.startsWith("/"))
+ {
+ urlPath = urlPath.substring(1);
+ }
+ if (index == 0)
+ {
+ return m_content.hasEntry(urlPath);
+ }
+ return getContentPath()[index - 1].hasEntry(urlPath);
+ }
+
+ public InputStream getInputStream(int index, String urlPath)
+ throws IOException
+ {
+ if (urlPath.startsWith("/"))
+ {
+ urlPath = urlPath.substring(1);
+ }
+ if (index == 0)
+ {
+ return m_content.getEntryAsStream(urlPath);
+ }
+ return getContentPath()[index - 1].getEntryAsStream(urlPath);
+ }
+
+ public URL getLocalURL(int index, String urlPath)
+ {
+ if (urlPath.startsWith("/"))
+ {
+ urlPath = urlPath.substring(1);
+ }
+ if (index == 0)
+ {
+ return m_content.getEntryAsURL(urlPath);
+ }
+ return getContentPath()[index - 1].getEntryAsURL(urlPath);
+ }
+
+ private URL createURL(int port, String path)
+ {
+ // Add a slash if there is one already, otherwise
+ // the is no slash separating the host from the file
+ // in the resulting URL.
+ if (!path.startsWith("/"))
+ {
+ path = "/" + path;
+ }
+
+ try
+ {
+ return m_secureAction.createURL(null,
+ FelixConstants.BUNDLE_URL_PROTOCOL + "://" +
+ m_id + ":" + port + path, m_streamHandler);
+ }
+ catch (MalformedURLException ex)
+ {
+ m_logger.log(m_bundle,
+ Logger.LOG_ERROR,
+ "Unable to create resource URL.",
+ ex);
+ }
+ return null;
+ }
+
+ //
+ // Fragment and dependency management methods.
+ //
+
+ public synchronized List<Module> getFragments()
+ {
+ return m_fragments;
+ }
+
+ public synchronized void attachFragments(List<Module> fragments) throws Exception
+ {
+ // Remove the host wires for this module from old fragments.
+ // We will generally only remove host wires when we are uninstalling
+ // the module.
+ for (int i = 0; (m_fragments != null) && (i < m_fragments.size()); i++)
+ {
+ // If the fragment has no wires, then there is no reason to try to
+ // remove ourself from its wires since it has apparently already
+ // been refreshed.
+ if (m_fragments.get(i).getWires() != null)
+ {
+ List<Wire> hostWires = new ArrayList<Wire>(m_fragments.get(i).getWires());
+ for (Iterator<Wire> it = hostWires.iterator(); it.hasNext(); )
+ {
+ Wire hostWire = it.next();
+ if (hostWire.getExporter().equals(this))
+ {
+ it.remove();
+ ((ModuleImpl) m_fragments.get(i)).setWires(hostWires);
+ break;
+ }
+ }
+ }
+ }
+
+ // Close previous fragment contents.
+ for (int i = 0; (m_fragmentContents != null) && (i < m_fragmentContents.length); i++)
+ {
+ m_fragmentContents[i].close();
+ }
+ m_fragmentContents = null;
+
+ // Close the old content path, since we'll need to recalculate it for
+ // for the added (or removed) fragments.
+ for (int i = 0; (m_contentPath != null) && (i < m_contentPath.length); i++)
+ {
+ // Don't close this module's content, if it is on the content path.
+ if (m_content != m_contentPath[i])
+ {
+ m_contentPath[i].close();
+ }
+ }
+ m_contentPath = null;
+
+ // Remove cached capabilities and requirements.
+ m_cachedCapabilities = null;
+ m_cachedRequirements = null;
+ m_cachedDynamicRequirements = null;
+
+ // Update the dependencies on the new fragments.
+ m_fragments = fragments;
+
+ // We need to sort the fragments and add ourself as a dependent of each one.
+ // We also need to create an array of fragment contents to attach to our
+ // content path.
+ if (m_fragments != null)
+ {
+ // Sort fragments according to ID order, if necessary.
+ // Note that this sort order isn't 100% correct since
+ // it uses a string, but it is likely close enough and
+ // avoids having to create more objects.
+ if (m_fragments.size() > 1)
+ {
+ SortedMap<String, Module> sorted = new TreeMap<String, Module>();
+ for (Module f : m_fragments)
+ {
+ sorted.put(f.getId(), f);
+ }
+ m_fragments = new ArrayList(sorted.values());
+ }
+ m_fragmentContents = new Content[m_fragments.size()];
+ for (int i = 0; (m_fragments != null) && (i < m_fragments.size()); i++)
+ {
+ m_fragmentContents[i] =
+ m_fragments.get(i).getContent()
+ .getEntryAsContent(FelixConstants.CLASS_PATH_DOT);
+ }
+ // Recalculate the content path for the new fragments.
+ m_contentPath = initializeContentPath();
+ }
+ }
+
+ public synchronized List<Module> getDependentImporters()
+ {
+ return m_dependentImporters;
+ }
+
+ public synchronized void addDependentImporter(Module module)
+ {
+ if (!m_dependentImporters.contains(module))
+ {
+ m_dependentImporters.add(module);
+ }
+ }
+
+ public synchronized void removeDependentImporter(Module module)
+ {
+ m_dependentImporters.remove(module);
+ }
+
+ public synchronized List<Module> getDependentRequirers()
+ {
+ return m_dependentRequirers;
+ }
+
+ public synchronized void addDependentRequirer(Module module)
+ {
+ if (!m_dependentRequirers.contains(module))
+ {
+ m_dependentRequirers.add(module);
+ }
+ }
+
+ public synchronized void removeDependentRequirer(Module module)
+ {
+ m_dependentRequirers.remove(module);
+ }
+
+ public synchronized List<Module> getDependents()
+ {
+ List<Module> dependents;
+ if (Util.isFragment(this))
+ {
+ dependents = new ArrayList<Module>();
+ for (int i = 0; (m_wires != null) && (i < m_wires.size()); i++)
+ {
+ dependents.add(m_wires.get(i).getExporter());
+ }
+ }
+ else
+ {
+ dependents = new ArrayList<Module>
+ (m_dependentImporters.size() + m_dependentRequirers.size());
+ dependents.addAll(m_dependentImporters);
+ dependents.addAll(m_dependentRequirers);
+ }
+ return dependents;
+ }
+
+ public synchronized void close()
+ {
+ m_content.close();
+ for (int i = 0; (m_contentPath != null) && (i < m_contentPath.length); i++)
+ {
+ m_contentPath[i].close();
+ }
+ m_contentPath = null;
+ for (int i = 0; (m_fragmentContents != null) && (i < m_fragmentContents.length); i++)
+ {
+ m_fragmentContents[i].close();
+ }
+ m_fragmentContents = null;
+ m_classLoader = null;
+ }
+
+ @Override
+ public String toString()
+ {
+ return m_id;
+ }
+
+ private synchronized ModuleClassLoader getClassLoader()
+ {
+ if (m_classLoader == null)
+ {
+ // Determine which class loader to use based on which
+ // Java platform we are running on.
+ Class clazz;
+ if (m_isPreJava5)
+ {
+ clazz = ModuleClassLoader.class;
+ }
+ else
+ {
+ try
+ {
+ clazz = ModuleClassLoaderJava5.class;
+ }
+ catch (Throwable th)
+ {
+ // If we are on pre-Java5 then we will get a verify error
+ // here since we try to override a getResources() which is
+ // a final method in pre-Java5.
+ m_isPreJava5 = true;
+ clazz = ModuleClassLoader.class;
+ }
+ }
+
+ // Use SecureAction to create the class loader if security is
+ // enabled; otherwise, create it directly.
+ try
+ {
+ Constructor ctor = (Constructor) m_secureAction.getConstructor(
+ clazz, new Class[] { ModuleImpl.class, ClassLoader.class });
+ m_classLoader = (ModuleClassLoader)
+ m_secureAction.invoke(ctor,
+ new Object[] { this, determineParentClassLoader() });
+ }
+ catch (Exception ex)
+ {
+ throw new RuntimeException("Unable to create module class loader: "
+ + ex.getMessage() + " [" + ex.getClass().getName() + "]");
+ }
+ }
+ return m_classLoader;
+ }
+
+ private ClassLoader determineParentClassLoader()
+ {
+ // Determine the class loader's parent based on the
+ // configuration property; use boot class loader by
+ // default.
+ String cfg = (String) m_configMap.get(Constants.FRAMEWORK_BUNDLE_PARENT);
+ cfg = (cfg == null) ? Constants.FRAMEWORK_BUNDLE_PARENT_BOOT : cfg;
+ final ClassLoader parent;
+ if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_APP))
+ {
+ parent = m_secureAction.getSystemClassLoader();
+ }
+ else if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_EXT))
+ {
+ parent = m_secureAction.getParentClassLoader(m_secureAction.getSystemClassLoader());
+ }
+ else if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK))
+ {
+ parent = m_secureAction.getClassLoader(ModuleImpl.class);
+ }
+ // On Android we cannot set the parent class loader to be null, so
+ // we special case that situation here and set it to the system
+ // class loader by default instead, which is not really spec.
+ else if (m_bootClassLoader == null)
+ {
+ parent = m_secureAction.getSystemClassLoader();
+ }
+ else
+ {
+ parent = null;
+ }
+ return parent;
+ }
+
+ private Object searchImports(String name, boolean isClass)
throws ClassNotFoundException, ResourceNotFoundException
{
- // Check if the package is imported.
- BundleRevision provider = m_importedPkgs.get(pkgName);
- if (provider != null)
+ // We delegate to the module's wires to find the class or resource.
+ List<Wire> wires = getWires();
+ for (int i = 0; (wires != null) && (i < wires.size()); i++)
{
// If we find the class or resource, then return it.
Object result = (isClass)
- ? (Object) ((BundleWiringImpl) provider.getWiring()).getClassByDelegation(name)
- : (Object) ((BundleWiringImpl) provider.getWiring()).getResourceByDelegation(name);
+ ? (Object) wires.get(i).getClass(name)
+ : (Object) wires.get(i).getResource(name);
if (result != null)
{
return result;
}
-
- // If no class was found, then we must throw an exception
- // since the provider of this package did not contain the
- // requested class and imported packages are atomic.
- throw new ClassNotFoundException(name);
- }
-
- // Check if the package is required.
- List<BundleRevision> providers = m_requiredPkgs.get(pkgName);
- if (providers != null)
- {
- for (BundleRevision p : providers)
- {
- // If we find the class or resource, then return it.
- try
- {
- Object result = (isClass)
- ? (Object) ((BundleWiringImpl) p.getWiring()).getClassByDelegation(name)
- : (Object) ((BundleWiringImpl) p.getWiring()).getResourceByDelegation(name);
- if (result != null)
- {
- return result;
- }
- }
- catch (ClassNotFoundException ex)
- {
- // Since required packages can be split, don't throw an
- // exception here if it is not found. Instead, we'll just
- // continue searching other required bundles and the
- // revision's local content.
- }
- }
}
return null;
}
private Object searchDynamicImports(
- final String pkgName, final String name, final boolean isClass)
+ final String name, String pkgName, final boolean isClass)
throws ClassNotFoundException, ResourceNotFoundException
{
// At this point, the module's imports were searched and so was the
// the module's content. Now we make an attempt to load the
// class/resource via a dynamic import, if possible.
- BundleRevision provider = null;
+ Wire wire = null;
try
{
- provider = m_resolver.resolve(m_revision, pkgName);
+ wire = m_resolver.resolve(this, pkgName);
}
catch (ResolveException ex)
{
@@ -990,15 +1454,15 @@
// If the dynamic import was successful, then this initial
// time we must directly return the result from dynamically
- // created package sources, but subsequent requests for
- // classes/resources in the associated package will be
- // processed as part of normal static imports.
- if (provider != null)
+ // created wire, but subsequent requests for classes/resources
+ // in the associated package will be processed as part of
+ // normal static imports.
+ if (wire != null)
{
// Return the class or resource.
return (isClass)
- ? (Object) ((BundleWiringImpl) provider.getWiring()).getClassByDelegation(name)
- : (Object) ((BundleWiringImpl) provider.getWiring()).getResourceByDelegation(name);
+ ? (Object) wire.getClass(name)
+ : (Object) wire.getResource(name);
}
// If implicit boot delegation is enabled, then try to guess whether
@@ -1077,11 +1541,11 @@
// TODO: FRAMEWORK - This check is a hack and we should see if we can think
// of another way to do it, since it won't necessarily work in all situations.
// Since Felix uses threads for changing the start level
- // and refreshing packages, it is possible that there are no
- // bundle classes on the call stack; therefore, as soon as we
+ // and refreshing packages, it is possible that there is no
+ // module classes on the call stack; therefore, as soon as we
// see Thread on the call stack we exit this loop. Other cases
- // where bundles actually use threads are not an issue because
- // the bundle classes will be on the call stack before the
+ // where modules actually use threads are not an issue because
+ // the module classes will be on the call stack before the
// Thread class.
if (Thread.class.equals(classes[i]))
{
@@ -1089,7 +1553,7 @@
}
// Break if the current class came from a bundle, since we should
// not implicitly boot delegate in that case.
- else if (isClassLoadedFromBundleRevision(classes[i]))
+ else if (isClassLoadedFromModule(classes[i]))
{
break;
}
@@ -1119,24 +1583,24 @@
return null;
}
- private boolean isClassLoadedFromBundleRevision(Class clazz)
+ private boolean isClassLoadedFromModule(Class clazz)
{
- // The target class is loaded by a bundle class loader,
+ // The target class is loaded by a module class loader,
// then return true.
- if (BundleClassLoader.class.isInstance(m_secureAction.getClassLoader(clazz)))
+ if (ModuleClassLoader.class.isInstance(m_secureAction.getClassLoader(clazz)))
{
return true;
}
// If the target class was loaded from a class loader that
- // came from a bundle, then return true.
+ // came from a module, then return true.
ClassLoader last = null;
for (ClassLoader cl = m_secureAction.getClassLoader(clazz);
(cl != null) && (last != cl);
cl = m_secureAction.getClassLoader(cl.getClass()))
{
last = cl;
- if (BundleClassLoader.class.isInstance(cl))
+ if (ModuleClassLoader.class.isInstance(cl))
{
return true;
}
@@ -1183,66 +1647,100 @@
return true;
}
- synchronized boolean isActivationTriggered()
+ boolean shouldBootDelegate(String pkgName)
{
- return m_isActivationTriggered;
- }
-
- boolean isActivationTrigger(String pkgName)
- {
- List<String> activationIncludes = m_revision.getActivationIncludes();
- List<String> activationExcludes = m_revision.getActivationExcludes();
-
- if ((activationIncludes == null) && (activationExcludes == null))
+ // Always boot delegate if the bundle has a configured
+ // boot class loader.
+ if (m_bootClassLoader != m_defBootClassLoader)
{
return true;
}
- // If there are no include filters then all classes are included
- // by default, otherwise try to find one match.
- boolean included = (activationIncludes == null);
- for (int i = 0;
- (!included) && (activationIncludes != null) && (i < activationIncludes.size());
- i++)
+ boolean result = false;
+
+ // Only consider delegation if we have a package name, since
+ // we don't want to promote the default package. The spec does
+ // not take a stand on this issue.
+ if (pkgName.length() > 0)
{
- included = activationIncludes.get(i).equals(pkgName);
+ for (int i = 0; !result && (i < m_bootPkgs.length); i++)
+ {
+ // Check if the boot package is wildcarded.
+ // A wildcarded boot package will be in the form "foo.",
+ // so a matching subpackage will start with "foo.", e.g.,
+ // "foo.bar".
+ if (m_bootPkgWildcards[i] && pkgName.startsWith(m_bootPkgs[i]))
+ {
+ return true;
+ }
+ // If not wildcarded, then check for an exact match.
+ else if (m_bootPkgs[i].equals(pkgName))
+ {
+ return true;
+ }
+ }
}
- // If there are no exclude filters then no classes are excluded
- // by default, otherwise try to find one match.
- boolean excluded = false;
- for (int i = 0;
- (!excluded) && (activationExcludes != null) && (i < activationExcludes.size());
- i++)
- {
- excluded = activationExcludes.get(i).equals(pkgName);
- }
- return included && !excluded;
+ return result;
}
- static class ToLocalUrlEnumeration implements Enumeration
+ ClassLoader getBootDelegationClassLoader()
{
- final Enumeration m_enumeration;
-
- ToLocalUrlEnumeration(Enumeration enumeration)
- {
- m_enumeration = enumeration;
- }
-
- public boolean hasMoreElements()
- {
- return m_enumeration.hasMoreElements();
- }
-
- public Object nextElement()
- {
- return convertToLocalUrl((URL) m_enumeration.nextElement());
- }
+ // Get the appropriate class loader for delegation.
+ ClassLoader parent = (m_classLoader == null)
+ ? determineParentClassLoader() : m_secureAction.getParentClassLoader(m_classLoader);
+ return (parent == null) ? m_bootClassLoader : parent;
}
- public class BundleClassLoaderJava5 extends BundleClassLoader
+ private static final Constructor m_dexFileClassConstructor;
+ private static final Method m_dexFileClassLoadDex;
+ private static final Method m_dexFileClassLoadClass;
+
+ static
{
- public BundleClassLoaderJava5(ClassLoader parent)
+ Constructor dexFileClassConstructor = null;
+ Method dexFileClassLoadDex = null;
+ Method dexFileClassLoadClass = null;
+ try
+ {
+ Class dexFileClass;
+ try
+ {
+ dexFileClass = Class.forName("dalvik.system.DexFile");
+ }
+ catch (Exception ex)
+ {
+ dexFileClass = Class.forName("android.dalvik.DexFile");
+ }
+
+ try
+ {
+ dexFileClassLoadDex = dexFileClass.getMethod("loadDex",
+ new Class[]{String.class, String.class, Integer.TYPE});
+ }
+ catch (Exception ex)
+ {
+ // Nothing we need to do
+ }
+ dexFileClassConstructor = dexFileClass.getConstructor(
+ new Class[] { java.io.File.class });
+ dexFileClassLoadClass = dexFileClass.getMethod("loadClass",
+ new Class[] { String.class, ClassLoader.class });
+ }
+ catch (Throwable ex)
+ {
+ dexFileClassConstructor = null;
+ dexFileClassLoadDex = null;
+ dexFileClassLoadClass = null;
+ }
+ m_dexFileClassConstructor = dexFileClassConstructor;
+ m_dexFileClassLoadDex= dexFileClassLoadDex;
+ m_dexFileClassLoadClass = dexFileClassLoadClass;
+ }
+
+ public class ModuleClassLoaderJava5 extends ModuleClassLoader
+ {
+ public ModuleClassLoaderJava5(ClassLoader parent)
{
super(parent);
}
@@ -1250,7 +1748,7 @@
@Override
public Enumeration getResources(String name)
{
- Enumeration urls = BundleWiringImpl.this.getResourcesByDelegation(name);
+ Enumeration urls = ModuleImpl.this.getResourcesByDelegation(name);
if (m_useLocalURLs)
{
urls = new ToLocalUrlEnumeration(urls);
@@ -1261,18 +1759,18 @@
@Override
protected Enumeration findResources(String name)
{
- return m_revision.getResourcesLocal(name);
+ return ModuleImpl.this.getResourcesLocal(name);
}
}
- public class BundleClassLoader extends SecureClassLoader implements BundleReference
+ public class ModuleClassLoader extends SecureClassLoader implements BundleReference
{
private final Map m_jarContentToDexFile;
private Object[][] m_cachedLibs = new Object[0][];
private static final int LIBNAME_IDX = 0;
private static final int LIBPATH_IDX = 1;
- public BundleClassLoader(ClassLoader parent)
+ public ModuleClassLoader(ClassLoader parent)
{
super(parent);
if (m_dexFileClassLoadClass != null)
@@ -1287,7 +1785,7 @@
public Bundle getBundle()
{
- return BundleWiringImpl.this.getBundle();
+ return ModuleImpl.this.getBundle();
}
@Override
@@ -1319,7 +1817,7 @@
String msg = name;
if (m_logger.getLogLevel() >= Logger.LOG_DEBUG)
{
- msg = diagnoseClassLoadError(m_resolver, m_revision, name);
+ msg = diagnoseClassLoadError(m_resolver, ModuleImpl.this, name);
ex = (msg != null)
? new ClassNotFoundException(msg, cnfe)
: ex;
@@ -1341,22 +1839,22 @@
{
Class clazz = null;
- // Search for class in bundle revision.
+ // Search for class in module.
if (clazz == null)
{
String actual = name.replace('.', '/') + ".class";
byte[] bytes = null;
- // Check the bundle class path.
- List<Content> contentPath = m_revision.getContentPath();
+ // Check the module class path.
+ Content[] contentPath = getContentPath();
Content content = null;
for (int i = 0;
(bytes == null) &&
- (i < contentPath.size()); i++)
+ (i < contentPath.length); i++)
{
- bytes = contentPath.get(i).getEntryAsBytes(actual);
- content = contentPath.get(i);
+ bytes = contentPath[i].getEntryAsBytes(actual);
+ content = contentPath[i];
}
if (bytes != null)
@@ -1375,20 +1873,19 @@
{
int activationPolicy =
((BundleImpl) getBundle()).isDeclaredActivationPolicyUsed()
- ? ((BundleRevisionImpl) ((BundleImpl) getBundle())
- .getCurrentRevision()).getDeclaredActivationPolicy()
- : EAGER_ACTIVATION;
+ ? ((BundleImpl) getBundle()).getCurrentModule().getDeclaredActivationPolicy()
+ : Module.EAGER_ACTIVATION;
- // If the revision is using deferred activation, then if
- // we load this class from this revision we need to activate
- // the bundle before returning the class. We will short
+ // If the module is using deferred activation, then if
+ // we load this class from this module we need to activate
+ // the module before returning the class. We will short
// circuit the trigger matching if the trigger is already
// tripped.
boolean isTriggerClass = m_isActivationTriggered
? false : isActivationTrigger(pkgName);
if (!m_isActivationTriggered
&& isTriggerClass
- && (activationPolicy == BundleRevisionImpl.LAZY_ACTIVATION)
+ && (activationPolicy == Module.LAZY_ACTIVATION)
&& (getBundle().getState() == Bundle.STARTING))
{
List deferredList = (List) m_deferredActivation.get();
@@ -1460,7 +1957,6 @@
// activation trigger has tripped.
if (!m_isActivationTriggered && isTriggerClass && (clazz != null))
{
-// TODO: OSGi R4.3 - This isn't protected by the correct lock.
m_isActivationTriggered = true;
}
}
@@ -1495,12 +1991,12 @@
private Object[] definePackage(String pkgName)
{
- String spectitle = (String) m_revision.getHeaders().get("Specification-Title");
- String specversion = (String) m_revision.getHeaders().get("Specification-Version");
- String specvendor = (String) m_revision.getHeaders().get("Specification-Vendor");
- String impltitle = (String) m_revision.getHeaders().get("Implementation-Title");
- String implversion = (String) m_revision.getHeaders().get("Implementation-Version");
- String implvendor = (String) m_revision.getHeaders().get("Implementation-Vendor");
+ String spectitle = (String) m_headerMap.get("Specification-Title");
+ String specversion = (String) m_headerMap.get("Specification-Version");
+ String specvendor = (String) m_headerMap.get("Specification-Vendor");
+ String impltitle = (String) m_headerMap.get("Implementation-Title");
+ String implversion = (String) m_headerMap.get("Implementation-Version");
+ String implvendor = (String) m_headerMap.get("Implementation-Vendor");
if ((spectitle != null)
|| (specversion != null)
|| (specvendor != null)
@@ -1562,7 +2058,7 @@
@Override
public URL getResource(String name)
{
- URL url = BundleWiringImpl.this.getResourceByDelegation(name);
+ URL url = ModuleImpl.this.getResourceByDelegation(name);
if (m_useLocalURLs)
{
url = convertToLocalUrl(url);
@@ -1573,10 +2069,10 @@
@Override
protected URL findResource(String name)
{
- return m_revision.getResourceLocal(name);
+ return ModuleImpl.this.getResourceLocal(name);
}
- // The findResources() method should only look at the revision itself, but
+ // The findResources() method should only look at the module itself, but
// instead it tries to delegate because in Java version prior to 1.5 the
// getResources() method was final and could not be overridden. We should
// override getResources() like getResource() to make it delegate, but we
@@ -1584,7 +2080,7 @@
@Override
protected Enumeration findResources(String name)
{
- Enumeration urls = BundleWiringImpl.this.getResourcesByDelegation(name);
+ Enumeration urls = ModuleImpl.this.getResourcesByDelegation(name);
if (m_useLocalURLs)
{
urls = new ToLocalUrlEnumeration(urls);
@@ -1626,15 +2122,15 @@
if (libs.get(libIdx).match(m_configMap, name))
{
// Search bundle content first for native library.
- result = m_revision.getContent().getEntryAsNativeLibrary(
+ result = getContent().getEntryAsNativeLibrary(
libs.get(libIdx).getEntryName());
// If not found, then search fragments in order.
for (int i = 0;
(result == null) && (m_fragmentContents != null)
- && (i < m_fragmentContents.size());
+ && (i < m_fragmentContents.length);
i++)
{
- result = m_fragmentContents.get(i).getEntryAsNativeLibrary(
+ result = m_fragmentContents[i].getEntryAsNativeLibrary(
libs.get(libIdx).getEntryName());
}
}
@@ -1657,7 +2153,7 @@
@Override
public String toString()
{
- return BundleWiringImpl.this.toString();
+ return ModuleImpl.this.toString();
}
}
@@ -1678,8 +2174,28 @@
return url;
}
+ static class ToLocalUrlEnumeration implements Enumeration
+ {
+ final Enumeration m_enumeration;
+
+ ToLocalUrlEnumeration(Enumeration enumeration)
+ {
+ m_enumeration = enumeration;
+ }
+
+ public boolean hasMoreElements()
+ {
+ return m_enumeration.hasMoreElements();
+ }
+
+ public Object nextElement()
+ {
+ return convertToLocalUrl((URL) m_enumeration.nextElement());
+ }
+ }
+
private static String diagnoseClassLoadError(
- StatefulResolver resolver, BundleRevision revision, String name)
+ StatefulResolver resolver, ModuleImpl module, String name)
{
// We will try to do some diagnostics here to help the developer
// deal with this exception.
@@ -1691,18 +2207,17 @@
return null;
}
- // First, get the bundle string of the revision doing the class loader.
- String importer = revision.getBundle().toString();
+ // First, get the bundle string of the module doing the class loader.
+ String importer = module.getBundle().toString();
- // Next, check to see if the revision imports the package.
- List<BundleWire> wires = (revision.getWiring() == null)
- ? null : revision.getWiring().getProvidedWires(null);
+ // Next, check to see if the module imports the package.
+ List<Wire> wires = module.getWires();
for (int i = 0; (wires != null) && (i < wires.size()); i++)
{
- if (wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
- wires.get(i).getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
+ if (wires.get(i).getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
+ wires.get(i).getCapability().getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
{
- String exporter = wires.get(i).getProviderWiring().getBundle().toString();
+ String exporter = wires.get(i).getExporter().getBundle().toString();
StringBuffer sb = new StringBuffer("*** Package '");
sb.append(pkgName);
@@ -1726,7 +2241,7 @@
// Next, check to see if the package was optionally imported and
// whether or not there is an exporter available.
- List<BundleRequirement> reqs = revision.getWiring().getRequirements(null);
+ List<Requirement> reqs = module.getRequirements();
/*
* TODO: RB - Fix diagnostic message for optional imports.
for (int i = 0; (reqs != null) && (i < reqs.length); i++)
@@ -1785,29 +2300,29 @@
}
}
*/
- // Next, check to see if the package is dynamically imported by the revision.
- if (resolver.isAllowedDynamicImport(revision, pkgName))
+ // Next, check to see if the package is dynamically imported by the module.
+ if (resolver.isAllowedDynamicImport(module, pkgName))
{
// Try to see if there is an exporter available.
- Map<String, String> dirs = Collections.EMPTY_MAP;
- Map<String, Object> attrs = new HashMap<String, Object>(1);
- attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
- BundleRequirementImpl req = new BundleRequirementImpl(
- revision, BundleCapabilityImpl.PACKAGE_NAMESPACE, dirs, attrs);
- Set<BundleCapability> exporters = resolver.getCandidates(req, false);
+ List<Directive> dirs = Collections.EMPTY_LIST;
+ List<Attribute> attrs = new ArrayList(1);
+ attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
+ Requirement req = new RequirementImpl(
+ module, Capability.PACKAGE_NAMESPACE, dirs, attrs);
+ Set<Capability> exporters = resolver.getCandidates(req, false);
- BundleRevision provider = null;
+ Wire wire = null;
try
{
- provider = resolver.resolve(revision, pkgName);
+ wire = resolver.resolve(module, pkgName);
}
catch (Exception ex)
{
- provider = null;
+ wire = null;
}
String exporter = (exporters.isEmpty())
- ? null : exporters.iterator().next().getRevision().getBundle().toString();
+ ? null : exporters.iterator().next().getModule().getBundle().toString();
StringBuffer sb = new StringBuffer("*** Class '");
sb.append(name);
@@ -1816,7 +2331,7 @@
sb.append("' is dynamically imported by bundle ");
sb.append(importer);
sb.append(".");
- if ((exporters.size() > 0) && (provider == null))
+ if ((exporters.size() > 0) && (wire == null))
{
sb.append(" However, bundle ");
sb.append(exporter);
@@ -1828,18 +2343,18 @@
}
// Next, check to see if there are any exporters for the package at all.
- Map<String, String> dirs = Collections.EMPTY_MAP;
- Map<String, Object> attrs = new HashMap<String, Object>(1);
- attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
- BundleRequirementImpl req = new BundleRequirementImpl(
- revision, BundleCapabilityImpl.PACKAGE_NAMESPACE, dirs, attrs);
- Set<BundleCapability> exports = resolver.getCandidates(req, false);
+ List<Directive> dirs = Collections.EMPTY_LIST;
+ List<Attribute> attrs = new ArrayList(1);
+ attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
+ Requirement req = new RequirementImpl(
+ module, Capability.PACKAGE_NAMESPACE, dirs, attrs);
+ Set<Capability> exports = resolver.getCandidates(req, false);
if (exports.size() > 0)
{
boolean classpath = false;
try
{
- m_secureAction.getClassLoader(BundleClassLoader.class).loadClass(name);
+ m_secureAction.getClassLoader(ModuleClassLoader.class).loadClass(name);
classpath = true;
}
catch (NoClassDefFoundError err)
@@ -1851,7 +2366,7 @@
// Ignore
}
- String exporter = exports.iterator().next().getRevision().getBundle().toString();
+ String exporter = exports.iterator().next().getModule().getBundle().toString();
StringBuffer sb = new StringBuffer("*** Class '");
sb.append(name);
@@ -1892,7 +2407,7 @@
// class loader.
try
{
- m_secureAction.getClassLoader(BundleClassLoader.class).loadClass(name);
+ m_secureAction.getClassLoader(ModuleClassLoader.class).loadClass(name);
StringBuffer sb = new StringBuffer("*** Package '");
sb.append(pkgName);
@@ -1935,4 +2450,4 @@
return sb.toString();
}
-}
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
index 73ae668..09ac0bc 100644
--- a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
@@ -19,14 +19,14 @@
package org.apache.felix.framework;
import java.util.*;
+import org.apache.felix.framework.resolver.Module;
+import org.apache.felix.framework.resolver.Wire;
import org.apache.felix.framework.util.VersionRange;
import org.osgi.framework.AdminPermission;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.packageadmin.RequiredBundle;
@@ -114,7 +114,7 @@
String sym = bundles[i].getSymbolicName();
if ((sym != null) && sym.equals(symbolicName))
{
- Version v = ((BundleImpl) bundles[i]).getCurrentRevision().getVersion();
+ Version v = ((BundleImpl) bundles[i]).getCurrentModule().getVersion();
if ((vr == null) || vr.isInRange(v))
{
list.add(bundles[i]);
@@ -129,8 +129,8 @@
Arrays.sort(bundles,new Comparator() {
public int compare(Object o1, Object o2)
{
- Version v1 = ((BundleImpl) o1).getCurrentRevision().getVersion();
- Version v2 = ((BundleImpl) o2).getCurrentRevision().getVersion();
+ Version v1 = ((BundleImpl) o1).getCurrentModule().getVersion();
+ Version v2 = ((BundleImpl) o2).getCurrentModule().getVersion();
// Compare in reverse order to get descending sort.
return v2.compareTo(v1);
}
@@ -140,8 +140,7 @@
public int getBundleType(Bundle bundle)
{
- Map headerMap = ((BundleRevisionImpl)
- ((BundleImpl) bundle).getCurrentRevision()).getHeaders();
+ Map headerMap = ((BundleImpl) bundle).getCurrentModule().getHeaders();
if (headerMap.containsKey(Constants.FRAGMENT_HOST))
{
return PackageAdmin.BUNDLE_TYPE_FRAGMENT;
@@ -196,14 +195,15 @@
if ((getBundleType(bundle) & BUNDLE_TYPE_FRAGMENT) == 0)
{
List<Bundle> list = new ArrayList<Bundle>();
- // Iterate through revisions
- for (BundleRevision revision : ((BundleImpl) bundle).getRevisions())
+ // Iterate through modules
+ List<Module> modules = ((BundleImpl) bundle).getModules();
+ for (int modIdx = 0; modIdx < modules.size(); modIdx++)
{
// Get attached fragments.
- if (revision.getWiring() != null)
+ ModuleImpl module = (ModuleImpl) modules.get(modIdx);
+ if (module.isResolved())
{
- List<BundleRevision> fragments =
- ((BundleWiringImpl) revision.getWiring()).getFragments();
+ List<Module> fragments = module.getFragments();
for (int i = 0; (fragments != null) && (i < fragments.size()); i++)
{
Bundle b = fragments.get(i).getBundle();
@@ -215,7 +215,7 @@
}
}
// Convert list to an array.
- return (list.isEmpty())
+ return (list.size() == 0)
? null
: (Bundle[]) list.toArray(new Bundle[list.size()]);
}
@@ -228,16 +228,18 @@
if ((getBundleType(bundle) & BUNDLE_TYPE_FRAGMENT) != 0)
{
List<Bundle> list = new ArrayList<Bundle>();
- // Iterate through revisions
- for (BundleRevision revision : ((BundleImpl) bundle).getRevisions())
+ // Iterate through modules
+ List<Module> modules = ((BundleImpl) bundle).getModules();
+ for (int modIdx = 0; modIdx < modules.size(); modIdx++)
{
// Get hosts
- if (revision.getWiring() != null)
+ ModuleImpl module = (ModuleImpl) modules.get(modIdx);
+ if (module.isResolved())
{
- List<BundleWire> hostWires = revision.getWiring().getRequiredWires(null);
+ List<Wire> hostWires = module.getWires();
for (int i = 0; (hostWires != null) && (i < hostWires.size()); i++)
{
- Bundle b = hostWires.get(i).getProviderWiring().getBundle();
+ Bundle b = hostWires.get(i).getExporter().getBundle();
if (b != null)
{
list.add(b);
@@ -256,15 +258,17 @@
public RequiredBundle[] getRequiredBundles(String symbolicName)
{
List list = new ArrayList();
- for (Bundle bundle : m_felix.getBundles())
+ Bundle[] bundles = m_felix.getBundles();
+ for (int i = 0; i < bundles.length; i++)
{
+ BundleImpl impl = (BundleImpl) bundles[i];
if ((symbolicName == null)
- || (symbolicName.equals(bundle.getSymbolicName())))
+ || (symbolicName.equals(impl.getCurrentModule().getSymbolicName())))
{
- list.add(new RequiredBundleImpl(m_felix, (BundleImpl) bundle));
+ list.add(new RequiredBundleImpl(m_felix, impl));
}
}
- return (list.isEmpty())
+ return (list.size() == 0)
? null
: (RequiredBundle[]) list.toArray(new RequiredBundle[list.size()]);
}
diff --git a/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java b/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java
index 855223b..9f013a6 100644
--- a/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java
@@ -18,7 +18,10 @@
*/
package org.apache.felix.framework;
+import java.util.HashSet;
+import java.util.List;
import java.util.Set;
+import org.apache.felix.framework.resolver.Module;
import org.osgi.framework.Bundle;
import org.osgi.framework.Version;
import org.osgi.service.packageadmin.RequiredBundle;
@@ -48,18 +51,38 @@
public Bundle[] getRequiringBundles()
{
- // If the package is stale, then return null per the spec.
+ // Spec says to return null for stale bundles.
if (m_bundle.isStale())
{
return null;
}
- Set<Bundle> set = m_felix.getRequiringBundles(m_bundle);
- return set.toArray(new Bundle[set.size()]);
+
+ // We need to find all modules that require any of the modules
+ // associated with this bundle and save the associated bundle
+ // of the dependent modules.
+ Set bundleSet = new HashSet();
+ // Loop through all of this bundle's modules.
+ List<Module> modules = m_bundle.getModules();
+ for (int modIdx = 0; (modules != null) && (modIdx < modules.size()); modIdx++)
+ {
+ // For each of this bundle's modules, loop through all of the
+ // modules that require it and add them to the module list.
+ List<Module> dependents = ((ModuleImpl) modules.get(modIdx)).getDependentRequirers();
+ for (int depIdx = 0; (dependents != null) && (depIdx < dependents.size()); depIdx++)
+ {
+ if (dependents.get(depIdx).getBundle() != null)
+ {
+ bundleSet.add(dependents.get(depIdx).getBundle());
+ }
+ }
+ }
+ // Convert to an array.
+ return (Bundle[]) bundleSet.toArray(new Bundle[bundleSet.size()]);
}
public Version getVersion()
{
- return m_bundle.getVersion();
+ return m_bundle.getCurrentModule().getVersion();
}
public boolean isRemovalPending()
@@ -72,7 +95,7 @@
if (m_toString == null)
{
m_toString = m_bundle.getSymbolicName()
- + "; version=" + m_bundle.getVersion();
+ + "; version=" + m_bundle.getCurrentModule().getVersion();
}
return m_toString;
}
diff --git a/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java b/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
index 6d983c9..f9937b0 100644
--- a/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
@@ -27,28 +27,27 @@
import java.util.SortedSet;
import java.util.StringTokenizer;
import java.util.TreeSet;
+import org.apache.felix.framework.capabilityset.Capability;
import org.apache.felix.framework.capabilityset.CapabilitySet;
+import org.apache.felix.framework.capabilityset.Requirement;
import org.apache.felix.framework.resolver.CandidateComparator;
+import org.apache.felix.framework.resolver.Module;
import org.apache.felix.framework.resolver.ResolveException;
import org.apache.felix.framework.resolver.Resolver;
+import org.apache.felix.framework.resolver.Wire;
import org.apache.felix.framework.util.Util;
import org.apache.felix.framework.util.manifestparser.R4Library;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
import org.osgi.framework.BundlePermission;
import org.osgi.framework.Constants;
import org.osgi.framework.PackagePermission;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
class ResolverStateImpl implements Resolver.ResolverState
{
private final Logger m_logger;
- // Set of all revisions.
- private final Set<BundleRevision> m_revisions;
+ // Set of all modules.
+ private final Set<Module> m_modules;
// Set of all fragments.
- private final Set<BundleRevision> m_fragments;
+ private final Set<Module> m_fragments;
// Capability sets.
private final Map<String, CapabilitySet> m_capSets;
// Execution environment.
@@ -56,21 +55,11 @@
// Parsed framework environments
private final Set<String> m_fwkExecEnvSet;
-// void dump()
-// {
-// for (Entry<String, CapabilitySet> entry : m_capSets.entrySet())
-// {
-// System.out.println("+++ START CAPSET " + entry.getKey());
-// entry.getValue().dump();
-// System.out.println("+++ END CAPSET " + entry.getKey());
-// }
-// }
-
ResolverStateImpl(Logger logger, String fwkExecEnvStr)
{
m_logger = logger;
- m_revisions = new HashSet<BundleRevision>();
- m_fragments = new HashSet<BundleRevision>();
+ m_modules = new HashSet<Module>();
+ m_fragments = new HashSet<Module>();
m_capSets = new HashMap<String, CapabilitySet>();
m_fwkExecEnvStr = (fwkExecEnvStr != null) ? fwkExecEnvStr.trim() : null;
@@ -78,26 +67,24 @@
List<String> indices = new ArrayList<String>();
indices.add(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
- m_capSets.put(BundleCapabilityImpl.BUNDLE_NAMESPACE, new CapabilitySet(indices, true));
+ m_capSets.put(Capability.MODULE_NAMESPACE, new CapabilitySet(indices, true));
indices = new ArrayList<String>();
- indices.add(BundleCapabilityImpl.PACKAGE_ATTR);
- m_capSets.put(BundleCapabilityImpl.PACKAGE_NAMESPACE, new CapabilitySet(indices, true));
+ indices.add(Capability.PACKAGE_ATTR);
+ m_capSets.put(Capability.PACKAGE_NAMESPACE, new CapabilitySet(indices, true));
indices = new ArrayList<String>();
indices.add(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
- m_capSets.put(BundleCapabilityImpl.HOST_NAMESPACE, new CapabilitySet(indices, true));
+ m_capSets.put(Capability.HOST_NAMESPACE, new CapabilitySet(indices, true));
}
- synchronized void addRevision(BundleRevision br)
+ synchronized void addModule(Module m)
{
- m_revisions.add(br);
- List<BundleCapability> caps = (br.getWiring() == null)
- ? br.getDeclaredCapabilities(null)
- : br.getWiring().getCapabilities(null);
+ m_modules.add(m);
+ List<Capability> caps = m.getCapabilities();
if (caps != null)
{
- for (BundleCapability cap : caps)
+ for (Capability cap : caps)
{
CapabilitySet capSet = m_capSets.get(cap.getNamespace());
if (capSet == null)
@@ -109,21 +96,19 @@
}
}
- if (Util.isFragment(br))
+ if (Util.isFragment(m))
{
- m_fragments.add(br);
+ m_fragments.add(m);
}
}
- synchronized void removeRevision(BundleRevision br)
+ synchronized void removeModule(Module m)
{
- m_revisions.remove(br);
- List<BundleCapability> caps = (br.getWiring() == null)
- ? br.getDeclaredCapabilities(null)
- : br.getWiring().getCapabilities(null);
+ m_modules.remove(m);
+ List<Capability> caps = m.getCapabilities();
if (caps != null)
{
- for (BundleCapability cap : caps)
+ for (Capability cap : caps)
{
CapabilitySet capSet = m_capSets.get(cap.getNamespace());
if (capSet != null)
@@ -133,39 +118,42 @@
}
}
- if (Util.isFragment(br))
+ if (Util.isFragment(m))
{
- m_fragments.remove(br);
+ m_fragments.remove(m);
}
}
- synchronized Set<BundleRevision> getFragments()
+ synchronized Set<Module> getFragments()
{
return new HashSet(m_fragments);
}
-// TODO: OSGi R4.3 - This will need to be changed once BundleWiring.getCapabilities()
-// is correctly implemented, since it already has to remove substituted caps.
- synchronized void removeSubstitutedCapabilities(BundleRevision br)
+ synchronized void removeSubstitutedCapabilities(Module module)
{
- if (br.getWiring() != null)
+ if (module.isResolved())
{
- // Loop through the revision's package wires and determine if any
- // of them overlap any of the packages exported by the revision.
- // If so, then the framework must have chosen to have the revision
+ // Loop through the module's package wires and determine if any
+ // of them overlap any of the packages exported by the module.
+ // If so, then the framework must have chosen to have the module
// import rather than export the package, so we need to remove the
// corresponding package capability from the package capability set.
- for (BundleWire w : br.getWiring().getRequiredWires(null))
+ List<Wire> wires = module.getWires();
+ List<Capability> caps = module.getCapabilities();
+ for (int wireIdx = 0; (wires != null) && (wireIdx < wires.size()); wireIdx++)
{
- if (w.getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ Wire wire = wires.get(wireIdx);
+ if (wire.getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
- for (BundleCapability cap : br.getWiring().getCapabilities(null))
+ for (int capIdx = 0;
+ (caps != null) && (capIdx < caps.size());
+ capIdx++)
{
- if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
- && w.getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)
- .equals(cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)))
+ if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+ && wire.getCapability().getAttribute(Capability.PACKAGE_ATTR).getValue()
+ .equals(caps.get(capIdx).getAttribute(Capability.PACKAGE_ATTR).getValue()))
{
- m_capSets.get(BundleCapabilityImpl.PACKAGE_NAMESPACE).removeCapability(cap);
+ m_capSets.get(Capability.PACKAGE_NAMESPACE).removeCapability(caps.get(capIdx));
break;
}
}
@@ -178,62 +166,61 @@
// ResolverState methods.
//
- public synchronized SortedSet<BundleCapability> getCandidates(
- BundleRequirementImpl req, boolean obeyMandatory)
+ public synchronized SortedSet<Capability> getCandidates(
+ Requirement req, boolean obeyMandatory)
{
- BundleRevisionImpl reqRevision = (BundleRevisionImpl) req.getRevision();
- SortedSet<BundleCapability> result =
- new TreeSet<BundleCapability>(new CandidateComparator());
+ Module module = req.getModule();
+ SortedSet<Capability> result = new TreeSet<Capability>(new CandidateComparator());
CapabilitySet capSet = m_capSets.get(req.getNamespace());
if (capSet != null)
{
- Set<BundleCapability> matches = capSet.match(req.getFilter(), obeyMandatory);
- for (BundleCapability cap : matches)
+ Set<Capability> matches = capSet.match(req.getFilter(), obeyMandatory);
+ for (Capability cap : matches)
{
if (System.getSecurityManager() != null)
{
- if (req.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) && (
- !((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getSecurityContext()).impliesDirect(
- new PackagePermission((String) cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR),
+ if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE) && (
+ !((BundleProtectionDomain) cap.getModule().getSecurityContext()).impliesDirect(
+ new PackagePermission((String) cap.getAttribute(Capability.PACKAGE_ATTR).getValue(),
PackagePermission.EXPORTONLY)) ||
- !((reqRevision == null) ||
- ((BundleProtectionDomain) reqRevision.getSecurityContext()).impliesDirect(
- new PackagePermission((String) cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR),
- cap.getRevision().getBundle(),PackagePermission.IMPORT))
+ !((module == null) ||
+ ((BundleProtectionDomain) module.getSecurityContext()).impliesDirect(
+ new PackagePermission((String) cap.getAttribute(Capability.PACKAGE_ATTR).getValue(),
+ cap.getModule().getBundle(),PackagePermission.IMPORT))
)))
{
- if (reqRevision != cap.getRevision())
+ if (module != cap.getModule())
{
continue;
}
}
- else if (req.getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE) && (
- !((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getSecurityContext()).impliesDirect(
- new BundlePermission(cap.getRevision().getSymbolicName(), BundlePermission.PROVIDE)) ||
- !((reqRevision == null) ||
- ((BundleProtectionDomain) reqRevision.getSecurityContext()).impliesDirect(
- new BundlePermission(reqRevision.getSymbolicName(), BundlePermission.REQUIRE))
+ else if (req.getNamespace().equals(Capability.MODULE_NAMESPACE) && (
+ !((BundleProtectionDomain) cap.getModule().getSecurityContext()).impliesDirect(
+ new BundlePermission(cap.getModule().getSymbolicName(), BundlePermission.PROVIDE)) ||
+ !((module == null) ||
+ ((BundleProtectionDomain) module.getSecurityContext()).impliesDirect(
+ new BundlePermission(module.getSymbolicName(), BundlePermission.REQUIRE))
)))
{
continue;
}
- else if (req.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE) &&
- (!((BundleProtectionDomain) reqRevision.getSecurityContext())
+ else if (req.getNamespace().equals(Capability.HOST_NAMESPACE) &&
+ (!((BundleProtectionDomain) req.getModule().getSecurityContext())
.impliesDirect(new BundlePermission(
- reqRevision.getSymbolicName(),
+ req.getModule().getSymbolicName(),
BundlePermission.FRAGMENT))
- || !((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getSecurityContext())
+ || !((BundleProtectionDomain) cap.getModule().getSecurityContext())
.impliesDirect(new BundlePermission(
- cap.getRevision().getSymbolicName(),
+ cap.getModule().getSymbolicName(),
BundlePermission.HOST))))
{
continue;
}
}
- if (req.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE)
- && (cap.getRevision().getWiring() != null))
+ if (req.getNamespace().equals(Capability.HOST_NAMESPACE)
+ && cap.getModule().isResolved())
{
continue;
}
@@ -245,11 +232,10 @@
return result;
}
- public void checkExecutionEnvironment(BundleRevision revision) throws ResolveException
+ public void checkExecutionEnvironment(Module module) throws ResolveException
{
String bundleExecEnvStr = (String)
- ((BundleRevisionImpl) revision).getHeaders().get(
- Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
+ module.getHeaders().get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
if (bundleExecEnvStr != null)
{
bundleExecEnvStr = bundleExecEnvStr.trim();
@@ -274,19 +260,17 @@
{
throw new ResolveException(
"Execution environment not supported: "
- + bundleExecEnvStr, revision, null);
+ + bundleExecEnvStr, module, null);
}
}
}
}
- public void checkNativeLibraries(BundleRevision revision) throws ResolveException
+ public void checkNativeLibraries(Module module) throws ResolveException
{
- // Next, try to resolve any native code, since the revision is
+ // Next, try to resolve any native code, since the module is
// not resolvable if its native code cannot be loaded.
-// TODO: OSGi R4.3 - Is it sufficient to just check declared native libs here?
-// List<R4Library> libs = ((BundleWiringImpl) revision.getWiring()).getNativeLibraries();
- List<R4Library> libs = ((BundleRevisionImpl) revision).getDeclaredNativeLibraries();
+ List<R4Library> libs = module.getNativeLibraries();
if (libs != null)
{
String msg = null;
@@ -297,7 +281,7 @@
String entryName = libs.get(libIdx).getEntryName();
if (entryName != null)
{
- if (!((BundleRevisionImpl) revision).getContent().hasEntry(entryName))
+ if (!module.getContent().hasEntry(entryName))
{
msg = "Native library does not exist: " + entryName;
}
@@ -312,7 +296,7 @@
}
if (msg != null)
{
- throw new ResolveException(msg, revision, null);
+ throw new ResolveException(msg, module, null);
}
}
}
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
index 02b5fd4..0ff2ca4 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
@@ -22,15 +22,17 @@
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.*;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.resolver.Module;
+import org.apache.felix.framework.resolver.Wire;
import org.apache.felix.framework.util.MapToDictionary;
import org.apache.felix.framework.util.StringMap;
import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
import org.osgi.framework.*;
import org.osgi.framework.BundleReference;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
class ServiceRegistrationImpl implements ServiceRegistration
{
@@ -383,15 +385,9 @@
// ServiceReference implementation
//
- class ServiceReferenceImpl extends BundleCapabilityImpl implements ServiceReference
+ class ServiceReferenceImpl implements ServiceReference, Capability
{
- private final ServiceReferenceMap m_map;
-
- private ServiceReferenceImpl()
- {
- super(null, null, Collections.EMPTY_MAP, Collections.EMPTY_MAP);
- m_map = new ServiceReferenceMap();
- }
+ private ServiceReferenceImpl() {}
ServiceRegistrationImpl getRegistration()
{
@@ -402,39 +398,41 @@
// Capability methods.
//
- @Override
- public BundleRevision getRevision()
+ public Module getModule()
{
throw new UnsupportedOperationException("Not supported yet.");
}
- @Override
public String getNamespace()
{
return "service-reference";
}
- @Override
- public Map<String, String> getDirectives()
+ public Directive getDirective(String name)
{
- return Collections.EMPTY_MAP;
+ return null;
}
- @Override
- public Map<String, Object> getAttributes()
- {
- return m_map;
- }
-
- @Override
- public List<String> getUses()
+ public List<Directive> getDirectives()
{
return Collections.EMPTY_LIST;
}
- //
- // ServiceReference methods.
- //
+ public Attribute getAttribute(String name)
+ {
+ Object value = ServiceRegistrationImpl.this.getProperty(name);
+ return (value == null) ? null : new Attribute(name, value, false);
+ }
+
+ public List<Attribute> getAttributes()
+ {
+ return Collections.EMPTY_LIST;
+ }
+
+ public List<String> getUses()
+ {
+ return Collections.EMPTY_LIST;
+ }
public Object getProperty(String s)
{
@@ -485,12 +483,12 @@
// Get the package.
String pkgName =
Util.getClassPackage(className);
- BundleRevision requesterRevision = ((BundleImpl) requester).getCurrentRevision();
+ Module requesterModule = ((BundleImpl) requester).getCurrentModule();
// Get package wiring from service requester.
- BundleWire requesterWire = Util.getWire(requesterRevision, pkgName);
+ Wire requesterWire = Util.getWire(requesterModule, pkgName);
// Get package wiring from service provider.
- BundleRevision providerRevision = ((BundleImpl) m_bundle).getCurrentRevision();
- BundleWire providerWire = Util.getWire(providerRevision, pkgName);
+ Module providerModule = ((BundleImpl) m_bundle).getCurrentModule();
+ Wire providerWire = Util.getWire(providerModule, pkgName);
// There are four situations that may occur here:
// 1. Neither the requester, nor provider have wires for the package.
@@ -505,10 +503,10 @@
// the service is wired. Otherwise, as in case 1, if the requester
// does not have access to the class at all, we do not filter, but if
// it does have access we check if it is the same class accessible to
- // the providing revision. For case 3, the provider will not have a wire
+ // the providing module. For case 3, the provider will not have a wire
// if it is exporting the package, so we determine if the requester
// is wired to it or somehow using the same class. For case 4, we
- // simply compare the exporting revisions from the package wiring to
+ // simply compare the exporting modules from the package wiring to
// determine if we need to filter the service reference.
// Case 1: Both requester and provider have no wire.
@@ -518,9 +516,7 @@
// registration must have same class as requester.
try
{
- Class requestClass =
- ((BundleWiringImpl) requesterRevision.getWiring())
- .getClassByDelegation(className);
+ Class requestClass = requesterModule.getClassByDelegation(className);
allow = getRegistration().isClassAccessible(requestClass);
}
catch (Exception ex)
@@ -534,7 +530,7 @@
else if ((requesterWire == null) && (providerWire != null))
{
// Allow if the requester is the exporter of the provider's wire.
- if (providerWire.getProviderWiring().getRevision().equals(requesterRevision))
+ if (providerWire.getExporter().equals(requesterModule))
{
allow = true;
}
@@ -545,15 +541,12 @@
try
{
// Try to load class from requester.
- Class requestClass =((BundleWiringImpl)
- requesterRevision.getWiring()).getClassByDelegation(className);
+ Class requestClass = requesterModule.getClassByDelegation(className);
try
{
// If requester has access to the class, verify it is the
// same class as the provider.
- allow = (((BundleWiringImpl)
- providerRevision.getWiring())
- .getClassByDelegation(className) == requestClass);
+ allow = (providerWire.getClass(className) == requestClass);
}
catch (Exception ex)
{
@@ -574,10 +567,9 @@
// If the provider is the exporter of the requester's package, then check
// if the requester is wired to the latest version of the provider, if so
// then allow else don't (the provider has been updated but not refreshed).
- if (((BundleImpl) m_bundle).hasRevision(
- requesterWire.getProviderWiring().getRevision()))
+ if (((BundleImpl) m_bundle).hasModule(requesterWire.getExporter()))
{
- allow = providerRevision.equals(requesterWire.getProviderWiring().getRevision());
+ allow = providerModule.equals(requesterWire.getExporter());
}
// If the provider is not the exporter of the requester's package,
// then try to use the service registration to see if the requester's
@@ -587,9 +579,7 @@
try
{
// Load the class from the requesting bundle.
- Class requestClass = ((BundleWiringImpl)
- requesterRevision.getWiring())
- .getClassByDelegation(className);
+ Class requestClass = requesterModule.getClassByDelegation(className);
// Get the service registration and ask it to check
// if the service object is assignable to the requesting
// bundle's class.
@@ -606,9 +596,8 @@
else
{
// Include service reference if the wires have the
- // same source revision.
- allow = providerWire.getProviderWiring().getRevision()
- .equals(requesterWire.getProviderWiring().getRevision());
+ // same source module.
+ allow = providerWire.getExporter().equals(requesterWire.getExporter());
}
return allow;
@@ -653,67 +642,4 @@
return (id.compareTo(otherId) < 0) ? 1 : -1;
}
}
-
- private class ServiceReferenceMap implements Map
- {
- public int size()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public boolean isEmpty()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public boolean containsKey(Object o)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public boolean containsValue(Object o)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public Object get(Object o)
- {
- return ServiceRegistrationImpl.this.getProperty((String) o);
- }
-
- public Object put(Object k, Object v)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public Object remove(Object o)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void putAll(Map map)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void clear()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public Set<Object> keySet()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public Collection<Object> values()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public Set<Entry<Object, Object>> entrySet()
- {
- return Collections.EMPTY_SET;
- }
- }
}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
index 1dfe6a5..4bbf780 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
@@ -19,14 +19,13 @@
package org.apache.felix.framework;
import java.util.*;
+import org.apache.felix.framework.capabilityset.Capability;
import org.apache.felix.framework.capabilityset.CapabilitySet;
import org.apache.felix.framework.capabilityset.SimpleFilter;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
import org.osgi.framework.*;
import org.osgi.framework.hooks.service.*;
import org.osgi.framework.launch.Framework;
-import org.osgi.framework.wiring.BundleCapability;
public class ServiceRegistry
{
@@ -99,7 +98,7 @@
// Get the bundles current registered services.
ServiceRegistration[] regs = (ServiceRegistration[]) m_regsMap.get(bundle);
m_regsMap.put(bundle, addServiceRegistration(regs, reg));
- m_regCapSet.addCapability((BundleCapabilityImpl) reg.getReference());
+ m_regCapSet.addCapability((Capability) reg.getReference());
}
// Notify callback objects about registered service.
@@ -127,7 +126,7 @@
// Now remove the registered service.
ServiceRegistration[] regs = (ServiceRegistration[]) m_regsMap.get(bundle);
m_regsMap.put(bundle, removeServiceRegistration(regs, reg));
- m_regCapSet.removeCapability((BundleCapabilityImpl) reg.getReference());
+ m_regCapSet.removeCapability((Capability) reg.getReference());
}
// Notify callback objects about unregistering service.
@@ -209,7 +208,7 @@
}
// else just use the specified filter.
- Set<BundleCapability> matches = m_regCapSet.match(filter, false);
+ Set<Capability> matches = m_regCapSet.match(filter, false);
return new ArrayList(matches);
}
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
index e701477..7e856a7 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
@@ -132,7 +132,7 @@
}
}
Felix felix = (Felix) framework;
- long bundleId = Util.getBundleIdFromRevisionId(u.getHost());
+ long bundleId = Util.getBundleIdFromModuleId(u.getHost());
Bundle bundle = felix.getBundle(bundleId);
if (bundle != null)
{
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
index 1be90ea..f5bddb8 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
@@ -24,14 +24,14 @@
import java.net.URLConnection;
import java.security.Permission;
import java.util.List;
+import org.apache.felix.framework.resolver.Module;
import org.apache.felix.framework.util.Util;
-import org.osgi.framework.wiring.BundleRevision;
class URLHandlersBundleURLConnection extends URLConnection
{
private Felix m_framework;
- private BundleRevision m_targetRevision;
+ private Module m_targetModule;
private int m_classPathIdx = -1;
private int m_contentLength;
private long m_contentTime;
@@ -78,9 +78,9 @@
}
// Verify that the resource pointed to by the URL exists.
// The URL is constructed like this:
- // bundle://<revision-id>:<bundle-classpath-index>/<resource-path>
- // Where <revision-id> = <bundle-id>.<revision>
- long bundleId = Util.getBundleIdFromRevisionId(url.getHost());
+ // bundle://<module-id>:<bundle-classpath-index>/<resource-path>
+ // Where <module-id> = <bundle-id>.<revision>
+ long bundleId = Util.getBundleIdFromModuleId(url.getHost());
BundleImpl bundle = (BundleImpl) m_framework.getBundle(bundleId);
if (bundle == null)
{
@@ -88,27 +88,27 @@
}
m_contentTime = bundle.getLastModified();
- // Get the bundle's revisions to find the target revision.
- List<BundleRevision> revisions = bundle.getRevisions();
- if ((revisions == null) || revisions.isEmpty())
+ // Get the bundle's modules to find the target module.
+ List<Module> modules = bundle.getModules();
+ if ((modules == null) || modules.isEmpty())
{
throw new IOException("Resource does not exist: " + url);
}
- // Search for matching revision name.
- for (BundleRevision br : revisions)
+ // Search for matching module name.
+ for (Module m : modules)
{
- if (((BundleRevisionImpl) br).getId().equals(url.getHost()))
+ if (m.getId().equals(url.getHost()))
{
- m_targetRevision = br;
+ m_targetModule = m;
break;
}
}
- // If not found, assume the current revision.
- if (m_targetRevision == null)
+ // If not found, assume the current module.
+ if (m_targetModule == null)
{
- m_targetRevision = revisions.get(revisions.size() - 1);
+ m_targetModule = modules.get(modules.size() - 1);
}
// If the resource cannot be found at the current class path index,
@@ -123,12 +123,9 @@
{
m_classPathIdx = 0;
}
-// TODO: OSGi R4.3 - This is messed up. We need to fix resource lookup.
- if (!((BundleRevisionImpl) m_targetRevision)
- .hasInputStream(m_classPathIdx, url.getPath()))
+ if (!m_targetModule.hasInputStream(m_classPathIdx, url.getPath()))
{
- URL newurl = ((BundleWiringImpl)
- m_targetRevision.getWiring()).getResourceByDelegation(url.getPath());
+ URL newurl = m_targetModule.getResourceByDelegation(url.getPath());
if (newurl == null)
{
throw new IOException("Resource does not exist: " + url);
@@ -141,12 +138,11 @@
{
if (!connected)
{
- if ((m_targetRevision == null) || (m_classPathIdx < 0))
+ if ((m_targetModule == null) || (m_classPathIdx < 0))
{
throw new IOException("Resource does not exist: " + url);
}
- m_is = ((BundleRevisionImpl)
- m_targetRevision).getInputStream(m_classPathIdx, url.getPath());
+ m_is = m_targetModule.getInputStream(m_classPathIdx, url.getPath());
m_contentLength = (m_is == null) ? 0 : m_is.available();
m_contentType = URLConnection.guessContentTypeFromName(url.getFile());
connected = true;
@@ -227,11 +223,10 @@
*/
URL getLocalURL()
{
- if ((m_targetRevision == null) || (m_classPathIdx < 0))
+ if ((m_targetModule == null) || (m_classPathIdx < 0))
{
return url;
}
- return ((BundleRevisionImpl)
- m_targetRevision).getLocalURL(m_classPathIdx, url.getPath());
+ return m_targetModule.getLocalURL(m_classPathIdx, url.getPath());
}
}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java b/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
index ff88bf6..72ec9fd 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
@@ -22,6 +22,7 @@
import java.util.Map;
import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.resolver.Content;
/**
* <p>
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/ContentDirectoryContent.java b/framework/src/main/java/org/apache/felix/framework/cache/ContentDirectoryContent.java
index 4d8a2dd..aed76c6 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/ContentDirectoryContent.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/ContentDirectoryContent.java
@@ -18,6 +18,7 @@
*/
package org.apache.felix.framework.cache;
+import org.apache.felix.framework.resolver.Content;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java b/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java
index 4e7e929..3452ff8 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java
@@ -18,6 +18,7 @@
*/
package org.apache.felix.framework.cache;
+import org.apache.felix.framework.resolver.Content;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java b/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
index 54ee13f..8275272 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
@@ -26,6 +26,7 @@
import org.apache.felix.framework.Logger;
import org.apache.felix.framework.util.StringMap;
+import org.apache.felix.framework.resolver.Content;
/**
* <p>
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java b/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java
index 12ca117..3b5512a 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java
@@ -34,6 +34,7 @@
import org.apache.felix.framework.util.FelixConstants;
import org.apache.felix.framework.util.ZipFileX;
import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.resolver.Content;
import org.osgi.framework.Constants;
public class JarContent implements Content
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java b/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java
index 064d4e5..75daf4e 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java
@@ -32,6 +32,7 @@
import org.apache.felix.framework.util.ZipFileX;
import org.apache.felix.framework.util.StringMap;
import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.resolver.Content;
/**
* <p>
diff --git a/framework/src/main/java/org/apache/felix/framework/capabilityset/Attribute.java b/framework/src/main/java/org/apache/felix/framework/capabilityset/Attribute.java
new file mode 100644
index 0000000..f484d3e
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/capabilityset/Attribute.java
@@ -0,0 +1,53 @@
+/*
+ * 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.capabilityset;
+
+public class Attribute
+{
+ private final String m_name;
+ private final Object m_value;
+ private final boolean m_isMandatory;
+
+ public Attribute(String name, Object value, boolean isMandatory)
+ {
+ m_name = name;
+ m_value = value;
+ m_isMandatory = isMandatory;
+ }
+
+ public String getName()
+ {
+ return m_name;
+ }
+
+ public Object getValue()
+ {
+ return m_value;
+ }
+
+ public boolean isMandatory()
+ {
+ return m_isMandatory;
+ }
+
+ public String toString()
+ {
+ return m_name + "=" + m_value;
+ }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/capabilityset/Capability.java b/framework/src/main/java/org/apache/felix/framework/capabilityset/Capability.java
new file mode 100644
index 0000000..2a77b6a
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/capabilityset/Capability.java
@@ -0,0 +1,41 @@
+/*
+ * 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.capabilityset;
+
+import org.apache.felix.framework.resolver.Module;
+import java.util.List;
+
+public interface Capability
+{
+ static final String MODULE_NAMESPACE = "module";
+ static final String HOST_NAMESPACE = "host";
+ static final String PACKAGE_NAMESPACE = "package";
+ static final String SINGLETON_NAMESPACE = "singleton";
+
+ public static final String PACKAGE_ATTR = "package";
+ public static final String VERSION_ATTR = "version";
+
+ Module getModule();
+ String getNamespace();
+ Directive getDirective(String name);
+ List<Directive> getDirectives();
+ Attribute getAttribute(String name);
+ List<Attribute> getAttributes();
+ List<String> getUses();
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java b/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
index 7d2bd16..cd1990a 100644
--- a/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
+++ b/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
@@ -32,77 +32,45 @@
import java.util.TreeMap;
import org.apache.felix.framework.util.SecureAction;
import org.apache.felix.framework.util.StringComparator;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.osgi.framework.wiring.BundleCapability;
public class CapabilitySet
{
- private final Map<String, Map<Object, Set<BundleCapability>>> m_indices;
- private final Set<BundleCapability> m_capSet = new HashSet<BundleCapability>();
+ private final Map<String, Map<Object, Set<Capability>>> m_indices;
+ private final Set<Capability> m_capSet = new HashSet<Capability>();
private final static SecureAction m_secureAction = new SecureAction();
-public void dump()
-{
- for (Entry<String, Map<Object, Set<BundleCapability>>> entry : m_indices.entrySet())
- {
- boolean header1 = false;
- for (Entry<Object, Set<BundleCapability>> entry2 : entry.getValue().entrySet())
- {
- boolean header2 = false;
- for (BundleCapability cap : entry2.getValue())
- {
- if (cap.getRevision().getBundle().getBundleId() != 0)
- {
- if (!header1)
- {
- System.out.println(entry.getKey() + ":");
- header1 = true;
- }
- if (!header2)
- {
- System.out.println(" " + entry2.getKey());
- header2 = true;
- }
- System.out.println(" " + cap);
- }
- }
- }
- }
-}
-
public CapabilitySet(List<String> indexProps, boolean caseSensitive)
{
m_indices = (caseSensitive)
- ? new TreeMap<String, Map<Object, Set<BundleCapability>>>()
- : new TreeMap<String, Map<Object, Set<BundleCapability>>>(
- new StringComparator(false));
+ ? new TreeMap<String, Map<Object, Set<Capability>>>()
+ : new TreeMap<String, Map<Object, Set<Capability>>>(new StringComparator(false));
for (int i = 0; (indexProps != null) && (i < indexProps.size()); i++)
{
- m_indices.put(
- indexProps.get(i), new HashMap<Object, Set<BundleCapability>>());
+ m_indices.put(indexProps.get(i), new HashMap<Object, Set<Capability>>());
}
}
- public void addCapability(BundleCapability cap)
+ public void addCapability(Capability cap)
{
m_capSet.add(cap);
// Index capability.
- for (Entry<String, Map<Object, Set<BundleCapability>>> entry : m_indices.entrySet())
+ for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
{
- Object value = cap.getAttributes().get(entry.getKey());
- if (value != null)
+ Attribute capAttr = cap.getAttribute(entry.getKey());
+ if (capAttr != null)
{
- if (value.getClass().isArray())
+ Object capValue = capAttr.getValue();
+ if (capValue.getClass().isArray())
{
- value = convertArrayToList(value);
+ capValue = convertArrayToList(capValue);
}
- Map<Object, Set<BundleCapability>> index = entry.getValue();
+ Map<Object, Set<Capability>> index = entry.getValue();
- if (value instanceof Collection)
+ if (capValue instanceof Collection)
{
- Collection c = (Collection) value;
+ Collection c = (Collection) capValue;
for (Object o : c)
{
indexCapability(index, cap, o);
@@ -110,43 +78,44 @@
}
else
{
- indexCapability(index, cap, value);
+ indexCapability(index, cap, capValue);
}
}
}
}
private void indexCapability(
- Map<Object, Set<BundleCapability>> index, BundleCapability cap, Object capValue)
+ Map<Object, Set<Capability>> index, Capability cap, Object capValue)
{
- Set<BundleCapability> caps = index.get(capValue);
+ Set<Capability> caps = index.get(capValue);
if (caps == null)
{
- caps = new HashSet<BundleCapability>();
+ caps = new HashSet<Capability>();
index.put(capValue, caps);
}
caps.add(cap);
}
- public void removeCapability(BundleCapability cap)
+ public void removeCapability(Capability cap)
{
if (m_capSet.remove(cap))
{
- for (Entry<String, Map<Object, Set<BundleCapability>>> entry : m_indices.entrySet())
+ for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
{
- Object value = cap.getAttributes().get(entry.getKey());
- if (value != null)
+ Attribute capAttr = cap.getAttribute(entry.getKey());
+ if (capAttr != null)
{
- if (value.getClass().isArray())
+ Object capValue = capAttr.getValue();
+ if (capValue.getClass().isArray())
{
- value = convertArrayToList(value);
+ capValue = convertArrayToList(capValue);
}
- Map<Object, Set<BundleCapability>> index = entry.getValue();
+ Map<Object, Set<Capability>> index = entry.getValue();
- if (value instanceof Collection)
+ if (capValue instanceof Collection)
{
- Collection c = (Collection) value;
+ Collection c = (Collection) capValue;
for (Object o : c)
{
deindexCapability(index, cap, o);
@@ -154,7 +123,7 @@
}
else
{
- deindexCapability(index, cap, value);
+ deindexCapability(index, cap, capValue);
}
}
}
@@ -162,30 +131,30 @@
}
private void deindexCapability(
- Map<Object, Set<BundleCapability>> index, BundleCapability cap, Object value)
+ Map<Object, Set<Capability>> index, Capability cap, Object capValue)
{
- Set<BundleCapability> caps = index.get(value);
+ Set<Capability> caps = index.get(capValue);
if (caps != null)
{
caps.remove(cap);
if (caps.isEmpty())
{
- index.remove(value);
+ index.remove(capValue);
}
}
}
- public Set<BundleCapability> match(SimpleFilter sf, boolean obeyMandatory)
+ public Set<Capability> match(SimpleFilter sf, boolean obeyMandatory)
{
- Set<BundleCapability> matches = match(m_capSet, sf);
+ Set<Capability> matches = match(m_capSet, sf);
return (obeyMandatory)
? matchMandatory(matches, sf)
: matches;
}
- private Set<BundleCapability> match(Set<BundleCapability> caps, SimpleFilter sf)
+ private Set<Capability> match(Set<Capability> caps, SimpleFilter sf)
{
- Set<BundleCapability> matches = new HashSet<BundleCapability>();
+ Set<Capability> matches = new HashSet<Capability>();
if (sf.getOperation() == SimpleFilter.MATCH_ALL)
{
@@ -227,10 +196,10 @@
}
else
{
- Map<Object, Set<BundleCapability>> index = m_indices.get(sf.getName());
+ Map<Object, Set<Capability>> index = m_indices.get(sf.getName());
if ((sf.getOperation() == SimpleFilter.EQ) && (index != null))
{
- Set<BundleCapability> existingCaps = index.get(sf.getValue());
+ Set<Capability> existingCaps = index.get(sf.getValue());
if (existingCaps != null)
{
matches.addAll(existingCaps);
@@ -239,12 +208,13 @@
}
else
{
- for (Iterator<BundleCapability> it = caps.iterator(); it.hasNext(); )
+ for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
{
- BundleCapability cap = it.next();
- Object lhs = cap.getAttributes().get(sf.getName());
- if (lhs != null)
+ Capability cap = it.next();
+ Attribute attr = cap.getAttribute(sf.getName());
+ if (attr != null)
{
+ Object lhs = attr.getValue();
if (compare(lhs, sf.getValue(), sf.getOperation()))
{
matches.add(cap);
@@ -257,12 +227,12 @@
return matches;
}
- public static boolean matches(BundleCapability cap, SimpleFilter sf)
+ public static boolean matches(Capability cap, SimpleFilter sf)
{
return matchesInternal(cap, sf) && matchMandatory(cap, sf);
}
- private static boolean matchesInternal(BundleCapability cap, SimpleFilter sf)
+ private static boolean matchesInternal(Capability cap, SimpleFilter sf)
{
boolean matched = true;
@@ -302,9 +272,10 @@
else
{
matched = false;
- Object lhs = cap.getAttributes().get(sf.getName());
- if (lhs != null)
+ Attribute attr = cap.getAttribute(sf.getName());
+ if (attr != null)
{
+ Object lhs = attr.getValue();
matched = compare(lhs, sf.getValue(), sf.getOperation());
}
}
@@ -312,12 +283,11 @@
return matched;
}
- private static Set<BundleCapability> matchMandatory(
- Set<BundleCapability> caps, SimpleFilter sf)
+ private static Set<Capability> matchMandatory(Set<Capability> caps, SimpleFilter sf)
{
- for (Iterator<BundleCapability> it = caps.iterator(); it.hasNext(); )
+ for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
{
- BundleCapability cap = it.next();
+ Capability cap = it.next();
if (!matchMandatory(cap, sf))
{
it.remove();
@@ -326,13 +296,13 @@
return caps;
}
- private static boolean matchMandatory(BundleCapability cap, SimpleFilter sf)
+ private static boolean matchMandatory(Capability cap, SimpleFilter sf)
{
- Map<String, Object> attrs = cap.getAttributes();
- for (Entry<String, Object> entry : attrs.entrySet())
+ List<Attribute> attrs = cap.getAttributes();
+ for (int attrIdx = 0; attrIdx < attrs.size(); attrIdx++)
{
- if (((BundleCapabilityImpl) cap).isAttributeMandatory(entry.getKey())
- && !matchMandatoryAttrbute(entry.getKey(), sf))
+ if (attrs.get(attrIdx).isMandatory()
+ && !matchMandatory(attrs.get(attrIdx), sf))
{
return false;
}
@@ -340,9 +310,9 @@
return true;
}
- private static boolean matchMandatoryAttrbute(String attrName, SimpleFilter sf)
+ private static boolean matchMandatory(Attribute attr, SimpleFilter sf)
{
- if ((sf.getName() != null) && sf.getName().equals(attrName))
+ if ((sf.getName() != null) && sf.getName().equals(attr.getName()))
{
return true;
}
@@ -353,7 +323,7 @@
{
SimpleFilter sf2 = (SimpleFilter) list.get(i);
if ((sf2.getName() != null)
- && sf2.getName().equals(attrName))
+ && sf2.getName().equals(attr.getName()))
{
return true;
}
diff --git a/framework/src/main/java/org/apache/felix/framework/capabilityset/Directive.java b/framework/src/main/java/org/apache/felix/framework/capabilityset/Directive.java
new file mode 100644
index 0000000..0541d2b
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/capabilityset/Directive.java
@@ -0,0 +1,46 @@
+/*
+ * 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.capabilityset;
+
+public class Directive
+{
+ private final String m_name;
+ private final Object m_value;
+
+ public Directive(String name, Object value)
+ {
+ m_name = name;
+ m_value = value;
+ }
+
+ public String getName()
+ {
+ return m_name;
+ }
+
+ public Object getValue()
+ {
+ return m_value;
+ }
+
+ public String toString()
+ {
+ return m_name + "=" + m_value;
+ }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/capabilityset/Requirement.java b/framework/src/main/java/org/apache/felix/framework/capabilityset/Requirement.java
new file mode 100644
index 0000000..65ee7e7
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/capabilityset/Requirement.java
@@ -0,0 +1,32 @@
+/*
+ * 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.capabilityset;
+
+import java.util.List;
+import org.apache.felix.framework.resolver.Module;
+
+public interface Requirement
+{
+ Module getModule();
+ String getNamespace();
+ SimpleFilter getFilter();
+ boolean isOptional();
+ Directive getDirective(String name);
+ List<Directive> getDirectives();
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java b/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java
index 7a96ad1..6e6387f 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java
@@ -19,77 +19,75 @@
package org.apache.felix.framework.resolver;
import java.util.Comparator;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.capabilityset.Capability;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
-import org.osgi.framework.wiring.BundleCapability;
-public class CandidateComparator implements Comparator<BundleCapability>
+public class CandidateComparator implements Comparator<Capability>
{
- public int compare(BundleCapability cap1, BundleCapability cap2)
+ public int compare(Capability cap1, Capability cap2)
{
// First check resolved state, since resolved capabilities have priority
// over unresolved ones. Compare in reverse order since we want to sort
// in descending order.
int c = 0;
- if ((cap1.getRevision().getWiring() != null)
- && (cap2.getRevision().getWiring() == null))
+ if (cap1.getModule().isResolved() && !cap2.getModule().isResolved())
{
c = -1;
}
- else if ((cap1.getRevision().getWiring() == null)
- && (cap2.getRevision().getWiring() != null))
+ else if (!cap1.getModule().isResolved() && cap2.getModule().isResolved())
{
c = 1;
}
- // Compare revision capabilities.
- if ((c == 0) && cap1.getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+ // Compare module capabilities.
+ if ((c == 0) && cap1.getNamespace().equals(Capability.MODULE_NAMESPACE))
{
- c = ((Comparable) cap1.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
- .compareTo(cap2.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE));
+ c = ((Comparable) cap1.getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)
+ .getValue()).compareTo(cap2.getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)
+ .getValue());
if (c == 0)
{
- Version v1 = (!cap1.getAttributes().containsKey(Constants.BUNDLE_VERSION_ATTRIBUTE))
+ Version v1 = (cap1.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE) == null)
? Version.emptyVersion
- : (Version) cap1.getAttributes().get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- Version v2 = (!cap2.getAttributes().containsKey(Constants.BUNDLE_VERSION_ATTRIBUTE))
+ : (Version) cap1.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE).getValue();
+ Version v2 = (cap2.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE) == null)
? Version.emptyVersion
- : (Version) cap2.getAttributes().get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+ : (Version) cap2.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE).getValue();
// Compare these in reverse order, since we want
// highest version to have priority.
c = v2.compareTo(v1);
}
}
// Compare package capabilities.
- else if ((c == 0) && cap1.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ else if ((c == 0) && cap1.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
- c = ((Comparable) cap1.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR))
- .compareTo(cap2.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
+ c = ((Comparable) cap1.getAttribute(Capability.PACKAGE_ATTR).getValue())
+ .compareTo(cap2.getAttribute(Capability.PACKAGE_ATTR).getValue());
if (c == 0)
{
- Version v1 = (!cap1.getAttributes().containsKey(BundleCapabilityImpl.VERSION_ATTR))
+ Version v1 = (cap1.getAttribute(Capability.VERSION_ATTR) == null)
? Version.emptyVersion
- : (Version) cap1.getAttributes().get(BundleCapabilityImpl.VERSION_ATTR);
- Version v2 = (!cap2.getAttributes().containsKey(BundleCapabilityImpl.VERSION_ATTR))
+ : (Version) cap1.getAttribute(Capability.VERSION_ATTR).getValue();
+ Version v2 = (cap2.getAttribute(Capability.VERSION_ATTR) == null)
? Version.emptyVersion
- : (Version) cap2.getAttributes().get(BundleCapabilityImpl.VERSION_ATTR);
+ : (Version) cap2.getAttribute(Capability.VERSION_ATTR).getValue();
// Compare these in reverse order, since we want
// highest version to have priority.
c = v2.compareTo(v1);
}
}
- // Finally, compare bundle identity.
+ // Finally, compare module identity.
if (c == 0)
{
- if (cap1.getRevision().getBundle().getBundleId() <
- cap2.getRevision().getBundle().getBundleId())
+ if (cap1.getModule().getBundle().getBundleId() <
+ cap2.getModule().getBundle().getBundleId())
{
c = -1;
}
- else if (cap1.getRevision().getBundle().getBundleId() >
- cap2.getRevision().getBundle().getBundleId())
+ else if (cap1.getModule().getBundle().getBundleId() >
+ cap2.getModule().getBundle().getBundleId())
{
c = 1;
}
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
index bd61f3d..b99d541 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
@@ -30,39 +30,34 @@
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
-import org.apache.felix.framework.BundleRevisionImpl;
-import org.apache.felix.framework.BundleWiringImpl;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.capabilityset.Requirement;
import org.apache.felix.framework.resolver.Resolver.ResolverState;
import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
class Candidates
{
- private final BundleRevision m_root;
+ private final Module m_root;
- // Set of all candidate bundle revisions.
- private final Set<BundleRevision> m_candidateRevisions;
+ // Set of all candidate modules.
+ private final Set<Module> m_candidateModules;
// Maps a capability to requirements that match it.
- private final Map<BundleCapability, Set<BundleRequirement>> m_dependentMap;
+ private final Map<Capability, Set<Requirement>> m_dependentMap;
// Maps a requirement to the capability it matches.
- private final Map<BundleRequirement, SortedSet<BundleCapability>> m_candidateMap;
+ private final Map<Requirement, SortedSet<Capability>> m_candidateMap;
// Maps a host capability to a map containing its potential fragments;
// the fragment map maps a fragment symbolic name to a map that maps
// a version to a list of fragments requirements matching that symbolic
// name and version.
- private final Map<BundleCapability,
- Map<String, Map<Version, List<BundleRequirement>>>> m_hostFragments;
- // Maps a bundle revision to its associated wrapped revision; this only happens
- // when a revision being resolved has fragments to attach to it.
- private final Map<BundleRevision, HostBundleRevision> m_allWrappedHosts;
+ private final Map<Capability, Map<String, Map<Version, List<Requirement>>>> m_hostFragments;
+ // Maps a module to its associated wrapped module; this only happens
+ // when a module being resolved has fragments to attach to it.
+ private final Map<Module, HostModule> m_allWrappedHosts;
// Map used when populating candidates to hold intermediate and final results.
- private final Map<BundleRevision, Object> m_populateResultCache;
+ private final Map<Module, Object> m_populateResultCache;
// Flag to signal if fragments are present in the candidate map.
private boolean m_fragmentsPresent = false;
@@ -76,16 +71,16 @@
* @param wrappedHosts the wrapped hosts map.
**/
private Candidates(
- BundleRevision root,
- Set<BundleRevision> candidateRevisions,
- Map<BundleCapability, Set<BundleRequirement>> dependentMap,
- Map<BundleRequirement, SortedSet<BundleCapability>> candidateMap,
- Map<BundleCapability, Map<String, Map<Version, List<BundleRequirement>>>> hostFragments,
- Map<BundleRevision, HostBundleRevision> wrappedHosts, Map<BundleRevision, Object> populateResultCache,
+ Module root,
+ Set<Module> candidateModules,
+ Map<Capability, Set<Requirement>> dependentMap,
+ Map<Requirement, SortedSet<Capability>> candidateMap,
+ Map<Capability, Map<String, Map<Version, List<Requirement>>>> hostFragments,
+ Map<Module, HostModule> wrappedHosts, Map<Module, Object> populateResultCache,
boolean fragmentsPresent)
{
m_root = root;
- m_candidateRevisions = candidateRevisions;
+ m_candidateModules = candidateModules;
m_dependentMap = dependentMap;
m_candidateMap = candidateMap;
m_hostFragments = hostFragments;
@@ -99,16 +94,16 @@
* @param state the resolver state used for populating the candidates.
* @param root the root module for the resolve.
**/
- public Candidates(ResolverState state, BundleRevision root)
+ public Candidates(ResolverState state, Module root)
{
m_root = root;
- m_candidateRevisions = new HashSet<BundleRevision>();
- m_dependentMap = new HashMap<BundleCapability, Set<BundleRequirement>>();
- m_candidateMap = new HashMap<BundleRequirement, SortedSet<BundleCapability>>();
+ m_candidateModules = new HashSet<Module>();
+ m_dependentMap = new HashMap<Capability, Set<Requirement>>();
+ m_candidateMap = new HashMap<Requirement, SortedSet<Capability>>();
m_hostFragments =
- new HashMap<BundleCapability, Map<String, Map<Version, List<BundleRequirement>>>>();
- m_allWrappedHosts = new HashMap<BundleRevision, HostBundleRevision>();
- m_populateResultCache = new HashMap<BundleRevision, Object>();
+ new HashMap<Capability, Map<String, Map<Version, List<Requirement>>>>();
+ m_allWrappedHosts = new HashMap<Module, HostModule>();
+ m_populateResultCache = new HashMap<Module, Object>();
populate(state, m_root);
}
@@ -123,17 +118,17 @@
* @param req the requirement being resolved.
* @param candidates the potential candidates matching the requirement.
**/
- public Candidates(ResolverState state, BundleRevision root,
- BundleRequirement req, SortedSet<BundleCapability> candidates)
+ public Candidates(ResolverState state, Module root,
+ Requirement req, SortedSet<Capability> candidates)
{
m_root = root;
- m_candidateRevisions = new HashSet<BundleRevision>();
- m_dependentMap = new HashMap<BundleCapability, Set<BundleRequirement>>();
- m_candidateMap = new HashMap<BundleRequirement, SortedSet<BundleCapability>>();
+ m_candidateModules = new HashSet<Module>();
+ m_dependentMap = new HashMap<Capability, Set<Requirement>>();
+ m_candidateMap = new HashMap<Requirement, SortedSet<Capability>>();
m_hostFragments =
- new HashMap<BundleCapability, Map<String, Map<Version, List<BundleRequirement>>>>();
- m_allWrappedHosts = new HashMap<BundleRevision, HostBundleRevision>();
- m_populateResultCache = new HashMap<BundleRevision, Object>();
+ new HashMap<Capability, Map<String, Map<Version, List<Requirement>>>>();
+ m_allWrappedHosts = new HashMap<Module, HostModule>();
+ m_populateResultCache = new HashMap<Module, Object>();
add(req, candidates);
@@ -143,17 +138,17 @@
/**
* Populates additional candidates for the specified module.
* @param state the resolver state used for populating the candidates.
- * @param revision the module whose candidates should be populated.
+ * @param module the module whose candidates should be populated.
*/
// TODO: FELIX3 - Modify to not be recursive.
- public final void populate(ResolverState state, BundleRevision revision)
+ public final void populate(ResolverState state, Module module)
{
- // Determine if we've already calculated this revision's candidates.
+ // Determine if we've already calculated this module's candidates.
// The result cache will have one of three values:
// 1. A resolve exception if we've already attempted to populate the
- // revision's candidates but were unsuccessful.
+ // module's candidates but were unsuccessful.
// 2. Boolean.TRUE indicating we've already attempted to populate the
- // revision's candidates and were successful.
+ // module's candidates and were successful.
// 3. An array containing the cycle count, current map of candidates
// for already processed requirements, and a list of remaining
// requirements whose candidates still need to be calculated.
@@ -163,19 +158,19 @@
// until we've popped completely out of the cycle.
// Keeps track of the number of times we've reentered this method
- // for the current revision.
+ // for the current module.
Integer cycleCount = null;
// Keeps track of the candidates we've already calculated for the
- // current revision's requirements.
- Map<BundleRequirement, SortedSet<BundleCapability>> localCandidateMap = null;
+ // current module's requirements.
+ Map<Requirement, SortedSet<Capability>> localCandidateMap = null;
- // Keeps track of the current revision's requirements for which we
+ // Keeps track of the current module's requirements for which we
// haven't yet found candidates.
- List<BundleRequirement> remainingReqs = null;
+ List<Requirement> remainingReqs = null;
- // Get the cache value for the current revision.
- Object cacheValue = m_populateResultCache.get(revision);
+ // Get the cache value for the current module.
+ Object cacheValue = m_populateResultCache.get(module);
// This is case 1.
if (cacheValue instanceof ResolveException)
@@ -200,75 +195,65 @@
remainingReqs = (List) ((Object[]) cacheValue)[2];
}
- // If there is no cache value for the current revision, then this is
+ // If there is no cache value for the current module, then this is
// the first time we are attempting to populate its candidates, so
// do some one-time checks and initialization.
if ((remainingReqs == null) && (localCandidateMap == null))
{
// Verify that any required execution environment is satisfied.
- state.checkExecutionEnvironment(revision);
+ state.checkExecutionEnvironment(module);
// Verify that any native libraries match the current platform.
- state.checkNativeLibraries(revision);
+ state.checkNativeLibraries(module);
// Record cycle count.
cycleCount = new Integer(0);
// Create a local map for populating candidates first, just in case
- // the revision is not resolvable.
+ // the module is not resolvable.
localCandidateMap = new HashMap();
- // Create a modifiable list of the revision's requirements.
- remainingReqs = new ArrayList(revision.getDeclaredRequirements(null));
+ // Create a modifiable list of the module's requirements.
+ remainingReqs = new ArrayList(module.getRequirements());
// Add these value to the result cache so we know we are
// in the middle of populating candidates for the current
- // revision.
- m_populateResultCache.put(revision,
+ // module.
+ m_populateResultCache.put(module,
cacheValue = new Object[] { cycleCount, localCandidateMap, remainingReqs });
}
// If we have requirements remaining, then find candidates for them.
while (remainingReqs.size() > 0)
{
- BundleRequirement req = remainingReqs.remove(0);
-
- // Ignore dynamic requirements.
- String resolution = req.getDirectives().get(Constants.RESOLUTION_DIRECTIVE);
-// TODO: OSGi R4.3 - Use proper "dynamic" constant.
- if ((resolution != null) && resolution.equals("dynamic"))
- {
- continue;
- }
+ Requirement req = remainingReqs.remove(0);
// Get satisfying candidates and populate their candidates if necessary.
ResolveException rethrow = null;
- SortedSet<BundleCapability> candidates =
- state.getCandidates((BundleRequirementImpl) req, true);
- for (Iterator<BundleCapability> itCandCap = candidates.iterator();
- itCandCap.hasNext(); )
+ SortedSet<Capability> candidates = state.getCandidates(req, true);
+ for (Iterator<Capability> itCandCap = candidates.iterator(); itCandCap.hasNext(); )
{
- BundleCapability candCap = itCandCap.next();
+ Capability candCap = itCandCap.next();
- // If the candidate revision is a fragment, then always attempt
+ // If the candidate module is a fragment, then always attempt
// to populate candidates for its dependency, since it must be
// attached to a host to be used. Otherwise, if the candidate
- // revision is not already resolved and is not the current version
+ // module is not already resolved and is not the current module
// we are trying to populate, then populate the candidates for
// its dependencies as well.
// NOTE: Technically, we don't have to check to see if the
- // candidate revision is equal to the current revision, but this
+ // candidate module is equal to the current module, but this
// saves us from recursing and also simplifies exceptions messages
// since we effectively chain exception messages for each level
// of recursion; thus, any avoided recursion results in fewer
// exceptions to chain when an error does occur.
- if (Util.isFragment(candCap.getRevision())
- || ((candCap.getRevision().getWiring() == null)
- && !candCap.getRevision().equals(revision)))
+ if (Util.isFragment(candCap.getModule())
+ || (!candCap.getModule().isResolved()
+ && !candCap.getModule().equals(module)))
{
try
{
- populate(state, candCap.getRevision());
+ populate(state, candCap.getModule());
}
catch (ResolveException ex)
{
@@ -286,16 +271,16 @@
// If there are no candidates for the current requirement
// and it is not optional, then create, cache, and throw
// a resolve exception.
- if (candidates.isEmpty() && !((BundleRequirementImpl) req).isOptional())
+ if (candidates.isEmpty() && !req.isOptional())
{
- String msg = "Unable to resolve " + revision
+ String msg = "Unable to resolve " + module
+ ": missing requirement " + req;
if (rethrow != null)
{
msg = msg + " [caused by: " + rethrow.getMessage() + "]";
}
- rethrow = new ResolveException(msg, revision, req);
- m_populateResultCache.put(revision, rethrow);
+ rethrow = new ResolveException(msg, module, req);
+ m_populateResultCache.put(module, rethrow);
throw rethrow;
}
// If we actually have candidates for the requirement, then
@@ -314,8 +299,8 @@
}
else if (cycleCount.intValue() == 0)
{
- // Record that the revision was successfully populated.
- m_populateResultCache.put(revision, Boolean.TRUE);
+ // Record that the module was successfully populated.
+ m_populateResultCache.put(module, Boolean.TRUE);
// Merge local candidate map into global candidate map.
if (localCandidateMap.size() > 0)
@@ -325,57 +310,44 @@
}
}
- public final void populateOptional(ResolverState state, BundleRevision revision)
+ public final void populateOptional(ResolverState state, Module module)
{
- // We will always attempt to populate optional fragments, since this
- // is necessary for greedy resolving of fragment. Howevere, we'll only
- // attempt to populate optional non-fragment revisions if they aren't
- // already resolved.
- boolean isFragment = Util.isFragment(revision);
- if (!isFragment && (revision.getWiring() != null))
- {
- return;
- }
-
try
{
- // If the optional revision is a fragment, then we only want to populate
+ // If the optional module is a fragment, then we only want to populate
// the fragment if it has a candidate host in the set of already populated
- // revisions. We do this to avoid unnecessary work in prepare(). If the
+ // modules. We do this to avoid unnecessary work in prepare(). If the
// fragment has a host, we'll prepopulate the result cache here to avoid
// having to do the host lookup again in populate().
+ boolean isFragment = Util.isFragment(module);
if (isFragment)
{
- // Get the current result cache value, to make sure the revision
+ // Get the current result cache value, to make sure the module
// hasn't already been populated.
- Object cacheValue = m_populateResultCache.get(revision);
+ Object cacheValue = m_populateResultCache.get(module);
if (cacheValue == null)
{
- // Create a modifiable list of the revision's requirements.
- List<BundleRequirement> remainingReqs =
- new ArrayList(revision.getDeclaredRequirements(null));
+ // Create a modifiable list of the module's requirements.
+ List<Requirement> remainingReqs = new ArrayList(module.getRequirements());
// Find the host requirement.
- BundleRequirement hostReq = null;
- for (Iterator<BundleRequirement> it = remainingReqs.iterator();
- it.hasNext(); )
+ Requirement hostReq = null;
+ for (Iterator<Requirement> it = remainingReqs.iterator(); it.hasNext(); )
{
- BundleRequirement r = it.next();
- if (r.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE))
+ Requirement r = it.next();
+ if (r.getNamespace().equals(Capability.HOST_NAMESPACE))
{
hostReq = r;
it.remove();
- break;
}
}
// Get candidates hosts and keep any that have been populated.
- SortedSet<BundleCapability> hosts =
- state.getCandidates((BundleRequirementImpl) hostReq, false);
- for (Iterator<BundleCapability> it = hosts.iterator(); it.hasNext(); )
+ SortedSet<Capability> hosts = state.getCandidates(hostReq, false);
+ for (Iterator<Capability> it = hosts.iterator(); it.hasNext(); )
{
- BundleCapability host = it.next();
- if (!isPopulated(host.getRevision()))
+ Capability host = it.next();
+ if (!isPopulated(host.getModule()))
{
it.remove();
}
@@ -393,65 +365,63 @@
// the work we've done so far.
// Verify that any required execution environment is satisfied.
- state.checkExecutionEnvironment(revision);
+ state.checkExecutionEnvironment(module);
// Verify that any native libraries match the current platform.
- state.checkNativeLibraries(revision);
+ state.checkNativeLibraries(module);
// Record cycle count, but start at -1 since it will
// be incremented again in populate().
Integer cycleCount = new Integer(-1);
// Create a local map for populating candidates first, just in case
- // the revision is not resolvable.
- Map<BundleRequirement, SortedSet<BundleCapability>> localCandidateMap =
- new HashMap<BundleRequirement, SortedSet<BundleCapability>>();
+ // the module is not resolvable.
+ Map<Requirement, SortedSet<Capability>> localCandidateMap = new HashMap();
// Add the discovered host candidates to the local candidate map.
localCandidateMap.put(hostReq, hosts);
// Add these value to the result cache so we know we are
// in the middle of populating candidates for the current
- // revision.
- m_populateResultCache.put(revision,
+ // module.
+ m_populateResultCache.put(module,
new Object[] { cycleCount, localCandidateMap, remainingReqs });
}
}
- // Try to populate candidates for the optional revision.
- populate(state, revision);
+ // Try to populate candidates for the optional module.
+ populate(state, module);
}
catch (ResolveException ex)
{
- // Ignore since the revision is optional.
+ // Ignore since the module is optional.
}
}
- private boolean isPopulated(BundleRevision revision)
+ private boolean isPopulated(Module module)
{
- Object value = m_populateResultCache.get(revision);
+ Object value = m_populateResultCache.get(module);
return ((value != null) && (value instanceof Boolean));
}
- private void populateDynamic(ResolverState state, BundleRevision revision)
+ private void populateDynamic(ResolverState state, Module module)
{
// There should be one entry in the candidate map, which are the
// the candidates for the matching dynamic requirement. Get the
// matching candidates and populate their candidates if necessary.
ResolveException rethrow = null;
- Entry<BundleRequirement, SortedSet<BundleCapability>> entry =
+ Entry<Requirement, SortedSet<Capability>> entry =
m_candidateMap.entrySet().iterator().next();
- BundleRequirement dynReq = entry.getKey();
- SortedSet<BundleCapability> candidates = entry.getValue();
- for (Iterator<BundleCapability> itCandCap = candidates.iterator();
- itCandCap.hasNext(); )
+ Requirement dynReq = entry.getKey();
+ SortedSet<Capability> candidates = entry.getValue();
+ for (Iterator<Capability> itCandCap = candidates.iterator(); itCandCap.hasNext(); )
{
- BundleCapability candCap = itCandCap.next();
- if (candCap.getRevision().getWiring() == null)
+ Capability candCap = itCandCap.next();
+ if (!candCap.getModule().isResolved())
{
try
{
- populate(state, candCap.getRevision());
+ populate(state, candCap.getModule());
}
catch (ResolveException ex)
{
@@ -468,7 +438,7 @@
{
if (rethrow == null)
{
- rethrow = new ResolveException("Dynamic import failed.", revision, dynReq);
+ rethrow = new ResolveException("Dynamic import failed.", module, dynReq);
}
throw rethrow;
}
@@ -483,9 +453,9 @@
* @param req the requirement to add.
* @param candidates the candidates matching the requirement.
**/
- private void add(BundleRequirement req, SortedSet<BundleCapability> candidates)
+ private void add(Requirement req, SortedSet<Capability> candidates)
{
- if (req.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE))
+ if (req.getNamespace().equals(Capability.HOST_NAMESPACE))
{
m_fragmentsPresent = true;
}
@@ -493,14 +463,14 @@
// Record the candidates.
m_candidateMap.put(req, candidates);
- // Make a list of all candidate revisions for determining singetons.
+ // Make a list of all candidate modules for determining singetons.
// Add the requirement as a dependent on the candidates. Keep track
// of fragments for hosts.
- for (BundleCapability cap : candidates)
+ for (Capability cap : candidates)
{
- // Remember the revision for all capabilities so we can
+ // Remember the module for all capabilities so we can
// determine which ones are singletons.
- m_candidateRevisions.add(cap.getRevision());
+ m_candidateModules.add(cap.getModule());
}
}
@@ -510,9 +480,9 @@
* be further modified by the caller.
* @param candidates the bulk requirements and candidates to add.
**/
- private void add(Map<BundleRequirement, SortedSet<BundleCapability>> candidates)
+ private void add(Map<Requirement, SortedSet<Capability>> candidates)
{
- for (Entry<BundleRequirement, SortedSet<BundleCapability>> entry : candidates.entrySet())
+ for (Entry<Requirement, SortedSet<Capability>> entry : candidates.entrySet())
{
add(entry.getKey(), entry.getValue());
}
@@ -525,9 +495,9 @@
* @param m the module whose wrapper is desired.
* @return the wrapper module or the module itself if it was not wrapped.
**/
- public BundleRevision getWrappedHost(BundleRevision m)
+ public Module getWrappedHost(Module m)
{
- BundleRevision wrapped = m_allWrappedHosts.get(m);
+ Module wrapped = m_allWrappedHosts.get(m);
return (wrapped == null) ? m : wrapped;
}
@@ -536,7 +506,7 @@
* @param req the requirement whose candidates are desired.
* @return the matching candidates or null.
**/
- public SortedSet<BundleCapability> getCandidates(BundleRequirement req)
+ public SortedSet<Capability> getCandidates(Requirement req)
{
return m_candidateMap.get(req);
}
@@ -557,7 +527,7 @@
* @throws ResolveException if the removal of any unselected fragments result
* in the root module being unable to resolve.
**/
- public void prepare(List<BundleRevision> existingSingletons)
+ public void prepare(List<Module> existingSingletons)
{
boolean init = false;
@@ -567,12 +537,12 @@
init = true;
}
- final Map<String, BundleRevision> singletons = new HashMap<String, BundleRevision>();
+ final Map<String, Module> singletons = new HashMap<String, Module>();
- for (Iterator<BundleRevision> it = m_candidateRevisions.iterator(); it.hasNext(); )
+ for (Iterator<Module> it = m_candidateModules.iterator(); it.hasNext(); )
{
- BundleRevision br = it.next();
- if (isSingleton(br))
+ Module m = it.next();
+ if (isSingleton(m))
{
if (!init)
{
@@ -581,28 +551,28 @@
}
// See if there is an existing singleton for the
- // revision's symbolic name.
- BundleRevision singleton = singletons.get(br.getSymbolicName());
- // If there is no existing singleton or this revision is
- // a resolved singleton or this revision has a higher version
+ // module's symbolic name.
+ Module singleton = singletons.get(m.getSymbolicName());
+ // If there is no existing singleton or this module is
+ // a resolved singleton or this module has a higher version
// and the existing singleton is not resolved, then select
- // this revision as the singleton.
+ // this module as the singleton.
if ((singleton == null)
- || (br.getWiring() != null)
- || ((br.getVersion().compareTo(singleton.getVersion()) > 0)
- && (singleton.getWiring() == null)))
+ || m.isResolved()
+ || ((m.getVersion().compareTo(singleton.getVersion()) > 0)
+ && !singleton.isResolved()))
{
- singletons.put(br.getSymbolicName(), br);
- // Remove the singleton revision from the candidates
+ singletons.put(m.getSymbolicName(), m);
+ // Remove the singleton module from the candidates
// if it wasn't selected.
if (singleton != null)
{
- removeRevision(singleton);
+ removeModule(singleton);
}
}
else
{
- removeRevision(br);
+ removeModule(m);
}
}
}
@@ -610,11 +580,11 @@
// If the root is a singleton, then prefer it over any other singleton.
if (isSingleton(m_root))
{
- BundleRevision singleton = singletons.get(m_root.getSymbolicName());
+ Module singleton = singletons.get(m_root.getSymbolicName());
singletons.put(m_root.getSymbolicName(), m_root);
if ((singleton != null) && !singleton.equals(m_root))
{
- if (singleton.getWiring() != null)
+ if (singleton.isResolved())
{
throw new ResolveException(
"Cannot resolve singleton "
@@ -624,7 +594,7 @@
+ " singleton is already resolved.",
m_root, null);
}
- removeRevision(singleton);
+ removeModule(singleton);
}
}
@@ -632,12 +602,12 @@
// singletons passed into this method.
for (int i = 0; (existingSingletons != null) && (i < existingSingletons.size()); i++)
{
- BundleRevision existing = existingSingletons.get(i);
- BundleRevision singleton = singletons.get(existing.getSymbolicName());
+ Module existing = existingSingletons.get(i);
+ Module singleton = singletons.get(existing.getSymbolicName());
if ((singleton != null) && (singleton != existing))
{
singletons.remove(singleton.getSymbolicName());
- removeRevision(singleton);
+ removeModule(singleton);
}
}
@@ -645,9 +615,9 @@
// 1. Select the fragments to attach to a given host.
// 2. Wrap hosts and attach fragments.
// 3. Remove any unselected fragments. This is necessary because
- // other revisions may depend on the capabilities of unselected
+ // other modules may depend on the capabilities of unselected
// fragments, so we need to remove the unselected fragments and
- // any revisions that depends on them, which could ultimately cause
+ // any modules that depends on them, which could ultimately cause
// the entire resolve to fail.
// 4. Replace all fragments with any host it was merged into
// (effectively multiplying it).
@@ -656,31 +626,28 @@
// with host's attached fragment capabilities.
// Steps 1 and 2
- List<HostBundleRevision> hostRevisions = new ArrayList<HostBundleRevision>();
- List<BundleRevision> unselectedFragments = new ArrayList<BundleRevision>();
- for (Entry<BundleCapability, Map<String, Map<Version, List<BundleRequirement>>>>
- hostEntry : m_hostFragments.entrySet())
+ List<HostModule> wrappedHosts = new ArrayList<HostModule>();
+ List<Module> unselectedFragments = new ArrayList<Module>();
+ for (Entry<Capability, Map<String, Map<Version, List<Requirement>>>> hostEntry :
+ m_hostFragments.entrySet())
{
// Step 1
- BundleCapability hostCap = hostEntry.getKey();
- Map<String, Map<Version, List<BundleRequirement>>> fragments
- = hostEntry.getValue();
- List<BundleRevision> selectedFragments = new ArrayList<BundleRevision>();
- for (Entry<String, Map<Version, List<BundleRequirement>>> fragEntry
- : fragments.entrySet())
+ Capability hostCap = hostEntry.getKey();
+ Map<String, Map<Version, List<Requirement>>> fragments = hostEntry.getValue();
+ List<Module> selectedFragments = new ArrayList<Module>();
+ for (Entry<String, Map<Version, List<Requirement>>> fragEntry : fragments.entrySet())
{
boolean isFirst = true;
- for (Entry<Version, List<BundleRequirement>> versionEntry
+ for (Entry<Version, List<Requirement>> versionEntry
: fragEntry.getValue().entrySet())
{
- for (BundleRequirement hostReq : versionEntry.getValue())
+ for (Requirement hostReq : versionEntry.getValue())
{
// Select the highest version of the fragment that
// is not removal pending.
- if (isFirst
- && !((BundleRevisionImpl) hostReq.getRevision()).isRemovalPending())
+ if (isFirst && !hostReq.getModule().isRemovalPending())
{
- selectedFragments.add(hostReq.getRevision());
+ selectedFragments.add(hostReq.getModule());
isFirst = false;
}
// For any fragment that wasn't selected, remove the
@@ -691,11 +658,11 @@
else
{
m_dependentMap.get(hostCap).remove(hostReq);
- SortedSet<BundleCapability> hosts = m_candidateMap.get(hostReq);
+ SortedSet<Capability> hosts = m_candidateMap.get(hostReq);
hosts.remove(hostCap);
if (hosts.isEmpty())
{
- unselectedFragments.add(hostReq.getRevision());
+ unselectedFragments.add(hostReq.getModule());
}
}
}
@@ -703,48 +670,47 @@
}
// Step 2
- HostBundleRevision wrappedHost =
- new HostBundleRevision(hostCap.getRevision(), selectedFragments);
- hostRevisions.add(wrappedHost);
- m_allWrappedHosts.put(hostCap.getRevision(), wrappedHost);
+ HostModule wrappedHost = new HostModule(hostCap.getModule(), selectedFragments);
+ wrappedHosts.add(wrappedHost);
+ m_allWrappedHosts.put(hostCap.getModule(), wrappedHost);
}
// Step 3
- for (BundleRevision br : unselectedFragments)
+ for (Module m : unselectedFragments)
{
- removeRevision(br);
+ removeModule(m);
}
// Step 4
- for (HostBundleRevision hostRevision : hostRevisions)
+ for (HostModule wrappedHost : wrappedHosts)
{
// Replaces capabilities from fragments with the capabilities
// from the merged host.
- for (BundleCapability c : hostRevision.getDeclaredCapabilities(null))
+ for (Capability c : wrappedHost.getCapabilities())
{
- Set<BundleRequirement> dependents =
+ Set<Requirement> dependents =
m_dependentMap.get(((HostedCapability) c).getDeclaredCapability());
if (dependents != null)
{
- for (BundleRequirement r : dependents)
+ for (Requirement r : dependents)
{
- Set<BundleCapability> cands = m_candidateMap.get(r);
+ Set<Capability> cands = m_candidateMap.get(r);
cands.remove(((HostedCapability) c).getDeclaredCapability());
cands.add(c);
}
}
}
- // Copy candidates for fragment requirements to the host.
+ // Copies candidates for fragment requirements to the host.
// This doesn't record the reverse dependency, but that
// information should not be needed at this point anymore.
- for (BundleRequirement r : hostRevision.getDeclaredRequirements(null))
+ for (Requirement r : wrappedHost.getRequirements())
{
- SortedSet<BundleCapability> cands =
+ SortedSet<Capability> cands =
m_candidateMap.get(((HostedRequirement) r).getDeclaredRequirement());
if (cands != null)
{
- m_candidateMap.put(r, new TreeSet<BundleCapability>(cands));
+ m_candidateMap.put(r, new TreeSet<Capability>(cands));
}
}
}
@@ -752,45 +718,44 @@
private void populateDependents()
{
- for (Entry<BundleRequirement, SortedSet<BundleCapability>> entry
- : m_candidateMap.entrySet())
+ for (Entry<Requirement, SortedSet<Capability>> entry : m_candidateMap.entrySet())
{
- BundleRequirement req = entry.getKey();
- SortedSet<BundleCapability> caps = entry.getValue();
- for (BundleCapability cap : caps)
+ Requirement req = entry.getKey();
+ SortedSet<Capability> caps = entry.getValue();
+ for (Capability cap : caps)
{
// Record the requirement as dependent on the capability.
- Set<BundleRequirement> dependents = m_dependentMap.get(cap);
+ Set<Requirement> dependents = m_dependentMap.get(cap);
if (dependents == null)
{
- dependents = new HashSet<BundleRequirement>();
+ dependents = new HashSet<Requirement>();
m_dependentMap.put(cap, dependents);
}
dependents.add(req);
// Keep track of hosts and associated fragments.
- if (req.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE))
+ if (req.getNamespace().equals(Capability.HOST_NAMESPACE))
{
- Map<String, Map<Version, List<BundleRequirement>>>
+ Map<String, Map<Version, List<Requirement>>>
fragments = m_hostFragments.get(cap);
if (fragments == null)
{
- fragments = new HashMap<String, Map<Version, List<BundleRequirement>>>();
+ fragments = new HashMap<String, Map<Version, List<Requirement>>>();
m_hostFragments.put(cap, fragments);
}
- Map<Version, List<BundleRequirement>> fragmentVersions =
- fragments.get(req.getRevision().getSymbolicName());
+ Map<Version, List<Requirement>> fragmentVersions =
+ fragments.get(req.getModule().getSymbolicName());
if (fragmentVersions == null)
{
fragmentVersions =
- new TreeMap<Version, List<BundleRequirement>>(Collections.reverseOrder());
- fragments.put(req.getRevision().getSymbolicName(), fragmentVersions);
+ new TreeMap<Version, List<Requirement>>(Collections.reverseOrder());
+ fragments.put(req.getModule().getSymbolicName(), fragmentVersions);
}
- List<BundleRequirement> actual = fragmentVersions.get(req.getRevision().getVersion());
+ List<Requirement> actual = fragmentVersions.get(req.getModule().getVersion());
if (actual == null)
{
- actual = new ArrayList<BundleRequirement>();
- fragmentVersions.put(req.getRevision().getVersion(), actual);
+ actual = new ArrayList<Requirement>();
+ fragmentVersions.put(req.getModule().getVersion(), actual);
}
actual.add(req);
}
@@ -803,26 +768,26 @@
* as a fragment or a singleton. This process may cause other modules to
* become unresolved if they depended on the module's capabilities and there
* is no other candidate.
- * @param revision the module to remove.
+ * @param module the module to remove.
* @throws ResolveException if removing the module caused the resolve to fail.
**/
- private void removeRevision(BundleRevision revision) throws ResolveException
+ private void removeModule(Module module) throws ResolveException
{
- if (m_root.equals(revision))
+ if (m_root.equals(module))
{
// TODO: SINGLETON RESOLVER - Improve this message.
String msg = "Unable to resolve " + m_root;
ResolveException ex = new ResolveException(msg, m_root, null);
throw ex;
}
- Set<BundleRevision> unresolvedRevisions = new HashSet<BundleRevision>();
- remove(revision, unresolvedRevisions);
- while (!unresolvedRevisions.isEmpty())
+ Set<Module> unresolvedModules = new HashSet<Module>();
+ remove(module, unresolvedModules);
+ while (!unresolvedModules.isEmpty())
{
- Iterator<BundleRevision> it = unresolvedRevisions.iterator();
- revision = it.next();
+ Iterator<Module> it = unresolvedModules.iterator();
+ module = it.next();
it.remove();
- remove(revision, unresolvedRevisions);
+ remove(module, unresolvedModules);
}
}
@@ -830,23 +795,22 @@
* Removes the specified module from the internal data structures, which
* involves removing its requirements and its capabilities. This may cause
* other modules to become unresolved as a result.
- * @param br the module to remove.
- * @param unresolvedRevisions a list to containing any additional modules that
+ * @param m the module to remove.
+ * @param unresolvedModules a list to containing any additional modules that
* that became unresolved as a result of removing this module and will
* also need to be removed.
* @throws ResolveException if removing the module caused the resolve to fail.
**/
- private void remove(BundleRevision br, Set<BundleRevision> unresolvedRevisions)
- throws ResolveException
+ private void remove(Module m, Set<Module> unresolvedModules) throws ResolveException
{
- for (BundleRequirement r : br.getDeclaredRequirements(null))
+ for (Requirement r : m.getRequirements())
{
remove(r);
}
- for (BundleCapability c : br.getDeclaredCapabilities(null))
+ for (Capability c : m.getCapabilities())
{
- remove(c, unresolvedRevisions);
+ remove(c, unresolvedModules);
}
}
@@ -854,16 +818,16 @@
* Removes a requirement from the internal data structures.
* @param req the requirement to remove.
**/
- private void remove(BundleRequirement req)
+ private void remove(Requirement req)
{
- boolean isFragment = req.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE);
+ boolean isFragment = req.getNamespace().equals(Capability.HOST_NAMESPACE);
- SortedSet<BundleCapability> candidates = m_candidateMap.remove(req);
+ SortedSet<Capability> candidates = m_candidateMap.remove(req);
if (candidates != null)
{
- for (BundleCapability cap : candidates)
+ for (Capability cap : candidates)
{
- Set<BundleRequirement> dependents = m_dependentMap.get(cap);
+ Set<Requirement> dependents = m_dependentMap.get(cap);
if (dependents != null)
{
dependents.remove(req);
@@ -871,25 +835,25 @@
if (isFragment)
{
- Map<String, Map<Version, List<BundleRequirement>>>
+ Map<String, Map<Version, List<Requirement>>>
fragments = m_hostFragments.get(cap);
if (fragments != null)
{
- Map<Version, List<BundleRequirement>> fragmentVersions =
- fragments.get(req.getRevision().getSymbolicName());
+ Map<Version, List<Requirement>> fragmentVersions =
+ fragments.get(req.getModule().getSymbolicName());
if (fragmentVersions != null)
{
- List<BundleRequirement> actual =
- fragmentVersions.get(req.getRevision().getVersion());
+ List<Requirement> actual =
+ fragmentVersions.get(req.getModule().getVersion());
if (actual != null)
{
actual.remove(req);
if (actual.isEmpty())
{
- fragmentVersions.remove(req.getRevision().getVersion());
+ fragmentVersions.remove(req.getModule().getVersion());
if (fragmentVersions.isEmpty())
{
- fragments.remove(req.getRevision().getSymbolicName());
+ fragments.remove(req.getModule().getSymbolicName());
if (fragments.isEmpty())
{
m_hostFragments.remove(cap);
@@ -908,34 +872,33 @@
* Removes a capability from the internal data structures. This may cause
* other modules to become unresolved as a result.
* @param c the capability to remove.
- * @param unresolvedRevisions a list to containing any additional modules that
+ * @param unresolvedModules a list to containing any additional modules that
* that became unresolved as a result of removing this module and will
* also need to be removed.
* @throws ResolveException if removing the module caused the resolve to fail.
**/
- private void remove(BundleCapability c, Set<BundleRevision> unresolvedRevisions)
- throws ResolveException
+ private void remove(Capability c, Set<Module> unresolvedModules) throws ResolveException
{
- Set<BundleRequirement> dependents = m_dependentMap.remove(c);
+ Set<Requirement> dependents = m_dependentMap.remove(c);
if (dependents != null)
{
- for (BundleRequirement r : dependents)
+ for (Requirement r : dependents)
{
- SortedSet<BundleCapability> candidates = m_candidateMap.get(r);
+ SortedSet<Capability> candidates = m_candidateMap.get(r);
candidates.remove(c);
if (candidates.isEmpty())
{
m_candidateMap.remove(r);
- if (!((BundleRequirementImpl) r).isOptional())
+ if (!r.isOptional())
{
- if (m_root.equals(r.getRevision()))
+ if (m_root.equals(r.getModule()))
{
String msg = "Unable to resolve " + m_root
+ ": missing requirement " + r;
ResolveException ex = new ResolveException(msg, m_root, r);
throw ex;
}
- unresolvedRevisions.add(r.getRevision());
+ unresolvedModules.add(r.getModule());
}
}
}
@@ -949,65 +912,54 @@
**/
public Candidates copy()
{
- Map<BundleCapability, Set<BundleRequirement>> dependentMap =
- new HashMap<BundleCapability, Set<BundleRequirement>>();
- for (Entry<BundleCapability, Set<BundleRequirement>> entry : m_dependentMap.entrySet())
+ Map<Capability, Set<Requirement>> dependentMap =
+ new HashMap<Capability, Set<Requirement>>();
+ for (Entry<Capability, Set<Requirement>> entry : m_dependentMap.entrySet())
{
- Set<BundleRequirement> dependents = new HashSet<BundleRequirement>(entry.getValue());
+ Set<Requirement> dependents = new HashSet<Requirement>(entry.getValue());
dependentMap.put(entry.getKey(), dependents);
}
- Map<BundleRequirement, SortedSet<BundleCapability>> candidateMap =
- new HashMap<BundleRequirement, SortedSet<BundleCapability>>();
- for (Entry<BundleRequirement, SortedSet<BundleCapability>> entry
- : m_candidateMap.entrySet())
+ Map<Requirement, SortedSet<Capability>> candidateMap =
+ new HashMap<Requirement, SortedSet<Capability>>();
+ for (Entry<Requirement, SortedSet<Capability>> entry : m_candidateMap.entrySet())
{
- SortedSet<BundleCapability> candidates =
- new TreeSet<BundleCapability>(entry.getValue());
+ SortedSet<Capability> candidates = new TreeSet<Capability>(entry.getValue());
candidateMap.put(entry.getKey(), candidates);
}
return new Candidates(
- m_root, m_candidateRevisions, dependentMap, candidateMap,
+ m_root, m_candidateModules, dependentMap, candidateMap,
m_hostFragments, m_allWrappedHosts, m_populateResultCache,
m_fragmentsPresent);
}
public void dump()
{
- // Create set of all revisions from requirements.
- Set<BundleRevision> revisions = new HashSet<BundleRevision>();
- for (Entry<BundleRequirement, SortedSet<BundleCapability>> entry
+ // Create set of all modules from requirements.
+ Set<Module> modules = new HashSet();
+ for (Entry<Requirement, SortedSet<Capability>> entry
: m_candidateMap.entrySet())
{
- revisions.add(entry.getKey().getRevision());
+ modules.add(entry.getKey().getModule());
}
- // Now dump the revisions.
+ // Now dump the modules.
System.out.println("=== BEGIN CANDIDATE MAP ===");
- for (BundleRevision br : revisions)
+ for (Module module : modules)
{
- System.out.println(" " + br
- + " (" + ((br.getWiring() != null) ? "RESOLVED)" : "UNRESOLVED)"));
- List<BundleRequirement> reqs = (br.getWiring() != null)
- ? br.getWiring().getRequirements(null)
- : br.getDeclaredRequirements(null);
- for (BundleRequirement req : reqs)
+ System.out.println(" " + module
+ + " (" + (module.isResolved() ? "RESOLVED)" : "UNRESOLVED)"));
+ for (Requirement req : module.getRequirements())
{
- Set<BundleCapability> candidates = m_candidateMap.get(req);
+ Set<Capability> candidates = m_candidateMap.get(req);
if ((candidates != null) && (candidates.size() > 0))
{
System.out.println(" " + req + ": " + candidates);
}
}
-// TODO: OSGi R4.3 - Need to check what getWiring().getRequirements() returns
-// with respect to dynamic imports; is it the union of all declared
-// dynamic imports from fragments and host?
- reqs = (br.getWiring() != null)
- ? Util.getDynamicRequirements(br.getWiring().getRequirements(null))
- : Util.getDynamicRequirements(br.getDeclaredRequirements(null));
- for (BundleRequirement req : reqs)
+ for (Requirement req : module.getDynamicRequirements())
{
- Set<BundleCapability> candidates = m_candidateMap.get(req);
+ Set<Capability> candidates = m_candidateMap.get(req);
if ((candidates != null) && (candidates.size() > 0))
{
System.out.println(" " + req + ": " + candidates);
@@ -1021,22 +973,26 @@
* Returns true if the specified module is a singleton
* (i.e., directive singleton:=true).
*
- * @param revision the module to check for singleton status.
+ * @param module the module to check for singleton status.
* @return true if the module is a singleton, false otherwise.
**/
- private static boolean isSingleton(BundleRevision revision)
+ private static boolean isSingleton(Module module)
{
- final List<BundleCapability> modCaps =
+ final List<Capability> modCaps =
Util.getCapabilityByNamespace(
- revision, BundleCapabilityImpl.BUNDLE_NAMESPACE);
+ module, Capability.MODULE_NAMESPACE);
if (modCaps == null || modCaps.isEmpty())
{
return false;
}
- String value = modCaps.get(0).getDirectives().get(Constants.SINGLETON_DIRECTIVE);
- if (value != null)
+ final List<Directive> dirs = modCaps.get(0).getDirectives();
+ for (int dirIdx = 0; (dirs != null) && (dirIdx < dirs.size()); dirIdx++)
{
- return Boolean.valueOf(value);
+ if (dirs.get(dirIdx).getName().equalsIgnoreCase(Constants.SINGLETON_DIRECTIVE)
+ && Boolean.valueOf((String) dirs.get(dirIdx).getValue()))
+ {
+ return true;
+ }
}
return false;
}
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/Content.java b/framework/src/main/java/org/apache/felix/framework/resolver/Content.java
similarity index 98%
rename from framework/src/main/java/org/apache/felix/framework/cache/Content.java
rename to framework/src/main/java/org/apache/felix/framework/resolver/Content.java
index b1cb0e4..f820ec8 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/Content.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Content.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.felix.framework.cache;
+package org.apache.felix.framework.resolver;
import java.io.IOException;
import java.io.InputStream;
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/HostBundleRevision.java b/framework/src/main/java/org/apache/felix/framework/resolver/HostBundleRevision.java
deleted file mode 100644
index 9551ec1..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/HostBundleRevision.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.resolver;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Version;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWiring;
-
-class HostBundleRevision implements BundleRevision
-{
- private final BundleRevision m_host;
- private final List<BundleRevision> m_fragments;
- private List<BundleCapability> m_cachedCapabilities = null;
- private List<BundleRequirement> m_cachedRequirements = null;
-
- public HostBundleRevision(BundleRevision host, List<BundleRevision> fragments)
- {
- m_host = host;
- m_fragments = fragments;
- }
-
- public BundleRevision getHost()
- {
- return m_host;
- }
-
- public List<BundleRevision> getFragments()
- {
- return m_fragments;
- }
-
- public String getSymbolicName()
- {
- return m_host.getSymbolicName();
- }
-
- public Version getVersion()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public List<BundleCapability> getDeclaredCapabilities(String namespace)
- {
- if (m_cachedCapabilities == null)
- {
- List<BundleCapability> caps = new ArrayList<BundleCapability>();
-
- // Wrap host capabilities.
- for (BundleCapability cap : m_host.getDeclaredCapabilities(null))
- {
- caps.add(new HostedCapability(this, (BundleCapabilityImpl) cap));
- }
-
- // Wrap fragment capabilities.
- if (m_fragments != null)
- {
- for (BundleRevision fragment : m_fragments)
- {
- for (BundleCapability cap : fragment.getDeclaredCapabilities(null))
- {
- if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
- {
- caps.add(new HostedCapability(this, (BundleCapabilityImpl) cap));
- }
- }
- }
- }
- m_cachedCapabilities = Collections.unmodifiableList(caps);
- }
- return m_cachedCapabilities;
- }
-
- public List<BundleRequirement> getDeclaredRequirements(String namespace)
- {
- if (m_cachedRequirements == null)
- {
- List<BundleRequirement> reqs = new ArrayList<BundleRequirement>();
-
- // Wrap host requirements.
- for (BundleRequirement req : m_host.getDeclaredRequirements(null))
- {
- reqs.add(new HostedRequirement(this, (BundleRequirementImpl) req));
- }
-
- // Wrap fragment requirements.
- if (m_fragments != null)
- {
- for (BundleRevision fragment : m_fragments)
- {
- for (BundleRequirement req : fragment.getDeclaredRequirements(null))
- {
- if (req.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
- || req.getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
- {
- reqs.add(new HostedRequirement(this, (BundleRequirementImpl) req));
- }
- }
- }
- }
- m_cachedRequirements = Collections.unmodifiableList(reqs);
- }
- return m_cachedRequirements;
- }
-
- public int getTypes()
- {
- return m_host.getTypes();
- }
-
- public BundleWiring getWiring()
- {
- return null;
- }
-
- public Bundle getBundle()
- {
- return m_host.getBundle();
- }
-
- public String toString()
- {
- return m_host.toString();
- }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/HostModule.java b/framework/src/main/java/org/apache/felix/framework/resolver/HostModule.java
new file mode 100644
index 0000000..819eeef
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/HostModule.java
@@ -0,0 +1,244 @@
+/*
+ * 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.resolver;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+
+class HostModule implements Module
+{
+ private final Module m_host;
+ private final List<Module> m_fragments;
+ private List<Capability> m_cachedCapabilities = null;
+ private List<Requirement> m_cachedRequirements = null;
+
+ public HostModule(Module module, List<Module> fragments)
+ {
+ m_host = module;
+ m_fragments = fragments;
+ }
+
+ public Module getHost()
+ {
+ return m_host;
+ }
+
+ public List<Module> getFragments()
+ {
+ return m_fragments;
+ }
+
+ public String getId()
+ {
+ return m_host.getId();
+ }
+
+ public List<Capability> getCapabilities()
+ {
+ if (m_cachedCapabilities == null)
+ {
+ List<Capability> capList = new ArrayList<Capability>();
+
+ // Wrap host capabilities.
+ List<Capability> caps = m_host.getCapabilities();
+ for (int capIdx = 0;
+ (caps != null) && (capIdx < caps.size());
+ capIdx++)
+ {
+ capList.add(
+ new HostedCapability(this, caps.get(capIdx)));
+ }
+
+ // Wrap fragment capabilities.
+ for (int fragIdx = 0;
+ (m_fragments != null) && (fragIdx < m_fragments.size());
+ fragIdx++)
+ {
+ caps = m_fragments.get(fragIdx).getCapabilities();
+ for (int capIdx = 0;
+ (caps != null) && (capIdx < caps.size());
+ capIdx++)
+ {
+ if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+ {
+ capList.add(
+ new HostedCapability(this, caps.get(capIdx)));
+ }
+ }
+ }
+ m_cachedCapabilities = Collections.unmodifiableList(capList);
+ }
+ return m_cachedCapabilities;
+ }
+
+ public List<Requirement> getRequirements()
+ {
+ if (m_cachedRequirements == null)
+ {
+ List<Requirement> reqList = new ArrayList<Requirement>();
+
+ // Wrap host requirements.
+ List<Requirement> reqs = m_host.getRequirements();
+ for (int reqIdx = 0;
+ (reqs != null) && (reqIdx < reqs.size());
+ reqIdx++)
+ {
+ reqList.add(
+ new HostedRequirement(this, reqs.get(reqIdx)));
+ }
+
+ // Wrap fragment requirements.
+ for (int fragIdx = 0;
+ (m_fragments != null) && (fragIdx < m_fragments.size());
+ fragIdx++)
+ {
+ reqs = m_fragments.get(fragIdx).getRequirements();
+ for (int reqIdx = 0;
+ (reqs != null) && (reqIdx < reqs.size());
+ reqIdx++)
+ {
+ if (reqs.get(reqIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+ || reqs.get(reqIdx).getNamespace().equals(Capability.MODULE_NAMESPACE))
+ {
+ reqList.add(
+ new HostedRequirement(this, reqs.get(reqIdx)));
+ }
+ }
+ }
+ m_cachedRequirements = Collections.unmodifiableList(reqList);
+ }
+ return m_cachedRequirements;
+ }
+
+ public String toString()
+ {
+ return m_host.getId();
+ }
+
+ public Map getHeaders()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public boolean isExtension()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public String getSymbolicName()
+ {
+ return m_host.getSymbolicName();
+ }
+
+ public Version getVersion()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public List<Requirement> getDynamicRequirements()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public List<R4Library> getNativeLibraries()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public int getDeclaredActivationPolicy()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public Bundle getBundle()
+ {
+ return m_host.getBundle();
+ }
+
+ public List<Wire> getWires()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public boolean isResolved()
+ {
+ return false;
+ }
+
+ public Object getSecurityContext()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public boolean isRemovalPending()
+ {
+ return m_host.isRemovalPending();
+ }
+
+ public Content getContent()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public Class getClassByDelegation(String name) throws ClassNotFoundException
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public URL getResourceByDelegation(String name)
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public Enumeration getResourcesByDelegation(String name)
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public URL getEntry(String name)
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public boolean hasInputStream(int index, String urlPath) throws IOException
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public InputStream getInputStream(int index, String urlPath) throws IOException
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public URL getLocalURL(int index, String urlPath)
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java b/framework/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
index 70c282e..04c68b7 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
@@ -19,20 +19,18 @@
package org.apache.felix.framework.resolver;
import java.util.List;
-import java.util.Map;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Directive;
-public class HostedCapability extends BundleCapabilityImpl
+public class HostedCapability implements Capability
{
- private final BundleRevision m_host;
- private final BundleCapabilityImpl m_cap;
+ private final Module m_host;
+ private final Capability m_cap;
- public HostedCapability(BundleRevision host, BundleCapabilityImpl cap)
+ public HostedCapability(Module module, Capability cap)
{
- super(host, cap.getNamespace(), cap.getDirectives(), cap.getAttributes());
- m_host = host;
+ m_host = module;
m_cap = cap;
}
@@ -68,36 +66,41 @@
return hash;
}
- public BundleCapabilityImpl getDeclaredCapability()
+ public Capability getDeclaredCapability()
{
return m_cap;
}
- @Override
- public BundleRevision getRevision()
+ public Module getModule()
{
return m_host;
}
- @Override
public String getNamespace()
{
return m_cap.getNamespace();
}
- @Override
- public Map<String, String> getDirectives()
+ public Directive getDirective(String name)
+ {
+ return m_cap.getDirective(name);
+ }
+
+ public List<Directive> getDirectives()
{
return m_cap.getDirectives();
}
- @Override
- public Map<String, Object> getAttributes()
+ public Attribute getAttribute(String name)
+ {
+ return m_cap.getAttribute(name);
+ }
+
+ public List<Attribute> getAttributes()
{
return m_cap.getAttributes();
}
- @Override
public List<String> getUses()
{
return m_cap.getUses();
@@ -110,10 +113,10 @@
{
return getAttributes().toString();
}
- if (getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ if (getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
return "[" + m_host + "] "
- + getNamespace() + "; " + getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
+ + getNamespace() + "; " + getAttribute(Capability.PACKAGE_ATTR);
}
return "[" + m_host + "] " + getNamespace() + "; " + getAttributes();
}
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/HostedRequirement.java b/framework/src/main/java/org/apache/felix/framework/resolver/HostedRequirement.java
index 7af7a14..10f6f53 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/HostedRequirement.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/HostedRequirement.java
@@ -18,20 +18,19 @@
*/
package org.apache.felix.framework.resolver;
-import java.util.Map;
+import java.util.List;
+import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.capabilityset.Requirement;
import org.apache.felix.framework.capabilityset.SimpleFilter;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.osgi.framework.wiring.BundleRevision;
-public class HostedRequirement extends BundleRequirementImpl
+public class HostedRequirement implements Requirement
{
- private final BundleRevision m_host;
- private final BundleRequirementImpl m_req;
+ private final Module m_host;
+ private final Requirement m_req;
- public HostedRequirement(BundleRevision host, BundleRequirementImpl req)
+ public HostedRequirement(Module module, Requirement req)
{
- super(host, req.getNamespace(), req.getDirectives(), req.getAttributes());
- m_host = host;
+ m_host = module;
m_req = req;
}
@@ -67,48 +66,41 @@
return hash;
}
- public BundleRequirementImpl getDeclaredRequirement()
+ public Requirement getDeclaredRequirement()
{
return m_req;
}
- @Override
- public BundleRevision getRevision()
+ public Module getModule()
{
return m_host;
}
- @Override
public String getNamespace()
{
return m_req.getNamespace();
}
- @Override
public SimpleFilter getFilter()
{
return m_req.getFilter();
}
- @Override
public boolean isOptional()
{
return m_req.isOptional();
}
- @Override
- public Map<String, String> getDirectives()
+ public Directive getDirective(String name)
+ {
+ return m_req.getDirective(name);
+ }
+
+ public List<Directive> getDirectives()
{
return m_req.getDirectives();
}
- @Override
- public Map<String, Object> getAttributes()
- {
- return m_req.getAttributes();
- }
-
- @Override
public String toString()
{
return "[" + m_host + "] " + getNamespace() + "; " + getFilter().toString();
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Module.java b/framework/src/main/java/org/apache/felix/framework/resolver/Module.java
new file mode 100644
index 0000000..7d9f84f
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Module.java
@@ -0,0 +1,81 @@
+/*
+ * 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.resolver;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+
+public interface Module
+{
+ final static int EAGER_ACTIVATION = 0;
+ final static int LAZY_ACTIVATION = 1;
+
+ // Metadata access methods.
+ Map getHeaders();
+ boolean isExtension();
+ String getSymbolicName();
+ Version getVersion();
+ List<Capability> getCapabilities();
+ List<Requirement> getRequirements();
+ List<Requirement> getDynamicRequirements();
+ List<R4Library> getNativeLibraries();
+ int getDeclaredActivationPolicy();
+
+ // Run-time data access methods.
+ Bundle getBundle();
+ String getId();
+ List<Wire> getWires();
+ boolean isResolved();
+ Object getSecurityContext();
+ // TODO: FRAGMENT RESOLVER - Technically, this is only necessary for fragments.
+ // When we refactoring for the new R4.3 framework API, we'll have to see
+ // if this is still necessary, since the new BundleWirings API will give
+ // us another way to detect it.
+ boolean isRemovalPending();
+
+ // Content access methods.
+ Content getContent();
+ Class getClassByDelegation(String name) throws ClassNotFoundException;
+ URL getResourceByDelegation(String name);
+ Enumeration getResourcesByDelegation(String name);
+ URL getEntry(String name);
+
+ // TODO: ML - For expediency, the index argument was added to these methods
+ // but it is not clear that this makes sense in the long run. This needs to
+ // be readdressed in the future, perhaps by the spec to clearly indicate
+ // how resources on the bundle class path are searched, which is why we
+ // need the index number in the first place -- to differentiate among
+ // resources with the same name on the bundle class path. This was previously
+ // handled as part of the resource path, but that approach is not spec
+ // compliant.
+ boolean hasInputStream(int index, String urlPath)
+ throws IOException;
+ InputStream getInputStream(int index, String urlPath)
+ throws IOException;
+ URL getLocalURL(int index, String urlPath);
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java
index 360ef3d..8e69cd3 100755
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java
@@ -18,31 +18,30 @@
*/
package org.apache.felix.framework.resolver;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
+import org.apache.felix.framework.capabilityset.Requirement;
public class ResolveException extends RuntimeException
{
- private final BundleRevision m_revision;
- private final BundleRequirement m_req;
+ private final Module m_module;
+ private final Requirement m_req;
/**
* Constructs an instance of <code>ResolveException</code> with the specified detail message.
* @param msg the detail message.
*/
- public ResolveException(String msg, BundleRevision revision, BundleRequirement req)
+ public ResolveException(String msg, Module module, Requirement req)
{
super(msg);
- m_revision = revision;
+ m_module = module;
m_req = req;
}
- public BundleRevision getRevision()
+ public Module getModule()
{
- return m_revision;
+ return m_module;
}
- public BundleRequirement getRequirement()
+ public Requirement getRequirement()
{
return m_req;
}
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java b/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
index 25e0ad0..9d65b4f 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
@@ -22,23 +22,19 @@
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Requirement;
public interface Resolver
{
- Map<BundleRevision, List<ResolverWire>> resolve(
- ResolverState state, BundleRevision revision, Set<BundleRevision> optional);
- Map<BundleRevision, List<ResolverWire>> resolve(
- ResolverState state, BundleRevision revision, String pkgName,
- Set<BundleRevision> fragments);
+ Map<Module, List<Wire>> resolve(ResolverState state, Module module, Set<Module> fragments);
+ Map<Module, List<Wire>> resolve(
+ ResolverState state, Module module, String pkgName, Set<Module> fragments);
public static interface ResolverState
{
- SortedSet<BundleCapability> getCandidates(
- BundleRequirementImpl req, boolean obeyMandatory);
- void checkExecutionEnvironment(BundleRevision revision) throws ResolveException;
- void checkNativeLibraries(BundleRevision revision) throws ResolveException;
+ SortedSet<Capability> getCandidates(Requirement req, boolean obeyMandatory);
+ void checkExecutionEnvironment(Module module) throws ResolveException;
+ void checkNativeLibraries(Module module) throws ResolveException;
}
}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
index 80cb321..04dca7d 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
@@ -28,17 +28,15 @@
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedSet;
-import org.apache.felix.framework.BundleWiringImpl;
import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Capability;
import org.apache.felix.framework.capabilityset.CapabilitySet;
+import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.capabilityset.Requirement;
import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
+import org.apache.felix.framework.util.manifestparser.RequirementImpl;
import org.osgi.framework.Constants;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
public class ResolverImpl implements Resolver
{
@@ -56,13 +54,13 @@
m_logger = logger;
}
- public Map<BundleRevision, List<ResolverWire>> resolve(
- ResolverState state, BundleRevision revision, Set<BundleRevision> optional)
+ public Map<Module, List<Wire>> resolve(
+ ResolverState state, Module module, Set<Module> fragments)
{
- Map<BundleRevision, List<ResolverWire>> wireMap = new HashMap<BundleRevision, List<ResolverWire>>();
- Map<BundleRevision, Packages> revisionPkgMap = new HashMap<BundleRevision, Packages>();
+ Map<Module, List<Wire>> wireMap = new HashMap<Module, List<Wire>>();
+ Map<Module, Packages> modulePkgMap = new HashMap<Module, Packages>();
- if (revision.getWiring() == null)
+ if (!module.isResolved())
{
boolean retryFragments;
do
@@ -72,12 +70,12 @@
try
{
// Populate all candidates.
- Candidates allCandidates = new Candidates(state, revision);
+ Candidates allCandidates = new Candidates(state, module);
// Try to populate optional fragments.
- for (BundleRevision br : optional)
+ for (Module fragment : fragments)
{
- allCandidates.populateOptional(state, br);
+ allCandidates.populateOptional(state, fragment);
}
// Merge any fragments into hosts.
@@ -88,18 +86,16 @@
ResolveException rethrow = null;
- // If the requested revision is a fragment, then
+ // If the requested module is a fragment, then
// ultimately we will verify the host.
- List<BundleRequirement> hostReqs =
- revision.getDeclaredRequirements(BundleCapabilityImpl.HOST_NAMESPACE);
-
- BundleRevision target = revision;
+ Requirement hostReq = getHostRequirement(module);
+ Module target = module;
do
{
rethrow = null;
- revisionPkgMap.clear();
+ modulePkgMap.clear();
m_packageSourcesCache.clear();
allCandidates = (m_usesPermutations.size() > 0)
@@ -109,24 +105,24 @@
// If we are resolving a fragment, then we
// actually want to verify its host.
- if (!hostReqs.isEmpty())
+ if (hostReq != null)
{
- target = allCandidates.getCandidates(hostReqs.get(0))
- .iterator().next().getRevision();
+ target = allCandidates.getCandidates(hostReq)
+ .iterator().next().getModule();
}
calculatePackageSpaces(
- allCandidates.getWrappedHost(target), allCandidates, revisionPkgMap,
+ allCandidates.getWrappedHost(target), allCandidates, modulePkgMap,
new HashMap(), new HashSet());
//System.out.println("+++ PACKAGE SPACES START +++");
-//dumpRevisionPkgMap(revisionPkgMap);
+//dumpModulePkgMap(modulePkgMap);
//System.out.println("+++ PACKAGE SPACES END +++");
try
{
checkPackageSpaceConsistency(
false, allCandidates.getWrappedHost(target),
- allCandidates, revisionPkgMap, new HashMap());
+ allCandidates, modulePkgMap, new HashMap());
}
catch (ResolveException ex)
{
@@ -137,20 +133,19 @@
&& ((m_usesPermutations.size() > 0) || (m_importPermutations.size() > 0)));
// If there is a resolve exception, then determine if an
- // optionally resolved revision is to blame (typically a fragment).
- // If so, then remove the optionally resolved resolved and try
+ // optionally resolved module is to blame (typically a fragment).
+ // If so, then remove the optionally resolved module and try
// again; otherwise, rethrow the resolve exception.
if (rethrow != null)
{
- BundleRevision faultyRevision =
- getActualBundleRevision(rethrow.getRevision());
+ Module faultyModule = getActualModule(rethrow.getModule());
if (rethrow.getRequirement() instanceof HostedRequirement)
{
- faultyRevision =
+ faultyModule =
((HostedRequirement) rethrow.getRequirement())
- .getDeclaredRequirement().getRevision();
+ .getDeclaredRequirement().getModule();
}
- if (optional.remove(faultyRevision))
+ if (fragments.remove(faultyModule))
{
retryFragments = true;
}
@@ -166,7 +161,7 @@
wireMap =
populateWireMap(
allCandidates.getWrappedHost(target),
- revisionPkgMap, wireMap, allCandidates);
+ modulePkgMap, wireMap, allCandidates);
}
}
finally
@@ -182,25 +177,24 @@
return wireMap;
}
- public Map<BundleRevision, List<ResolverWire>> resolve(
- ResolverState state, BundleRevision revision, String pkgName,
- Set<BundleRevision> optional)
+ public Map<Module, List<Wire>> resolve(
+ ResolverState state, Module module, String pkgName, Set<Module> fragments)
{
// We can only create a dynamic import if the following
// conditions are met:
- // 1. The specified revision is resolved.
+ // 1. The specified module is resolved.
// 2. The package in question is not already imported.
// 3. The package in question is not accessible via require-bundle.
- // 4. The package in question is not exported by the revision.
- // 5. The package in question matches a dynamic import of the revision.
+ // 4. The package in question is not exported by the bundle.
+ // 5. The package in question matches a dynamic import of the bundle.
// The following call checks all of these conditions and returns
// the associated dynamic import and matching capabilities.
Candidates allCandidates =
- getDynamicImportCandidates(state, revision, pkgName);
+ getDynamicImportCandidates(state, module, pkgName);
if (allCandidates != null)
{
- Map<BundleRevision, List<ResolverWire>> wireMap = new HashMap<BundleRevision, List<ResolverWire>>();
- Map<BundleRevision, Packages> revisionPkgMap = new HashMap<BundleRevision, Packages>();
+ Map<Module, List<Wire>> wireMap = new HashMap<Module, List<Wire>>();
+ Map<Module, Packages> modulePkgMap = new HashMap<Module, Packages>();
boolean retryFragments;
do
@@ -210,16 +204,16 @@
try
{
// Try to populate optional fragments.
- for (BundleRevision br : optional)
+ for (Module fragment : fragments)
{
- allCandidates.populateOptional(state, br);
+ allCandidates.populateOptional(state, fragment);
}
// Merge any fragments into hosts.
allCandidates.prepare(getResolvedSingletons(state));
// Record the initial candidate permutation.
- m_usesPermutations.add(allCandidates);
+ m_usesPermutations.add(allCandidates);
ResolveException rethrow = null;
@@ -227,7 +221,7 @@
{
rethrow = null;
- revisionPkgMap.clear();
+ modulePkgMap.clear();
m_packageSourcesCache.clear();
allCandidates = (m_usesPermutations.size() > 0)
@@ -235,23 +229,23 @@
: m_importPermutations.remove(0);
//allCandidates.dump();
- // For a dynamic import, the instigating revision
+ // For a dynamic import, the instigating module
// will never be a fragment since fragments never
// execute code, so we don't need to check for
// this case like we do for a normal resolve.
calculatePackageSpaces(
- allCandidates.getWrappedHost(revision), allCandidates, revisionPkgMap,
+ allCandidates.getWrappedHost(module), allCandidates, modulePkgMap,
new HashMap(), new HashSet());
//System.out.println("+++ PACKAGE SPACES START +++");
-//dumpRevisionPkgMap(revisionPkgMap);
+//dumpModulePkgMap(modulePkgMap);
//System.out.println("+++ PACKAGE SPACES END +++");
try
{
checkPackageSpaceConsistency(
- false, allCandidates.getWrappedHost(revision),
- allCandidates, revisionPkgMap, new HashMap());
+ false, allCandidates.getWrappedHost(module),
+ allCandidates, modulePkgMap, new HashMap());
}
catch (ResolveException ex)
{
@@ -262,20 +256,19 @@
&& ((m_usesPermutations.size() > 0) || (m_importPermutations.size() > 0)));
// If there is a resolve exception, then determine if an
- // optionally resolved revision is to blame (typically a fragment).
- // If so, then remove the optionally resolved revision and try
+ // optionally resolved module is to blame (typically a fragment).
+ // If so, then remove the optionally resolved module and try
// again; otherwise, rethrow the resolve exception.
if (rethrow != null)
{
- BundleRevision faultyRevision =
- getActualBundleRevision(rethrow.getRevision());
+ Module faultyModule = getActualModule(rethrow.getModule());
if (rethrow.getRequirement() instanceof HostedRequirement)
{
- faultyRevision =
+ faultyModule =
((HostedRequirement) rethrow.getRequirement())
- .getDeclaredRequirement().getRevision();
+ .getDeclaredRequirement().getModule();
}
- if (optional.remove(faultyRevision))
+ if (fragments.remove(faultyModule))
{
retryFragments = true;
}
@@ -289,7 +282,7 @@
else
{
wireMap = populateDynamicWireMap(
- revision, pkgName, revisionPkgMap, wireMap, allCandidates);
+ module, pkgName, modulePkgMap, wireMap, allCandidates);
return wireMap;
}
}
@@ -306,89 +299,112 @@
return null;
}
- private static List<BundleRevision> getResolvedSingletons(ResolverState state)
+ private static List<Module> getResolvedSingletons(ResolverState state)
{
- BundleRequirementImpl req = new BundleRequirementImpl(
+ Requirement req = new RequirementImpl(
null,
- BundleCapabilityImpl.SINGLETON_NAMESPACE,
- Collections.EMPTY_MAP,
- Collections.EMPTY_MAP);
- SortedSet<BundleCapability> caps = state.getCandidates(req, true);
- List<BundleRevision> singletons = new ArrayList();
- for (BundleCapability cap : caps)
+ Capability.SINGLETON_NAMESPACE,
+ Collections.EMPTY_LIST,
+ Collections.EMPTY_LIST);
+ SortedSet<Capability> caps = state.getCandidates(req, true);
+ List<Module> singletons = new ArrayList();
+ for (Capability cap : caps)
{
- if (cap.getRevision().getWiring() != null)
+ if (cap.getModule().isResolved())
{
- singletons.add(cap.getRevision());
+ singletons.add(cap.getModule());
}
}
return singletons;
}
- private static Candidates getDynamicImportCandidates(
- ResolverState state, BundleRevision revision, String pkgName)
+ private static Capability getHostCapability(Module m)
{
- // Unresolved revisions cannot dynamically import, nor can the default
+ for (Capability c : m.getCapabilities())
+ {
+ if (c.getNamespace().equals(Capability.HOST_NAMESPACE))
+ {
+ return c;
+ }
+ }
+ return null;
+ }
+
+ private static Requirement getHostRequirement(Module m)
+ {
+ for (Requirement r : m.getRequirements())
+ {
+ if (r.getNamespace().equals(Capability.HOST_NAMESPACE))
+ {
+ return r;
+ }
+ }
+ return null;
+ }
+
+ private static Candidates getDynamicImportCandidates(
+ ResolverState state, Module module, String pkgName)
+ {
+ // Unresolved modules cannot dynamically import, nor can the default
// package be dynamically imported.
- if ((revision.getWiring() == null) || pkgName.length() == 0)
+ if (!module.isResolved() || pkgName.length() == 0)
{
return null;
}
- // If the revision doesn't have dynamic imports, then just return
+ // If the module doesn't have dynamic imports, then just return
// immediately.
- List<BundleRequirement> dynamics =
- Util.getDynamicRequirements(revision.getWiring().getRequirements(null));
+ List<Requirement> dynamics = module.getDynamicRequirements();
if ((dynamics == null) || dynamics.isEmpty())
{
return null;
}
- // If the revision exports this package, then we cannot
+ // If any of the module exports this package, then we cannot
// attempt to dynamically import it.
- for (BundleCapability cap : revision.getWiring().getCapabilities(null))
+ List<Capability> caps = module.getCapabilities();
+ for (int i = 0; (caps != null) && (i < caps.size()); i++)
{
- if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
- && cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
+ if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+ && caps.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+ {
+ return null;
+ }
+ }
+ // If any of our wires have this package, then we cannot
+ // attempt to dynamically import it.
+ List<Wire> wires = module.getWires();
+ for (int i = 0; (wires != null) && (i < wires.size()); i++)
+ {
+ if (wires.get(i).hasPackage(pkgName))
{
return null;
}
}
- // If this revision already imports or requires this package, then
- // we cannot dynamically import it.
- if (((BundleWiringImpl) revision.getWiring()).hasPackageSource(pkgName))
- {
- return null;
- }
-
// Loop through the importer's dynamic requirements to determine if
// there is a matching one for the package from which we want to
// load a class.
- Map<String, Object> attrs = new HashMap(1);
- attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
- BundleRequirementImpl req = new BundleRequirementImpl(
- revision,
- BundleCapabilityImpl.PACKAGE_NAMESPACE,
- Collections.EMPTY_MAP,
- attrs);
- SortedSet<BundleCapability> candidates = state.getCandidates(req, false);
+ List<Directive> dirs = Collections.EMPTY_LIST;
+ List<Attribute> attrs = new ArrayList(1);
+ attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
+ Requirement req = new RequirementImpl(
+ module, Capability.PACKAGE_NAMESPACE, dirs, attrs);
+ SortedSet<Capability> candidates = state.getCandidates(req, false);
// First find a dynamic requirement that matches the capabilities.
- BundleRequirementImpl dynReq = null;
+ Requirement dynReq = null;
for (int dynIdx = 0;
(candidates.size() > 0) && (dynReq == null) && (dynIdx < dynamics.size());
dynIdx++)
{
- for (Iterator<BundleCapability> itCand = candidates.iterator();
+ for (Iterator<Capability> itCand = candidates.iterator();
(dynReq == null) && itCand.hasNext(); )
{
- BundleCapability cap = itCand.next();
- if (CapabilitySet.matches(
- (BundleCapabilityImpl) cap,
- ((BundleRequirementImpl) dynamics.get(dynIdx)).getFilter()))
+ Capability cap = itCand.next();
+ if (CapabilitySet.matches(cap, dynamics.get(dynIdx).getFilter()))
{
- dynReq = (BundleRequirementImpl) dynamics.get(dynIdx);
+ dynReq = dynamics.get(dynIdx);
}
}
}
@@ -397,12 +413,10 @@
// any candidates that do not match it.
if (dynReq != null)
{
- for (Iterator<BundleCapability> itCand = candidates.iterator();
- itCand.hasNext(); )
+ for (Iterator<Capability> itCand = candidates.iterator(); itCand.hasNext(); )
{
- BundleCapability cap = itCand.next();
- if (!CapabilitySet.matches(
- (BundleCapabilityImpl) cap, dynReq.getFilter()))
+ Capability cap = itCand.next();
+ if (!CapabilitySet.matches(cap, dynReq.getFilter()))
{
itCand.remove();
}
@@ -417,78 +431,72 @@
if (candidates.size() > 0)
{
- allCandidates = new Candidates(state, revision, dynReq, candidates);
+ allCandidates = new Candidates(state, module, dynReq, candidates);
}
return allCandidates;
}
private void calculatePackageSpaces(
- BundleRevision revision,
+ Module module,
Candidates allCandidates,
- Map<BundleRevision, Packages> revisionPkgMap,
- Map<BundleCapability, List<BundleRevision>> usesCycleMap,
- Set<BundleRevision> cycle)
+ Map<Module, Packages> modulePkgMap,
+ Map<Capability, List<Module>> usesCycleMap,
+ Set<Module> cycle)
{
- if (cycle.contains(revision))
+ if (cycle.contains(module))
{
return;
}
- cycle.add(revision);
+ cycle.add(module);
// Create parallel arrays for requirement and proposed candidate
- // capability or actual capability if revision is resolved or not.
- List<BundleRequirement> reqs = new ArrayList();
- List<BundleCapability> caps = new ArrayList();
- boolean isDynamicImporting = false;
- if (revision.getWiring() != null)
+ // capability or actual capability if module is resolved or not.
+ List<Requirement> reqs = new ArrayList();
+ List<Capability> caps = new ArrayList();
+ boolean isDynamicImport = false;
+ if (module.isResolved())
{
// Use wires to get actual requirements and satisfying capabilities.
- for (BundleWire wire : revision.getWiring().getRequiredWires(null))
+ for (Wire wire : module.getWires())
{
// Wrap the requirement as a hosted requirement
// if it comes from a fragment, since we will need
// to know the host.
- BundleRequirement r = wire.getRequirement();
- if (!r.getRevision().equals(wire.getRequirerWiring().getRevision()))
+ Requirement r = wire.getRequirement();
+ if (!r.getModule().equals(wire.getImporter()))
{
- r = new HostedRequirement(
- wire.getRequirerWiring().getRevision(),
- (BundleRequirementImpl) r);
+ r = new HostedRequirement(wire.getImporter(), r);
}
// Wrap the capability as a hosted capability
// if it comes from a fragment, since we will need
// to know the host.
- BundleCapability c = wire.getCapability();
- if (!c.getRevision().equals(wire.getProviderWiring().getRevision()))
+ Capability c = wire.getCapability();
+ if (!c.getModule().equals(wire.getExporter()))
{
- c = new HostedCapability(
- wire.getProviderWiring().getRevision(),
- (BundleCapabilityImpl) c);
+ c = new HostedCapability(wire.getExporter(), c);
}
reqs.add(r);
caps.add(c);
}
- // Since the revision is resolved, it could be dynamically importing,
+ // Since the module is resolved, it could be dynamically importing,
// so check to see if there are candidates for any of its dynamic
// imports.
- for (BundleRequirement req
- : Util.getDynamicRequirements(revision.getWiring().getRequirements(null)))
+ for (Requirement req : module.getDynamicRequirements())
{
// Get the candidates for the current requirement.
- SortedSet<BundleCapability> candCaps =
- allCandidates.getCandidates((BundleRequirementImpl) req);
+ SortedSet<Capability> candCaps = allCandidates.getCandidates(req);
// Optional requirements may not have any candidates.
if (candCaps == null)
{
continue;
}
- BundleCapability cap = candCaps.iterator().next();
+ Capability cap = candCaps.iterator().next();
reqs.add(req);
caps.add(cap);
- isDynamicImporting = true;
+ isDynamicImport = true;
// Can only dynamically import one at a time, so break
// out of the loop after the first.
break;
@@ -496,94 +504,88 @@
}
else
{
- for (BundleRequirement req : revision.getDeclaredRequirements(null))
+ for (Requirement req : module.getRequirements())
{
- String resolution = req.getDirectives().get(Constants.RESOLUTION_DIRECTIVE);
-// TODO: OSGi R4.3 - Use proper "dynamic" constant.
- if ((resolution == null) || !resolution.equals("dynamic"))
+ // Get the candidates for the current requirement.
+ SortedSet<Capability> candCaps = allCandidates.getCandidates(req);
+ // Optional requirements may not have any candidates.
+ if (candCaps == null)
{
- // Get the candidates for the current requirement.
- SortedSet<BundleCapability> candCaps =
- allCandidates.getCandidates((BundleRequirementImpl) req);
- // Optional requirements may not have any candidates.
- if (candCaps == null)
- {
- continue;
- }
-
- BundleCapability cap = candCaps.iterator().next();
- reqs.add(req);
- caps.add(cap);
+ continue;
}
+
+ Capability cap = candCaps.iterator().next();
+ reqs.add(req);
+ caps.add(cap);
}
}
- // First, add all exported packages to the target revision's package space.
- calculateExportedPackages(revision, allCandidates, revisionPkgMap);
- Packages revisionPkgs = revisionPkgMap.get(revision);
+ // First, add all exported packages to the target module's package space.
+ calculateExportedPackages(module, allCandidates, modulePkgMap);
+ Packages modulePkgs = modulePkgMap.get(module);
- // Second, add all imported packages to the target revision's package space.
+ // Second, add all imported packages to the target module's package space.
for (int i = 0; i < reqs.size(); i++)
{
- BundleRequirement req = reqs.get(i);
- BundleCapability cap = caps.get(i);
- calculateExportedPackages(cap.getRevision(), allCandidates, revisionPkgMap);
- mergeCandidatePackages(revision, req, cap, revisionPkgMap, allCandidates);
+ Requirement req = reqs.get(i);
+ Capability cap = caps.get(i);
+ calculateExportedPackages(cap.getModule(), allCandidates, modulePkgMap);
+ mergeCandidatePackages(module, req, cap, modulePkgMap, allCandidates);
}
// Third, have all candidates to calculate their package spaces.
for (int i = 0; i < caps.size(); i++)
{
calculatePackageSpaces(
- caps.get(i).getRevision(), allCandidates, revisionPkgMap,
+ caps.get(i).getModule(), allCandidates, modulePkgMap,
usesCycleMap, cycle);
}
- // Fourth, if the target revision is unresolved or is dynamically importing,
+ // Fourth, if the target module is unresolved or is dynamically importing,
// then add all the uses constraints implied by its imported and required
// packages to its package space.
- // NOTE: We do not need to do this for resolved revisions because their
+ // NOTE: We do not need to do this for resolved modules because their
// package space is consistent by definition and these uses constraints
- // are only needed to verify the consistency of a resolving revision. The
- // only exception is if a resolved revision is dynamically importing, then
+ // are only needed to verify the consistency of a resolving module. The
+ // only exception is if a resolve module is dynamically importing, then
// we need to calculate its uses constraints again to make sure the new
// import is consistent with the existing package space.
- if ((revision.getWiring() == null) || isDynamicImporting)
+ if (!module.isResolved() || isDynamicImport)
{
- for (Entry<String, List<Blame>> entry : revisionPkgs.m_importedPkgs.entrySet())
+ for (Entry<String, List<Blame>> entry : modulePkgs.m_importedPkgs.entrySet())
{
for (Blame blame : entry.getValue())
{
- // Ignore revisions that import from themselves.
- if (!blame.m_cap.getRevision().equals(revision))
+ // Ignore modules that import from themselves.
+ if (!blame.m_cap.getModule().equals(module))
{
- List<BundleRequirement> blameReqs = new ArrayList();
+ List<Requirement> blameReqs = new ArrayList();
blameReqs.add(blame.m_reqs.get(0));
mergeUses(
- revision,
- revisionPkgs,
+ module,
+ modulePkgs,
blame.m_cap,
blameReqs,
- revisionPkgMap,
+ modulePkgMap,
allCandidates,
usesCycleMap);
}
}
}
- for (Entry<String, List<Blame>> entry : revisionPkgs.m_requiredPkgs.entrySet())
+ for (Entry<String, List<Blame>> entry : modulePkgs.m_requiredPkgs.entrySet())
{
for (Blame blame : entry.getValue())
{
- List<BundleRequirement> blameReqs = new ArrayList();
+ List<Requirement> blameReqs = new ArrayList();
blameReqs.add(blame.m_reqs.get(0));
mergeUses(
- revision,
- revisionPkgs,
+ module,
+ modulePkgs,
blame.m_cap,
blameReqs,
- revisionPkgMap,
+ modulePkgMap,
allCandidates,
usesCycleMap);
}
@@ -592,27 +594,27 @@
}
private void mergeCandidatePackages(
- BundleRevision current, BundleRequirement currentReq, BundleCapability candCap,
- Map<BundleRevision, Packages> revisionPkgMap,
+ Module current, Requirement currentReq, Capability candCap,
+ Map<Module, Packages> modulePkgMap,
Candidates allCandidates)
{
- if (candCap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ if (candCap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
mergeCandidatePackage(
- current, false, currentReq, candCap, revisionPkgMap);
+ current, false, currentReq, candCap, modulePkgMap);
}
- else if (candCap.getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+ else if (candCap.getNamespace().equals(Capability.MODULE_NAMESPACE))
{
// TODO: FELIX3 - THIS NEXT LINE IS A HACK. IMPROVE HOW/WHEN WE CALCULATE EXPORTS.
calculateExportedPackages(
- candCap.getRevision(), allCandidates, revisionPkgMap);
+ candCap.getModule(), allCandidates, modulePkgMap);
// Get the candidate's package space to determine which packages
- // will be visible to the current revision.
- Packages candPkgs = revisionPkgMap.get(candCap.getRevision());
+ // will be visible to the current module.
+ Packages candPkgs = modulePkgMap.get(candCap.getModule());
// We have to merge all exported packages from the candidate,
- // since the current revision requires it.
+ // since the current module requires it.
for (Entry<String, Blame> entry : candPkgs.m_exportedPkgs.entrySet())
{
mergeCandidatePackage(
@@ -620,27 +622,24 @@
true,
currentReq,
entry.getValue().m_cap,
- revisionPkgMap);
+ modulePkgMap);
}
// If the candidate requires any other bundles with reexport visibility,
// then we also need to merge their packages too.
- List<BundleRequirement> reqs = (candCap.getRevision().getWiring() != null)
- ? candCap.getRevision().getWiring().getRequirements(null)
- : candCap.getRevision().getDeclaredRequirements(null);
- for (BundleRequirement req : reqs)
+ for (Requirement req : candCap.getModule().getRequirements())
{
- if (req.getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+ if (req.getNamespace().equals(Capability.MODULE_NAMESPACE))
{
- String value = req.getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
- if ((value != null) && value.equals(Constants.VISIBILITY_REEXPORT)
+ Directive dir = req.getDirective(Constants.VISIBILITY_DIRECTIVE);
+ if ((dir != null) && dir.getValue().equals(Constants.VISIBILITY_REEXPORT)
&& (allCandidates.getCandidates(req) != null))
{
mergeCandidatePackages(
current,
currentReq,
allCandidates.getCandidates(req).iterator().next(),
- revisionPkgMap,
+ modulePkgMap,
allCandidates);
}
}
@@ -649,17 +648,17 @@
}
private void mergeCandidatePackage(
- BundleRevision current, boolean requires,
- BundleRequirement currentReq, BundleCapability candCap,
- Map<BundleRevision, Packages> revisionPkgMap)
+ Module current, boolean requires,
+ Requirement currentReq, Capability candCap,
+ Map<Module, Packages> modulePkgMap)
{
- if (candCap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ if (candCap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
String pkgName = (String)
- candCap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
+ candCap.getAttribute(Capability.PACKAGE_ATTR).getValue();
// Since this capability represents a package, it will become
- // a hard constraint on the revisions's package space, so we need
+ // a hard constraint on the module's package space, so we need
// to make sure it doesn't conflict with any other hard constraints
// or any other uses constraints.
@@ -671,7 +670,7 @@
// any existing hard constraints.
//
- Packages currentPkgs = revisionPkgMap.get(current);
+ Packages currentPkgs = modulePkgMap.get(current);
if (requires)
{
@@ -694,44 +693,44 @@
currentImportedBlames.add(new Blame(candCap, blameReqs));
}
-//dumpRevisionPkgs(current, currentPkgs);
+//dumpModulePkgs(current, currentPkgs);
}
}
private void mergeUses(
- BundleRevision current, Packages currentPkgs,
- BundleCapability mergeCap, List<BundleRequirement> blameReqs,
- Map<BundleRevision, Packages> revisionPkgMap,
+ Module current, Packages currentPkgs,
+ Capability mergeCap, List<Requirement> blameReqs,
+ Map<Module, Packages> modulePkgMap,
Candidates allCandidates,
- Map<BundleCapability, List<BundleRevision>> cycleMap)
+ Map<Capability, List<Module>> cycleMap)
{
- if (!mergeCap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ if (!mergeCap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
return;
}
- // If the candidate revision is the same as the current revision,
+ // If the candidate module is the same as the current module,
// then we don't need to verify and merge the uses constraints
// since this will happen as we build up the package space.
- else if (current.equals(mergeCap.getRevision()))
+ else if (current == mergeCap.getModule())
{
return;
}
// Check for cycles.
- List<BundleRevision> list = cycleMap.get(mergeCap);
+ List<Module> list = cycleMap.get(mergeCap);
if ((list != null) && list.contains(current))
{
return;
}
- list = (list == null) ? new ArrayList<BundleRevision>() : list;
+ list = (list == null) ? new ArrayList<Module>() : list;
list.add(current);
cycleMap.put(mergeCap, list);
- for (BundleCapability candSourceCap : getPackageSources(mergeCap, revisionPkgMap))
+ for (Capability candSourceCap : getPackageSources(mergeCap, modulePkgMap))
{
- for (String usedPkgName : ((BundleCapabilityImpl) candSourceCap).getUses())
+ for (String usedPkgName : candSourceCap.getUses())
{
- Packages candSourcePkgs = revisionPkgMap.get(candSourceCap.getRevision());
+ Packages candSourcePkgs = modulePkgMap.get(candSourceCap.getModule());
Blame candExportedBlame = candSourcePkgs.m_exportedPkgs.get(usedPkgName);
List<Blame> candSourceBlames = null;
if (candExportedBlame != null)
@@ -759,17 +758,17 @@
{
if (blame.m_reqs != null)
{
- List<BundleRequirement> blameReqs2 = new ArrayList(blameReqs);
+ List<Requirement> blameReqs2 = new ArrayList(blameReqs);
blameReqs2.add(blame.m_reqs.get(blame.m_reqs.size() - 1));
usedCaps.add(new Blame(blame.m_cap, blameReqs2));
mergeUses(current, currentPkgs, blame.m_cap, blameReqs2,
- revisionPkgMap, allCandidates, cycleMap);
+ modulePkgMap, allCandidates, cycleMap);
}
else
{
usedCaps.add(new Blame(blame.m_cap, blameReqs));
mergeUses(current, currentPkgs, blame.m_cap, blameReqs,
- revisionPkgMap, allCandidates, cycleMap);
+ modulePkgMap, allCandidates, cycleMap);
}
}
}
@@ -777,26 +776,26 @@
}
private void checkPackageSpaceConsistency(
- boolean isDynamicImporting,
- BundleRevision revision,
+ boolean isDynamicImport,
+ Module module,
Candidates allCandidates,
- Map<BundleRevision, Packages> revisionPkgMap,
- Map<BundleRevision, Object> resultCache)
+ Map<Module, Packages> modulePkgMap,
+ Map<Module, Object> resultCache)
{
- if ((revision.getWiring() != null) && !isDynamicImporting)
+ if (module.isResolved() && !isDynamicImport)
{
return;
}
- else if(resultCache.containsKey(revision))
+ else if(resultCache.containsKey(module))
{
return;
}
- Packages pkgs = revisionPkgMap.get(revision);
+ Packages pkgs = modulePkgMap.get(module);
ResolveException rethrow = null;
Candidates permutation = null;
- Set<BundleRequirement> mutated = null;
+ Set<Requirement> mutated = null;
// Check for conflicting imports from fragments.
for (Entry<String, List<Blame>> entry : pkgs.m_importedPkgs.entrySet())
@@ -810,7 +809,7 @@
{
sourceBlame = blame;
}
- else if (!sourceBlame.m_cap.getRevision().equals(blame.m_cap.getRevision()))
+ else if (!sourceBlame.m_cap.getModule().equals(blame.m_cap.getModule()))
{
// Try to permutate the conflicting requirement.
permutate(allCandidates, blame.m_reqs.get(0), m_importPermutations);
@@ -818,22 +817,22 @@
permutate(allCandidates, sourceBlame.m_reqs.get(0), m_importPermutations);
// Report conflict.
ResolveException ex = new ResolveException(
- "Uses constraint violation. Unable to resolve bundle revision "
- + revision.getSymbolicName()
- + " [" + revision
+ "Uses constraint violation. Unable to resolve module "
+ + module.getSymbolicName()
+ + " [" + module
+ "] because it is exposed to package '"
+ entry.getKey()
- + "' from bundle revisions "
- + sourceBlame.m_cap.getRevision().getSymbolicName()
- + " [" + sourceBlame.m_cap.getRevision()
+ + "' from modules "
+ + sourceBlame.m_cap.getModule().getSymbolicName()
+ + " [" + sourceBlame.m_cap.getModule()
+ "] and "
- + blame.m_cap.getRevision().getSymbolicName()
- + " [" + blame.m_cap.getRevision()
+ + blame.m_cap.getModule().getSymbolicName()
+ + " [" + blame.m_cap.getModule()
+ "] via two dependency chains.\n\nChain 1:\n"
+ toStringBlame(sourceBlame)
+ "\n\nChain 2:\n"
+ toStringBlame(blame),
- revision,
+ module,
blame.m_reqs.get(0));
m_logger.log(
Logger.LOG_DEBUG,
@@ -856,7 +855,7 @@
}
for (Blame usedBlame : pkgs.m_usedPkgs.get(pkgName))
{
- if (!isCompatible(exportBlame.m_cap, usedBlame.m_cap, revisionPkgMap))
+ if (!isCompatible(exportBlame.m_cap, usedBlame.m_cap, modulePkgMap))
{
// Create a candidate permutation that eliminates all candidates
// that conflict with existing selected candidates.
@@ -866,14 +865,14 @@
rethrow = (rethrow != null)
? rethrow
: new ResolveException(
- "Uses constraint violation. Unable to resolve bundle revision "
- + revision.getSymbolicName()
- + " [" + revision
+ "Uses constraint violation. Unable to resolve module "
+ + module.getSymbolicName()
+ + " [" + module
+ "] because it exports package '"
+ pkgName
- + "' and is also exposed to it from bundle revision "
- + usedBlame.m_cap.getRevision().getSymbolicName()
- + " [" + usedBlame.m_cap.getRevision()
+ + "' and is also exposed to it from module "
+ + usedBlame.m_cap.getModule().getSymbolicName()
+ + " [" + usedBlame.m_cap.getModule()
+ "] via the following dependency chain:\n\n"
+ toStringBlame(usedBlame),
null,
@@ -881,11 +880,11 @@
mutated = (mutated != null)
? mutated
- : new HashSet<BundleRequirement>();
+ : new HashSet();
for (int reqIdx = usedBlame.m_reqs.size() - 1; reqIdx >= 0; reqIdx--)
{
- BundleRequirement req = usedBlame.m_reqs.get(reqIdx);
+ Requirement req = usedBlame.m_reqs.get(reqIdx);
// If we've already permutated this requirement in another
// uses constraint, don't permutate it again just continue
@@ -896,10 +895,9 @@
}
// See if we can permutate the candidates for blamed
- // requirement; there may be no candidates if the revision
+ // requirement; there may be no candidates if the module
// associated with the requirement is already resolved.
- SortedSet<BundleCapability> candidates =
- permutation.getCandidates(req);
+ SortedSet<Capability> candidates = permutation.getCandidates(req);
if ((candidates != null) && (candidates.size() > 1))
{
mutated.add(req);
@@ -940,7 +938,7 @@
}
for (Blame usedBlame : pkgs.m_usedPkgs.get(pkgName))
{
- if (!isCompatible(importBlame.m_cap, usedBlame.m_cap, revisionPkgMap))
+ if (!isCompatible(importBlame.m_cap, usedBlame.m_cap, modulePkgMap))
{
// Create a candidate permutation that eliminates any candidates
// that conflict with existing selected candidates.
@@ -950,17 +948,17 @@
rethrow = (rethrow != null)
? rethrow
: new ResolveException(
- "Uses constraint violation. Unable to resolve bundle revision "
- + revision.getSymbolicName()
- + " [" + revision
+ "Uses constraint violation. Unable to resolve module "
+ + module.getSymbolicName()
+ + " [" + module
+ "] because it is exposed to package '"
+ pkgName
- + "' from bundle revisions "
- + importBlame.m_cap.getRevision().getSymbolicName()
- + " [" + importBlame.m_cap.getRevision()
+ + "' from modules "
+ + importBlame.m_cap.getModule().getSymbolicName()
+ + " [" + importBlame.m_cap.getModule()
+ "] and "
- + usedBlame.m_cap.getRevision().getSymbolicName()
- + " [" + usedBlame.m_cap.getRevision()
+ + usedBlame.m_cap.getModule().getSymbolicName()
+ + " [" + usedBlame.m_cap.getModule()
+ "] via two dependency chains.\n\nChain 1:\n"
+ toStringBlame(importBlame)
+ "\n\nChain 2:\n"
@@ -974,7 +972,7 @@
for (int reqIdx = usedBlame.m_reqs.size() - 1; reqIdx >= 0; reqIdx--)
{
- BundleRequirement req = usedBlame.m_reqs.get(reqIdx);
+ Requirement req = usedBlame.m_reqs.get(reqIdx);
// If we've already permutated this requirement in another
// uses constraint, don't permutate it again just continue
@@ -985,10 +983,9 @@
}
// See if we can permutate the candidates for blamed
- // requirement; there may be no candidates if the revision
+ // requirement; there may be no candidates if the module
// associated with the requirement is already resolved.
- SortedSet<BundleCapability> candidates =
- permutation.getCandidates(req);
+ SortedSet<Capability> candidates = permutation.getCandidates(req);
if ((candidates != null) && (candidates.size() > 1))
{
mutated.add(req);
@@ -1019,7 +1016,7 @@
// Try to permutate the candidate for the original
// import requirement; only permutate it if we haven't
// done so already.
- BundleRequirement req = importBlame.m_reqs.get(0);
+ Requirement req = importBlame.m_reqs.get(0);
if (!mutated.contains(req))
{
// Since there may be lots of uses constraint violations
@@ -1039,10 +1036,10 @@
}
}
- resultCache.put(revision, Boolean.TRUE);
+ resultCache.put(module, Boolean.TRUE);
- // Now check the consistency of all revisions on which the
- // current revision depends. Keep track of the current number
+ // Now check the consistency of all modules on which the
+ // current module depends. Keep track of the current number
// of permutations so we know if the lower level check was
// able to create a permutation or not in the case of failure.
int permCount = m_usesPermutations.size() + m_importPermutations.size();
@@ -1050,23 +1047,23 @@
{
for (Blame importBlame : entry.getValue())
{
- if (!revision.equals(importBlame.m_cap.getRevision()))
+ if (!module.equals(importBlame.m_cap.getModule()))
{
try
{
checkPackageSpaceConsistency(
- false, importBlame.m_cap.getRevision(),
- allCandidates, revisionPkgMap, resultCache);
+ false, importBlame.m_cap.getModule(),
+ allCandidates, modulePkgMap, resultCache);
}
catch (ResolveException ex)
{
// If the lower level check didn't create any permutations,
// then we should create an import permutation for the
- // requirement with the dependency on the failing revision
+ // requirement with the dependency on the failing module
// to backtrack on our current candidate selection.
if (permCount == (m_usesPermutations.size() + m_importPermutations.size()))
{
- BundleRequirement req = importBlame.m_reqs.get(0);
+ Requirement req = importBlame.m_reqs.get(0);
permutate(allCandidates, req, m_importPermutations);
}
throw ex;
@@ -1077,9 +1074,9 @@
}
private static void permutate(
- Candidates allCandidates, BundleRequirement req, List<Candidates> permutations)
+ Candidates allCandidates, Requirement req, List<Candidates> permutations)
{
- SortedSet<BundleCapability> candidates = allCandidates.getCandidates(req);
+ SortedSet<Capability> candidates = allCandidates.getCandidates(req);
if (candidates.size() > 1)
{
Candidates perm = allCandidates.copy();
@@ -1092,9 +1089,9 @@
}
private static void permutateIfNeeded(
- Candidates allCandidates, BundleRequirement req, List<Candidates> permutations)
+ Candidates allCandidates, Requirement req, List<Candidates> permutations)
{
- SortedSet<BundleCapability> candidates = allCandidates.getCandidates(req);
+ SortedSet<Capability> candidates = allCandidates.getCandidates(req);
if (candidates.size() > 1)
{
// Check existing permutations to make sure we haven't
@@ -1106,7 +1103,7 @@
boolean permutated = false;
for (Candidates existingPerm : permutations)
{
- Set<BundleCapability> existingPermCands = existingPerm.getCandidates(req);
+ Set<Capability> existingPermCands = existingPerm.getCandidates(req);
if (!existingPermCands.iterator().next().equals(candidates.iterator().next()))
{
permutated = true;
@@ -1122,79 +1119,73 @@
}
private static void calculateExportedPackages(
- BundleRevision revision,
+ Module module,
Candidates allCandidates,
- Map<BundleRevision, Packages> revisionPkgMap)
+ Map<Module, Packages> modulePkgMap)
{
- Packages packages = revisionPkgMap.get(revision);
+ Packages packages = modulePkgMap.get(module);
if (packages != null)
{
return;
}
- packages = new Packages(revision);
+ packages = new Packages(module);
// Get all exported packages.
- List<BundleCapability> caps = (revision.getWiring() != null)
- ? revision.getWiring().getCapabilities(null)
- : revision.getDeclaredCapabilities(null);
- Map<String, BundleCapability> exports =
- new HashMap<String, BundleCapability>(caps.size());
- for (BundleCapability cap : caps)
+ Map<String, Capability> exports =
+ new HashMap<String, Capability>(module.getCapabilities().size());
+ for (Capability cap : module.getCapabilities())
{
- if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ if (cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
exports.put(
- (String) cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR),
+ (String) cap.getAttribute(Capability.PACKAGE_ATTR).getValue(),
cap);
}
}
// Remove substitutable exports that were imported.
- // For resolved revisions look at the wires, for resolving
- // revisions look in the candidate map to determine which
+ // For resolved modules look at the wires, for resolving
+ // modules look in the candidate map to determine which
// exports are substitutable.
- if (revision.getWiring() != null)
+ if (module.isResolved())
{
- for (BundleWire wire : revision.getWiring().getRequiredWires(null))
+ for (Wire wire : module.getWires())
{
- if (wire.getRequirement().getNamespace().equals(
- BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ if (wire.getRequirement().getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
String pkgName = (String) wire.getCapability()
- .getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
+ .getAttribute(Capability.PACKAGE_ATTR).getValue();
exports.remove(pkgName);
}
}
}
else
{
- for (BundleRequirement req : revision.getDeclaredRequirements(null))
+ for (Requirement req : module.getRequirements())
{
- if (req.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
- Set<BundleCapability> cands =
- allCandidates.getCandidates((BundleRequirementImpl) req);
+ Set<Capability> cands = allCandidates.getCandidates(req);
if ((cands != null) && !cands.isEmpty())
{
String pkgName = (String) cands.iterator().next()
- .getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
+ .getAttribute(Capability.PACKAGE_ATTR).getValue();
exports.remove(pkgName);
}
}
}
}
- // Add all non-substituted exports to the revisions's package space.
- for (Entry<String, BundleCapability> entry : exports.entrySet())
+ // Add all non-substituted exports to the module's package space.
+ for (Entry<String, Capability> entry : exports.entrySet())
{
packages.m_exportedPkgs.put(
entry.getKey(), new Blame(entry.getValue(), null));
}
- revisionPkgMap.put(revision, packages);
+ modulePkgMap.put(module, packages);
}
private boolean isCompatible(
- BundleCapability currentCap, BundleCapability candCap,
- Map<BundleRevision, Packages> revisionPkgMap)
+ Capability currentCap, Capability candCap, Map<Module, Packages> modulePkgMap)
{
if ((currentCap != null) && (candCap != null))
{
@@ -1203,34 +1194,32 @@
return true;
}
- List<BundleCapability> currentSources =
+ List<Capability> currentSources =
getPackageSources(
currentCap,
- revisionPkgMap);
- List<BundleCapability> candSources =
+ modulePkgMap);
+ List<Capability> candSources =
getPackageSources(
candCap,
- revisionPkgMap);
+ modulePkgMap);
- return currentSources.containsAll(candSources)
- || candSources.containsAll(currentSources);
+ return currentSources.containsAll(candSources) || candSources.containsAll(currentSources);
}
return true;
}
- private Map<BundleCapability, List<BundleCapability>> m_packageSourcesCache
- = new HashMap();
+ private Map<Capability, List<Capability>> m_packageSourcesCache = new HashMap();
- private List<BundleCapability> getPackageSources(
- BundleCapability cap, Map<BundleRevision, Packages> revisionPkgMap)
+ private List<Capability> getPackageSources(
+ Capability cap, Map<Module, Packages> modulePkgMap)
{
- if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ if (cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
- List<BundleCapability> sources = m_packageSourcesCache.get(cap);
+ List<Capability> sources = m_packageSourcesCache.get(cap);
if (sources == null)
{
sources = getPackageSourcesInternal(
- cap, revisionPkgMap, new ArrayList(), new HashSet());
+ cap, modulePkgMap, new ArrayList(), new HashSet());
m_packageSourcesCache.put(cap, sources);
}
return sources;
@@ -1239,11 +1228,11 @@
return Collections.EMPTY_LIST;
}
- private static List<BundleCapability> getPackageSourcesInternal(
- BundleCapability cap, Map<BundleRevision, Packages> revisionPkgMap,
- List<BundleCapability> sources, Set<BundleCapability> cycleMap)
+ private static List<Capability> getPackageSourcesInternal(
+ Capability cap, Map<Module, Packages> modulePkgMap, List<Capability> sources,
+ Set<Capability> cycleMap)
{
- if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ if (cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
if (cycleMap.contains(cap))
{
@@ -1252,31 +1241,28 @@
cycleMap.add(cap);
// Get the package name associated with the capability.
- String pkgName = cap.getAttributes()
- .get(BundleCapabilityImpl.PACKAGE_ATTR).toString();
+ String pkgName = cap.getAttribute(Capability.PACKAGE_ATTR).getValue().toString();
- // Since a revision can export the same package more than once, get
+ // Since a module can export the same package more than once, get
// all package capabilities for the specified package name.
- List<BundleCapability> caps = (cap.getRevision().getWiring() != null)
- ? cap.getRevision().getWiring().getCapabilities(null)
- : cap.getRevision().getDeclaredCapabilities(null);
+ List<Capability> caps = cap.getModule().getCapabilities();
for (int capIdx = 0; capIdx < caps.size(); capIdx++)
{
- if (caps.get(capIdx).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
- && caps.get(capIdx).getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
+ if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+ && caps.get(capIdx).getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
{
sources.add(caps.get(capIdx));
}
}
// Then get any addition sources for the package from required bundles.
- Packages pkgs = revisionPkgMap.get(cap.getRevision());
+ Packages pkgs = modulePkgMap.get(cap.getModule());
List<Blame> required = pkgs.m_requiredPkgs.get(pkgName);
if (required != null)
{
for (Blame blame : required)
{
- getPackageSourcesInternal(blame.m_cap, revisionPkgMap, sources, cycleMap);
+ getPackageSourcesInternal(blame.m_cap, modulePkgMap, sources, cycleMap);
}
}
}
@@ -1284,16 +1270,16 @@
return sources;
}
- private static BundleRevision getActualBundleRevision(BundleRevision br)
+ private static Module getActualModule(Module m)
{
- if (br instanceof HostBundleRevision)
+ if (m instanceof HostModule)
{
- return ((HostBundleRevision) br).getHost();
+ return ((HostModule) m).getHost();
}
- return br;
+ return m;
}
- private static BundleCapability getActualCapability(BundleCapability c)
+ private static Capability getActualCapability(Capability c)
{
if (c instanceof HostedCapability)
{
@@ -1302,7 +1288,7 @@
return c;
}
- private static BundleRequirement getActualRequirement(BundleRequirement r)
+ private static Requirement getActualRequirement(Requirement r)
{
if (r instanceof HostedRequirement)
{
@@ -1311,76 +1297,77 @@
return r;
}
- private static Map<BundleRevision, List<ResolverWire>> populateWireMap(
- BundleRevision revision, Map<BundleRevision, Packages> revisionPkgMap,
- Map<BundleRevision, List<ResolverWire>> wireMap,
+ private static Map<Module, List<Wire>> populateWireMap(
+ Module module, Map<Module, Packages> modulePkgMap,
+ Map<Module, List<Wire>> wireMap,
Candidates allCandidates)
{
- BundleRevision unwrappedRevision = getActualBundleRevision(revision);
- if ((unwrappedRevision.getWiring() == null)
- && !wireMap.containsKey(unwrappedRevision))
+ Module unwrappedModule = getActualModule(module);
+ if (!unwrappedModule.isResolved() && !wireMap.containsKey(unwrappedModule))
{
- wireMap.put(unwrappedRevision, (List<ResolverWire>) Collections.EMPTY_LIST);
+ wireMap.put(unwrappedModule, (List<Wire>) Collections.EMPTY_LIST);
- List<ResolverWire> packageWires = new ArrayList<ResolverWire>();
- List<ResolverWire> requireWires = new ArrayList<ResolverWire>();
+ List<Wire> packageWires = new ArrayList<Wire>();
+ List<Wire> moduleWires = new ArrayList<Wire>();
- for (BundleRequirement req : revision.getDeclaredRequirements(null))
+ for (Requirement req : module.getRequirements())
{
- SortedSet<BundleCapability> cands = allCandidates.getCandidates(req);
+ SortedSet<Capability> cands = allCandidates.getCandidates(req);
if ((cands != null) && (cands.size() > 0))
{
- BundleCapability cand = cands.iterator().next();
- // Ignore revisions that import themselves.
- if (!revision.equals(cand.getRevision()))
+ Capability cand = cands.iterator().next();
+ if (!cand.getModule().isResolved())
{
- if (cand.getRevision().getWiring() == null)
- {
- populateWireMap(cand.getRevision(),
- revisionPkgMap, wireMap, allCandidates);
- }
- Packages candPkgs = revisionPkgMap.get(cand.getRevision());
- ResolverWire wire = new ResolverWireImpl(
- unwrappedRevision,
- getActualRequirement(req),
- getActualBundleRevision(cand.getRevision()),
- getActualCapability(cand));
- if (req.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
- {
- packageWires.add(wire);
- }
- else if (req.getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
- {
- requireWires.add(wire);
- }
+ populateWireMap(cand.getModule(),
+ modulePkgMap, wireMap, allCandidates);
+ }
+ // Ignore modules that import themselves.
+ if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+ && !module.equals(cand.getModule()))
+ {
+ packageWires.add(
+ new WireImpl(
+ unwrappedModule,
+ getActualRequirement(req),
+ getActualModule(cand.getModule()),
+ getActualCapability(cand)));
+ }
+ else if (req.getNamespace().equals(Capability.MODULE_NAMESPACE))
+ {
+ Packages candPkgs = modulePkgMap.get(cand.getModule());
+ moduleWires.add(
+ new WireModuleImpl(
+ unwrappedModule,
+ getActualRequirement(req),
+ getActualModule(cand.getModule()),
+ getActualCapability(cand),
+ candPkgs.getExportedAndReexportedPackages()));
}
}
}
- // Combine package wires with require wires last.
- packageWires.addAll(requireWires);
- wireMap.put(unwrappedRevision, packageWires);
+ // Combine wires with module wires last.
+ packageWires.addAll(moduleWires);
+ wireMap.put(unwrappedModule, packageWires);
// Add host wire for any fragments.
- if (revision instanceof HostBundleRevision)
+ if (module instanceof HostModule)
{
- List<BundleRevision> fragments = ((HostBundleRevision) revision).getFragments();
- for (BundleRevision fragment : fragments)
+ List<Module> fragments = ((HostModule) module).getFragments();
+ for (Module fragment : fragments)
{
- List<ResolverWire> hostWires = wireMap.get(fragment);
+ List<Wire> hostWires = wireMap.get(fragment);
if (hostWires == null)
{
- hostWires = new ArrayList<ResolverWire>();
+ hostWires = new ArrayList<Wire>();
wireMap.put(fragment, hostWires);
}
hostWires.add(
- new ResolverWireImpl(
- getActualBundleRevision(fragment),
- fragment.getDeclaredRequirements(
- BundleCapabilityImpl.HOST_NAMESPACE).get(0),
- unwrappedRevision,
- unwrappedRevision.getDeclaredCapabilities(
- BundleCapabilityImpl.HOST_NAMESPACE).get(0)));
+ new WireImpl(
+ getActualModule(fragment),
+ getHostRequirement(fragment),
+ unwrappedModule,
+ getHostCapability(unwrappedModule)));
}
}
}
@@ -1388,68 +1375,66 @@
return wireMap;
}
- private static Map<BundleRevision, List<ResolverWire>> populateDynamicWireMap(
- BundleRevision revision, String pkgName, Map<BundleRevision, Packages> revisionPkgMap,
- Map<BundleRevision, List<ResolverWire>> wireMap, Candidates allCandidates)
+ private static Map<Module, List<Wire>> populateDynamicWireMap(
+ Module module, String pkgName, Map<Module, Packages> modulePkgMap,
+ Map<Module, List<Wire>> wireMap, Candidates allCandidates)
{
- wireMap.put(revision, (List<ResolverWire>) Collections.EMPTY_LIST);
+ wireMap.put(module, (List<Wire>) Collections.EMPTY_LIST);
- List<ResolverWire> packageWires = new ArrayList<ResolverWire>();
+ List<Wire> packageWires = new ArrayList<Wire>();
- Packages pkgs = revisionPkgMap.get(revision);
+ Packages pkgs = modulePkgMap.get(module);
for (Entry<String, List<Blame>> entry : pkgs.m_importedPkgs.entrySet())
{
for (Blame blame : entry.getValue())
{
- // Ignore revisions that import themselves.
- if (!revision.equals(blame.m_cap.getRevision())
- && blame.m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)
- .equals(pkgName))
+ // Ignore modules that import themselves.
+ if (!module.equals(blame.m_cap.getModule())
+ && blame.m_cap.getAttribute(
+ Capability.PACKAGE_ATTR).getValue().equals(pkgName))
{
- if (blame.m_cap.getRevision().getWiring() == null)
+ if (!blame.m_cap.getModule().isResolved())
{
- populateWireMap(blame.m_cap.getRevision(), revisionPkgMap, wireMap,
+ populateWireMap(blame.m_cap.getModule(), modulePkgMap, wireMap,
allCandidates);
}
- Packages candPkgs = revisionPkgMap.get(blame.m_cap.getRevision());
- Map<String, Object> attrs = new HashMap(1);
- attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
+ List<Attribute> attrs = new ArrayList();
+ attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
packageWires.add(
- new ResolverWireImpl(
- revision,
+ new WireImpl(
+ module,
// We need an unique requirement here or else subsequent
// dynamic imports for the same dynamic requirement will
// conflict with previous ones.
- new BundleRequirementImpl(
- revision,
- BundleCapabilityImpl.PACKAGE_NAMESPACE,
- Collections.EMPTY_MAP,
+ new RequirementImpl(
+ module,
+ Capability.PACKAGE_NAMESPACE,
+ new ArrayList(0),
attrs),
- getActualBundleRevision(blame.m_cap.getRevision()),
+ getActualModule(blame.m_cap.getModule()),
getActualCapability(blame.m_cap)));
}
}
}
- wireMap.put(revision, packageWires);
+ wireMap.put(module, packageWires);
return wireMap;
}
- private static void dumpRevisionPkgMap(Map<BundleRevision, Packages> revisionPkgMap)
+ private static void dumpModulePkgMap(Map<Module, Packages> modulePkgMap)
{
- System.out.println("+++BUNDLE REVISION PKG MAP+++");
- for (Entry<BundleRevision, Packages> entry : revisionPkgMap.entrySet())
+ System.out.println("+++MODULE PKG MAP+++");
+ for (Entry<Module, Packages> entry : modulePkgMap.entrySet())
{
- dumpRevisionPkgs(entry.getKey(), entry.getValue());
+ dumpModulePkgs(entry.getKey(), entry.getValue());
}
}
- private static void dumpRevisionPkgs(BundleRevision revision, Packages packages)
+ private static void dumpModulePkgs(Module module, Packages packages)
{
- System.out.println(revision
- + " (" + ((revision.getWiring() != null) ? "RESOLVED)" : "UNRESOLVED)"));
+ System.out.println(module + " (" + (module.isResolved() ? "RESOLVED)" : "UNRESOLVED)"));
System.out.println(" EXPORTED");
for (Entry<String, Blame> entry : packages.m_exportedPkgs.entrySet())
{
@@ -1479,13 +1464,13 @@
{
for (int i = 0; i < blame.m_reqs.size(); i++)
{
- BundleRequirement req = blame.m_reqs.get(i);
+ Requirement req = blame.m_reqs.get(i);
sb.append(" ");
- sb.append(req.getRevision().getSymbolicName());
+ sb.append(req.getModule().getSymbolicName());
sb.append(" [");
- sb.append(req.getRevision().toString());
+ sb.append(req.getModule().toString());
sb.append("]\n");
- if (req.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
sb.append(" import: ");
}
@@ -1493,9 +1478,9 @@
{
sb.append(" require: ");
}
- sb.append(((BundleRequirementImpl) req).getFilter().toString());
+ sb.append(req.getFilter().toString());
sb.append("\n |");
- if (req.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
sb.append("\n export: ");
}
@@ -1505,29 +1490,27 @@
}
if ((i + 1) < blame.m_reqs.size())
{
- BundleCapability cap = Util.getSatisfyingCapability(
- blame.m_reqs.get(i + 1).getRevision(),
- (BundleRequirementImpl) blame.m_reqs.get(i));
- if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ Capability cap = Util.getSatisfyingCapability(
+ blame.m_reqs.get(i + 1).getModule(),
+ blame.m_reqs.get(i));
+ if (cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
- sb.append(BundleCapabilityImpl.PACKAGE_ATTR);
- sb.append("=");
- sb.append(cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).toString());
- BundleCapability usedCap;
+ sb.append(cap.getAttribute(Capability.PACKAGE_ATTR).toString());
+ Capability usedCap;
if ((i + 2) < blame.m_reqs.size())
{
usedCap = Util.getSatisfyingCapability(
- blame.m_reqs.get(i + 2).getRevision(),
- (BundleRequirementImpl) blame.m_reqs.get(i + 1));
+ blame.m_reqs.get(i + 2).getModule(),
+ blame.m_reqs.get(i + 1));
}
else
{
usedCap = Util.getSatisfyingCapability(
- blame.m_cap.getRevision(),
- (BundleRequirementImpl) blame.m_reqs.get(i + 1));
+ blame.m_cap.getModule(),
+ blame.m_reqs.get(i + 1));
}
sb.append("; uses:=");
- sb.append(usedCap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
+ sb.append(usedCap.getAttribute(Capability.PACKAGE_ATTR).getValue());
}
else
{
@@ -1537,73 +1520,102 @@
}
else
{
- BundleCapability export = Util.getSatisfyingCapability(
- blame.m_cap.getRevision(),
- (BundleRequirementImpl) blame.m_reqs.get(i));
- sb.append(BundleCapabilityImpl.PACKAGE_ATTR);
- sb.append("=");
- sb.append(export.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).toString());
- if (!export.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)
- .equals(blame.m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)))
+ Capability export = Util.getSatisfyingCapability(
+ blame.m_cap.getModule(),
+ blame.m_reqs.get(i));
+ sb.append(export.getAttribute(Capability.PACKAGE_ATTR).toString());
+ if (!export.getAttribute(Capability.PACKAGE_ATTR).getValue()
+ .equals(blame.m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue()))
{
sb.append("; uses:=");
- sb.append(blame.m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
+ sb.append(blame.m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue());
sb.append("\n export: ");
- sb.append(BundleCapabilityImpl.PACKAGE_ATTR);
- sb.append("=");
- sb.append(blame.m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).toString());
+ sb.append(blame.m_cap.getAttribute(Capability.PACKAGE_ATTR).toString());
}
sb.append("\n ");
- sb.append(blame.m_cap.getRevision().getSymbolicName());
+ sb.append(blame.m_cap.getModule().getSymbolicName());
sb.append(" [");
- sb.append(blame.m_cap.getRevision().toString());
+ sb.append(blame.m_cap.getModule().toString());
sb.append("]");
}
}
}
else
{
- sb.append(blame.m_cap.getRevision().toString());
+ sb.append(blame.m_cap.getModule().toString());
}
return sb.toString();
}
private static class Packages
{
- private final BundleRevision m_revision;
+ private final Module m_module;
public final Map<String, Blame> m_exportedPkgs = new HashMap();
public final Map<String, List<Blame>> m_importedPkgs = new HashMap();
public final Map<String, List<Blame>> m_requiredPkgs = new HashMap();
public final Map<String, List<Blame>> m_usedPkgs = new HashMap();
- public Packages(BundleRevision revision)
+ public Packages(Module module)
{
- m_revision = revision;
+ m_module = module;
+ }
+
+ public List<String> getExportedAndReexportedPackages()
+ {
+ List<String> pkgs = new ArrayList();
+ // Grab the module's actual exported packages.
+ // Note that we ignore the calculated exported packages here,
+ // because bundles that import their own exports still continue
+ // to provide access to their exports when they are required; i.e.,
+ // the implicitly reexport the packages if wired to another provider.
+ for (Capability cap : m_module.getCapabilities())
+ {
+ if (cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+ {
+ pkgs.add((String)
+ cap.getAttribute(Capability.PACKAGE_ATTR).getValue());
+ }
+ }
+ // Grab all required and reexported required packages.
+ for (Entry<String, List<Blame>> entry : m_requiredPkgs.entrySet())
+ {
+ for (Blame blame : entry.getValue())
+ {
+ Directive dir = blame.m_reqs.get(
+ blame.m_reqs.size() - 1).getDirective(Constants.VISIBILITY_DIRECTIVE);
+ if ((dir != null)
+ && dir.getValue().equals(Constants.VISIBILITY_REEXPORT))
+ {
+ pkgs.add((String)
+ blame.m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue());
+ break;
+ }
+ }
+ }
+ return pkgs;
}
}
private static class Blame
{
- public final BundleCapability m_cap;
- public final List<BundleRequirement> m_reqs;
+ public final Capability m_cap;
+ public final List<Requirement> m_reqs;
- public Blame(BundleCapability cap, List<BundleRequirement> reqs)
+ public Blame(Capability cap, List<Requirement> reqs)
{
m_cap = cap;
m_reqs = reqs;
}
- @Override
public String toString()
{
- return m_cap.getRevision()
- + "." + m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)
- + (((m_reqs == null) || m_reqs.isEmpty())
+ return m_cap.getModule()
+ + "." + m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue()
+ + (((m_reqs == null) || (m_reqs.size() == 0))
? " NO BLAME"
: " BLAMED ON " + m_reqs);
}
- @Override
public boolean equals(Object o)
{
return (o instanceof Blame) && m_reqs.equals(((Blame) o).m_reqs)
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWire.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWire.java
deleted file mode 100644
index 69162b9..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWire.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.resolver;
-
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-
-public interface ResolverWire
-{
- /**
- * Returns the importing bundle revision.
- * @return The importing bundle revision.
- **/
- public BundleRevision getRequirer();
- /**
- * Returns the associated requirement from the importing bundle revision
- * that resulted in the creation of this wire.
- * @return
- **/
- public BundleRequirement getRequirement();
- /**
- * Returns the exporting bundle revision.
- * @return The exporting bundle revision.
- **/
- public BundleRevision getProvider();
- /**
- * Returns the associated capability from the exporting bundle revision
- * that satisfies the requirement of the importing bundle revision.
- * @return
- **/
- public BundleCapability getCapability();
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWireImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWireImpl.java
deleted file mode 100644
index d89012e..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWireImpl.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.resolver;
-
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-
-class ResolverWireImpl implements ResolverWire
-{
- private final BundleRevision m_requirer;
- private final BundleRequirement m_req;
- private final BundleRevision m_provider;
- private final BundleCapability m_cap;
-
- public ResolverWireImpl(
- BundleRevision requirer, BundleRequirement req,
- BundleRevision provider, BundleCapability cap)
- {
- m_requirer = requirer;
- m_req = req;
- m_provider = provider;
- m_cap = cap;
- }
-
- public BundleRevision getRequirer()
- {
- return m_requirer;
- }
-
- public BundleRequirement getRequirement()
- {
- return m_req;
- }
-
- public BundleRevision getProvider()
- {
- return m_provider;
- }
-
- public BundleCapability getCapability()
- {
- return m_cap;
- }
-
- public String toString()
- {
- return "[" + m_requirer + "] "
- + m_req
- + " -> "
- + "[" + m_provider + "]";
- }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Wire.java b/framework/src/main/java/org/apache/felix/framework/resolver/Wire.java
new file mode 100644
index 0000000..c3b609c
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Wire.java
@@ -0,0 +1,100 @@
+/*
+ * 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.resolver;
+
+import java.net.URL;
+import java.util.Enumeration;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Requirement;
+
+public interface Wire
+{
+ /**
+ * Returns the importing module.
+ * @return The importing module.
+ **/
+ public Module getImporter();
+ /**
+ * Returns the associated requirement from the importing module that
+ * resulted in the creation of this wire.
+ * @return
+ **/
+ public Requirement getRequirement();
+ /**
+ * Returns the exporting module.
+ * @return The exporting module.
+ **/
+ public Module getExporter();
+ /**
+ * Returns the associated capability from the exporting module that
+ * satisfies the requirement of the importing module.
+ * @return
+ **/
+ public Capability getCapability();
+ /**
+ * Returns whether or not the wire has a given package name. For some
+ * wires, such as ones for Require-Bundle, there may be many packages.
+ * This method is necessary since the set of packages attained by wires
+ * restrict which packages can be dynamically imported (i.e., you cannot
+ * dynamically import a package that is already attainable from an
+ * existing wire).
+ * @return <tt>true</tt> if the package name is attainable from this wire,
+ * <tt>false</tt> otherwise.
+ **/
+ public boolean hasPackage(String pkgName);
+ /**
+ * Requests a class from the exporting module. If the class is found, then
+ * it is returned. If the class is not found, then this method may or may
+ * not throw an exception depending on the wire type (e.g., for an
+ * imported package or a required bundle). Throwing an exception indicates
+ * that the search should be aborted, while returning a <tt>null</tt>
+ * indicates that the search should continue.
+ * @return The class if found or <tt>null</tt> if not found and the search
+ * should continue.
+ * @throws java.lang.ClassNotFoundException If the class was not found and
+ * the search should be aborted.
+ **/
+ public Class getClass(String name) throws ClassNotFoundException;
+ /**
+ * Requests a resource from the exporting module. If the resource is found,
+ * then an URL is returned. If the resource is not found, then this method may
+ * or may not throw an exception depending on the wire type (e.g., for an
+ * imported package or a required bundle). Throwing an exception indicates
+ * that the search should be aborted, while returning a <tt>null</tt>
+ * indicates that the search should continue.
+ * @return An URL to the resource if found or <tt>null</tt> if not found
+ * and the search should continue.
+ * @throws ResourceNotFoundException If the resource was not found and
+ * the search should be aborted.
+ **/
+ public URL getResource(String name) throws ResourceNotFoundException;
+ /**
+ * Requests resources from the exporting module. If the resources are found,
+ * then an enumeration of URLs is returned. If the resources are not found,
+ * then this method may or may not throw an exception depending on the wire
+ * type (e.g., for an imported package or a required bundle). Throwing an
+ * exception indicates that the search should be aborted, while returning a
+ * <tt>null</tt> indicates that the search should continue.
+ * @return An enumeration of URLs for the resource if found or <tt>null</tt>
+ * if not found and the search should continue.
+ * @throws ResourceNotFoundException If the resource was not found and
+ * the search should be aborted.
+ **/
+ public Enumeration getResources(String name) throws ResourceNotFoundException;
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/WireImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/WireImpl.java
new file mode 100755
index 0000000..8e2358d
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WireImpl.java
@@ -0,0 +1,177 @@
+/*
+ * 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.resolver;
+
+import java.net.URL;
+import java.util.Enumeration;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.util.manifestparser.CapabilityImpl;
+
+class WireImpl implements Wire
+{
+ private final Module m_importer;
+ private final Requirement m_req;
+ private final Module m_exporter;
+ private final Capability m_cap;
+
+ public WireImpl(Module importer, Requirement ip, Module exporter, Capability ep)
+ {
+ m_importer = importer;
+ m_req = ip;
+ m_exporter = exporter;
+ m_cap = ep;
+ }
+
+ public Module getImporter()
+ {
+ return m_importer;
+ }
+
+ public Requirement getRequirement()
+ {
+ return m_req;
+ }
+
+ public Module getExporter()
+ {
+ return m_exporter;
+ }
+
+ public Capability getCapability()
+ {
+ return m_cap;
+ }
+
+ public String toString()
+ {
+ return "[" + m_importer + "] "
+ + m_req.getNamespace() + "; "
+ + m_req.getFilter() + " -> "
+ + "[" + m_exporter + "]";
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.framework.searchpolicy.IWire#getClass(java.lang.String)
+ */
+ public boolean hasPackage(String pkgName)
+ {
+ return (m_cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
+ m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName));
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.framework.searchpolicy.IWire#getClass(java.lang.String)
+ */
+ public Class getClass(String name) throws ClassNotFoundException
+ {
+ Class clazz = null;
+
+ // Get the package of the target class.
+ String pkgName = Util.getClassPackage(name);
+
+ // Only check when the package of the target class is
+ // the same as the package for the wire.
+ if (m_cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
+ m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+ {
+ // Check the include/exclude filters from the target package
+ // to make sure that the class is actually visible. We delegate
+ // to the exporting module, rather than its content, so it can
+ // it can follow any internal wires it may have (e.g., if the
+ // package has multiple sources).
+ if (((CapabilityImpl) m_cap).isIncluded(name))
+ {
+ clazz = m_exporter.getClassByDelegation(name);
+ }
+
+ // If no class was found, then we must throw an exception
+ // since the exporter for this package did not contain the
+ // requested class.
+ if (clazz == null)
+ {
+ throw new ClassNotFoundException(name);
+ }
+ }
+
+ return clazz;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.framework.searchpolicy.IWire#getResource(java.lang.String)
+ */
+ public URL getResource(String name) throws ResourceNotFoundException
+ {
+ URL url = null;
+
+ // Get the package of the target class.
+ String pkgName = Util.getResourcePackage(name);
+
+ // Only check when the package of the target resource is
+ // the same as the package for the wire.
+ if (m_cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
+ m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+ {
+ // Delegate to the exporting module, rather than its
+ // content, so that it can follow any internal wires it may have
+ // (e.g., if the package has multiple sources).
+ url = m_exporter.getResourceByDelegation(name);
+
+ // If no resource was found, then we must throw an exception
+ // since the exporter for this package did not contain the
+ // requested class.
+ if (url == null)
+ {
+ throw new ResourceNotFoundException(name);
+ }
+ }
+
+ return url;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.framework.searchpolicy.IWire#getResources(java.lang.String)
+ */
+ public Enumeration getResources(String name) throws ResourceNotFoundException
+ {
+ Enumeration urls = null;
+
+ // Get the package of the target class.
+ String pkgName = Util.getResourcePackage(name);
+
+ // Only check when the package of the target resource is
+ // the same as the package for the wire.
+ if (m_cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
+ m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+ {
+ urls = m_exporter.getResourcesByDelegation(name);
+
+ // If no resource was found, then we must throw an exception
+ // since the exporter for this package did not contain the
+ // requested class.
+ if ((urls == null) || !urls.hasMoreElements())
+ {
+ throw new ResourceNotFoundException(name);
+ }
+ }
+
+ return urls;
+ }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/WireModuleImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/WireModuleImpl.java
new file mode 100644
index 0000000..a1bfc06
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WireModuleImpl.java
@@ -0,0 +1,164 @@
+/*
+ * 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.resolver;
+
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.List;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.util.Util;
+
+class WireModuleImpl implements Wire
+{
+ private final Module m_importer;
+ private final Requirement m_req;
+ private final Module m_exporter;
+ private final Capability m_cap;
+ private final List<String> m_packages;
+
+ public WireModuleImpl(Module importer, Requirement requirement,
+ Module exporter, Capability capability, List<String> packages)
+ {
+ m_importer = importer;
+ m_req = requirement;
+ m_exporter = exporter;
+ m_cap = capability;
+ m_packages = packages;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.framework.searchpolicy.IWire#getImporter()
+ */
+ public Module getImporter()
+ {
+ return m_importer;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.framework.searchpolicy.IWire#getRequirement()
+ */
+ public Requirement getRequirement()
+ {
+ return m_req;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.framework.searchpolicy.IWire#getExporter()
+ */
+ public Module getExporter()
+ {
+ return m_exporter;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.framework.searchpolicy.IWire#getCapability()
+ */
+ public Capability getCapability()
+ {
+ return m_cap;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.framework.searchpolicy.IWire#hasPackage(java.lang.String)
+ */
+ public boolean hasPackage(String pkgName)
+ {
+ return m_packages.contains(pkgName);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.framework.searchpolicy.IWire#getClass(java.lang.String)
+ */
+ public Class getClass(String name) throws ClassNotFoundException
+ {
+ // Get the package of the target class.
+ String pkgName = Util.getClassPackage(name);
+ if (m_packages.contains(pkgName))
+ {
+ try
+ {
+ Class clazz = m_exporter.getClassByDelegation(name);
+ if (clazz != null)
+ {
+ return clazz;
+ }
+ }
+ catch (ClassNotFoundException ex)
+ {
+ // Do not throw the exception here, since we want
+ // to continue search other package sources and
+ // ultimately the module's own content.
+ }
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.framework.searchpolicy.IWire#getResource(java.lang.String)
+ */
+ public URL getResource(String name) throws ResourceNotFoundException
+ {
+ // Get the package of the target class.
+ String pkgName = Util.getResourcePackage(name);
+ if (m_packages.contains(pkgName))
+ {
+ URL url = m_exporter.getResourceByDelegation(name);
+ if (url != null)
+ {
+ return url;
+ }
+
+ // Don't throw ResourceNotFoundException because module
+ // dependencies support split packages.
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.framework.searchpolicy.IWire#getResources(java.lang.String)
+ */
+ public Enumeration getResources(String name) throws ResourceNotFoundException
+ {
+ // Get the package of the target class.
+ String pkgName = Util.getResourcePackage(name);
+
+ // See if we have a resolved package for the resource's package.
+ if (m_packages.contains(pkgName))
+ {
+ Enumeration urls = m_exporter.getResourcesByDelegation(name);
+ if ((urls != null) && urls.hasMoreElements())
+ {
+ return urls;
+ }
+
+ // Don't throw ResourceNotFoundException because module
+ // dependencies support split packages.
+ }
+
+ return null;
+ }
+
+ public String toString()
+ {
+ return m_req + " -> " + "[" + m_exporter + "]";
+ }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/Util.java b/framework/src/main/java/org/apache/felix/framework/util/Util.java
index c52e1a5..66437af 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/Util.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/Util.java
@@ -22,22 +22,21 @@
import java.net.URL;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.capabilityset.Capability;
import org.apache.felix.framework.capabilityset.CapabilitySet;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
+import org.apache.felix.framework.resolver.Module;
+import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.resolver.Wire;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
public class Util
{
@@ -87,11 +86,11 @@
}
/**
- * Converts a revision identifier to a bundle identifier. Revision IDs
+ * Converts a module identifier to a bundle identifier. Module IDs
* are typically <tt><bundle-id>.<revision></tt>; this
* method returns only the portion corresponding to the bundle ID.
**/
- public static long getBundleIdFromRevisionId(String id)
+ public static long getBundleIdFromModuleId(String id)
{
try
{
@@ -281,21 +280,15 @@
return allow;
}
- public static BundleCapability getSatisfyingCapability(
- BundleRevision br, BundleRequirementImpl req)
+ public static Capability getSatisfyingCapability(Module m, Requirement req)
{
- List<BundleCapability> caps = (br.getWiring() != null)
- ? br.getWiring().getCapabilities(null)
- : br.getDeclaredCapabilities(null);
- if (caps != null)
+ List<Capability> caps = m.getCapabilities();
+ for (int i = 0; (caps != null) && (i < caps.size()); i++)
{
- for (BundleCapability cap : caps)
+ if (caps.get(i).getNamespace().equals(req.getNamespace())
+ && CapabilitySet.matches(caps.get(i), req.getFilter()))
{
- if (cap.getNamespace().equals(req.getNamespace())
- && CapabilitySet.matches((BundleCapabilityImpl) cap, req.getFilter()))
- {
- return cap;
- }
+ return caps.get(i);
}
}
return null;
@@ -304,65 +297,33 @@
/**
* Returns all the capabilities from a module that has a specified namespace.
*
- * @param br module providing capabilities
+ * @param module module providing capabilities
* @param namespace capability namespace
* @return array of matching capabilities or empty if none found
*/
- public static List<BundleCapability> getCapabilityByNamespace(
- BundleRevision br, String namespace)
+ public static List<Capability> getCapabilityByNamespace(Module module, String namespace)
{
- final List<BundleCapability> matching = new ArrayList();
- final List<BundleCapability> caps = (br.getWiring() != null)
- ? br.getWiring().getCapabilities(null)
- : br.getDeclaredCapabilities(null);
- if (caps != null)
+ final List<Capability> matching = new ArrayList();
+ final List<Capability> caps = module.getCapabilities();
+ for (int capIdx = 0; (caps != null) && (capIdx < caps.size()); capIdx++)
{
- for (BundleCapability cap : caps)
+ if (caps.get(capIdx).getNamespace().equals(namespace))
{
- if (cap.getNamespace().equals(namespace))
- {
- matching.add(cap);
- }
+ matching.add(caps.get(capIdx));
}
}
return matching;
}
- public static List<BundleRequirement> getDynamicRequirements(
- List<BundleRequirement> reqs)
+ public static Wire getWire(Module m, String name)
{
- List<BundleRequirement> result = new ArrayList<BundleRequirement>();
- if (reqs != null)
+ List<Wire> wires = m.getWires();
+ for (int i = 0; (wires != null) && (i < wires.size()); i++)
{
- for (BundleRequirement req : reqs)
+ if (wires.get(i).getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
+ wires.get(i).getCapability().getAttribute(Capability.PACKAGE_ATTR).getValue().equals(name))
{
- String resolution = req.getDirectives().get(Constants.RESOLUTION_DIRECTIVE);
- if ((resolution != null) && resolution.equals("dynamic"))
- {
- result.add(req);
- }
- }
- }
- return result;
- }
-
- public static BundleWire getWire(BundleRevision br, String name)
- {
- if (br.getWiring() != null)
- {
- List<BundleWire> wires = br.getWiring().getRequiredWires(null);
- if (wires != null)
- {
- for (BundleWire w : wires)
- {
- if (w.getCapability().getNamespace()
- .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
- w.getCapability().getAttributes()
- .get(BundleCapabilityImpl.PACKAGE_ATTR).equals(name))
- {
- return w;
- }
- }
+ return wires.get(i);
}
}
return null;
@@ -614,8 +575,9 @@
* @return <code>true</code> if the module declares a fragment host, <code>false</code>
* otherwise.
*/
- public static boolean isFragment(BundleRevision revision)
+ public static boolean isFragment(Module module)
{
- return ((revision.getTypes() & BundleRevision.TYPE_FRAGMENT) > 0);
+ Map headerMap = module.getHeaders();
+ return headerMap.containsKey(Constants.FRAGMENT_HOST);
}
}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/CapabilityImpl.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/CapabilityImpl.java
new file mode 100644
index 0000000..7944c95
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/CapabilityImpl.java
@@ -0,0 +1,230 @@
+/*
+ * 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.util.manifestparser;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.StringTokenizer;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.capabilityset.SimpleFilter;
+import org.apache.felix.framework.resolver.Module;
+import org.apache.felix.framework.util.Util;
+import org.osgi.framework.Constants;
+
+public class CapabilityImpl implements Capability
+{
+ private final Module m_module;
+ private final String m_namespace;
+ private final List<Directive> m_dirs;
+ private final List<Directive> m_dirsConst;
+ private final List<Attribute> m_attrs;
+ private final List<Attribute> m_attrsConst;
+ private final List<String> m_uses;
+ private final List<List<String>> m_includeFilter;
+ private final List<List<String>> m_excludeFilter;
+
+ public CapabilityImpl(Module module, String namespace,
+ List<Directive> dirs, List<Attribute> attrs)
+ {
+ m_namespace = namespace;
+ m_module = module;
+ m_dirs = dirs;
+ m_dirsConst = Collections.unmodifiableList(m_dirs);
+ m_attrs = attrs;
+ m_attrsConst = Collections.unmodifiableList(m_attrs);
+
+ // Find all export directives: uses, mandatory, include, and exclude.
+ String mandatory = "";
+ List<String> uses = new ArrayList(0);
+ List<List<String>> includeFilter = null, excludeFilter = null;
+ for (int dirIdx = 0; dirIdx < m_dirs.size(); dirIdx++)
+ {
+ if (m_dirs.get(dirIdx).getName().equals(Constants.USES_DIRECTIVE))
+ {
+ // Parse these uses directive.
+ StringTokenizer tok = new StringTokenizer(
+ (String) m_dirs.get(dirIdx).getValue(), ",");
+ uses = new ArrayList<String>(tok.countTokens());
+ while (tok.hasMoreTokens())
+ {
+ uses.add(tok.nextToken().trim());
+ }
+ }
+ else if (m_dirs.get(dirIdx).getName().equals(Constants.MANDATORY_DIRECTIVE))
+ {
+ mandatory = (String) m_dirs.get(dirIdx).getValue();
+ }
+ else if (m_dirs.get(dirIdx).getName().equals(Constants.INCLUDE_DIRECTIVE)
+ || m_dirs.get(dirIdx).getName().equals(Constants.EXCLUDE_DIRECTIVE))
+ {
+ List<List<String>> filterList = null;
+
+ List<String> filters = ManifestParser.parseDelimitedString(
+ (String) m_dirs.get(dirIdx).getValue(), ",");
+ filterList = new ArrayList<List<String>>(filters.size());
+
+ for (int filterIdx = 0; filterIdx < filters.size(); filterIdx++)
+ {
+ List<String> substrings = SimpleFilter.parseSubstring(filters.get(filterIdx));
+ filterList.add(substrings);
+ }
+
+ if (m_dirs.get(dirIdx).getName().equals(Constants.INCLUDE_DIRECTIVE))
+ {
+ includeFilter = filterList;
+ }
+ else
+ {
+ excludeFilter = filterList;
+ }
+ }
+ }
+
+ // Set final values.
+ m_uses = uses;
+ m_includeFilter = includeFilter;
+ m_excludeFilter = excludeFilter;
+
+ // Parse mandatory directive and mark specified
+ // attributes as mandatory.
+ StringTokenizer tok = new StringTokenizer(mandatory, ", ");
+ while (tok.hasMoreTokens())
+ {
+ // Get attribute name.
+ String attrName = tok.nextToken().trim();
+ // Find attribute and mark it as mandatory.
+ boolean found = false;
+ for (int i = 0; (!found) && (i < m_attrs.size()); i++)
+ {
+ if (m_attrs.get(i).getName().equals(attrName))
+ {
+ m_attrs.set(i, new Attribute(
+ m_attrs.get(i).getName(),
+ m_attrs.get(i).getValue(), true));
+ found = true;
+ }
+ }
+ // If a specified mandatory attribute was not found,
+ // then error.
+ if (!found)
+ {
+ throw new IllegalArgumentException(
+ "Mandatory attribute '" + attrName + "' does not exist.");
+ }
+ }
+ }
+
+ public Module getModule()
+ {
+ return m_module;
+ }
+
+ public String getNamespace()
+ {
+ return m_namespace;
+ }
+
+ public Directive getDirective(String name)
+ {
+ for (int i = 0; i < m_dirs.size(); i++)
+ {
+ if (m_dirs.get(i).getName().equals(name))
+ {
+ return m_dirs.get(i);
+ }
+ }
+ return null;
+ }
+
+ public List<Directive> getDirectives()
+ {
+ return m_dirsConst;
+ }
+
+ public Attribute getAttribute(String name)
+ {
+ for (int i = 0; i < m_attrs.size(); i++)
+ {
+ if (m_attrs.get(i).getName().equals(name))
+ {
+ return m_attrs.get(i);
+ }
+ }
+ return null;
+ }
+
+ public List<Attribute> getAttributes()
+ {
+ return m_attrsConst;
+ }
+
+ public List<String> getUses()
+ {
+ return m_uses;
+ }
+
+ public boolean isIncluded(String name)
+ {
+ if ((m_includeFilter == null) && (m_excludeFilter == null))
+ {
+ return true;
+ }
+
+ // Get the class name portion of the target class.
+ String className = Util.getClassName(name);
+
+ // If there are no include filters then all classes are included
+ // by default, otherwise try to find one match.
+ boolean included = (m_includeFilter == null);
+ for (int i = 0;
+ (!included) && (m_includeFilter != null) && (i < m_includeFilter.size());
+ i++)
+ {
+ included = SimpleFilter.compareSubstring(m_includeFilter.get(i), className);
+ }
+
+ // If there are no exclude filters then no classes are excluded
+ // by default, otherwise try to find one match.
+ boolean excluded = false;
+ for (int i = 0;
+ (!excluded) && (m_excludeFilter != null) && (i < m_excludeFilter.size());
+ i++)
+ {
+ excluded = SimpleFilter.compareSubstring(m_excludeFilter.get(i), className);
+ }
+ return included && !excluded;
+ }
+
+ public String toString()
+ {
+ if (m_module == null)
+ {
+ return m_attrs.toString();
+ }
+ if (m_namespace.equals(Capability.PACKAGE_NAMESPACE))
+ {
+ return "[" + m_module + "] "
+ + m_namespace + "; " + getAttribute(Capability.PACKAGE_ATTR);
+ }
+ return "[" + m_module + "] " + m_namespace + "; " + m_attrs;
+ }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
index ce075ad..3ca16aa 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
@@ -21,35 +21,35 @@
import java.util.*;
import java.util.ArrayList;
import java.util.Map.Entry;
-import org.apache.felix.framework.BundleRevisionImpl;
import org.apache.felix.framework.Logger;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.resolver.Module;
+import org.apache.felix.framework.capabilityset.Requirement;
import org.apache.felix.framework.util.FelixConstants;
import org.apache.felix.framework.util.VersionRange;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
import org.osgi.framework.*;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
public class ManifestParser
{
private final Logger m_logger;
private final Map m_configMap;
private final Map m_headerMap;
- private volatile int m_activationPolicy = BundleRevisionImpl.EAGER_ACTIVATION;
+ private volatile int m_activationPolicy = Module.EAGER_ACTIVATION;
private volatile String m_activationIncludeDir;
private volatile String m_activationExcludeDir;
private volatile boolean m_isExtension = false;
private volatile String m_bundleSymbolicName;
private volatile Version m_bundleVersion;
- private volatile List<BundleCapability> m_capabilities;
- private volatile List<BundleRequirement> m_requirements;
+ private volatile List<Capability> m_capabilities;
+ private volatile List<Requirement> m_requirements;
+ private volatile List<Requirement> m_dynamicRequirements;
private volatile List<R4LibraryClause> m_libraryClauses;
private volatile boolean m_libraryHeadersOptional = false;
- public ManifestParser(Logger logger, Map configMap, BundleRevision owner, Map headerMap)
+ public ManifestParser(Logger logger, Map configMap, Module owner, Map headerMap)
throws BundleException
{
m_logger = logger;
@@ -65,7 +65,7 @@
}
// Create lists to hold capabilities and requirements.
- List<BundleCapabilityImpl> capList = new ArrayList();
+ List<Capability> capList = new ArrayList();
//
// Parse bundle version.
@@ -76,8 +76,7 @@
{
try
{
- m_bundleVersion = Version.parseVersion(
- (String) headerMap.get(Constants.BUNDLE_VERSION));
+ m_bundleVersion = Version.parseVersion((String) headerMap.get(Constants.BUNDLE_VERSION));
}
catch (RuntimeException ex)
{
@@ -94,41 +93,37 @@
// Parse bundle symbolic name.
//
- BundleCapabilityImpl requireCap = parseBundleSymbolicName(owner, m_headerMap);
- if (requireCap != null)
+ Capability moduleCap = parseBundleSymbolicName(owner, m_headerMap);
+ if (moduleCap != null)
{
m_bundleSymbolicName = (String)
- requireCap.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
+ moduleCap.getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE).getValue();
- // Add a bundle capability and a host capability to all
+ // Add a module capability and a host capability to all
// non-fragment bundles. A host capability is the same
- // as a require capability, but with a different capability
- // namespace. Bundle capabilities resolve required-bundle
+ // as a module capability, but with a different capability
+ // namespace. Module capabilities resolve required-bundle
// dependencies, while host capabilities resolve fragment-host
// dependencies.
if (headerMap.get(Constants.FRAGMENT_HOST) == null)
{
- capList.add(requireCap);
- capList.add(new BundleCapabilityImpl(
- owner, BundleCapabilityImpl.HOST_NAMESPACE,
- Collections.EMPTY_MAP,
-// TODO: OSGi R4.3 - Wraps map as unmodifiable twice.
- requireCap.getAttributes()));
+ capList.add(moduleCap);
+ capList.add(new CapabilityImpl(
+ owner, Capability.HOST_NAMESPACE, new ArrayList<Directive>(0),
+ ((CapabilityImpl) moduleCap).getAttributes()));
}
// Add a singleton capability if the bundle is a singleton.
// This is sort of a hack, but we need this for the resolver
// to be able to resolve singletons. It is not possible to
- // attach this information to the bundle or host capabilities
+ // attach this information to the module or host capabilities
// because fragments don't have those capabilities, but fragments
// can be singletons too.
- if (isSingleton(requireCap))
+ if (isSingleton(moduleCap))
{
- capList.add(new BundleCapabilityImpl(
- owner, BundleCapabilityImpl.SINGLETON_NAMESPACE,
- Collections.EMPTY_MAP,
-// TODO: OSGi R4.3 - Wraps map as unmodifiable twice.
- requireCap.getAttributes()));
+ capList.add(new CapabilityImpl(
+ owner, Capability.SINGLETON_NAMESPACE, new ArrayList<Directive>(0),
+ ((CapabilityImpl) moduleCap).getAttributes()));
}
}
@@ -143,7 +138,7 @@
// Parse Fragment-Host.
//
- List<BundleRequirementImpl> hostReqs = parseFragmentHost(m_logger, owner, m_headerMap);
+ List<Requirement> hostReqs = parseFragmentHost(m_logger, owner, m_headerMap);
//
// Parse Require-Bundle
@@ -152,7 +147,7 @@
List<ParsedHeaderClause> requireClauses =
parseStandardHeader((String) headerMap.get(Constants.REQUIRE_BUNDLE));
requireClauses = normalizeRequireClauses(m_logger, requireClauses, getManifestVersion());
- List<BundleRequirementImpl> requireReqs = convertRequires(requireClauses, owner);
+ List<Requirement> requireReqs = convertRequires(requireClauses, owner);
//
// Parse Import-Package.
@@ -161,7 +156,7 @@
List<ParsedHeaderClause> importClauses =
parseStandardHeader((String) headerMap.get(Constants.IMPORT_PACKAGE));
importClauses = normalizeImportClauses(m_logger, importClauses, getManifestVersion());
- List<BundleRequirement> importReqs = convertImports(importClauses, owner);
+ List<Requirement> importReqs = convertImports(importClauses, owner);
//
// Parse DynamicImport-Package.
@@ -170,7 +165,7 @@
List<ParsedHeaderClause> dynamicClauses =
parseStandardHeader((String) headerMap.get(Constants.DYNAMICIMPORT_PACKAGE));
dynamicClauses = normalizeDynamicImportClauses(m_logger, dynamicClauses, getManifestVersion());
- List<BundleRequirement> dynamicReqs = convertImports(dynamicClauses, owner);
+ m_dynamicRequirements = convertImports(dynamicClauses, owner);
//
// Parse Export-Package.
@@ -181,7 +176,7 @@
parseStandardHeader((String) headerMap.get(Constants.EXPORT_PACKAGE));
exportClauses = normalizeExportClauses(logger, exportClauses,
getManifestVersion(), m_bundleSymbolicName, m_bundleVersion);
- List<BundleCapability> exportCaps = convertExports(exportClauses, owner);
+ List<Capability> exportCaps = convertExports(exportClauses, owner);
//
// Calculate implicit imports.
@@ -209,17 +204,16 @@
// Combine all requirements.
m_requirements = new ArrayList(
- importReqs.size() + requireReqs.size() + hostReqs.size() + dynamicReqs.size());
+ importReqs.size() + requireReqs.size() + hostReqs.size());
m_requirements.addAll(importReqs);
m_requirements.addAll(requireReqs);
m_requirements.addAll(hostReqs);
- m_requirements.addAll(dynamicReqs);
//
// Parse Bundle-NativeCode.
//
- // Parse native library clauses.
+ // Get native library entry names for module library sources.
m_libraryClauses =
parseLibraryStrings(
m_logger,
@@ -245,14 +239,18 @@
m_isExtension = checkExtensionBundle(headerMap);
}
- private static boolean isSingleton(BundleCapabilityImpl cap)
+ private static boolean isSingleton(Capability cap)
{
- if (cap.getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+ if (cap.getNamespace().equals(Capability.MODULE_NAMESPACE))
{
- String value = cap.getDirectives().get(Constants.SINGLETON_DIRECTIVE);
- if ((value != null) && Boolean.valueOf(value))
+ final List<Directive> dirs = cap.getDirectives();
+ for (int dirIdx = 0; (dirs != null) && (dirIdx < dirs.size()); dirIdx++)
{
- return true;
+ if (dirs.get(dirIdx).getName().equalsIgnoreCase(Constants.SINGLETON_DIRECTIVE)
+ && Boolean.valueOf((String) dirs.get(dirIdx).getValue()))
+ {
+ return true;
+ }
}
}
return false;
@@ -264,17 +262,27 @@
{
// Verify that the values are equals if the package specifies
// both version and specification-version attributes.
- Set dupeSet = new HashSet();
- for (ParsedHeaderClause clause : clauses)
+ Map<String, Attribute> attrMap = new HashMap();
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
+ // Put attributes for current clause in a map for easy lookup.
+ attrMap.clear();
+ for (int attrIdx = 0;
+ attrIdx < clauses.get(clauseIdx).m_attrs.size();
+ attrIdx++)
+ {
+ Attribute attr = clauses.get(clauseIdx).m_attrs.get(attrIdx);
+ attrMap.put(attr.getName(), attr);
+ }
+
// Check for "version" and "specification-version" attributes
// and verify they are the same if both are specified.
- Object v = clause.m_attrs.get(Constants.VERSION_ATTRIBUTE);
- Object sv = clause.m_attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+ Attribute v = attrMap.get(Constants.VERSION_ATTRIBUTE);
+ Attribute sv = attrMap.get(Constants.PACKAGE_SPECIFICATION_VERSION);
if ((v != null) && (sv != null))
{
// Verify they are equal.
- if (!((String) v).trim().equals(((String) sv).trim()))
+ if (!((String) v.getValue()).trim().equals(((String) sv.getValue()).trim()))
{
throw new IllegalArgumentException(
"Both version and specification-version are specified, but they are not equal.");
@@ -285,26 +293,40 @@
// it to the VersionRange type.
if ((v != null) || (sv != null))
{
- clause.m_attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+ attrMap.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
v = (v == null) ? sv : v;
- clause.m_attrs.put(
- Constants.VERSION_ATTRIBUTE,
- VersionRange.parse(v.toString()));
+ attrMap.put(Constants.VERSION_ATTRIBUTE,
+ new Attribute(
+ Constants.VERSION_ATTRIBUTE,
+ VersionRange.parse(v.getValue().toString()),
+ v.isMandatory()));
}
// If bundle version is specified, then convert its type to VersionRange.
- v = clause.m_attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+ v = attrMap.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
if (v != null)
{
- clause.m_attrs.put(
- Constants.BUNDLE_VERSION_ATTRIBUTE,
- VersionRange.parse(v.toString()));
+ attrMap.put(Constants.BUNDLE_VERSION_ATTRIBUTE,
+ new Attribute(
+ Constants.BUNDLE_VERSION_ATTRIBUTE,
+ VersionRange.parse(v.getValue().toString()),
+ v.isMandatory()));
}
- // Verify java.* is not imported, nor any duplicate imports.
- for (int pathIdx = 0; pathIdx < clause.m_paths.size(); pathIdx++)
+ // Re-copy the attributes in case they changed.
+ clauses.get(clauseIdx).m_attrs.clear();
+ clauses.get(clauseIdx).m_attrs.addAll(attrMap.values());
+ }
+
+ // Verify java.* is not imported, nor any duplicate imports.
+ Set dupeSet = new HashSet();
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+ {
+ // Verify that the named package has not already been declared.
+ List<String> paths = clauses.get(clauseIdx).m_paths;
+ for (int pathIdx = 0; pathIdx < paths.size(); pathIdx++)
{
- String pkgName = clause.m_paths.get(pathIdx);
+ String pkgName = paths.get(pathIdx);
if (!dupeSet.contains(pkgName))
{
// Verify that java.* packages are not imported.
@@ -314,7 +336,7 @@
"Importing java.* packages not allowed: " + pkgName);
}
// Make sure a package name was specified.
- else if (clause.m_paths.get(pathIdx).length() == 0)
+ else if (clauses.get(clauseIdx).m_paths.get(pathIdx).length() == 0)
{
throw new BundleException(
"Imported package names cannot be zero length.");
@@ -326,11 +348,17 @@
throw new BundleException("Duplicate import: " + pkgName);
}
}
+ }
- if (!mv.equals("2"))
+ if (!mv.equals("2"))
+ {
+ // Check to make sure that R3 bundles have only specified
+ // the 'specification-version' attribute and no directives
+ // on their imports; ignore all unknown attributes.
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
// R3 bundles cannot have directives on their imports.
- if (!clause.m_dirs.isEmpty())
+ if (clauses.get(clauseIdx).m_dirs.size() != 0)
{
throw new BundleException("R3 imports cannot contain directives.");
}
@@ -340,26 +368,37 @@
// because the package class normalizes to "version" to avoid having
// future special cases. This could be changed if more strict behavior
// is required.
- if (!clause.m_attrs.isEmpty())
+ if (clauses.get(clauseIdx).m_attrs.size() != 0)
{
// R3 package requirements should only have version attributes.
- Object pkgVersion = clause.m_attrs.get(BundleCapabilityImpl.VERSION_ATTR);
- pkgVersion = (pkgVersion == null)
- ? new VersionRange(Version.emptyVersion, true, null, true)
- : pkgVersion;
- for (Entry<String, Object> entry : clause.m_attrs.entrySet())
+ Attribute pkgVersion =
+ new Attribute(Capability.VERSION_ATTR,
+ new VersionRange(Version.emptyVersion, true, null, true), false);
+ for (int attrIdx = 0;
+ attrIdx < clauses.get(clauseIdx).m_attrs.size();
+ attrIdx++)
{
- if (!entry.getKey().equals(BundleCapabilityImpl.VERSION_ATTR))
+ if (clauses.get(clauseIdx).m_attrs.get(attrIdx)
+ .getName().equals(Capability.VERSION_ATTR))
+ {
+ pkgVersion = clauses.get(clauseIdx).m_attrs.get(attrIdx);
+ }
+ else
{
logger.log(Logger.LOG_WARNING,
"Unknown R3 import attribute: "
- + entry.getKey());
+ + clauses.get(clauseIdx).m_attrs.get(attrIdx).getName());
}
}
- // Remove all other attributes except package version.
- clause.m_attrs.clear();
- clause.m_attrs.put(BundleCapabilityImpl.VERSION_ATTR, pkgVersion);
+ // Recreate the import to remove any other attributes
+ // and add version if missing.
+ ArrayList<Attribute> attrs = new ArrayList<Attribute>(1);
+ attrs.add(pkgVersion);
+ clauses.set(clauseIdx, new ParsedHeaderClause(
+ clauses.get(clauseIdx).m_paths,
+ clauses.get(clauseIdx).m_dirs,
+ attrs));
}
}
}
@@ -367,8 +406,8 @@
return clauses;
}
- private static List<BundleRequirement> convertImports(
- List<ParsedHeaderClause> clauses, BundleRevision owner)
+ private static List<Requirement> convertImports(
+ List<ParsedHeaderClause> clauses, Module owner)
{
// Now convert generic header clauses into requirements.
List reqList = new ArrayList();
@@ -379,23 +418,18 @@
pathIdx++)
{
// Prepend the package name to the array of attributes.
- Map<String, Object> attrs = clauses.get(clauseIdx).m_attrs;
- // Note that we use a linked hash map here to ensure the
- // package attribute is first, which will make indexing
- // more efficient.
-// TODO: OSGi R4.3 - This is a hack...perhaps we should use the standard "key"
-// notion where namespace is also the name of the key attribute.
- Map<String, Object> newAttrs = new LinkedHashMap<String, Object>(attrs.size() + 1);
- newAttrs.put(
- BundleCapabilityImpl.PACKAGE_ATTR,
- clauses.get(clauseIdx).m_paths.get(pathIdx));
- newAttrs.putAll(attrs);
+ List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
+ List<Attribute> newAttrs = new ArrayList<Attribute>(attrs.size() + 1);
+ newAttrs.add(new Attribute(
+ Capability.PACKAGE_ATTR,
+ clauses.get(clauseIdx).m_paths.get(pathIdx), false));
+ newAttrs.addAll(attrs);
// Create package requirement and add to requirement list.
reqList.add(
- new BundleRequirementImpl(
+ new RequirementImpl(
owner,
- BundleCapabilityImpl.PACKAGE_NAMESPACE,
+ Capability.PACKAGE_NAMESPACE,
clauses.get(clauseIdx).m_dirs,
newAttrs));
}
@@ -410,30 +444,27 @@
{
// Verify that the values are equals if the package specifies
// both version and specification-version attributes.
- for (ParsedHeaderClause clause : clauses)
+ Map<String, Attribute> attrMap = new HashMap();
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
- if (!mv.equals("2"))
+ // Put attributes for current clause in a map for easy lookup.
+ attrMap.clear();
+ for (int attrIdx = 0;
+ attrIdx < clauses.get(clauseIdx).m_attrs.size();
+ attrIdx++)
{
- // R3 bundles cannot have directives on their imports.
- if (!clause.m_dirs.isEmpty())
- {
- throw new BundleException("R3 imports cannot contain directives.");
- }
+ Attribute attr = clauses.get(clauseIdx).m_attrs.get(attrIdx);
+ attrMap.put(attr.getName(), attr);
}
- // Add the resolution directive to indicate that these are
- // dynamic imports.
-// TODO: OSGi R4.3 - Use real constant value for "dynamic".
- clause.m_dirs.put(Constants.RESOLUTION_DIRECTIVE, "dynamic");
-
// Check for "version" and "specification-version" attributes
// and verify they are the same if both are specified.
- Object v = clause.m_attrs.get(Constants.VERSION_ATTRIBUTE);
- Object sv = clause.m_attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+ Attribute v = attrMap.get(Constants.VERSION_ATTRIBUTE);
+ Attribute sv = attrMap.get(Constants.PACKAGE_SPECIFICATION_VERSION);
if ((v != null) && (sv != null))
{
// Verify they are equal.
- if (!((String) v).trim().equals(((String) sv).trim()))
+ if (!((String) v.getValue()).trim().equals(((String) sv.getValue()).trim()))
{
throw new IllegalArgumentException(
"Both version and specification-version are specified, but they are not equal.");
@@ -444,27 +475,40 @@
// it to the VersionRange type.
if ((v != null) || (sv != null))
{
- clause.m_attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+ attrMap.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
v = (v == null) ? sv : v;
- clause.m_attrs.put(
- Constants.VERSION_ATTRIBUTE,
- VersionRange.parse(v.toString()));
+ attrMap.put(Constants.VERSION_ATTRIBUTE,
+ new Attribute(
+ Constants.VERSION_ATTRIBUTE,
+ VersionRange.parse(v.getValue().toString()),
+ v.isMandatory()));
}
// If bundle version is specified, then convert its type to VersionRange.
- v = clause.m_attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+ v = attrMap.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
if (v != null)
{
- clause.m_attrs.put(
- Constants.BUNDLE_VERSION_ATTRIBUTE,
- VersionRange.parse(v.toString()));
+ attrMap.put(Constants.BUNDLE_VERSION_ATTRIBUTE,
+ new Attribute(
+ Constants.BUNDLE_VERSION_ATTRIBUTE,
+ VersionRange.parse(v.getValue().toString()),
+ v.isMandatory()));
}
- // Dynamic imports can have duplicates, so verify that java.*
- // packages are not imported.
- for (int pathIdx = 0; pathIdx < clause.m_paths.size(); pathIdx++)
+ // Re-copy the attributes in case they changed.
+ clauses.get(clauseIdx).m_attrs.clear();
+ clauses.get(clauseIdx).m_attrs.addAll(attrMap.values());
+ }
+
+ // Dynamic imports can have duplicates, so just check for import
+ // of java.*.
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+ {
+ // Verify that java.* packages are not imported.
+ List<String> paths = clauses.get(clauseIdx).m_paths;
+ for (int pathIdx = 0; pathIdx < paths.size(); pathIdx++)
{
- String pkgName = clause.m_paths.get(pathIdx);
+ String pkgName = paths.get(pathIdx);
if (pkgName.startsWith("java."))
{
throw new BundleException(
@@ -478,6 +522,21 @@
}
}
+ if (!mv.equals("2"))
+ {
+ // Check to make sure that R3 bundles have only specified
+ // the 'specification-version' attribute and no directives
+ // on their imports; ignore all unknown attributes.
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+ {
+ // R3 bundles cannot have directives on their imports.
+ if (clauses.get(clauseIdx).m_dirs.size() != 0)
+ {
+ throw new BundleException("R3 imports cannot contain directives.");
+ }
+ }
+ }
+
return clauses;
}
@@ -487,33 +546,49 @@
throws BundleException
{
// Verify that "java.*" packages are not exported.
- for (ParsedHeaderClause clause : clauses)
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
// Verify that the named package has not already been declared.
- for (int pathIdx = 0; pathIdx < clause.m_paths.size(); pathIdx++)
+ for (int pathIdx = 0; pathIdx < clauses.get(clauseIdx).m_paths.size(); pathIdx++)
{
// Verify that java.* packages are not exported.
- if (clause.m_paths.get(pathIdx).startsWith("java."))
+ if (clauses.get(clauseIdx).m_paths.get(pathIdx).startsWith("java."))
{
throw new BundleException(
"Exporting java.* packages not allowed: "
- + clause.m_paths.get(pathIdx));
+ + clauses.get(clauseIdx).m_paths.get(pathIdx));
}
- else if (clause.m_paths.get(pathIdx).length() == 0)
+ else if (clauses.get(clauseIdx).m_paths.get(pathIdx).length() == 0)
{
throw new BundleException(
"Exported package names cannot be zero length.");
}
}
+ }
+
+ // If both version and specification-version attributes are specified,
+ // then verify that the values are equal.
+ Map<String, Attribute> attrMap = new HashMap();
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+ {
+ // Put attributes for current clause in a map for easy lookup.
+ attrMap.clear();
+ for (int attrIdx = 0;
+ attrIdx < clauses.get(clauseIdx).m_attrs.size();
+ attrIdx++)
+ {
+ Attribute attr = clauses.get(clauseIdx).m_attrs.get(attrIdx);
+ attrMap.put(attr.getName(), attr);
+ }
// Check for "version" and "specification-version" attributes
// and verify they are the same if both are specified.
- Object v = clause.m_attrs.get(Constants.VERSION_ATTRIBUTE);
- Object sv = clause.m_attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+ Attribute v = attrMap.get(Constants.VERSION_ATTRIBUTE);
+ Attribute sv = attrMap.get(Constants.PACKAGE_SPECIFICATION_VERSION);
if ((v != null) && (sv != null))
{
// Verify they are equal.
- if (!((String) v).trim().equals(((String) sv).trim()))
+ if (!((String) v.getValue()).trim().equals(((String) sv.getValue()).trim()))
{
throw new IllegalArgumentException(
"Both version and specification-version are specified, but they are not equal.");
@@ -523,7 +598,8 @@
// Always add the default version if not specified.
if ((v == null) && (sv == null))
{
- v = Version.emptyVersion;
+ v = new Attribute(
+ Constants.VERSION_ATTRIBUTE, Version.emptyVersion, false);
}
// Ensure that only the "version" attribute is used and convert
@@ -531,34 +607,57 @@
if ((v != null) || (sv != null))
{
// Convert version attribute to type Version.
- clause.m_attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+ attrMap.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
v = (v == null) ? sv : v;
- clause.m_attrs.put(
- Constants.VERSION_ATTRIBUTE,
- Version.parseVersion(v.toString()));
- }
+ attrMap.put(Constants.VERSION_ATTRIBUTE,
+ new Attribute(
+ Constants.VERSION_ATTRIBUTE,
+ Version.parseVersion(v.getValue().toString()),
+ v.isMandatory()));
- // If this is an R4 bundle, then make sure it doesn't specify
- // bundle symbolic name or bundle version attributes.
- if (mv.equals("2"))
+ // Re-copy the attributes since they have changed.
+ clauses.get(clauseIdx).m_attrs.clear();
+ clauses.get(clauseIdx).m_attrs.addAll(attrMap.values());
+ }
+ }
+
+ // If this is an R4 bundle, then make sure it doesn't specify
+ // bundle symbolic name or bundle version attributes.
+ if (mv.equals("2"))
+ {
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
- // Find symbolic name and version attribute, if present.
- if (clause.m_attrs.containsKey(Constants.BUNDLE_VERSION_ATTRIBUTE)
- || clause.m_attrs.containsKey(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
+ // R3 package capabilities should only have a version attribute.
+ List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
+ for (int attrIdx = 0; attrIdx < attrs.size(); attrIdx++)
{
- throw new BundleException(
- "Exports must not specify bundle symbolic name or bundle version.");
+ // Find symbolic name and version attribute, if present.
+ if (attrs.get(attrIdx).getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE) ||
+ attrs.get(attrIdx).getName().equals(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
+ {
+ throw new BundleException(
+ "Exports must not specify bundle symbolic name or bundle version.");
+ }
}
// Now that we know that there are no bundle symbolic name and version
// attributes, add them since the spec says they are there implicitly.
- clause.m_attrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn);
- clause.m_attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bv);
+ attrs.add(new Attribute(
+ Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn, false));
+ attrs.add(new Attribute(
+ Constants.BUNDLE_VERSION_ATTRIBUTE, bv, false));
+ ((ArrayList) attrs).trimToSize();
}
- else if (!mv.equals("2"))
+ }
+ else if (!mv.equals("2"))
+ {
+ // Check to make sure that R3 bundles have only specified
+ // the 'specification-version' attribute and no directives
+ // on their exports; ignore all unknown attributes.
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
// R3 bundles cannot have directives on their exports.
- if (!clause.m_dirs.isEmpty())
+ if (clauses.get(clauseIdx).m_dirs.size() != 0)
{
throw new BundleException("R3 exports cannot contain directives.");
}
@@ -568,31 +667,37 @@
// because the package class normalizes to "version" to avoid having
// future special cases. This could be changed if more strict behavior
// is required.
- if (!clause.m_attrs.isEmpty())
+ if (clauses.get(clauseIdx).m_attrs.size() != 0)
{
// R3 package capabilities should only have a version attribute.
- Object pkgVersion = clause.m_attrs.get(BundleCapabilityImpl.VERSION_ATTR);
- pkgVersion = (pkgVersion == null)
- ? Version.emptyVersion
- : pkgVersion;
- for (Entry<String, Object> entry : clause.m_attrs.entrySet())
+ List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
+ Attribute pkgVersion = new Attribute(Capability.VERSION_ATTR, Version.emptyVersion, false);
+ for (int attrIdx = 0; attrIdx < attrs.size(); attrIdx++)
{
- if (!entry.getKey().equals(BundleCapabilityImpl.VERSION_ATTR))
+ if (attrs.get(attrIdx).getName().equals(Capability.VERSION_ATTR))
+ {
+ pkgVersion = attrs.get(attrIdx);
+ }
+ else
{
logger.log(
Logger.LOG_WARNING,
"Unknown R3 export attribute: "
- + entry.getKey());
+ + attrs.get(attrIdx).getName());
}
}
- // Remove all other attributes except package version.
- clause.m_attrs.clear();
- clause.m_attrs.put(BundleCapabilityImpl.VERSION_ATTR, pkgVersion);
+ // Recreate the export to remove any other attributes
+ // and add version if missing.
+ List<Attribute> newAttrs = new ArrayList<Attribute>(2);
+ newAttrs.add(pkgVersion);
+ clauses.set(clauseIdx, new ParsedHeaderClause(
+ clauses.get(clauseIdx).m_paths,
+ clauses.get(clauseIdx).m_dirs,
+ newAttrs));
}
}
}
-
return clauses;
}
@@ -638,16 +743,21 @@
return m_bundleVersion;
}
- public List<BundleCapability> getCapabilities()
+ public List<Capability> getCapabilities()
{
return m_capabilities;
}
- public List<BundleRequirement> getRequirements()
+ public List<Requirement> getRequirements()
{
return m_requirements;
}
+ public List<Requirement> getDynamicRequirements()
+ {
+ return m_dynamicRequirements;
+ }
+
public List<R4LibraryClause> getLibraryClauses()
{
return m_libraryClauses;
@@ -743,7 +853,7 @@
// Select the matching native clause.
int selected = 0;
- if (clauseList.isEmpty())
+ if (clauseList.size() == 0)
{
// If optional clause exists, no error thrown.
if (m_libraryHeadersOptional)
@@ -826,7 +936,7 @@
}
}
- if (selection.isEmpty())
+ if (selection.size() == 0)
{
// Re-init index list.
selection.clear();
@@ -857,7 +967,7 @@
}
// Return the first sorted clause
- if (selection.isEmpty())
+ if (selection.size() == 0)
{
return 0;
}
@@ -868,7 +978,7 @@
}
private static List<ParsedHeaderClause> calculateImplicitImports(
- List<BundleCapability> exports, List<ParsedHeaderClause> imports)
+ List<Capability> exports, List<ParsedHeaderClause> imports)
throws BundleException
{
List<ParsedHeaderClause> clauseList = new ArrayList();
@@ -890,32 +1000,34 @@
// Add import requirement for each export capability.
for (int i = 0; i < exports.size(); i++)
{
- if (map.get(exports.get(i).getAttributes()
- .get(BundleCapabilityImpl.PACKAGE_ATTR)) == null)
+ if (map.get(exports.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue()) == null)
{
// Convert Version to VersionRange.
- Map<String, Object> attrs = new HashMap<String, Object>();
- Object version = exports.get(i).getAttributes().get(Constants.VERSION_ATTRIBUTE);
- if (version != null)
+ List<Attribute> attrs = new ArrayList<Attribute>(exports.get(i).getAttributes());
+ for (int attrIdx = 0; (attrs != null) && (attrIdx < attrs.size()); attrIdx++)
{
- attrs.put(
- Constants.VERSION_ATTRIBUTE,
- VersionRange.parse(version.toString()));
+ if (attrs.get(attrIdx).getName().equals(Constants.VERSION_ATTRIBUTE))
+ {
+ attrs.set(attrIdx, new Attribute(
+ attrs.get(attrIdx).getName(),
+ VersionRange.parse(attrs.get(attrIdx).getValue().toString()),
+ attrs.get(attrIdx).isMandatory()));
+ }
}
List<String> paths = new ArrayList();
paths.add((String)
- exports.get(i).getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
+ exports.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue());
clauseList.add(
- new ParsedHeaderClause(paths, Collections.EMPTY_MAP, attrs));
+ new ParsedHeaderClause(paths, new ArrayList<Directive>(0), attrs));
}
}
return clauseList;
}
- private static List<BundleCapability> calculateImplicitUses(
- List<BundleCapability> exports, List<ParsedHeaderClause> imports)
+ private static List<Capability> calculateImplicitUses(
+ List<Capability> exports, List<ParsedHeaderClause> imports)
throws BundleException
{
// Add a "uses" directive onto each export of R3 bundles
@@ -933,14 +1045,16 @@
+ imports.get(i).m_paths.get(pathIdx);
}
}
+ Directive uses = new Directive(
+ Constants.USES_DIRECTIVE, usesValue);
for (int i = 0; i < exports.size(); i++)
{
- Map<String, String> dirs = new HashMap<String, String>(1);
- dirs.put(Constants.USES_DIRECTIVE, usesValue);
- exports.set(i, new BundleCapabilityImpl(
- exports.get(i).getRevision(),
- BundleCapabilityImpl.PACKAGE_NAMESPACE,
- dirs,
+ List<Directive> dirList = new ArrayList<Directive>(1);
+ dirList.add(uses);
+ exports.set(i, new CapabilityImpl(
+ exports.get(i).getModule(),
+ Capability.PACKAGE_NAMESPACE,
+ dirList,
exports.get(i).getAttributes()));
}
@@ -949,13 +1063,13 @@
private static boolean checkExtensionBundle(Map headerMap) throws BundleException
{
- Object extension = parseExtensionBundleHeader(
+ Directive extension = parseExtensionBundleHeader(
(String) headerMap.get(Constants.FRAGMENT_HOST));
if (extension != null)
{
- if (!(Constants.EXTENSION_FRAMEWORK.equals(extension) ||
- Constants.EXTENSION_BOOTCLASSPATH.equals(extension)))
+ if (!(Constants.EXTENSION_FRAMEWORK.equals(extension.getValue()) ||
+ Constants.EXTENSION_BOOTCLASSPATH.equals(extension.getValue())))
{
throw new BundleException(
"Extension bundle must have either 'extension:=framework' or 'extension:=bootclasspath'");
@@ -973,8 +1087,7 @@
return false;
}
- private static BundleCapabilityImpl parseBundleSymbolicName(
- BundleRevision owner, Map headerMap)
+ private static Capability parseBundleSymbolicName(Module owner, Map headerMap)
throws BundleException
{
List<ParsedHeaderClause> clauses = parseStandardHeader(
@@ -1015,14 +1128,16 @@
}
}
- // Create a require capability and return it.
+ // Create a module capability and return it.
String symName = (String) clauses.get(0).m_paths.get(0);
- Map<String, Object> attrs = new HashMap<String, Object>(2);
- attrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symName);
- attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersion);
- return new BundleCapabilityImpl(
+ List<Attribute> attrs = new ArrayList<Attribute>(2);
+ attrs.add(new Attribute(
+ Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symName, false));
+ attrs.add(new Attribute(
+ Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersion, false));
+ return new CapabilityImpl(
owner,
- BundleCapabilityImpl.BUNDLE_NAMESPACE,
+ Capability.MODULE_NAMESPACE,
clauses.get(0).m_dirs,
attrs);
}
@@ -1030,11 +1145,11 @@
return null;
}
- private static List<BundleRequirementImpl> parseFragmentHost(
- Logger logger, BundleRevision owner, Map headerMap)
+ private static List<Requirement> parseFragmentHost(
+ Logger logger, Module owner, Map headerMap)
throws BundleException
{
- List<BundleRequirementImpl> reqs = new ArrayList();
+ List<Requirement> reqs = new ArrayList();
String mv = getManifestVersion(headerMap);
if ((mv != null) && mv.equals("2"))
@@ -1058,12 +1173,10 @@
}
// Strip all attributes other than bundle-version.
- for (Iterator<Entry<String, Object>> it =
- clauses.get(0).m_attrs.entrySet().iterator();
- it.hasNext(); )
+ for (Iterator<Attribute> it = clauses.get(0).m_attrs.iterator(); it.hasNext(); )
{
- Entry<String, Object> entry = it.next();
- if (!entry.getKey().equals(Constants.BUNDLE_VERSION_ATTRIBUTE))
+ Attribute attr = it.next();
+ if (!attr.getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE))
{
it.remove();
}
@@ -1071,24 +1184,26 @@
// If the bundle-version attribute is specified, then convert
// it to the proper type.
- Object value = clauses.get(0).m_attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- if (value != null)
+ if (clauses.get(0).m_attrs.size() == 1)
{
- clauses.get(0).m_attrs.put(
- Constants.BUNDLE_VERSION_ATTRIBUTE,
- VersionRange.parse(value.toString()));
+ Attribute attr = clauses.get(0).m_attrs.get(0);
+ clauses.get(0).m_attrs.set(0,
+ new Attribute(
+ Constants.BUNDLE_VERSION_ATTRIBUTE,
+ VersionRange.parse(attr.getValue().toString()),
+ attr.isMandatory()));
}
// Prepend the host symbolic name to the array of attributes.
- Map<String, Object> attrs = clauses.get(0).m_attrs;
- Map<String, Object> newAttrs = new HashMap<String, Object>(attrs.size() + 1);
- newAttrs.put(
+ List<Attribute> attrs = clauses.get(0).m_attrs;
+ List<Attribute> newAttrs = new ArrayList<Attribute>(attrs.size() + 1);
+ newAttrs.add(new Attribute(
Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE,
- clauses.get(0).m_paths.get(0));
- newAttrs.putAll(attrs);
+ clauses.get(0).m_paths.get(0), false));
+ newAttrs.addAll(attrs);
- reqs.add(new BundleRequirementImpl(
- owner, BundleCapabilityImpl.HOST_NAMESPACE,
+ reqs.add(new RequirementImpl(
+ owner, Capability.HOST_NAMESPACE,
clauses.get(0).m_dirs,
newAttrs));
}
@@ -1107,11 +1222,11 @@
return reqs;
}
- public static List<BundleCapability> parseExportHeader(
- Logger logger, BundleRevision owner, String header, String bsn, Version bv)
+ public static List<Capability> parseExportHeader(
+ Logger logger, Module owner, String header, String bsn, Version bv)
{
- List<BundleCapability> caps = null;
+ List<Capability> caps = null;
try
{
List<ParsedHeaderClause> exportClauses = parseStandardHeader(header);
@@ -1125,10 +1240,10 @@
return caps;
}
- private static List<BundleCapability> convertExports(
- List<ParsedHeaderClause> clauses, BundleRevision owner)
+ private static List<Capability> convertExports(
+ List<ParsedHeaderClause> clauses, Module owner)
{
- List<BundleCapability> capList = new ArrayList();
+ List<Capability> capList = new ArrayList();
for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
for (int pathIdx = 0;
@@ -1136,18 +1251,18 @@
pathIdx++)
{
// Prepend the package name to the array of attributes.
- Map<String, Object> attrs = clauses.get(clauseIdx).m_attrs;
- Map<String, Object> newAttrs = new HashMap<String, Object>(attrs.size() + 1);
- newAttrs.put(
- BundleCapabilityImpl.PACKAGE_ATTR,
- clauses.get(clauseIdx).m_paths.get(pathIdx));
- newAttrs.putAll(attrs);
+ List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
+ List<Attribute> newAttrs = new ArrayList<Attribute>(attrs.size() + 1);
+ newAttrs.add(new Attribute(
+ Capability.PACKAGE_ATTR,
+ clauses.get(clauseIdx).m_paths.get(pathIdx), false));
+ newAttrs.addAll(attrs);
// Create package capability and add to capability list.
capList.add(
- new BundleCapabilityImpl(
+ new CapabilityImpl(
owner,
- BundleCapabilityImpl.PACKAGE_NAMESPACE,
+ Capability.PACKAGE_NAMESPACE,
clauses.get(clauseIdx).m_dirs,
newAttrs));
}
@@ -1169,13 +1284,19 @@
// Convert bundle version attribute to VersionRange type.
for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
- Object value = clauses.get(clauseIdx).m_attrs.get(
- Constants.BUNDLE_VERSION_ATTRIBUTE);
- if (value != null)
+ for (int attrIdx = 0;
+ attrIdx < clauses.get(clauseIdx).m_attrs.size();
+ attrIdx++)
{
- clauses.get(clauseIdx).m_attrs.put(
- Constants.BUNDLE_VERSION_ATTRIBUTE,
- VersionRange.parse(value.toString()));
+ Attribute attr = clauses.get(clauseIdx).m_attrs.get(attrIdx);
+ if (attr.getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE))
+ {
+ clauses.get(clauseIdx).m_attrs.set(attrIdx,
+ new Attribute(
+ Constants.BUNDLE_VERSION_ATTRIBUTE,
+ VersionRange.parse(attr.getValue().toString()),
+ attr.isMandatory()));
+ }
}
}
}
@@ -1183,35 +1304,30 @@
return clauses;
}
- private static List<BundleRequirementImpl> convertRequires(
- List<ParsedHeaderClause> clauses, BundleRevision owner)
+ private static List<Requirement> convertRequires(
+ List<ParsedHeaderClause> clauses, Module owner)
{
- List<BundleRequirementImpl> reqList = new ArrayList();
+ List<Requirement> reqList = new ArrayList();
for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
+ List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
+
for (int pathIdx = 0;
pathIdx < clauses.get(clauseIdx).m_paths.size();
pathIdx++)
{
- // Prepend the bundle symbolic name to the array of attributes.
- Map<String, Object> attrs = clauses.get(clauseIdx).m_attrs;
- // Note that we use a linked hash map here to ensure the
- // package attribute is first, which will make indexing
- // more efficient.
-// TODO: OSGi R4.3 - This is a hack...perhaps we should use the standard "key"
-// notion where namespace is also the name of the key attribute.
// Prepend the symbolic name to the array of attributes.
- Map<String, Object> newAttrs = new LinkedHashMap<String, Object>(attrs.size() + 1);
- newAttrs.put(
+ List<Attribute> newAttrs = new ArrayList<Attribute>(attrs.size() + 1);
+ newAttrs.add(new Attribute(
Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE,
- clauses.get(clauseIdx).m_paths.get(pathIdx));
- newAttrs.putAll(attrs);
+ clauses.get(clauseIdx).m_paths.get(pathIdx), false));
+ newAttrs.addAll(attrs);
// Create package requirement and add to requirement list.
reqList.add(
- new BundleRequirementImpl(
+ new RequirementImpl(
owner,
- BundleCapabilityImpl.BUNDLE_NAMESPACE,
+ Capability.MODULE_NAMESPACE,
clauses.get(clauseIdx).m_dirs,
newAttrs));
}
@@ -1220,26 +1336,27 @@
return reqList;
}
- public static String parseExtensionBundleHeader(String header)
+ public static Directive parseExtensionBundleHeader(String header)
throws BundleException
{
List<ParsedHeaderClause> clauses = parseStandardHeader(header);
- String result = null;
+ Directive result = null;
if (clauses.size() == 1)
{
// See if there is the "extension" directive.
- for (Entry<String, String> entry : clauses.get(0).m_dirs.entrySet())
+ List<Directive> dirs = clauses.get(0).m_dirs;
+ for (int dirIdx = 0; (result == null) && (dirIdx < dirs.size()); dirIdx++)
{
- if (Constants.EXTENSION_DIRECTIVE.equals(entry.getKey()))
+ if (Constants.EXTENSION_DIRECTIVE.equals(dirs.get(dirIdx).getName()))
{
// If the extension directive is specified, make sure
// the target is the system bundle.
if (FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(clauses.get(0).m_paths.get(0)) ||
Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(clauses.get(0).m_paths.get(0)))
{
- return entry.getValue();
+ result = (Directive) dirs.get(dirIdx);
}
else
{
@@ -1255,7 +1372,7 @@
private void parseActivationPolicy(Map headerMap)
{
- m_activationPolicy = BundleRevisionImpl.EAGER_ACTIVATION;
+ m_activationPolicy = Module.EAGER_ACTIVATION;
List<ParsedHeaderClause> clauses = parseStandardHeader(
(String) headerMap.get(Constants.BUNDLE_ACTIVATIONPOLICY));
@@ -1268,16 +1385,17 @@
{
if (clauses.get(0).m_paths.get(clauseIdx).equals(Constants.ACTIVATION_LAZY))
{
- m_activationPolicy = BundleRevisionImpl.LAZY_ACTIVATION;
- for (Entry<String, String> entry : clauses.get(0).m_dirs.entrySet())
+ m_activationPolicy = Module.LAZY_ACTIVATION;
+ for (int dirIdx = 0; dirIdx < clauses.get(0).m_dirs.size(); dirIdx++)
{
- if (entry.getKey().equalsIgnoreCase(Constants.INCLUDE_DIRECTIVE))
+ Directive dir = clauses.get(0).m_dirs.get(dirIdx);
+ if (dir.getName().equalsIgnoreCase(Constants.INCLUDE_DIRECTIVE))
{
- m_activationIncludeDir = entry.getValue();
+ m_activationIncludeDir = (String) dir.getValue();
}
- else if (entry.getKey().equalsIgnoreCase(Constants.EXCLUDE_DIRECTIVE))
+ else if (dir.getName().equalsIgnoreCase(Constants.EXCLUDE_DIRECTIVE))
{
- m_activationExcludeDir = entry.getValue();
+ m_activationExcludeDir = (String) dir.getValue();
}
}
break;
@@ -1353,8 +1471,8 @@
}
// Parse the directives/attributes.
- Map<String, String> dirs = new HashMap<String, String>();
- Map<String, Object> attrs = new HashMap<String, Object>();
+ Map<String, Directive> dirsMap = new HashMap();
+ Map<String, Attribute> attrsMap = new HashMap();
int idx = -1;
String sep = null;
for (int pieceIdx = pathCount; pieceIdx < pieces.size(); pieceIdx++)
@@ -1388,25 +1506,36 @@
if (sep.equals(FelixConstants.DIRECTIVE_SEPARATOR))
{
// Check for duplicates.
- if (dirs.get(key) != null)
+ if (dirsMap.get(key) != null)
{
throw new IllegalArgumentException(
"Duplicate directive: " + key);
}
- dirs.put(key, value);
+ dirsMap.put(key, new Directive(key, value));
}
else
{
// Check for duplicates.
- if (attrs.get(key) != null)
+ if (attrsMap.get(key) != null)
{
throw new IllegalArgumentException(
"Duplicate attribute: " + key);
}
- attrs.put(key, value);
+ attrsMap.put(key, new Attribute(key, value, false));
}
}
+ List<Directive> dirs = new ArrayList<Directive>(dirsMap.size());
+ for (Entry<String, Directive> entry : dirsMap.entrySet())
+ {
+ dirs.add(entry.getValue());
+ }
+ List<Attribute> attrs = new ArrayList<Attribute>(attrsMap.size());
+ for (Entry<String, Attribute> entry : attrsMap.entrySet())
+ {
+ attrs.add(entry.getValue());
+ }
+
return new ParsedHeaderClause(paths, dirs, attrs);
}
@@ -1504,4 +1633,4 @@
return libList;
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ParsedHeaderClause.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ParsedHeaderClause.java
index ab095e5..4be3ed8 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ParsedHeaderClause.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ParsedHeaderClause.java
@@ -19,16 +19,16 @@
package org.apache.felix.framework.util.manifestparser;
import java.util.List;
-import java.util.Map;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Directive;
public class ParsedHeaderClause
{
public final List<String> m_paths;
- public final Map<String, String> m_dirs;
- public final Map<String, Object> m_attrs;
+ public final List<Directive> m_dirs;
+ public final List<Attribute> m_attrs;
- public ParsedHeaderClause(
- List<String> paths, Map<String, String> dirs, Map<String, Object> attrs)
+ public ParsedHeaderClause(List<String> paths, List<Directive> dirs, List<Attribute> attrs)
{
m_paths = paths;
m_dirs = dirs;
diff --git a/framework/src/main/java/org/apache/felix/framework/wiring/BundleRequirementImpl.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/RequirementImpl.java
similarity index 68%
rename from framework/src/main/java/org/apache/felix/framework/wiring/BundleRequirementImpl.java
rename to framework/src/main/java/org/apache/felix/framework/util/manifestparser/RequirementImpl.java
index 00f579f..0f039fe 100644
--- a/framework/src/main/java/org/apache/felix/framework/wiring/BundleRequirementImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/RequirementImpl.java
@@ -6,9 +6,9 @@
* 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
@@ -16,73 +16,63 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.felix.framework.wiring;
+package org.apache.felix.framework.util.manifestparser;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import org.apache.felix.framework.capabilityset.CapabilitySet;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.capabilityset.Requirement;
import org.apache.felix.framework.capabilityset.SimpleFilter;
+import org.apache.felix.framework.resolver.Module;
import org.apache.felix.framework.util.VersionRange;
import org.osgi.framework.Constants;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-public class BundleRequirementImpl implements BundleRequirement
+public class RequirementImpl implements Requirement
{
- private final BundleRevision m_revision;
+ private final Module m_module;
private final String m_namespace;
private final SimpleFilter m_filter;
private final boolean m_optional;
- private final Map<String, String> m_dirs;
- private final Map<String, Object> m_attrs;
+ private final List<Directive> m_dirs;
+ private final List<Directive> m_dirsConst;
- public BundleRequirementImpl(
- BundleRevision revision, String namespace,
- Map<String, String> dirs, Map<String, Object> attrs)
+ public RequirementImpl(
+ Module module, String namespace,
+ List<Directive> dirs, List<Attribute> attrs)
{
- m_revision = revision;
+ m_module = module;
m_namespace = namespace;
- m_dirs = Collections.unmodifiableMap(dirs);
- m_attrs = Collections.unmodifiableMap(attrs);
+ m_dirs = dirs;
+ m_dirsConst = Collections.unmodifiableList(m_dirs);
m_filter = convertToFilter(attrs);
// Find resolution import directives.
boolean optional = false;
- if (m_dirs.containsKey(Constants.RESOLUTION_DIRECTIVE)
- && m_dirs.get(Constants.RESOLUTION_DIRECTIVE).equals(Constants.RESOLUTION_OPTIONAL))
+ for (int dirIdx = 0; dirIdx < m_dirs.size(); dirIdx++)
{
- optional = true;
+ if (m_dirs.get(dirIdx).getName().equals(Constants.RESOLUTION_DIRECTIVE))
+ {
+ optional = m_dirs.get(dirIdx).getValue().equals(Constants.RESOLUTION_OPTIONAL);
+ }
}
m_optional = optional;
}
+ public Module getModule()
+ {
+ return m_module;
+ }
+
public String getNamespace()
{
return m_namespace;
}
- public Map<String, String> getDirectives()
+ public SimpleFilter getFilter()
{
- return m_dirs;
- }
-
- public Map<String, Object> getAttributes()
- {
- return m_attrs;
- }
-
- public BundleRevision getRevision()
- {
- return m_revision;
- }
-
- public boolean matches(BundleCapability cap)
- {
- return CapabilitySet.matches((BundleCapabilityImpl) cap, getFilter());
+ return m_filter;
}
public boolean isOptional()
@@ -90,33 +80,45 @@
return m_optional;
}
- public SimpleFilter getFilter()
+ public Directive getDirective(String name)
{
- return m_filter;
+ for (int i = 0; i < m_dirs.size(); i++)
+ {
+ if (m_dirs.get(i).getName().equals(name))
+ {
+ return m_dirs.get(i);
+ }
+ }
+ return null;
+ }
+
+ public List<Directive> getDirectives()
+ {
+ return m_dirsConst;
}
public String toString()
{
- return "[" + m_revision + "] " + m_namespace + "; " + getFilter().toString();
+ return "[" + m_module + "] " + m_namespace + "; " + getFilter().toString();
}
- private static SimpleFilter convertToFilter(Map<String, Object> attrs)
+ private static SimpleFilter convertToFilter(List<Attribute> attrs)
{
// Rather than building a filter string to be parsed into a SimpleFilter,
// we will just create the parsed SimpleFilter directly.
List<SimpleFilter> filters = new ArrayList<SimpleFilter>();
- for (Entry<String, Object> entry : attrs.entrySet())
+ for (Attribute attr : attrs)
{
- if (entry.getValue() instanceof VersionRange)
+ if (attr.getValue() instanceof VersionRange)
{
- VersionRange vr = (VersionRange) entry.getValue();
+ VersionRange vr = (VersionRange) attr.getValue();
if (vr.isFloorInclusive())
{
filters.add(
new SimpleFilter(
- entry.getKey(),
+ attr.getName(),
vr.getFloor().toString(),
SimpleFilter.GTE));
}
@@ -126,7 +128,7 @@
new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT);
((List) not.getValue()).add(
new SimpleFilter(
- entry.getKey(),
+ attr.getName(),
vr.getFloor().toString(),
SimpleFilter.LTE));
filters.add(not);
@@ -138,7 +140,7 @@
{
filters.add(
new SimpleFilter(
- entry.getKey(),
+ attr.getName(),
vr.getCeiling().toString(),
SimpleFilter.LTE));
}
@@ -148,7 +150,7 @@
new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT);
((List) not.getValue()).add(
new SimpleFilter(
- entry.getKey(),
+ attr.getName(),
vr.getCeiling().toString(),
SimpleFilter.GTE));
filters.add(not);
@@ -157,12 +159,12 @@
}
else
{
- List<String> values = SimpleFilter.parseSubstring(entry.getValue().toString());
+ List<String> values = SimpleFilter.parseSubstring(attr.getValue().toString());
if (values.size() > 1)
{
filters.add(
new SimpleFilter(
- entry.getKey(),
+ attr.getName(),
values,
SimpleFilter.SUBSTRING));
}
@@ -170,7 +172,7 @@
{
filters.add(
new SimpleFilter(
- entry.getKey(),
+ attr.getName(),
values.get(0),
SimpleFilter.EQ));
}
diff --git a/framework/src/main/java/org/apache/felix/framework/wiring/BundleCapabilityImpl.java b/framework/src/main/java/org/apache/felix/framework/wiring/BundleCapabilityImpl.java
deleted file mode 100644
index e8ffef7..0000000
--- a/framework/src/main/java/org/apache/felix/framework/wiring/BundleCapabilityImpl.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * 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.wiring;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Collections;
-import java.util.Set;
-import java.util.Map;
-import java.util.List;
-import java.util.StringTokenizer;
-import org.apache.felix.framework.capabilityset.SimpleFilter;
-import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.util.manifestparser.ManifestParser;
-import org.osgi.framework.Constants;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-
-public class BundleCapabilityImpl implements BundleCapability
-{
- public static final String BUNDLE_NAMESPACE = "module";
- public static final String HOST_NAMESPACE = "host";
- public static final String PACKAGE_NAMESPACE = "package";
- public static final String SINGLETON_NAMESPACE = "singleton";
-
- public static final String PACKAGE_ATTR = "package";
- public static final String VERSION_ATTR = "version";
-
- private final BundleRevision m_revision;
- private final String m_namespace;
- private final Map<String, String> m_dirs;
- private final Map<String, Object> m_attrs;
- private final List<String> m_uses;
- private final List<List<String>> m_includeFilter;
- private final List<List<String>> m_excludeFilter;
- private final Set<String> m_mandatory;
-
- public BundleCapabilityImpl(BundleRevision revision, String namespace,
- Map<String, String> dirs, Map<String, Object> attrs)
- {
- m_namespace = namespace;
- m_revision = revision;
- m_dirs = Collections.unmodifiableMap(dirs);
- m_attrs = Collections.unmodifiableMap(attrs);
-
- // Find all export directives: uses, mandatory, include, and exclude.
-
- m_uses = new ArrayList(0);
- String value = m_dirs.get(Constants.USES_DIRECTIVE);
- if (value != null)
- {
- // Parse these uses directive.
- StringTokenizer tok = new StringTokenizer(value, ",");
- while (tok.hasMoreTokens())
- {
- m_uses.add(tok.nextToken().trim());
- }
- }
-
- value = m_dirs.get(Constants.INCLUDE_DIRECTIVE);
- if (value != null)
- {
- List<String> filters = ManifestParser.parseDelimitedString(value, ",");
- m_includeFilter = new ArrayList<List<String>>(filters.size());
- for (int filterIdx = 0; filterIdx < filters.size(); filterIdx++)
- {
- List<String> substrings = SimpleFilter.parseSubstring(filters.get(filterIdx));
- m_includeFilter.add(substrings);
- }
- }
- else
- {
- m_includeFilter = null;
- }
-
- value = m_dirs.get(Constants.EXCLUDE_DIRECTIVE);
- if (value != null)
- {
- List<String> filters = ManifestParser.parseDelimitedString(value, ",");
- m_excludeFilter = new ArrayList<List<String>>(filters.size());
- for (int filterIdx = 0; filterIdx < filters.size(); filterIdx++)
- {
- List<String> substrings = SimpleFilter.parseSubstring(filters.get(filterIdx));
- m_excludeFilter.add(substrings);
- }
- }
- else
- {
- m_excludeFilter = null;
- }
-
- m_mandatory = new HashSet<String>(0);
- value = m_dirs.get(Constants.MANDATORY_DIRECTIVE);
- if (value != null)
- {
- List<String> names = ManifestParser.parseDelimitedString(value, ",");
- for (String name : names)
- {
- // If attribute exists, then record it as mandatory.
- if (m_attrs.containsKey(name))
- {
- m_mandatory.add(name);
- }
- // Otherwise, report an error.
- else
- {
- throw new IllegalArgumentException(
- "Mandatory attribute '" + name + "' does not exist.");
- }
- }
- }
- }
-
- public BundleRevision getRevision()
- {
- return m_revision;
- }
-
- public String getNamespace()
- {
- return m_namespace;
- }
-
- public Map<String, String> getDirectives()
- {
- return m_dirs;
- }
-
- public Map<String, Object> getAttributes()
- {
- return m_attrs;
- }
-
- public boolean isAttributeMandatory(String name)
- {
- return !m_mandatory.isEmpty() && m_mandatory.contains(name);
- }
-
- public List<String> getUses()
- {
- return m_uses;
- }
-
- public boolean isIncluded(String name)
- {
- if ((m_includeFilter == null) && (m_excludeFilter == null))
- {
- return true;
- }
-
- // Get the class name portion of the target class.
- String className = Util.getClassName(name);
-
- // If there are no include filters then all classes are included
- // by default, otherwise try to find one match.
- boolean included = (m_includeFilter == null);
- for (int i = 0;
- (!included) && (m_includeFilter != null) && (i < m_includeFilter.size());
- i++)
- {
- included = SimpleFilter.compareSubstring(m_includeFilter.get(i), className);
- }
-
- // If there are no exclude filters then no classes are excluded
- // by default, otherwise try to find one match.
- boolean excluded = false;
- for (int i = 0;
- (!excluded) && (m_excludeFilter != null) && (i < m_excludeFilter.size());
- i++)
- {
- excluded = SimpleFilter.compareSubstring(m_excludeFilter.get(i), className);
- }
- return included && !excluded;
- }
-
- public String toString()
- {
- if (m_revision == null)
- {
- return m_attrs.toString();
- }
- if (m_namespace.equals(PACKAGE_NAMESPACE))
- {
- return "[" + m_revision + "] "
- + m_namespace + "; " + m_attrs.get(PACKAGE_ATTR);
- }
- return "[" + m_revision + "] " + m_namespace + "; " + m_attrs;
- }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/wiring/BundleWireImpl.java b/framework/src/main/java/org/apache/felix/framework/wiring/BundleWireImpl.java
deleted file mode 100644
index 2909b0a..0000000
--- a/framework/src/main/java/org/apache/felix/framework/wiring/BundleWireImpl.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.wiring;
-
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
-
-// TODO: OSGi R4.3 - Should this be in framework package?
-public class BundleWireImpl implements BundleWire
-{
- private final BundleRevision m_requirer;
- private final BundleRequirement m_req;
- private final BundleRevision m_provider;
- private final BundleCapability m_cap;
-
- public BundleWireImpl(BundleRevision requirer, BundleRequirement req,
- BundleRevision provider, BundleCapability cap)
- {
- m_requirer = requirer;
- m_req = req;
- m_provider = provider;
- m_cap = cap;
- }
-
- public BundleWiring getRequirerWiring()
- {
- return m_requirer.getWiring();
- }
-
- public BundleRequirement getRequirement()
- {
- return m_req;
- }
-
- public BundleWiring getProviderWiring()
- {
- return m_provider.getWiring();
- }
-
- public BundleCapability getCapability()
- {
- return m_cap;
- }
-
- public String toString()
- {
- return "[" + m_requirer + "] "
- + m_req
- + " -> "
- + "[" + m_provider + "]";
- }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/osgi/framework/AdaptPermission.java b/framework/src/main/java/org/osgi/framework/AdaptPermission.java
deleted file mode 100644
index f95c1fe..0000000
--- a/framework/src/main/java/org/osgi/framework/AdaptPermission.java
+++ /dev/null
@@ -1,635 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
- *
- * Licensed 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.osgi.framework;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.ObjectStreamField;
-import java.security.AccessController;
-import java.security.BasicPermission;
-import java.security.Permission;
-import java.security.PermissionCollection;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A bundle's authority to adapt an object to a type.
- *
- * <p>
- * {@code AdaptPermission} has one action: {@code adapt}.
- *
- * @ThreadSafe
- * @version $Id: bc4c5d392d2534a7744f6fc00f4665502f82033c $
- */
-public class AdaptPermission extends BasicPermission {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * The action string {@code initiate}.
- */
- public final static String ADAPT = "adapt";
-
- private final static int ACTION_ADAPT = 0x00000001;
- private final static int ACTION_ALL = ACTION_ADAPT;
- final static int ACTION_NONE = 0;
-
- /**
- * The actions mask.
- */
- transient int action_mask;
-
- /**
- * The actions in canonical form.
- *
- * @serial
- */
- private volatile String actions = null;
-
- /**
- * The bundle used by this AdaptPermission.
- */
- transient final Bundle bundle;
-
- /**
- * This holds a Filter matching object used to evaluate the filter in
- * implies.
- */
- transient Filter filter;
-
- /**
- * This map holds the properties of the permission, used to match a filter
- * in implies. This is not initialized until necessary, and then cached in
- * this object.
- */
- private transient volatile Map<String, Object> properties;
-
- /**
- * Creates a new granted {@code AdaptPermission} object.
- *
- * This constructor must only be used to create a permission that is going
- * to be checked.
- * <p>
- * Examples:
- *
- * <pre>
- * (adaptClass=com.acme.*)
- * (&(signer=\*,o=ACME,c=US)(adaptClass=com.acme.*))
- * (signer=\*,o=ACME,c=US)
- * </pre>
- *
- * <p>
- * When a signer key is used within the filter expression the signer value
- * must escape the special filter chars ('*', '(', ')').
- * <p>
- * The name is specified as a filter expression. The filter gives access to
- * the following attributes:
- * <ul>
- * <li>signer - A Distinguished Name chain used to sign the exporting
- * bundle. Wildcards in a DN are not matched according to the filter string
- * rules, but according to the rules defined for a DN chain.</li>
- * <li>location - The location of the exporting bundle.</li>
- * <li>id - The bundle ID of the exporting bundle.</li>
- * <li>name - The symbolic name of the exporting bundle.</li>
- * <li>adaptClass - The name of the type to which an object can be adapted.</li>
- * </ul>
- * Filter attribute names are processed in a case sensitive manner.
- *
- * @param filter A filter expression. Filter attribute names are processed
- * in a case sensitive manner. A special value of {@code "*"} can be
- * used to match all adaptations.
- * @param actions {@code adapt}.
- * @throws IllegalArgumentException If the filter has an invalid syntax.
- */
- public AdaptPermission(String filter, String actions) {
- this(parseFilter(filter), parseActions(actions));
- }
-
- /**
- * Creates a new requested {@code AdaptPermission} object to be used by the
- * code that must perform {@code checkPermission}. {@code AdaptPermission}
- * objects created with this constructor cannot be added to an
- * {@code AdaptPermission} permission collection.
- *
- * @param adaptClass The name of the type to which an object can be adapted.
- * @param adaptableBundle The bundle associated with the object being
- * adapted.
- * @param actions {@code adapt}.
- */
- public AdaptPermission(String adaptClass, Bundle adaptableBundle,
- String actions) {
- super(adaptClass);
- setTransients(null, parseActions(actions));
- this.bundle = adaptableBundle;
- if (adaptClass == null) {
- throw new NullPointerException("adaptClass must not be null");
- }
- if (adaptableBundle == null) {
- throw new NullPointerException("adaptableBundle must not be null");
- }
- }
-
- /**
- * Package private constructor used by AdaptPermissionCollection.
- *
- * @param filter name filter
- * @param mask action mask
- */
- AdaptPermission(Filter filter, int mask) {
- super((filter == null) ? "*" : filter.toString());
- setTransients(filter, mask);
- this.bundle = null;
- }
-
- /**
- * Called by constructors and when deserialized.
- *
- * @param filter Permission's filter or {@code null} for wildcard.
- * @param mask action mask
- */
- private void setTransients(Filter filter, int mask) {
- this.filter = filter;
- if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
- throw new IllegalArgumentException("invalid action string");
- }
- this.action_mask = mask;
- }
-
- /**
- * Parse action string into action mask.
- *
- * @param actions Action string.
- * @return action mask.
- */
- private static int parseActions(String actions) {
- boolean seencomma = false;
-
- int mask = ACTION_NONE;
-
- if (actions == null) {
- return mask;
- }
-
- char[] a = actions.toCharArray();
-
- int i = a.length - 1;
- if (i < 0)
- return mask;
-
- while (i != -1) {
- char c;
-
- // skip whitespace
- while ((i != -1)
- && ((c = a[i]) == ' ' || c == '\r' || c == '\n'
- || c == '\f' || c == '\t'))
- i--;
-
- // check for the known strings
- int matchlen;
-
- if (i >= 4 && (a[i - 4] == 'a' || a[i - 4] == 'A')
- && (a[i - 3] == 'd' || a[i - 3] == 'D')
- && (a[i - 2] == 'a' || a[i - 2] == 'A')
- && (a[i - 1] == 'p' || a[i - 1] == 'P')
- && (a[i] == 't' || a[i] == 'T')) {
- matchlen = 5;
- mask |= ACTION_ADAPT;
-
- }
- else {
- // parse error
- throw new IllegalArgumentException("invalid actions: "
- + actions);
- }
-
- // make sure we didn't just match the tail of a word
- // like "ackbarfadapt". Also, skip to the comma.
- seencomma = false;
- while (i >= matchlen && !seencomma) {
- switch (a[i - matchlen]) {
- case ',' :
- seencomma = true;
- /* FALLTHROUGH */
- case ' ' :
- case '\r' :
- case '\n' :
- case '\f' :
- case '\t' :
- break;
- default :
- throw new IllegalArgumentException(
- "invalid permission: " + actions);
- }
- i--;
- }
-
- // point i at the location of the comma minus one (or -1).
- i -= matchlen;
- }
-
- if (seencomma) {
- throw new IllegalArgumentException("invalid actions: " + actions);
- }
-
- return mask;
- }
-
- /**
- * Parse filter string into a Filter object.
- *
- * @param filterString The filter string to parse.
- * @return a Filter for this bundle.
- * @throws IllegalArgumentException If the filter syntax is invalid.
- */
- private static Filter parseFilter(String filterString) {
- filterString = filterString.trim();
- if (filterString.equals("*")) {
- return null;
- }
- try {
- return FrameworkUtil.createFilter(filterString);
- }
- catch (InvalidSyntaxException e) {
- IllegalArgumentException iae = new IllegalArgumentException(
- "invalid filter");
- iae.initCause(e);
- throw iae;
- }
- }
-
- /**
- * Determines if the specified permission is implied by this object.
- *
- * <p>
- * This method checks that the filter of the target is implied by the adapt
- * class name of this object. The list of {@code AdaptPermission} actions
- * must either match or allow for the list of the target object to imply the
- * target {@code AdaptPermission} action.
- * <p>
- *
- * @param p The requested permission.
- * @return {@code true} if the specified permission is implied by this
- * object; {@code false} otherwise.
- */
- public boolean implies(Permission p) {
- if (!(p instanceof AdaptPermission)) {
- return false;
- }
- AdaptPermission requested = (AdaptPermission) p;
- if (bundle != null) {
- return false;
- }
- // if requested permission has a filter, then it is an invalid argument
- if (requested.filter != null) {
- return false;
- }
- return implies0(requested, ACTION_NONE);
- }
-
- /**
- * Internal implies method. Used by the implies and the permission
- * collection implies methods.
- *
- * @param requested The requested AdaptPermission which has already be
- * validated as a proper argument. The requested AdaptPermission must
- * not have a filter expression.
- * @param effective The effective actions with which to start.
- * @return {@code true} if the specified permission is implied by this
- * object; {@code false} otherwise.
- */
- boolean implies0(AdaptPermission requested, int effective) {
- /* check actions first - much faster */
- effective |= action_mask;
- final int desired = requested.action_mask;
- if ((effective & desired) != desired) {
- return false;
- }
- /* Get filter */
- Filter f = filter;
- if (f == null) {
- // it's "*"
- return true;
- }
- return f.matches(requested.getProperties());
- }
-
- /**
- * Returns the canonical string representation of the
- * {@code AdaptPermission} actions.
- *
- * <p>
- * Always returns present {@code AdaptPermission} actions in the following
- * order: {@code adapt}.
- *
- * @return Canonical string representation of the {@code AdaptPermission}
- * actions.
- */
- public String getActions() {
- String result = actions;
- if (result == null) {
- actions = result = ADAPT;
- }
- return result;
- }
-
- /**
- * Returns a new {@code PermissionCollection} object suitable for storing
- * {@code AdaptPermission} objects.
- *
- * @return A new {@code PermissionCollection} object.
- */
- public PermissionCollection newPermissionCollection() {
- return new AdaptPermissionCollection();
- }
-
- /**
- * Determines the equality of two {@code AdaptPermission} objects.
- *
- * This method checks that specified permission has the same name and
- * {@code AdaptPermission} actions as this {@code AdaptPermission} object.
- *
- * @param obj The object to test for equality with this
- * {@code AdaptPermission} object.
- * @return {@code true} if {@code obj} is a {@code AdaptPermission}, and has
- * the same name and actions as this {@code AdaptPermission} object;
- * {@code false} otherwise.
- */
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
-
- if (!(obj instanceof AdaptPermission)) {
- return false;
- }
-
- AdaptPermission cp = (AdaptPermission) obj;
-
- return (action_mask == cp.action_mask)
- && getName().equals(cp.getName())
- && ((bundle == cp.bundle) || ((bundle != null) && bundle
- .equals(cp.bundle)));
- }
-
- /**
- * Returns the hash code value for this object.
- *
- * @return A hash code value for this object.
- */
- public int hashCode() {
- int h = 31 * 17 + getName().hashCode();
- h = 31 * h + getActions().hashCode();
- if (bundle != null) {
- h = 31 * h + bundle.hashCode();
- }
- return h;
- }
-
- /**
- * WriteObject is called to save the state of this permission object to a
- * stream. The actions are serialized, and the superclass takes care of the
- * name.
- */
- private synchronized void writeObject(java.io.ObjectOutputStream s)
- throws IOException {
- if (bundle != null) {
- throw new NotSerializableException("cannot serialize");
- }
- // Write out the actions. The superclass takes care of the name
- // call getActions to make sure actions field is initialized
- if (actions == null)
- getActions();
- s.defaultWriteObject();
- }
-
- /**
- * readObject is called to restore the state of this permission from a
- * stream.
- */
- private synchronized void readObject(java.io.ObjectInputStream s)
- throws IOException, ClassNotFoundException {
- // Read in the action, then initialize the rest
- s.defaultReadObject();
- setTransients(parseFilter(getName()), parseActions(actions));
- }
-
- /**
- * Called by {@code <@link AdaptPermission#implies(Permission)>}. This
- * method is only called on a requested permission which cannot have a
- * filter set.
- *
- * @return a map of properties for this permission.
- */
- private Map<String, Object> getProperties() {
- Map<String, Object> result = properties;
- if (result != null) {
- return result;
- }
- final Map<String, Object> map = new HashMap<String, Object>(5);
- map.put("adaptClass", getName());
- if (bundle != null) {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- map.put("id", new Long(bundle.getBundleId()));
- map.put("location", bundle.getLocation());
- String name = bundle.getSymbolicName();
- if (name != null) {
- map.put("name", name);
- }
- SignerProperty signer = new SignerProperty(bundle);
- if (signer.isBundleSigned()) {
- map.put("signer", signer);
- }
- return null;
- }
- });
- }
- return properties = map;
- }
-}
-
-/**
- * Stores a set of {@code AdaptPermission} permissions.
- *
- * @see java.security.Permission
- * @see java.security.Permissions
- * @see java.security.PermissionCollection
- */
-
-final class AdaptPermissionCollection extends PermissionCollection {
- static final long serialVersionUID = -3350758995234427603L;
- /**
- * Collection of permissions.
- *
- * @serial
- * @GuardedBy this
- */
- private Map<String, AdaptPermission> permissions;
-
- /**
- * Boolean saying if "*" is in the collection.
- *
- * @serial
- * @GuardedBy this
- */
- private boolean all_allowed;
-
- /**
- * Create an empty AdaptPermissions object.
- */
- public AdaptPermissionCollection() {
- permissions = new HashMap<String, AdaptPermission>();
- all_allowed = false;
- }
-
- /**
- * Adds a permission to this permission collection.
- *
- * @param permission The {@code AdaptPermission} object to add.
- * @throws IllegalArgumentException If the specified permission is not a
- * {@code AdaptPermission} instance or was constructed with a Bundle
- * object.
- * @throws SecurityException If this {@code AdaptPermissionCollection}
- * object has been marked read-only.
- */
- public void add(final Permission permission) {
- if (!(permission instanceof AdaptPermission)) {
- throw new IllegalArgumentException("invalid permission: "
- + permission);
- }
- if (isReadOnly()) {
- throw new SecurityException("attempt to add a Permission to a "
- + "readonly PermissionCollection");
- }
-
- final AdaptPermission ap = (AdaptPermission) permission;
- if (ap.bundle != null) {
- throw new IllegalArgumentException("cannot add to collection: "
- + ap);
- }
-
- final String name = ap.getName();
- synchronized (this) {
- Map<String, AdaptPermission> pc = permissions;
- final AdaptPermission existing = pc.get(name);
- if (existing != null) {
- final int oldMask = existing.action_mask;
- final int newMask = ap.action_mask;
- if (oldMask != newMask) {
- pc.put(name, new AdaptPermission(existing.filter, oldMask
- | newMask));
-
- }
- }
- else {
- pc.put(name, ap);
- }
-
- if (!all_allowed) {
- if (name.equals("*")) {
- all_allowed = true;
- }
- }
- }
- }
-
- /**
- * Determines if the specified permissions implies the permissions expressed
- * in {@code permission}.
- *
- * @param permission The Permission object to compare with this
- * {@code AdaptPermission} object.
- * @return {@code true} if {@code permission} is a proper subset of a
- * permission in the set; {@code false} otherwise.
- */
- public boolean implies(final Permission permission) {
- if (!(permission instanceof AdaptPermission)) {
- return false;
- }
- final AdaptPermission requested = (AdaptPermission) permission;
- /* if requested permission has a filter, then it is an invalid argument */
- if (requested.filter != null) {
- return false;
- }
-
- int effective = AdaptPermission.ACTION_NONE;
-
- Collection<AdaptPermission> perms;
- synchronized (this) {
- Map<String, AdaptPermission> pc = permissions;
- /* short circuit if the "*" Permission was added */
- if (all_allowed) {
- AdaptPermission ap = pc.get("*");
- if (ap != null) {
- effective |= ap.action_mask;
- final int desired = requested.action_mask;
- if ((effective & desired) == desired) {
- return true;
- }
- }
- }
- perms = pc.values();
- }
- /* iterate one by one over filteredPermissions */
- for (AdaptPermission perm : perms) {
- if (perm.implies0(requested, effective)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns an enumeration of all {@code AdaptPermission} objects in the
- * container.
- *
- * @return Enumeration of all {@code AdaptPermission} objects.
- */
- public synchronized Enumeration<Permission> elements() {
- List<Permission> all = new ArrayList<Permission>(permissions.values());
- return Collections.enumeration(all);
- }
-
- /* serialization logic */
- private static final ObjectStreamField[] serialPersistentFields = {
- new ObjectStreamField("permissions", HashMap.class),
- new ObjectStreamField("all_allowed", Boolean.TYPE) };
-
- private synchronized void writeObject(ObjectOutputStream out)
- throws IOException {
- ObjectOutputStream.PutField pfields = out.putFields();
- pfields.put("permissions", permissions);
- pfields.put("all_allowed", all_allowed);
- out.writeFields();
- }
-
- private synchronized void readObject(java.io.ObjectInputStream in)
- throws IOException, ClassNotFoundException {
- ObjectInputStream.GetField gfields = in.readFields();
- permissions = (HashMap<String, AdaptPermission>) gfields.get(
- "permissions", null);
- all_allowed = gfields.get("all_allowed", false);
- }
-}
diff --git a/framework/src/main/java/org/osgi/framework/AdminPermission.java b/framework/src/main/java/org/osgi/framework/AdminPermission.java
index fc7b1f4..1811791 100644
--- a/framework/src/main/java/org/osgi/framework/AdminPermission.java
+++ b/framework/src/main/java/org/osgi/framework/AdminPermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,13 +26,13 @@
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
-import java.util.List;
+import java.util.Iterator;
import java.util.Map;
/**
@@ -45,7 +45,7 @@
* class Bundle.loadClass
* execute Bundle.start
* Bundle.stop
- * BundleStartLevel.setStartLevel
+ * StartLevel.setBundleStartLevel
* extensionLifecycle BundleContext.installBundle for extension bundles
* Bundle.update for extension bundles
* Bundle.uninstall for extension bundles
@@ -56,25 +56,23 @@
* BundleContext.removeBundleListener for SynchronousBundleListener
* metadata Bundle.getHeaders
* Bundle.getLocation
- * resolve FrameworkWiring.refreshBundles
- * FrameworkWiring.resolveBundles
+ * resolve PackageAdmin.refreshPackages
+ * PackageAdmin.resolveBundles
* resource Bundle.getResource
* Bundle.getResources
* Bundle.getEntry
* Bundle.getEntryPaths
* Bundle.findEntries
* Bundle resource/entry URL creation
- * startlevel FrameworkStartLevel.setStartLevel
- * FrameworkStartLevel.setInitialBundleStartLevel
+ * startlevel StartLevel.setStartLevel
+ * StartLevel.setInitialBundleStartLevel
* context Bundle.getBundleContext
- * weave WovenClass.setBytes
- * WovenClass.getDynamicImports for modification
* </pre>
*
* <p>
* The special action "*" will represent all actions. The
- * {@code resolve} action is implied by the {@code class}, {@code execute} and
- * {@code resource} actions.
+ * <code>resolve</code> action is implied by the <code>class</code>,
+ * <code>execute</code> and <code>resource</code> actions.
* <p>
* The name of this permission is a filter expression. The filter gives access
* to the following attributes:
@@ -89,86 +87,79 @@
* Filter attribute names are processed in a case sensitive manner.
*
* @ThreadSafe
- * @version $Id: 43baf9a6d7ce5e6108507834e841e340fd91c513 $
+ * @version $Revision: 7743 $
*/
public final class AdminPermission extends BasicPermission {
static final long serialVersionUID = 307051004521261705L;
/**
- * The action string {@code class}. The {@code class} action
- * implies the {@code resolve} action.
+ * The action string <code>class</code>. The <code>class</code> action
+ * implies the <code>resolve</code> action.
*
* @since 1.3
*/
public final static String CLASS = "class";
/**
- * The action string {@code execute}. The {@code execute} action
- * implies the {@code resolve} action.
+ * The action string <code>execute</code>. The <code>execute</code> action
+ * implies the <code>resolve</code> action.
*
* @since 1.3
*/
public final static String EXECUTE = "execute";
/**
- * The action string {@code extensionLifecycle}.
+ * The action string <code>extensionLifecycle</code>.
*
* @since 1.3
*/
public final static String EXTENSIONLIFECYCLE = "extensionLifecycle";
/**
- * The action string {@code lifecycle}.
+ * The action string <code>lifecycle</code>.
*
* @since 1.3
*/
public final static String LIFECYCLE = "lifecycle";
/**
- * The action string {@code listener}.
+ * The action string <code>listener</code>.
*
* @since 1.3
*/
public final static String LISTENER = "listener";
/**
- * The action string {@code metadata}.
+ * The action string <code>metadata</code>.
*
* @since 1.3
*/
public final static String METADATA = "metadata";
/**
- * The action string {@code resolve}. The {@code resolve} action
- * is implied by the {@code class}, {@code execute} and
- * {@code resource} actions.
+ * The action string <code>resolve</code>. The <code>resolve</code> action
+ * is implied by the <code>class</code>, <code>execute</code> and
+ * <code>resource</code> actions.
*
* @since 1.3
*/
public final static String RESOLVE = "resolve";
/**
- * The action string {@code resource}. The {@code resource} action
- * implies the {@code resolve} action.
+ * The action string <code>resource</code>. The <code>resource</code> action
+ * implies the <code>resolve</code> action.
*
* @since 1.3
*/
public final static String RESOURCE = "resource";
/**
- * The action string {@code startlevel}.
+ * The action string <code>startlevel</code>.
*
* @since 1.3
*/
public final static String STARTLEVEL = "startlevel";
/**
- * The action string {@code context}.
+ * The action string <code>context</code>.
*
* @since 1.4
*/
public final static String CONTEXT = "context";
- /**
- * The action string {@code weave}.
- *
- * @since 1.6
- */
- public final static String WEAVE = "weave";
-
private final static int ACTION_CLASS = 0x00000001;
private final static int ACTION_EXECUTE = 0x00000002;
private final static int ACTION_LIFECYCLE = 0x00000004;
@@ -179,7 +170,6 @@
private final static int ACTION_STARTLEVEL = 0x00000100;
private final static int ACTION_EXTENSIONLIFECYCLE = 0x00000200;
private final static int ACTION_CONTEXT = 0x00000400;
- private final static int ACTION_WEAVE = 0x00000800;
private final static int ACTION_ALL = ACTION_CLASS
| ACTION_EXECUTE
| ACTION_LIFECYCLE
@@ -189,8 +179,7 @@
| ACTION_RESOURCE
| ACTION_STARTLEVEL
| ACTION_EXTENSIONLIFECYCLE
- | ACTION_CONTEXT
- | ACTION_WEAVE;
+ | ACTION_CONTEXT;
final static int ACTION_NONE = 0;
/**
@@ -214,23 +203,23 @@
/**
* The bundle governed by this AdminPermission - only used if filter == null
*/
- transient final Bundle bundle;
+ transient final Bundle bundle;
/**
- * This map holds the properties of the permission, used to match a filter
- * in implies. This is not initialized until necessary, and then cached in
- * this object.
+ * This dictionary holds the properties of the permission, used to match a
+ * filter in implies. This is not initialized until necessary, and then
+ * cached in this object.
*/
- private transient volatile Map<String, Object> properties;
+ private transient volatile Dictionary properties;
/**
* ThreadLocal used to determine if we have recursively called
* getProperties.
*/
- private static final ThreadLocal<Bundle> recurse = new ThreadLocal<Bundle>();
+ private static final ThreadLocal recurse = new ThreadLocal();
/**
- * Creates a new {@code AdminPermission} object that matches all
+ * Creates a new <code>AdminPermission</code> object that matches all
* bundles and has all actions. Equivalent to AdminPermission("*","*");
*/
public AdminPermission() {
@@ -258,13 +247,14 @@
* Null arguments are equivalent to "*".
*
* @param filter A filter expression that can use signer, location, id, and
- * name keys. A value of "*" or {@code null} matches all
- * bundle. Filter attribute names are processed in a case sensitive
- * manner.
- * @param actions {@code class}, {@code execute}, {@code extensionLifecycle}
- * , {@code lifecycle}, {@code listener}, {@code metadata},
- * {@code resolve} , {@code resource}, {@code startlevel},
- * {@code context} or {@code weave}. A value of "*" or {@code null}
+ * name keys. A value of "*" or <code>null</code> matches
+ * all bundle. Filter attribute names are processed in a case
+ * sensitive manner.
+ * @param actions <code>class</code>, <code>execute</code>,
+ * <code>extensionLifecycle</code>, <code>lifecycle</code>,
+ * <code>listener</code>, <code>metadata</code>, <code>resolve</code>
+ * , <code>resource</code>, <code>startlevel</code> or
+ * <code>context</code>. A value of "*" or <code>null</code>
* indicates all actions.
* @throws IllegalArgumentException If the filter has an invalid syntax.
*/
@@ -275,16 +265,17 @@
}
/**
- * Creates a new requested {@code AdminPermission} object to be used by the
- * code that must perform {@code checkPermission}. {@code AdminPermission}
- * objects created with this constructor cannot be added to an
- * {@code AdminPermission} permission collection.
+ * Creates a new requested <code>AdminPermission</code> object to be used by
+ * the code that must perform <code>checkPermission</code>.
+ * <code>AdminPermission</code> objects created with this constructor cannot
+ * be added to an <code>AdminPermission</code> permission collection.
*
* @param bundle A bundle.
- * @param actions {@code class}, {@code execute}, {@code extensionLifecycle}
- * , {@code lifecycle}, {@code listener}, {@code metadata},
- * {@code resolve} , {@code resource}, {@code startlevel},
- * {@code context}, {@code weave}. A value of "*" or {@code null}
+ * @param actions <code>class</code>, <code>execute</code>,
+ * <code>extensionLifecycle</code>, <code>lifecycle</code>,
+ * <code>listener</code>, <code>metadata</code>, <code>resolve</code>
+ * , <code>resource</code>, <code>startlevel</code>,
+ * <code>context</code>. A value of "*" or <code>null</code>
* indicates all actions.
* @since 1.3
*/
@@ -313,7 +304,7 @@
/**
* Package private constructor used by AdminPermissionCollection.
*
- * @param filter name filter or {@code null} for wildcard.
+ * @param filter name filter or <code>null</code> for wildcard.
* @param mask action mask
*/
AdminPermission(Filter filter, int mask) {
@@ -325,7 +316,7 @@
/**
* Called by constructors and when deserialized.
*
- * @param filter Permission's filter or {@code null} for wildcard.
+ * @param filter Permission's filter or <code>null</code> for wildcard.
* @param mask action mask
*/
private void setTransients(Filter filter, int mask) {
@@ -350,7 +341,11 @@
boolean seencomma = false;
int mask = ACTION_NONE;
-
+
+ if (actions == null) {
+ return mask;
+ }
+
char[] a = actions.toCharArray();
int i = a.length - 1;
@@ -512,29 +507,19 @@
}
else
- if (i >= 4
- && (a[i - 4] == 'w' || a[i - 4] == 'W')
- && (a[i - 3] == 'e' || a[i - 3] == 'E')
- && (a[i - 2] == 'a' || a[i - 2] == 'A')
- && (a[i - 1] == 'v' || a[i - 1] == 'V')
- && (a[i] == 'e' || a[i] == 'E')) {
- matchlen = 5;
- mask |= ACTION_WEAVE;
-
+ if (i >= 0 &&
+
+ (a[i] == '*')) {
+ matchlen = 1;
+ mask |= ACTION_ALL;
+
}
- else
- if (i >= 0
- && (a[i] == '*')) {
- matchlen = 1;
- mask |= ACTION_ALL;
-
- }
- else {
- // parse error
- throw new IllegalArgumentException(
- "invalid permission: "
- + actions);
- }
+ else {
+ // parse error
+ throw new IllegalArgumentException(
+ "invalid permission: "
+ + actions);
+ }
// make sure we didn't just match the tail of a word
// like "ackbarfstartlevel". Also, skip to the comma.
@@ -574,7 +559,7 @@
*
* @param filterString The filter string to parse.
* @return a Filter for this bundle. If the specified filterString is
- * {@code null} or equals "*", then {@code null} is
+ * <code>null</code> or equals "*", then <code>null</code> is
* returned to indicate a wildcard.
* @throws IllegalArgumentException If the filter syntax is invalid.
*/
@@ -604,7 +589,7 @@
* constructed with a bundle.
*
* <p>
- * This method returns {@code true} if the specified permission is an
+ * This method returns <code>true</code> if the specified permission is an
* AdminPermission AND
* <ul>
* <li>this object's filter matches the specified permission's bundle ID,
@@ -616,13 +601,13 @@
* actions.
* <p>
* Special case: if the specified permission was constructed with "*"
- * filter, then this method returns {@code true} if this object's
+ * filter, then this method returns <code>true</code> if this object's
* filter is "*" and this object's actions include all of the specified
* permission's actions
*
* @param p The requested permission.
- * @return {@code true} if the specified permission is implied by this
- * object; {@code false} otherwise.
+ * @return <code>true</code> if the specified permission is implied by this
+ * object; <code>false</code> otherwise.
*/
public boolean implies(Permission p) {
if (!(p instanceof AdminPermission)) {
@@ -647,8 +632,8 @@
* validated as a proper argument. The requested AdminPermission must
* not have a filter expression.
* @param effective The effective actions with which to start.
- * @return {@code true} if the specified permission is implied by this
- * object; {@code false} otherwise.
+ * @return <code>true</code> if the specified permission is implied by this
+ * object; <code>false</code> otherwise.
*/
boolean implies0(AdminPermission requested, int effective) {
/* check actions first - much faster */
@@ -668,8 +653,7 @@
if (requested.bundle == null) {
return false;
}
- Map<String, Object> requestedProperties = requested
- .getProperties();
+ Dictionary requestedProperties = requested.getProperties();
if (requestedProperties == null) {
/*
* If the requested properties are null, then we have detected a
@@ -679,21 +663,22 @@
*/
return true;
}
- return f.matches(requestedProperties);
+ return f.matchCase(requestedProperties);
}
/**
* Returns the canonical string representation of the
- * {@code AdminPermission} actions.
+ * <code>AdminPermission</code> actions.
*
* <p>
- * Always returns present {@code AdminPermission} actions in the following
- * order: {@code class}, {@code execute}, {@code extensionLifecycle},
- * {@code lifecycle}, {@code listener}, {@code metadata}, {@code resolve},
- * {@code resource}, {@code startlevel}, {@code context}, {@code weave}.
+ * Always returns present <code>AdminPermission</code> actions in the
+ * following order: <code>class</code>, <code>execute</code>,
+ * <code>extensionLifecycle</code>, <code>lifecycle</code>,
+ * <code>listener</code>, <code>metadata</code>, <code>resolve</code>,
+ * <code>resource</code>, <code>startlevel</code>, <code>context</code>.
*
- * @return Canonical string representation of the {@code AdminPermission}
- * actions.
+ * @return Canonical string representation of the
+ * <code>AdminPermission</code> actions.
*/
public String getActions() {
String result = actions;
@@ -750,11 +735,6 @@
sb.append(CONTEXT);
sb.append(',');
}
-
- if ((mask & ACTION_WEAVE) == ACTION_WEAVE) {
- sb.append(WEAVE);
- sb.append(',');
- }
// remove trailing comma
if (sb.length() > 0) {
@@ -767,21 +747,21 @@
}
/**
- * Returns a new {@code PermissionCollection} object suitable for
- * storing {@code AdminPermission}s.
+ * Returns a new <code>PermissionCollection</code> object suitable for
+ * storing <code>AdminPermission</code>s.
*
- * @return A new {@code PermissionCollection} object.
+ * @return A new <code>PermissionCollection</code> object.
*/
public PermissionCollection newPermissionCollection() {
return new AdminPermissionCollection();
}
/**
- * Determines the equality of two {@code AdminPermission} objects.
+ * Determines the equality of two <code>AdminPermission</code> objects.
*
* @param obj The object being compared for equality with this object.
- * @return {@code true} if {@code obj} is equivalent to this
- * {@code AdminPermission}; {@code false} otherwise.
+ * @return <code>true</code> if <code>obj</code> is equivalent to this
+ * <code>AdminPermission</code>; <code>false</code> otherwise.
*/
public boolean equals(Object obj) {
if (obj == this) {
@@ -844,18 +824,18 @@
}
/**
- * Called by {@code implies0} on an AdminPermission which was constructed
- * with a Bundle. This method loads a map with the filter-matchable
- * properties of this bundle. The map is cached so this lookup only happens
- * once.
+ * Called by <code>implies0</code> on an AdminPermission which was
+ * constructed with a Bundle. This method loads a dictionary with the
+ * filter-matchable properties of this bundle. The dictionary is cached so
+ * this lookup only happens once.
*
* This method should only be called on an AdminPermission which was
* constructed with a bundle
*
- * @return a map of properties for this bundle
+ * @return a dictionary of properties for this bundle
*/
- private Map<String, Object> getProperties() {
- Map<String, Object> result = properties;
+ private Dictionary getProperties() {
+ Dictionary result = properties;
if (result != null) {
return result;
}
@@ -870,24 +850,23 @@
}
recurse.set(bundle);
try {
- final Map<String, Object> map = new HashMap<String, Object>(
- 4);
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ final Dictionary dict = new Hashtable(4);
+ AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
- map.put("id", new Long(bundle.getBundleId()));
- map.put("location", bundle.getLocation());
+ dict.put("id", new Long(bundle.getBundleId()));
+ dict.put("location", bundle.getLocation());
String name = bundle.getSymbolicName();
if (name != null) {
- map.put("name", name);
+ dict.put("name", name);
}
SignerProperty signer = new SignerProperty(bundle);
if (signer.isBundleSigned()) {
- map.put("signer", signer);
+ dict.put("signer", signer);
}
return null;
}
});
- return properties = map;
+ return properties = dict;
}
finally {
recurse.set(null);
@@ -896,7 +875,7 @@
}
/**
- * Stores a collection of {@code AdminPermission}s.
+ * Stores a collection of <code>AdminPermission</code>s.
*/
final class AdminPermissionCollection extends PermissionCollection {
private static final long serialVersionUID = 3906372644575328048L;
@@ -905,7 +884,7 @@
*
* @GuardedBy this
*/
- private transient Map<String, AdminPermission> permissions;
+ private transient Map permissions;
/**
* Boolean saying if "*" is in the collection.
@@ -920,17 +899,17 @@
*
*/
public AdminPermissionCollection() {
- permissions = new HashMap<String, AdminPermission>();
+ permissions = new HashMap();
}
/**
* Adds a permission to this permission collection.
*
- * @param permission The {@code AdminPermission} object to add.
+ * @param permission The <code>AdminPermission</code> object to add.
* @throws IllegalArgumentException If the specified permission is not an
- * {@code AdminPermission} instance or was constructed with a
+ * <code>AdminPermission</code> instance or was constructed with a
* Bundle object.
- * @throws SecurityException If this {@code AdminPermissionCollection}
+ * @throws SecurityException If this <code>AdminPermissionCollection</code>
* object has been marked read-only.
*/
public void add(Permission permission) {
@@ -949,8 +928,8 @@
}
final String name = ap.getName();
synchronized (this) {
- Map<String, AdminPermission> pc = permissions;
- AdminPermission existing = pc.get(name);
+ Map pc = permissions;
+ AdminPermission existing = (AdminPermission) pc.get(name);
if (existing != null) {
int oldMask = existing.action_mask;
int newMask = ap.action_mask;
@@ -973,13 +952,13 @@
/**
* Determines if the specified permissions implies the permissions expressed
- * in {@code permission}.
+ * in <code>permission</code>.
*
* @param permission The Permission object to compare with the
- * {@code AdminPermission} objects in this collection.
- * @return {@code true} if {@code permission} is implied by an
- * {@code AdminPermission} in this collection,
- * {@code false} otherwise.
+ * <code>AdminPermission</code> objects in this collection.
+ * @return <code>true</code> if <code>permission</code> is implied by an
+ * <code>AdminPermission</code> in this collection,
+ * <code>false</code> otherwise.
*/
public boolean implies(Permission permission) {
if (!(permission instanceof AdminPermission)) {
@@ -992,12 +971,12 @@
return false;
}
int effective = AdminPermission.ACTION_NONE;
- Collection<AdminPermission> perms;
+ Collection perms;
synchronized (this) {
- Map<String, AdminPermission> pc = permissions;
+ Map pc = permissions;
// short circuit if the "*" Permission was added
if (all_allowed) {
- AdminPermission ap = pc.get("*");
+ AdminPermission ap = (AdminPermission) pc.get("*");
if (ap != null) {
effective |= ap.action_mask;
final int desired = requested.action_mask;
@@ -1010,8 +989,8 @@
}
// just iterate one by one
- for (AdminPermission perm : perms) {
- if (perm.implies0(requested, effective)) {
+ for (Iterator iter = perms.iterator(); iter.hasNext();) {
+ if (((AdminPermission) iter.next()).implies0(requested, effective)) {
return true;
}
}
@@ -1019,14 +998,13 @@
}
/**
- * Returns an enumeration of all {@code AdminPermission} objects in the
+ * Returns an enumeration of all <code>AdminPermission</code> objects in the
* container.
*
- * @return Enumeration of all {@code AdminPermission} objects.
+ * @return Enumeration of all <code>AdminPermission</code> objects.
*/
- public synchronized Enumeration<Permission> elements() {
- List<Permission> all = new ArrayList<Permission>(permissions.values());
- return Collections.enumeration(all);
+ public synchronized Enumeration elements() {
+ return Collections.enumeration(permissions.values());
}
/* serialization logic */
@@ -1036,21 +1014,19 @@
private synchronized void writeObject(ObjectOutputStream out)
throws IOException {
- Hashtable<String, AdminPermission> hashtable = new Hashtable<String, AdminPermission>(
- permissions);
+ Hashtable hashtable = new Hashtable(permissions);
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("permissions", hashtable);
pfields.put("all_allowed", all_allowed);
out.writeFields();
}
- private synchronized void readObject(java.io.ObjectInputStream in)
+ private synchronized void readObject(java.io.ObjectInputStream in)
throws IOException,
ClassNotFoundException {
ObjectInputStream.GetField gfields = in.readFields();
- Hashtable<String, AdminPermission> hashtable = (Hashtable<String, AdminPermission>) gfields
- .get("permissions", null);
- permissions = new HashMap<String, AdminPermission>(hashtable);
+ Hashtable hashtable = (Hashtable) gfields.get("permissions", null);
+ permissions = new HashMap(hashtable);
all_allowed = gfields.get("all_allowed", false);
}
}
diff --git a/framework/src/main/java/org/osgi/framework/AllServiceListener.java b/framework/src/main/java/org/osgi/framework/AllServiceListener.java
index 9874a4b..688f51e 100644
--- a/framework/src/main/java/org/osgi/framework/AllServiceListener.java
+++ b/framework/src/main/java/org/osgi/framework/AllServiceListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,35 +17,35 @@
package org.osgi.framework;
/**
- * A {@code ServiceEvent} listener that does not filter based upon
- * package wiring. {@code AllServiceListener} is a listener interface
+ * A <code>ServiceEvent</code> listener that does not filter based upon
+ * package wiring. <code>AllServiceListener</code> is a listener interface
* that may be implemented by a bundle developer. When a
- * {@code ServiceEvent} is fired, it is synchronously delivered to an
- * {@code AllServiceListener}. The Framework may deliver
- * {@code ServiceEvent} objects to an {@code AllServiceListener}
+ * <code>ServiceEvent</code> is fired, it is synchronously delivered to an
+ * <code>AllServiceListener</code>. The Framework may deliver
+ * <code>ServiceEvent</code> objects to an <code>AllServiceListener</code>
* out of order and may concurrently call and/or reenter an
- * {@code AllServiceListener}.
+ * <code>AllServiceListener</code>.
* <p>
- * An {@code AllServiceListener} object is registered with the Framework
- * using the {@code BundleContext.addServiceListener} method.
- * {@code AllServiceListener} objects are called with a
- * {@code ServiceEvent} object when a service is registered, modified, or
+ * An <code>AllServiceListener</code> object is registered with the Framework
+ * using the <code>BundleContext.addServiceListener</code> method.
+ * <code>AllServiceListener</code> objects are called with a
+ * <code>ServiceEvent</code> object when a service is registered, modified, or
* is in the process of unregistering.
*
* <p>
- * {@code ServiceEvent} object delivery to
- * {@code AllServiceListener} objects is filtered by the filter specified
+ * <code>ServiceEvent</code> object delivery to
+ * <code>AllServiceListener</code> objects is filtered by the filter specified
* when the listener was registered. If the Java Runtime Environment supports
- * permissions, then additional filtering is done. {@code ServiceEvent}
+ * permissions, then additional filtering is done. <code>ServiceEvent</code>
* objects are only delivered to the listener if the bundle which defines the
- * listener object's class has the appropriate {@code ServicePermission}
+ * listener object's class has the appropriate <code>ServicePermission</code>
* to get the service using at least one of the named classes under which the
* service was registered.
*
* <p>
- * Unlike normal {@code ServiceListener} objects,
- * {@code AllServiceListener} objects receive all
- * {@code ServiceEvent} objects regardless of whether the package source
+ * Unlike normal <code>ServiceListener</code> objects,
+ * <code>AllServiceListener</code> objects receive all
+ * <code>ServiceEvent</code> objects regardless of whether the package source
* of the listening bundle is equal to the package source of the bundle that
* registered the service. This means that the listener may not be able to cast
* the service object to any of its corresponding service interfaces if the
@@ -55,7 +55,7 @@
* @see ServicePermission
* @ThreadSafe
* @since 1.3
- * @version $Id: 35cee8a49e89b7b222aa3f85e1af0b4a4b550ce6 $
+ * @version $Revision: 5673 $
*/
public interface AllServiceListener extends ServiceListener {
diff --git a/framework/src/main/java/org/osgi/framework/Bundle.java b/framework/src/main/java/org/osgi/framework/Bundle.java
index 8f4002c..692bc5e 100644
--- a/framework/src/main/java/org/osgi/framework/Bundle.java
+++ b/framework/src/main/java/org/osgi/framework/Bundle.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,28 +16,23 @@
package org.osgi.framework;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
-import java.security.cert.X509Certificate;
import java.util.Dictionary;
import java.util.Enumeration;
-import java.util.List;
import java.util.Map;
-import org.osgi.framework.wiring.FrameworkWiring;
-
/**
* An installed bundle in the Framework.
*
* <p>
- * A {@code Bundle} object is the access point to define the lifecycle of an
- * installed bundle. Each bundle installed in the OSGi environment must have an
- * associated {@code Bundle} object.
+ * A <code>Bundle</code> object is the access point to define the lifecycle of
+ * an installed bundle. Each bundle installed in the OSGi environment must have
+ * an associated <code>Bundle</code> object.
*
* <p>
- * A bundle must have a unique identity, a {@code long}, chosen by the
+ * A bundle must have a unique identity, a <code>long</code>, chosen by the
* Framework. This identity must not change during the lifecycle of a bundle,
* even when the bundle is updated. Uninstalling and then reinstalling the
* bundle must create a new unique identity.
@@ -58,59 +53,54 @@
* the valid states.
*
* <p>
- * A bundle should only have active threads of execution when its state is one
- * of {@code STARTING},{@code ACTIVE}, or {@code STOPPING}. An {@code
- * UNINSTALLED} bundle can not be set to another state; it is a zombie and can
- * only be reached because references are kept somewhere.
+ * A bundle should only execute code when its state is one of
+ * <code>STARTING</code>,<code>ACTIVE</code>, or <code>STOPPING</code>.
+ * An <code>UNINSTALLED</code> bundle can not be set to another state; it is a
+ * zombie and can only be reached because references are kept somewhere.
*
* <p>
- * The Framework is the only entity that is allowed to create {@code Bundle}
- * objects, and these objects are only valid within the Framework that created
- * them.
- *
- * <p>
- * Bundles have a natural ordering such that if two {@code Bundle}s have the
- * same {@link #getBundleId() bundle id} they are equal. A {@code Bundle} is
- * less than another {@code Bundle} if it has a lower {@link #getBundleId()
- * bundle id} and is greater if it has a higher bundle id.
+ * The Framework is the only entity that is allowed to create
+ * <code>Bundle</code> objects, and these objects are only valid within the
+ * Framework that created them.
*
* @ThreadSafe
- * @noimplement
- * @version $Id: 239108e8d54ff493587b9cdfe1688bdefc5a714c $
+ * @version $Revision: 6906 $
*/
-public interface Bundle extends Comparable<Bundle> {
+public interface Bundle {
/**
* The bundle is uninstalled and may not be used.
*
* <p>
- * The {@code UNINSTALLED} state is only visible after a bundle is
+ * The <code>UNINSTALLED</code> state is only visible after a bundle is
* uninstalled; the bundle is in an unusable state but references to the
- * {@code Bundle} object may still be available and used for introspection.
+ * <code>Bundle</code> object may still be available and used for
+ * introspection.
* <p>
- * The value of {@code UNINSTALLED} is 0x00000001.
+ * The value of <code>UNINSTALLED</code> is 0x00000001.
*/
- int UNINSTALLED = 0x00000001;
+ public static final int UNINSTALLED = 0x00000001;
/**
* The bundle is installed but not yet resolved.
*
* <p>
- * A bundle is in the {@code INSTALLED} state when it has been installed in
- * the Framework but is not or cannot be resolved.
+ * A bundle is in the <code>INSTALLED</code> state when it has been
+ * installed in the Framework but is not or cannot be resolved.
* <p>
* This state is visible if the bundle's code dependencies are not resolved.
- * The Framework may attempt to resolve an {@code INSTALLED} bundle's code
- * dependencies and move the bundle to the {@code RESOLVED} state.
+ * The Framework may attempt to resolve an <code>INSTALLED</code> bundle's
+ * code dependencies and move the bundle to the <code>RESOLVED</code>
+ * state.
* <p>
- * The value of {@code INSTALLED} is 0x00000002.
+ * The value of <code>INSTALLED</code> is 0x00000002.
*/
- int INSTALLED = 0x00000002;
+ public static final int INSTALLED = 0x00000002;
/**
* The bundle is resolved and is able to be started.
*
* <p>
- * A bundle is in the {@code RESOLVED} state when the Framework has
+ * A bundle is in the <code>RESOLVED</code> state when the Framework has
* successfully resolved the bundle's code dependencies. These dependencies
* include:
* <ul>
@@ -126,56 +116,57 @@
* </ul>
* <p>
* Note that the bundle is not active yet. A bundle must be put in the
- * {@code RESOLVED} state before it can be started. The Framework may
+ * <code>RESOLVED</code> state before it can be started. The Framework may
* attempt to resolve a bundle at any time.
* <p>
- * The value of {@code RESOLVED} is 0x00000004.
+ * The value of <code>RESOLVED</code> is 0x00000004.
*/
- int RESOLVED = 0x00000004;
+ public static final int RESOLVED = 0x00000004;
/**
* The bundle is in the process of starting.
*
* <p>
- * A bundle is in the {@code STARTING} state when its {@link #start(int)
- * start} method is active. A bundle must be in this state when the bundle's
- * {@link BundleActivator#start} is called. If the {@code
- * BundleActivator.start} method completes without exception, then the
- * bundle has successfully started and must move to the {@code ACTIVE}
- * state.
+ * A bundle is in the <code>STARTING</code> state when its
+ * {@link #start(int) start} method is active. A bundle must be in this
+ * state when the bundle's {@link BundleActivator#start} is called. If the
+ * <code>BundleActivator.start</code> method completes without exception,
+ * then the bundle has successfully started and must move to the
+ * <code>ACTIVE</code> state.
* <p>
- * If the bundle has a {@link Constants#ACTIVATION_LAZY lazy activation
- * policy}, then the bundle may remain in this state for some time until the
- * activation is triggered.
+ * If the bundle has a
+ * {@link Constants#ACTIVATION_LAZY lazy activation policy}, then the
+ * bundle may remain in this state for some time until the activation is
+ * triggered.
* <p>
- * The value of {@code STARTING} is 0x00000008.
+ * The value of <code>STARTING</code> is 0x00000008.
*/
- int STARTING = 0x00000008;
+ public static final int STARTING = 0x00000008;
/**
* The bundle is in the process of stopping.
*
* <p>
- * A bundle is in the {@code STOPPING} state when its {@link #stop(int)
- * stop} method is active. A bundle must be in this state when the bundle's
- * {@link BundleActivator#stop} method is called. When the {@code
- * BundleActivator.stop} method completes the bundle is stopped and must
- * move to the {@code RESOLVED} state.
+ * A bundle is in the <code>STOPPING</code> state when its
+ * {@link #stop(int) stop} method is active. A bundle must be in this state
+ * when the bundle's {@link BundleActivator#stop} method is called. When the
+ * <code>BundleActivator.stop</code> method completes the bundle is
+ * stopped and must move to the <code>RESOLVED</code> state.
* <p>
- * The value of {@code STOPPING} is 0x00000010.
+ * The value of <code>STOPPING</code> is 0x00000010.
*/
- int STOPPING = 0x00000010;
+ public static final int STOPPING = 0x00000010;
/**
* The bundle is now running.
*
* <p>
- * A bundle is in the {@code ACTIVE} state when it has been successfully
- * started and activated.
+ * A bundle is in the <code>ACTIVE</code> state when it has been
+ * successfully started and activated.
* <p>
- * The value of {@code ACTIVE} is 0x00000020.
+ * The value of <code>ACTIVE</code> is 0x00000020.
*/
- int ACTIVE = 0x00000020;
+ public static final int ACTIVE = 0x00000020;
/**
* The bundle start operation is transient and the persistent autostart
@@ -190,12 +181,12 @@
* @since 1.4
* @see #start(int)
*/
- int START_TRANSIENT = 0x00000001;
+ public static final int START_TRANSIENT = 0x00000001;
/**
* The bundle start operation must activate the bundle according to the
- * bundle's declared {@link Constants#BUNDLE_ACTIVATIONPOLICY activation
- * policy}.
+ * bundle's declared
+ * {@link Constants#BUNDLE_ACTIVATIONPOLICY activation policy}.
*
* <p>
* This bit may be set when calling {@link #start(int)} to notify the
@@ -206,7 +197,7 @@
* @see Constants#BUNDLE_ACTIVATIONPOLICY
* @see #start(int)
*/
- int START_ACTIVATION_POLICY = 0x00000002;
+ public static final int START_ACTIVATION_POLICY = 0x00000002;
/**
* The bundle stop is transient and the persistent autostart setting of the
@@ -221,7 +212,7 @@
* @since 1.4
* @see #stop(int)
*/
- int STOP_TRANSIENT = 0x00000001;
+ public static final int STOP_TRANSIENT = 0x00000001;
/**
* Request that all certificates used to sign the bundle be returned.
@@ -229,7 +220,7 @@
* @since 1.5
* @see #getSignerCertificates(int)
*/
- int SIGNERS_ALL = 1;
+ public final static int SIGNERS_ALL = 1;
/**
* Request that only certificates used to sign the bundle that are trusted
@@ -238,7 +229,7 @@
* @since 1.5
* @see #getSignerCertificates(int)
*/
- int SIGNERS_TRUSTED = 2;
+ public final static int SIGNERS_TRUSTED = 2;
/**
* Returns this bundle's current state.
@@ -246,23 +237,24 @@
* <p>
* A bundle can be in only one state at any time.
*
- * @return An element of {@code UNINSTALLED},{@code INSTALLED},
- * {@code RESOLVED}, {@code STARTING}, {@code STOPPING},
- * {@code ACTIVE}.
+ * @return An element of <code>UNINSTALLED</code>,<code>INSTALLED</code>,
+ * <code>RESOLVED</code>,<code>STARTING</code>,
+ * <code>STOPPING</code>,<code>ACTIVE</code>.
*/
- int getState();
+ public int getState();
/**
* Starts this bundle.
*
* <p>
- * If this bundle's state is {@code UNINSTALLED} then an
- * {@code IllegalStateException} is thrown.
+ * If this bundle's state is <code>UNINSTALLED</code> then an
+ * <code>IllegalStateException</code> is thrown.
* <p>
- * If the current start level is less than this bundle's start level:
+ * If the Framework implements the optional Start Level service and the
+ * current start level is less than this bundle's start level:
* <ul>
* <li>If the {@link #START_TRANSIENT} option is set, then a
- * {@code BundleException} is thrown indicating this bundle cannot be
+ * <code>BundleException</code> is thrown indicating this bundle cannot be
* started due to the Framework's current start level.
*
* <li>Otherwise, the Framework must set this bundle's persistent autostart
@@ -279,11 +271,11 @@
* <li>If this bundle is in the process of being activated or deactivated
* then this method must wait for activation or deactivation to complete
* before continuing. If this does not occur in a reasonable time, a
- * {@code BundleException} is thrown to indicate this bundle was unable to
- * be started.
+ * <code>BundleException</code> is thrown to indicate this bundle was unable
+ * to be started.
*
- * <li>If this bundle's state is {@code ACTIVE} then this method returns
- * immediately.
+ * <li>If this bundle's state is <code>ACTIVE</code> then this method
+ * returns immediately.
*
* <li>If the {@link #START_TRANSIENT} option is not set then set this
* bundle's autostart setting to <em>Started with declared activation</em>
@@ -292,111 +284,107 @@
* restarted and this bundle's autostart setting is not <em>Stopped</em>,
* this bundle must be automatically started.
*
- * <li>If this bundle's state is not {@code RESOLVED}, an attempt is made to
- * resolve this bundle. If the Framework cannot resolve this bundle, a
- * {@code BundleException} is thrown.
+ * <li>If this bundle's state is not <code>RESOLVED</code>, an attempt is
+ * made to resolve this bundle. If the Framework cannot resolve this bundle,
+ * a <code>BundleException</code> is thrown.
*
* <li>If the {@link #START_ACTIVATION_POLICY} option is set and this
* bundle's declared activation policy is {@link Constants#ACTIVATION_LAZY
* lazy} then:
* <ul>
- * <li>If this bundle's state is {@code STARTING} then this method returns
- * immediately.
- * <li>This bundle's state is set to {@code STARTING}.
+ * <li>If this bundle's state is <code>STARTING</code> then this method
+ * returns immediately.
+ * <li>This bundle's state is set to <code>STARTING</code>.
* <li>A bundle event of type {@link BundleEvent#LAZY_ACTIVATION} is fired.
* <li>This method returns immediately and the remaining steps will be
* followed when this bundle's activation is later triggered.
* </ul>
* <i></i>
- * <li>This bundle's state is set to {@code STARTING}.
+ * <li>This bundle's state is set to <code>STARTING</code>.
*
* <li>A bundle event of type {@link BundleEvent#STARTING} is fired.
*
* <li>The {@link BundleActivator#start} method of this bundle's
- * {@code BundleActivator}, if one is specified, is called. If the
- * {@code BundleActivator} is invalid or throws an exception then:
+ * <code>BundleActivator</code>, if one is specified, is called. If the
+ * <code>BundleActivator</code> is invalid or throws an exception then:
* <ul>
- * <li>This bundle's state is set to {@code STOPPING}.
+ * <li>This bundle's state is set to <code>STOPPING</code>.
* <li>A bundle event of type {@link BundleEvent#STOPPING} is fired.
* <li>Any services registered by this bundle must be unregistered.
* <li>Any services used by this bundle must be released.
* <li>Any listeners registered by this bundle must be removed.
- * <li>This bundle's state is set to {@code RESOLVED}.
+ * <li>This bundle's state is set to <code>RESOLVED</code>.
* <li>A bundle event of type {@link BundleEvent#STOPPED} is fired.
- * <li>A {@code BundleException} is then thrown.
+ * <li>A <code>BundleException</code> is then thrown.
* </ul>
* <i></i>
- * <li>If this bundle's state is {@code UNINSTALLED}, because this bundle
- * was uninstalled while the {@code BundleActivator.start} method was
- * running, a {@code BundleException} is thrown.
+ * <li>If this bundle's state is <code>UNINSTALLED</code>, because this
+ * bundle was uninstalled while the <code>BundleActivator.start</code>
+ * method was running, a <code>BundleException</code> is thrown.
*
- * <li>This bundle's state is set to {@code ACTIVE}.
+ * <li>This bundle's state is set to <code>ACTIVE</code>.
*
* <li>A bundle event of type {@link BundleEvent#STARTED} is fired.
* </ol>
*
* <b>Preconditions </b>
* <ul>
- * <li>{@code getState()} in { {@code INSTALLED}, {@code RESOLVED}
- * } or { {@code INSTALLED}, {@code RESOLVED},
- * {@code STARTING} } if this bundle has a lazy activation policy.
+ * <li><code>getState()</code> in { <code>INSTALLED</code>,
+ * <code>RESOLVED</code> } or { <code>INSTALLED</code>,
+ * <code>RESOLVED</code>, <code>STARTING</code> } if this bundle has
+ * a lazy activation policy.
* </ul>
* <b>Postconditions, no exceptions thrown </b>
* <ul>
* <li>Bundle autostart setting is modified unless the
* {@link #START_TRANSIENT} option was set.
- * <li>{@code getState()} in { {@code ACTIVE} } unless the
- * lazy activation policy was used.
- * <li>{@code BundleActivator.start()} has been called and did not throw an
- * exception unless the lazy activation policy was used.
+ * <li><code>getState()</code> in { <code>ACTIVE</code> }
+ * unless the lazy activation policy was used.
+ * <li><code>BundleActivator.start()</code> has been called and did not
+ * throw an exception unless the lazy activation policy was used.
* </ul>
* <b>Postconditions, when an exception is thrown </b>
* <ul>
* <li>Depending on when the exception occurred, bundle autostart setting is
* modified unless the {@link #START_TRANSIENT} option was set.
- * <li>{@code getState()} not in { {@code STARTING}, {@code ACTIVE}
- * }.
+ * <li><code>getState()</code> not in { <code>STARTING</code>,
+ * <code>ACTIVE</code> }.
* </ul>
*
* @param options The options for starting this bundle. See
* {@link #START_TRANSIENT} and {@link #START_ACTIVATION_POLICY}. The
* Framework must ignore unrecognized options.
- * @throws BundleException If this bundle could not be started.
- * BundleException types thrown by this method include:
- * {@link BundleException#START_TRANSIENT_ERROR},
- * {@link BundleException#NATIVECODE_ERROR},
- * {@link BundleException#RESOLVE_ERROR},
- * {@link BundleException#STATECHANGE_ERROR}, and
- * {@link BundleException#ACTIVATOR_ERROR}.
+ * @throws BundleException If this bundle could not be started. This could
+ * be because a code dependency could not be resolved or the
+ * specified <code>BundleActivator</code> could not be loaded or
+ * threw an exception or this bundle is a fragment.
* @throws IllegalStateException If this bundle has been uninstalled or this
* bundle tries to change its own state.
* @throws SecurityException If the caller does not have the appropriate
- * {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
+ * <code>AdminPermission[this,EXECUTE]</code>, and the Java Runtime
* Environment supports permissions.
* @since 1.4
*/
- void start(int options) throws BundleException;
+ public void start(int options) throws BundleException;
/**
* Starts this bundle with no options.
*
* <p>
- * This method performs the same function as calling {@code start(0)}.
+ * This method performs the same function as calling <code>start(0)</code>.
*
- * @throws BundleException If this bundle could not be started.
- * BundleException types thrown by this method include:
- * {@link BundleException#NATIVECODE_ERROR},
- * {@link BundleException#RESOLVE_ERROR},
- * {@link BundleException#STATECHANGE_ERROR}, and
- * {@link BundleException#ACTIVATOR_ERROR}.
+ * @throws BundleException If this bundle could not be started. This could
+ * be because a code dependency could not be resolved or the
+ * specified <code>BundleActivator</code> could not be loaded or
+ * threw an exception or this bundle is a fragment.
* @throws IllegalStateException If this bundle has been uninstalled or this
* bundle tries to change its own state.
* @throws SecurityException If the caller does not have the appropriate
- * {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
+ * <code>AdminPermission[this,EXECUTE]</code>, and the Java Runtime
* Environment supports permissions.
* @see #start(int)
*/
- void start() throws BundleException;
+ public void start() throws BundleException;
/**
* Stops this bundle.
@@ -404,58 +392,58 @@
* <p>
* The following steps are required to stop a bundle:
* <ol>
- * <li>If this bundle's state is {@code UNINSTALLED} then an
- * {@code IllegalStateException} is thrown.
+ * <li>If this bundle's state is <code>UNINSTALLED</code> then an
+ * <code>IllegalStateException</code> is thrown.
*
* <li>If this bundle is in the process of being activated or deactivated
* then this method must wait for activation or deactivation to complete
* before continuing. If this does not occur in a reasonable time, a
- * {@code BundleException} is thrown to indicate this bundle was unable to
- * be stopped.
+ * <code>BundleException</code> is thrown to indicate this bundle was unable
+ * to be stopped.
* <li>If the {@link #STOP_TRANSIENT} option is not set then then set this
* bundle's persistent autostart setting to to <em>Stopped</em>. When the
* Framework is restarted and this bundle's autostart setting is
* <em>Stopped</em>, this bundle must not be automatically started.
*
- * <li>If this bundle's state is not {@code STARTING} or {@code ACTIVE} then
- * this method returns immediately.
+ * <li>If this bundle's state is not <code>STARTING</code> or
+ * <code>ACTIVE</code> then this method returns immediately.
*
- * <li>This bundle's state is set to {@code STOPPING}.
+ * <li>This bundle's state is set to <code>STOPPING</code>.
*
* <li>A bundle event of type {@link BundleEvent#STOPPING} is fired.
*
- * <li>If this bundle's state was {@code ACTIVE} prior to setting the state
- * to {@code STOPPING}, the {@link BundleActivator#stop} method of this
- * bundle's {@code BundleActivator}, if one is specified, is called. If that
- * method throws an exception, this method must continue to stop this bundle
- * and a {@code BundleException} must be thrown after completion of the
- * remaining steps.
+ * <li>If this bundle's state was <code>ACTIVE</code> prior to setting the
+ * state to <code>STOPPING</code>, the {@link BundleActivator#stop} method
+ * of this bundle's <code>BundleActivator</code>, if one is specified, is
+ * called. If that method throws an exception, this method must continue to
+ * stop this bundle and a <code>BundleException</code> must be thrown after
+ * completion of the remaining steps.
*
* <li>Any services registered by this bundle must be unregistered.
* <li>Any services used by this bundle must be released.
* <li>Any listeners registered by this bundle must be removed.
*
- * <li>If this bundle's state is {@code UNINSTALLED}, because this bundle
- * was uninstalled while the {@code BundleActivator.stop} method was
- * running, a {@code BundleException} must be thrown.
+ * <li>If this bundle's state is <code>UNINSTALLED</code>, because this
+ * bundle was uninstalled while the <code>BundleActivator.stop</code> method
+ * was running, a <code>BundleException</code> must be thrown.
*
- * <li>This bundle's state is set to {@code RESOLVED}.
+ * <li>This bundle's state is set to <code>RESOLVED</code>.
*
* <li>A bundle event of type {@link BundleEvent#STOPPED} is fired.
* </ol>
*
* <b>Preconditions </b>
* <ul>
- * <li>{@code getState()} in { {@code ACTIVE} }.
+ * <li><code>getState()</code> in { <code>ACTIVE</code> }.
* </ul>
* <b>Postconditions, no exceptions thrown </b>
* <ul>
* <li>Bundle autostart setting is modified unless the
* {@link #STOP_TRANSIENT} option was set.
- * <li>{@code getState()} not in { {@code ACTIVE}, {@code STOPPING}
- * }.
- * <li>{@code BundleActivator.stop} has been called and did not throw an
- * exception.
+ * <li><code>getState()</code> not in { <code>ACTIVE</code>,
+ * <code>STOPPING</code> }.
+ * <li><code>BundleActivator.stop</code> has been called and did not throw
+ * an exception.
* </ul>
* <b>Postconditions, when an exception is thrown </b>
* <ul>
@@ -463,156 +451,143 @@
* {@link #STOP_TRANSIENT} option was set.
* </ul>
*
- * @param options The options for stopping this bundle. See
+ * @param options The options for stoping this bundle. See
* {@link #STOP_TRANSIENT}. The Framework must ignore unrecognized
* options.
- * @throws BundleException BundleException types thrown by this method
- * include: {@link BundleException#STATECHANGE_ERROR} and
- * {@link BundleException#ACTIVATOR_ERROR}.
+ * @throws BundleException If this bundle's <code>BundleActivator</code>
+ * threw an exception or this bundle is a fragment.
* @throws IllegalStateException If this bundle has been uninstalled or this
* bundle tries to change its own state.
* @throws SecurityException If the caller does not have the appropriate
- * {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
+ * <code>AdminPermission[this,EXECUTE]</code>, and the Java Runtime
* Environment supports permissions.
* @since 1.4
*/
- void stop(int options) throws BundleException;
+ public void stop(int options) throws BundleException;
/**
* Stops this bundle with no options.
*
* <p>
- * This method performs the same function as calling {@code stop(0)}.
+ * This method performs the same function as calling <code>stop(0)</code>.
*
- * @throws BundleException BundleException types thrown by this method
- * include: {@link BundleException#STATECHANGE_ERROR} and
- * {@link BundleException#ACTIVATOR_ERROR}.
+ * @throws BundleException If this bundle's <code>BundleActivator</code>
+ * threw an exception or this bundle is a fragment.
* @throws IllegalStateException If this bundle has been uninstalled or this
* bundle tries to change its own state.
* @throws SecurityException If the caller does not have the appropriate
- * {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
+ * <code>AdminPermission[this,EXECUTE]</code>, and the Java Runtime
* Environment supports permissions.
* @see #start(int)
*/
- void stop() throws BundleException;
+ public void stop() throws BundleException;
/**
- * Updates this bundle from an {@code InputStream}.
+ * Updates this bundle from an <code>InputStream</code>.
*
* <p>
- * If the specified {@code InputStream} is {@code null}, the Framework must
- * create the {@code InputStream} from which to read the updated bundle by
- * interpreting, in an implementation dependent manner, this bundle's
- * {@link Constants#BUNDLE_UPDATELOCATION Bundle-UpdateLocation} Manifest
- * header, if present, or this bundle's original location.
+ * If the specified <code>InputStream</code> is <code>null</code>, the
+ * Framework must create the <code>InputStream</code> from which to read the
+ * updated bundle by interpreting, in an implementation dependent manner,
+ * this bundle's {@link Constants#BUNDLE_UPDATELOCATION
+ * Bundle-UpdateLocation} Manifest header, if present, or this bundle's
+ * original location.
*
* <p>
- * If this bundle's state is {@code ACTIVE}, it must be stopped before the
- * update and started after the update successfully completes.
+ * If this bundle's state is <code>ACTIVE</code>, it must be stopped before
+ * the update and started after the update successfully completes.
*
* <p>
* If this bundle has exported any packages that are imported by another
- * bundle, these packages must remain exported until the
- * {@link FrameworkWiring#refreshBundles(java.util.Collection, FrameworkListener...)
- * FrameworkWiring.refreshBundles} method has been has been called or the
- * Framework is relaunched.
+ * bundle, these packages must not be updated. Instead, the previous package
+ * version must remain exported until the
+ * <code>PackageAdmin.refreshPackages</code> method has been has been called
+ * or the Framework is relaunched.
*
* <p>
* The following steps are required to update a bundle:
* <ol>
- * <li>If this bundle's state is {@code UNINSTALLED} then an
- * {@code IllegalStateException} is thrown.
+ * <li>If this bundle's state is <code>UNINSTALLED</code> then an
+ * <code>IllegalStateException</code> is thrown.
*
- * <li>If this bundle's state is {@code ACTIVE}, {@code STARTING} or
- * {@code STOPPING}, this bundle is stopped as described in the
- * {@code Bundle.stop} method. If {@code Bundle.stop} throws an exception,
- * the exception is rethrown terminating the update.
+ * <li>If this bundle's state is <code>ACTIVE</code>, <code>STARTING</code>
+ * or <code>STOPPING</code>, this bundle is stopped as described in the
+ * <code>Bundle.stop</code> method. If <code>Bundle.stop</code> throws an
+ * exception, the exception is rethrown terminating the update.
*
* <li>The updated version of this bundle is read from the input stream and
* installed. If the Framework is unable to install the updated version of
* this bundle, the original version of this bundle must be restored and a
- * {@code BundleException} must be thrown after completion of the remaining
- * steps.
+ * <code>BundleException</code> must be thrown after completion of the
+ * remaining steps.
*
- * <li>This bundle's state is set to {@code INSTALLED}.
+ * <li>This bundle's state is set to <code>INSTALLED</code>.
*
* <li>If the updated version of this bundle was successfully installed, a
* bundle event of type {@link BundleEvent#UPDATED} is fired.
*
- * <li>If this bundle's state was originally {@code ACTIVE}, the updated
- * bundle is started as described in the {@code Bundle.start} method. If
- * {@code Bundle.start} throws an exception, a Framework event of type
- * {@link FrameworkEvent#ERROR} is fired containing the exception.
+ * <li>If this bundle's state was originally <code>ACTIVE</code>, the
+ * updated bundle is started as described in the <code>Bundle.start</code>
+ * method. If <code>Bundle.start</code> throws an exception, a Framework
+ * event of type {@link FrameworkEvent#ERROR} is fired containing the
+ * exception.
* </ol>
*
* <b>Preconditions </b>
* <ul>
- * <li>{@code getState()} not in { {@code UNINSTALLED} }.
+ * <li><code>getState()</code> not in { <code>UNINSTALLED</code>
+ * }.
* </ul>
* <b>Postconditions, no exceptions thrown </b>
* <ul>
- * <li>{@code getState()} in { {@code INSTALLED}, {@code RESOLVED},
- * {@code ACTIVE} }.
+ * <li><code>getState()</code> in { <code>INSTALLED</code>,
+ * <code>RESOLVED</code>, <code>ACTIVE</code> }.
* <li>This bundle has been updated.
* </ul>
* <b>Postconditions, when an exception is thrown </b>
* <ul>
- * <li>{@code getState()} in { {@code INSTALLED}, {@code RESOLVED},
- * {@code ACTIVE} }.
+ * <li><code>getState()</code> in { <code>INSTALLED</code>,
+ * <code>RESOLVED</code>, <code>ACTIVE</code> }.
* <li>Original bundle is still used; no update occurred.
* </ul>
*
- * @param input The {@code InputStream} from which to read the new bundle or
- * {@code null} to indicate the Framework must create the input
- * stream from this bundle's {@link Constants#BUNDLE_UPDATELOCATION
- * Bundle-UpdateLocation} Manifest header, if present, or this
- * bundle's original location. The input stream must always be closed
- * when this method completes, even if an exception is thrown.
- * @throws BundleException If this bundle could not be updated.
- * BundleException types thrown by this method include:
- * {@link BundleException#READ_ERROR},
- * {@link BundleException#DUPLICATE_BUNDLE_ERROR},
- * {@link BundleException#MANIFEST_ERROR},
- * {@link BundleException#NATIVECODE_ERROR},
- * {@link BundleException#RESOLVE_ERROR},
- * {@link BundleException#STATECHANGE_ERROR}, and
- * {@link BundleException#ACTIVATOR_ERROR}.
+ * @param input The <code>InputStream</code> from which to read the new
+ * bundle or <code>null</code> to indicate the Framework must create
+ * the input stream from this bundle's
+ * {@link Constants#BUNDLE_UPDATELOCATION Bundle-UpdateLocation}
+ * Manifest header, if present, or this bundle's original location.
+ * The input stream must always be closed when this method completes,
+ * even if an exception is thrown.
+ * @throws BundleException If the input stream cannot be read or the update
+ * fails.
* @throws IllegalStateException If this bundle has been uninstalled or this
* bundle tries to change its own state.
* @throws SecurityException If the caller does not have the appropriate
- * {@code AdminPermission[this,LIFECYCLE]} for both the current
+ * <code>AdminPermission[this,LIFECYCLE]</code> for both the current
* bundle and the updated bundle, and the Java Runtime Environment
* supports permissions.
* @see #stop()
* @see #start()
*/
- void update(InputStream input) throws BundleException;
+ public void update(InputStream input) throws BundleException;
/**
* Updates this bundle.
*
* <p>
* This method performs the same function as calling
- * {@link #update(InputStream)} with a {@code null} InputStream.
+ * {@link #update(InputStream)} with a <code>null</code> InputStream.
*
- * @throws BundleException If this bundle could not be updated.
- * BundleException types thrown by this method include:
- * {@link BundleException#READ_ERROR},
- * {@link BundleException#DUPLICATE_BUNDLE_ERROR},
- * {@link BundleException#MANIFEST_ERROR},
- * {@link BundleException#NATIVECODE_ERROR},
- * {@link BundleException#RESOLVE_ERROR},
- * {@link BundleException#STATECHANGE_ERROR}, and
- * {@link BundleException#ACTIVATOR_ERROR}.
+ * @throws BundleException If the update fails.
* @throws IllegalStateException If this bundle has been uninstalled or this
* bundle tries to change its own state.
* @throws SecurityException If the caller does not have the appropriate
- * {@code AdminPermission[this,LIFECYCLE]} for both the current
+ * <code>AdminPermission[this,LIFECYCLE]</code> for both the current
* bundle and the updated bundle, and the Java Runtime Environment
* supports permissions.
* @see #update(InputStream)
*/
- void update() throws BundleException;
+ public void update() throws BundleException;
/**
* Uninstalls this bundle.
@@ -620,29 +595,28 @@
* <p>
* This method causes the Framework to notify other bundles that this bundle
* is being uninstalled, and then puts this bundle into the
- * {@code UNINSTALLED} state. The Framework must remove any resources
+ * <code>UNINSTALLED</code> state. The Framework must remove any resources
* related to this bundle that it is able to remove.
*
* <p>
* If this bundle has exported any packages, the Framework must continue to
* make these packages available to their importing bundles until the
- * {@link FrameworkWiring#refreshBundles(java.util.Collection, FrameworkListener...)
- * FrameworkWiring.refreshBundles} method has been called or the Framework
- * is relaunched.
+ * <code>PackageAdmin.refreshPackages</code> method has been called or the
+ * Framework is relaunched.
*
* <p>
* The following steps are required to uninstall a bundle:
* <ol>
- * <li>If this bundle's state is {@code UNINSTALLED} then an
- * {@code IllegalStateException} is thrown.
+ * <li>If this bundle's state is <code>UNINSTALLED</code> then an
+ * <code>IllegalStateException</code> is thrown.
*
- * <li>If this bundle's state is {@code ACTIVE}, {@code STARTING} or
- * {@code STOPPING}, this bundle is stopped as described in the
- * {@code Bundle.stop} method. If {@code Bundle.stop} throws an exception, a
- * Framework event of type {@link FrameworkEvent#ERROR} is fired containing
- * the exception.
+ * <li>If this bundle's state is <code>ACTIVE</code>, <code>STARTING</code>
+ * or <code>STOPPING</code>, this bundle is stopped as described in the
+ * <code>Bundle.stop</code> method. If <code>Bundle.stop</code> throws an
+ * exception, a Framework event of type {@link FrameworkEvent#ERROR} is
+ * fired containing the exception.
*
- * <li>This bundle's state is set to {@code UNINSTALLED}.
+ * <li>This bundle's state is set to <code>UNINSTALLED</code>.
*
* <li>A bundle event of type {@link BundleEvent#UNINSTALLED} is fired.
*
@@ -652,32 +626,33 @@
*
* <b>Preconditions </b>
* <ul>
- * <li>{@code getState()} not in { {@code UNINSTALLED} }.
+ * <li><code>getState()</code> not in { <code>UNINSTALLED</code>
+ * }.
* </ul>
* <b>Postconditions, no exceptions thrown </b>
* <ul>
- * <li>{@code getState()} in { {@code UNINSTALLED} }.
+ * <li><code>getState()</code> in { <code>UNINSTALLED</code>
+ * }.
* <li>This bundle has been uninstalled.
* </ul>
* <b>Postconditions, when an exception is thrown </b>
* <ul>
- * <li>{@code getState()} not in { {@code UNINSTALLED} }.
+ * <li><code>getState()</code> not in { <code>UNINSTALLED</code>
+ * }.
* <li>This Bundle has not been uninstalled.
* </ul>
*
* @throws BundleException If the uninstall failed. This can occur if
* another thread is attempting to change this bundle's state and
- * does not complete in a timely manner. BundleException types
- * thrown by this method include:
- * {@link BundleException#STATECHANGE_ERROR}
+ * does not complete in a timely manner.
* @throws IllegalStateException If this bundle has been uninstalled or this
* bundle tries to change its own state.
* @throws SecurityException If the caller does not have the appropriate
- * {@code AdminPermission[this,LIFECYCLE]}, and the Java Runtime
- * Environment supports permissions.
+ * <code>AdminPermission[this,LIFECYCLE]</code>, and the Java
+ * Runtime Environment supports permissions.
* @see #stop()
*/
- void uninstall() throws BundleException;
+ public void uninstall() throws BundleException;
/**
* Returns this bundle's Manifest headers and values. This method returns
@@ -686,7 +661,7 @@
*
* <p>
* Manifest header names are case-insensitive. The methods of the returned
- * {@code Dictionary} object must operate on header names in a
+ * <code>Dictionary</code> object must operate on header names in a
* case-insensitive manner.
*
* If a Manifest header value starts with "%", it must be
@@ -709,16 +684,16 @@
*
* <p>
* This method must continue to return Manifest header information while
- * this bundle is in the {@code UNINSTALLED} state.
+ * this bundle is in the <code>UNINSTALLED</code> state.
*
- * @return An unmodifiable {@code Dictionary} object containing this
- * bundle's Manifest headers and values.
- * @throws SecurityException If the caller does not have the appropriate
- * {@code AdminPermission[this,METADATA]}, and the Java Runtime
- * Environment supports permissions.
+ * @return A <code>Dictionary</code> object containing this bundle's
+ * Manifest headers and values.
+ * @throws SecurityException If the caller does not have the
+ * appropriate <code>AdminPermission[this,METADATA]</code>, and
+ * the Java Runtime Environment supports permissions.
* @see Constants#BUNDLE_LOCALIZATION
*/
- Dictionary<String, String> getHeaders();
+ public Dictionary/* <String,String> */getHeaders();
/**
* Returns this bundle's unique identifier. This bundle is assigned a unique
@@ -729,7 +704,7 @@
* A bundle's unique identifier has the following attributes:
* <ul>
* <li>Is unique and persistent.
- * <li>Is a {@code long}.
+ * <li>Is a <code>long</code>.
* <li>Its value is not reused for another bundle, even after a bundle is
* uninstalled.
* <li>Does not change while a bundle remains installed.
@@ -738,142 +713,151 @@
*
* <p>
* This method must continue to return this bundle's unique identifier while
- * this bundle is in the {@code UNINSTALLED} state.
+ * this bundle is in the <code>UNINSTALLED</code> state.
*
* @return The unique identifier of this bundle.
*/
- long getBundleId();
+ public long getBundleId();
/**
* Returns this bundle's location identifier.
*
* <p>
- * The location identifier is the location passed to {@code
- * BundleContext.installBundle} when a bundle is installed. The location
- * identifier does not change while this bundle remains installed, even if
- * this bundle is updated.
+ * The location identifier is the location passed to
+ * <code>BundleContext.installBundle</code> when a bundle is installed.
+ * The location identifier does not change while this bundle remains
+ * installed, even if this bundle is updated.
*
* <p>
* This method must continue to return this bundle's location identifier
- * while this bundle is in the {@code UNINSTALLED} state.
+ * while this bundle is in the <code>UNINSTALLED</code> state.
*
* @return The string representation of this bundle's location identifier.
- * @throws SecurityException If the caller does not have the appropriate
- * {@code AdminPermission[this,METADATA]}, and the Java Runtime
- * Environment supports permissions.
+ * @throws SecurityException If the caller does not have the
+ * appropriate <code>AdminPermission[this,METADATA]</code>, and
+ * the Java Runtime Environment supports permissions.
*/
- String getLocation();
+ public String getLocation();
/**
- * Returns this bundle's {@code ServiceReference} list for all services it
- * has registered or {@code null} if this bundle has no registered services.
+ * Returns this bundle's <code>ServiceReference</code> list for all
+ * services it has registered or <code>null</code> if this bundle has no
+ * registered services.
*
* <p>
- * If the Java runtime supports permissions, a {@code ServiceReference}
+ * If the Java runtime supports permissions, a <code>ServiceReference</code>
* object to a service is included in the returned list only if the caller
- * has the {@code ServicePermission} to get the service using at least one
- * of the named classes the service was registered under.
+ * has the <code>ServicePermission</code> to get the service using at
+ * least one of the named classes the service was registered under.
*
* <p>
* The list is valid at the time of the call to this method, however, as the
* Framework is a very dynamic environment, services can be modified or
* unregistered at anytime.
*
- * @return An array of {@code ServiceReference} objects or {@code null}.
- * @throws IllegalStateException If this bundle has been uninstalled.
+ * @return An array of <code>ServiceReference</code> objects or
+ * <code>null</code>.
+ * @throws IllegalStateException If this bundle has been
+ * uninstalled.
* @see ServiceRegistration
* @see ServiceReference
* @see ServicePermission
*/
- ServiceReference< ? >[] getRegisteredServices();
+ public ServiceReference[] getRegisteredServices();
/**
- * Returns this bundle's {@code ServiceReference} list for all services it
- * is using or returns {@code null} if this bundle is not using any
- * services. A bundle is considered to be using a service if its use count
- * for that service is greater than zero.
+ * Returns this bundle's <code>ServiceReference</code> list for all
+ * services it is using or returns <code>null</code> if this bundle is not
+ * using any services. A bundle is considered to be using a service if its
+ * use count for that service is greater than zero.
*
* <p>
- * If the Java Runtime Environment supports permissions, a {@code
- * ServiceReference} object to a service is included in the returned list
- * only if the caller has the {@code ServicePermission} to get the service
- * using at least one of the named classes the service was registered under.
+ * If the Java Runtime Environment supports permissions, a
+ * <code>ServiceReference</code> object to a service is included in the
+ * returned list only if the caller has the <code>ServicePermission</code>
+ * to get the service using at least one of the named classes the service
+ * was registered under.
* <p>
* The list is valid at the time of the call to this method, however, as the
* Framework is a very dynamic environment, services can be modified or
* unregistered at anytime.
*
- * @return An array of {@code ServiceReference} objects or {@code null}.
- * @throws IllegalStateException If this bundle has been uninstalled.
+ * @return An array of <code>ServiceReference</code> objects or
+ * <code>null</code>.
+ * @throws IllegalStateException If this bundle has been
+ * uninstalled.
* @see ServiceReference
* @see ServicePermission
*/
- ServiceReference< ? >[] getServicesInUse();
+ public ServiceReference[] getServicesInUse();
/**
* Determines if this bundle has the specified permissions.
*
* <p>
* If the Java Runtime Environment does not support permissions, this method
- * always returns {@code true}.
+ * always returns <code>true</code>.
* <p>
- * {@code permission} is of type {@code Object} to avoid referencing the
- * {@code java.security.Permission} class directly. This is to allow the
- * Framework to be implemented in Java environments which do not support
- * permissions.
+ * <code>permission</code> is of type <code>Object</code> to avoid
+ * referencing the <code>java.security.Permission</code> class directly.
+ * This is to allow the Framework to be implemented in Java environments
+ * which do not support permissions.
*
* <p>
* If the Java Runtime Environment does support permissions, this bundle and
* all its resources including embedded JAR files, belong to the same
- * {@code java.security.ProtectionDomain}; that is, they must share the same
- * set of permissions.
+ * <code>java.security.ProtectionDomain</code>; that is, they must share
+ * the same set of permissions.
*
* @param permission The permission to verify.
- * @return {@code true} if this bundle has the specified permission or the
- * permissions possessed by this bundle imply the specified
- * permission; {@code false} if this bundle does not have the
- * specified permission or {@code permission} is not an {@code
- * instanceof} {@code java.security.Permission}.
- * @throws IllegalStateException If this bundle has been uninstalled.
+ * @return <code>true</code> if this bundle has the specified permission
+ * or the permissions possessed by this bundle imply the specified
+ * permission; <code>false</code> if this bundle does not have the
+ * specified permission or <code>permission</code> is not an
+ * <code>instanceof</code> <code>java.security.Permission</code>.
+ * @throws IllegalStateException If this bundle has been
+ * uninstalled.
*/
- boolean hasPermission(Object permission);
+ public boolean hasPermission(Object permission);
/**
* Find the specified resource from this bundle's class loader.
*
* This bundle's class loader is called to search for the specified
- * resource. If this bundle's state is {@code INSTALLED}, this method must
- * attempt to resolve this bundle before attempting to get the specified
- * resource. If this bundle cannot be resolved, then only this bundle must
- * be searched for the specified resource. Imported packages cannot be
- * searched when this bundle has not been resolved. If this bundle is a
- * fragment bundle then {@code null} is returned.
+ * resource. If this bundle's state is <code>INSTALLED</code>, this method
+ * must attempt to resolve this bundle before attempting to get the
+ * specified resource. If this bundle cannot be resolved, then only this
+ * bundle must be searched for the specified resource. Imported packages
+ * cannot be searched when this bundle has not been resolved. If this bundle
+ * is a fragment bundle then <code>null</code> is returned.
* <p>
* Note: Jar and zip files are not required to include directory entries.
* URLs to directory entries will not be returned if the bundle contents do
* not contain directory entries.
*
- * @param name The name of the resource. See {@code ClassLoader.getResource}
- * for a description of the format of a resource name.
- * @return A URL to the named resource, or {@code null} if the resource
+ * @param name The name of the resource. See
+ * <code>ClassLoader.getResource</code> for a description of the
+ * format of a resource name.
+ * @return A URL to the named resource, or <code>null</code> if the resource
* could not be found or if this bundle is a fragment bundle or if
- * the caller does not have the appropriate {@code
- * AdminPermission[this,RESOURCE]}, and the Java Runtime Environment
- * supports permissions.
+ * the caller does not have the appropriate
+ * <code>AdminPermission[this,RESOURCE]</code>, and the Java Runtime
+ * Environment supports permissions.
* @throws IllegalStateException If this bundle has been uninstalled.
* @see #getEntry
* @see #findEntries
* @since 1.1
*/
- URL getResource(String name);
+ public URL getResource(String name);
/**
* Returns this bundle's Manifest headers and values localized to the
* specified locale.
*
* <p>
- * This method performs the same function as {@code Bundle.getHeaders()}
- * except the manifest header values are localized to the specified locale.
+ * This method performs the same function as
+ * <code>Bundle.getHeaders()</code> except the manifest header values are
+ * localized to the specified locale.
*
* <p>
* If a Manifest header value starts with "%", it must be
@@ -891,122 +875,128 @@
* bn
* </pre>
*
- * Where {@code bn} is this bundle's localization basename, {@code Ls},
- * {@code Cs} and {@code Vs} are the specified locale (language, country,
- * variant) and {@code Ld}, {@code Cd} and {@code Vd} are the default locale
- * (language, country, variant).
+ * Where <code>bn</code> is this bundle's localization basename,
+ * <code>Ls</code>, <code>Cs</code> and <code>Vs</code> are the
+ * specified locale (language, country, variant) and <code>Ld</code>,
+ * <code>Cd</code> and <code>Vd</code> are the default locale (language,
+ * country, variant).
*
- * If {@code null} is specified as the locale string, the header values must
- * be localized using the default locale. If the empty string ("")
- * is specified as the locale string, the header values must not be
- * localized and the raw (unlocalized) header values, including any leading
- * "%", must be returned. If no localization is found for a header
- * value, the header value without the leading "%" is returned.
+ * If <code>null</code> is specified as the locale string, the header
+ * values must be localized using the default locale. If the empty string
+ * ("") is specified as the locale string, the header values must
+ * not be localized and the raw (unlocalized) header values, including any
+ * leading "%", must be returned. If no localization is found for
+ * a header value, the header value without the leading "%" is
+ * returned.
*
* <p>
* This method must continue to return Manifest header information while
- * this bundle is in the {@code UNINSTALLED} state, however the header
- * values must only be available in the raw and default locale values.
+ * this bundle is in the <code>UNINSTALLED</code> state, however the
+ * header values must only be available in the raw and default locale
+ * values.
*
* @param locale The locale name into which the header values are to be
- * localized. If the specified locale is {@code null} then the locale
- * returned by {@code java.util.Locale.getDefault} is used. If the
- * specified locale is the empty string, this method will return the
- * raw (unlocalized) manifest headers including any leading
- * "%".
- * @return An unmodifiable {@code Dictionary} object containing this
- * bundle's Manifest headers and values.
- * @throws SecurityException If the caller does not have the appropriate
- * {@code AdminPermission[this,METADATA]}, and the Java Runtime
- * Environment supports permissions.
+ * localized. If the specified locale is <code>null</code> then the
+ * locale returned by <code>java.util.Locale.getDefault</code> is
+ * used. If the specified locale is the empty string, this method
+ * will return the raw (unlocalized) manifest headers including any
+ * leading "%".
+ * @return A <code>Dictionary</code> object containing this bundle's
+ * Manifest headers and values.
+ * @throws SecurityException If the caller does not have the
+ * appropriate <code>AdminPermission[this,METADATA]</code>, and
+ * the Java Runtime Environment supports permissions.
* @see #getHeaders()
* @see Constants#BUNDLE_LOCALIZATION
* @since 1.3
*/
- Dictionary<String, String> getHeaders(String locale);
+ public Dictionary/* <String,String> */getHeaders(String locale);
/**
- * Returns the symbolic name of this bundle as specified by its {@code
- * Bundle-SymbolicName} manifest header. The bundle symbolic name should be
- * based on the reverse domain name naming convention like that used for
- * java packages.
+ * Returns the symbolic name of this bundle as specified by its
+ * <code>Bundle-SymbolicName</code> manifest header. The bundle symbolic
+ * name together with a version must identify a unique bundle. The bundle
+ * symbolic name should be based on the reverse domain name naming
+ * convention like that used for java packages.
*
* <p>
* This method must continue to return this bundle's symbolic name while
- * this bundle is in the {@code UNINSTALLED} state.
+ * this bundle is in the <code>UNINSTALLED</code> state.
*
- * @return The symbolic name of this bundle or {@code null} if this bundle
- * does not have a symbolic name.
+ * @return The symbolic name of this bundle or <code>null</code> if this
+ * bundle does not have a symbolic name.
* @since 1.3
*/
- String getSymbolicName();
+ public String getSymbolicName();
/**
* Loads the specified class using this bundle's class loader.
*
* <p>
- * If this bundle is a fragment bundle then this method must throw a {@code
- * ClassNotFoundException}.
+ * If this bundle is a fragment bundle then this method must throw a
+ * <code>ClassNotFoundException</code>.
*
* <p>
- * If this bundle's state is {@code INSTALLED}, this method must attempt to
- * resolve this bundle before attempting to load the class.
+ * If this bundle's state is <code>INSTALLED</code>, this method must
+ * attempt to resolve this bundle before attempting to load the class.
*
* <p>
* If this bundle cannot be resolved, a Framework event of type
- * {@link FrameworkEvent#ERROR} is fired containing a {@code
- * BundleException} with details of the reason this bundle could not be
- * resolved. This method must then throw a {@code ClassNotFoundException}.
+ * {@link FrameworkEvent#ERROR} is fired containing a
+ * <code>BundleException</code> with details of the reason this bundle
+ * could not be resolved. This method must then throw a
+ * <code>ClassNotFoundException</code>.
*
* <p>
- * If this bundle's state is {@code UNINSTALLED}, then an {@code
- * IllegalStateException} is thrown.
+ * If this bundle's state is <code>UNINSTALLED</code>, then an
+ * <code>IllegalStateException</code> is thrown.
*
* @param name The name of the class to load.
* @return The Class object for the requested class.
- * @throws ClassNotFoundException If no such class can be found or if this
- * bundle is a fragment bundle or if the caller does not have the
- * appropriate {@code AdminPermission[this,CLASS]}, and the Java
- * Runtime Environment supports permissions.
- * @throws IllegalStateException If this bundle has been uninstalled.
+ * @throws ClassNotFoundException If no such class can be found or
+ * if this bundle is a fragment bundle or if the caller does not
+ * have the appropriate <code>AdminPermission[this,CLASS]</code>,
+ * and the Java Runtime Environment supports permissions.
+ * @throws IllegalStateException If this bundle has been
+ * uninstalled.
* @since 1.3
*/
- Class< ? > loadClass(String name) throws ClassNotFoundException;
+ public Class loadClass(String name) throws ClassNotFoundException;
/**
* Find the specified resources from this bundle's class loader.
*
* This bundle's class loader is called to search for the specified
- * resources. If this bundle's state is {@code INSTALLED}, this method must
- * attempt to resolve this bundle before attempting to get the specified
- * resources. If this bundle cannot be resolved, then only this bundle must
- * be searched for the specified resources. Imported packages cannot be
- * searched when a bundle has not been resolved. If this bundle is a
- * fragment bundle then {@code null} is returned.
+ * resources. If this bundle's state is <code>INSTALLED</code>, this method
+ * must attempt to resolve this bundle before attempting to get the
+ * specified resources. If this bundle cannot be resolved, then only this
+ * bundle must be searched for the specified resources. Imported packages
+ * cannot be searched when a bundle has not been resolved. If this bundle is
+ * a fragment bundle then <code>null</code> is returned.
* <p>
* Note: Jar and zip files are not required to include directory entries.
* URLs to directory entries will not be returned if the bundle contents do
* not contain directory entries.
*
- * @param name The name of the resource. See {@code
- * ClassLoader.getResources} for a description of the format of a
- * resource name.
- * @return An enumeration of URLs to the named resources, or {@code null} if
- * the resource could not be found or if this bundle is a fragment
- * bundle or if the caller does not have the appropriate {@code
- * AdminPermission[this,RESOURCE]}, and the Java Runtime Environment
- * supports permissions.
+ * @param name The name of the resource. See
+ * <code>ClassLoader.getResources</code> for a description of the
+ * format of a resource name.
+ * @return An enumeration of URLs to the named resources, or
+ * <code>null</code> if the resource could not be found or if this
+ * bundle is a fragment bundle or if the caller does not have the
+ * appropriate <code>AdminPermission[this,RESOURCE]</code>, and the
+ * Java Runtime Environment supports permissions.
* @throws IllegalStateException If this bundle has been uninstalled.
* @throws IOException If there is an I/O error.
* @since 1.3
*/
- Enumeration<URL> getResources(String name) throws IOException;
+ public Enumeration/* <URL> */getResources(String name) throws IOException;
/**
- * Returns an Enumeration of all the paths ({@code String} objects) to
- * entries within this bundle whose longest sub-path matches the specified
- * path. This bundle's class loader is not used to search for entries. Only
- * the contents of this bundle are searched.
+ * Returns an Enumeration of all the paths (<code>String</code> objects)
+ * to entries within this bundle whose longest sub-path matches the
+ * specified path. This bundle's class loader is not used to search for
+ * entries. Only the contents of this bundle are searched.
* <p>
* The specified path is always relative to the root of this bundle and may
* begin with a "/". A path value of "/" indicates the
@@ -1021,14 +1011,16 @@
* not contain directory entries.
*
* @param path The path name for which to return entry paths.
- * @return An Enumeration of the entry paths ({@code String} objects) or
- * {@code null} if no entry could be found or if the caller does not
- * have the appropriate {@code AdminPermission[this,RESOURCE]} and
- * the Java Runtime Environment supports permissions.
- * @throws IllegalStateException If this bundle has been uninstalled.
+ * @return An Enumeration of the entry paths (<code>String</code>
+ * objects) or <code>null</code> if no entry could be found or if
+ * the caller does not have the appropriate
+ * <code>AdminPermission[this,RESOURCE]</code> and the Java
+ * Runtime Environment supports permissions.
+ * @throws IllegalStateException If this bundle has been
+ * uninstalled.
* @since 1.3
*/
- Enumeration<String> getEntryPaths(String path);
+ public Enumeration/* <String> */getEntryPaths(String path);
/**
* Returns a URL to the entry at the specified path in this bundle. This
@@ -1044,14 +1036,15 @@
* not contain directory entries.
*
* @param path The path name of the entry.
- * @return A URL to the entry, or {@code null} if no entry could be found or
- * if the caller does not have the appropriate {@code
- * AdminPermission[this,RESOURCE]} and the Java Runtime Environment
- * supports permissions.
- * @throws IllegalStateException If this bundle has been uninstalled.
+ * @return A URL to the entry, or <code>null</code> if no entry could be
+ * found or if the caller does not have the appropriate
+ * <code>AdminPermission[this,RESOURCE]</code> and the Java
+ * Runtime Environment supports permissions.
+ * @throws IllegalStateException If this bundle has been
+ * uninstalled.
* @since 1.3
*/
- URL getEntry(String path);
+ public URL getEntry(String path);
/**
* Returns the time when this bundle was last modified. A bundle is
@@ -1064,21 +1057,21 @@
* @return The time when this bundle was last modified.
* @since 1.3
*/
- long getLastModified();
+ public long getLastModified();
/**
* Returns entries in this bundle and its attached fragments. This bundle's
* class loader is not used to search for entries. Only the contents of this
* bundle and its attached fragments are searched for the specified entries.
*
- * If this bundle's state is {@code INSTALLED}, this method must attempt to
- * resolve this bundle before attempting to find entries.
+ * If this bundle's state is <code>INSTALLED</code>, this method must
+ * attempt to resolve this bundle before attempting to find entries.
*
* <p>
* This method is intended to be used to obtain configuration, setup,
* localization and other information from this bundle. This method takes
* into account that the "contents" of this bundle can be extended
- * with fragments. This "bundle space" is not a name space with
+ * with fragments. This "bundle space" is not a namespace with
* unique members; the same entry name can be present multiple times. This
* method therefore returns an enumeration of URL objects. These URLs can
* come from different JARs but have the same path name. This method can
@@ -1118,41 +1111,44 @@
* using the wildcard character ("*"). If null is
* specified, this is equivalent to "*" and matches all
* files.
- * @param recurse If {@code true}, recurse into subdirectories. Otherwise
- * only return entries from the specified path.
+ * @param recurse If <code>true</code>, recurse into subdirectories.
+ * Otherwise only return entries from the specified path.
* @return An enumeration of URL objects for each matching entry, or
- * {@code null} if no matching entry could not be found or if the
- * caller does not have the appropriate
- * {@code AdminPermission[this,RESOURCE]}, and the Java Runtime
+ * <code>null</code> if an entry could not be found or if the caller
+ * does not have the appropriate
+ * <code>AdminPermission[this,RESOURCE]</code>, and the Java Runtime
* Environment supports permissions. The URLs are sorted such that
* entries from this bundle are returned first followed by the
- * entries from attached fragments in attachment order. If this
- * bundle is a fragment, then only matching entries in this fragment
- * are returned.
+ * entries from attached fragments in ascending bundle id order. If
+ * this bundle is a fragment, then only matching entries in this
+ * fragment are returned.
* @throws IllegalStateException If this bundle has been uninstalled.
* @since 1.3
*/
- Enumeration<URL> findEntries(String path, String filePattern,
+ public Enumeration/* <URL> */findEntries(String path, String filePattern,
boolean recurse);
/**
- * Returns this bundle's {@link BundleContext}. The returned {@code
- * BundleContext} can be used by the caller to act on behalf of this bundle.
+ * Returns this bundle's {@link BundleContext}. The returned
+ * <code>BundleContext</code> can be used by the caller to act on behalf
+ * of this bundle.
*
* <p>
* If this bundle is not in the {@link #STARTING}, {@link #ACTIVE}, or
* {@link #STOPPING} states or this bundle is a fragment bundle, then this
- * bundle has no valid {@code BundleContext}. This method will return
- * {@code null} if this bundle has no valid {@code BundleContext}.
+ * bundle has no valid <code>BundleContext</code>. This method will
+ * return <code>null</code> if this bundle has no valid
+ * <code>BundleContext</code>.
*
- * @return A {@code BundleContext} for this bundle or {@code null} if this
- * bundle has no valid {@code BundleContext}.
- * @throws SecurityException If the caller does not have the appropriate
- * {@code AdminPermission[this,CONTEXT]}, and the Java Runtime
- * Environment supports permissions.
+ * @return A <code>BundleContext</code> for this bundle or
+ * <code>null</code> if this bundle has no valid
+ * <code>BundleContext</code>.
+ * @throws SecurityException If the caller does not have the
+ * appropriate <code>AdminPermission[this,CONTEXT]</code>, and
+ * the Java Runtime Environment supports permissions.
* @since 1.4
*/
- BundleContext getBundleContext();
+ public BundleContext getBundleContext();
/**
* Return the certificates for the signers of this bundle and the
@@ -1162,81 +1158,37 @@
* on all signers of this bundle is returned. If
* {@link #SIGNERS_TRUSTED} is specified, then only information on
* the signers of this bundle trusted by the framework is returned.
- * @return The {@code X509Certificate}s for the signers of this bundle and
- * the {@code X509Certificate} chains for those signers. The keys of
- * the {@code Map} are the {@code X509Certificate}s of the signers
- * of this bundle. The value for a key is a {@code List} containing
- * the {@code X509Certificate} chain for the signer. The first item
- * in the {@code List} is the signer's {@code X509Certificate} which
- * is then followed by the rest of the {@code X509Certificate}
- * chain. The returned {@code Map} will be empty if there are no
- * signers. The returned {@code Map} is the property of the caller
- * who is free to modify it.
- * @throws IllegalArgumentException If the specified {@code signersType} is
- * not {@link #SIGNERS_ALL} or {@link #SIGNERS_TRUSTED}.
+ * @return The <code>X509Certificate</code>s for the signers of this bundle
+ * and the <code>X509Certificate</code> chains for those signers.
+ * The keys of the <code>Map</code> are the
+ * <code>X509Certificate</code>s of the signers of this bundle. The
+ * value for a key is a <code>List</code> containing the
+ * <code>X509Certificate</code> chain for the signer. The first item
+ * in the <code>List</code> is the signer's
+ * <code>X509Certificate</code> which is then followed by the rest
+ * of the <code>X509Certificate</code> chain. The returned
+ * <code>Map</code> will be empty if there are no signers. The
+ * returned <code>Map</code> is the property of the caller who is
+ * free to modify it.
+ * @throws IllegalArgumentException If the specified
+ * <code>signersType</code> is not {@link #SIGNERS_ALL} or
+ * {@link #SIGNERS_TRUSTED}.
* @since 1.5
*/
- Map<X509Certificate, List<X509Certificate>> getSignerCertificates(
+ public Map/* <X509Certificate, List<X509Certificate>> */getSignerCertificates(
int signersType);
-
+
/**
- * Returns the version of this bundle as specified by its {@code
- * Bundle-Version} manifest header. If this bundle does not have a specified
- * version then {@link Version#emptyVersion} is returned.
+ * Returns the version of this bundle as specified by its
+ * <code>Bundle-Version</code> manifest header. If this bundle does not have a
+ * specified version then {@link Version#emptyVersion} is returned.
*
* <p>
- * This method must continue to return this bundle's version while this
- * bundle is in the {@code UNINSTALLED} state.
+ * This method must continue to return this bundle's version while
+ * this bundle is in the <code>UNINSTALLED</code> state.
*
* @return The version of this bundle.
* @since 1.5
*/
- Version getVersion();
-
- /**
- * Adapt this bundle to the specified type.
- *
- * <p>
- * Adapting this bundle to the specified type may require certain checks,
- * including security checks, to succeed. If a check does not succeed, then
- * this bundle cannot be adapted and {@code null} is returned.
- *
- * @param <A> The type to which this bundle is to be adapted.
- * @param type Class object for the type to which this bundle is to be
- * adapted.
- * @return The object, of the specified type, to which this bundle has been
- * adapted or {@code null} if this bundle cannot be adapted to the
- * specified type.
- * @throws SecurityException If the caller does not have the appropriate
- * {@code AdaptPermission[type,this,ADAPT]}, and the Java Runtime
- * Environment supports permissions.
- * @since 1.6
- */
- <A> A adapt(Class<A> type);
-
- /**
- * Creates a {@code File} object for a file in the persistent storage area
- * provided for this bundle by the Framework. This method will return
- * {@code null} if the platform does not have file system support or this
- * bundle is a fragment bundle.
- *
- * <p>
- * A {@code File} object for the base directory of the persistent storage
- * area provided for this bundle by the Framework can be obtained by calling
- * this method with an empty string as {@code filename}.
- *
- * <p>
- * If the Java Runtime Environment supports permissions, the Framework will
- * ensure that this bundle has the {@code java.io.FilePermission} with
- * actions {@code read},{@code write},{@code delete} for all files
- * (recursively) in the persistent storage area provided for this bundle.
- *
- * @param filename A relative name to the file to be accessed.
- * @return A {@code File} object that represents the requested file or
- * {@code null} if the platform does not have file system support or
- * this bundle is a fragment bundle.
- * @throws IllegalStateException If this bundle has been uninstalled.
- * @since 1.6
- */
- File getDataFile(String filename);
+ public Version getVersion();
}
diff --git a/framework/src/main/java/org/osgi/framework/BundleActivator.java b/framework/src/main/java/org/osgi/framework/BundleActivator.java
index aefb036..56660b1 100644
--- a/framework/src/main/java/org/osgi/framework/BundleActivator.java
+++ b/framework/src/main/java/org/osgi/framework/BundleActivator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,33 +19,33 @@
/**
* Customizes the starting and stopping of a bundle.
* <p>
- * {@code BundleActivator} is an interface that may be implemented when a
+ * <code>BundleActivator</code> is an interface that may be implemented when a
* bundle is started or stopped. The Framework can create instances of a
- * bundle's {@code BundleActivator} as required. If an instance's
- * {@code BundleActivator.start} method executes successfully, it is
- * guaranteed that the same instance's {@code BundleActivator.stop}
+ * bundle's <code>BundleActivator</code> as required. If an instance's
+ * <code>BundleActivator.start</code> method executes successfully, it is
+ * guaranteed that the same instance's <code>BundleActivator.stop</code>
* method will be called when the bundle is to be stopped. The Framework must
- * not concurrently call a {@code BundleActivator} object.
+ * not concurrently call a <code>BundleActivator</code> object.
*
* <p>
- * {@code BundleActivator} is specified through the
- * {@code Bundle-Activator} Manifest header. A bundle can only specify a
- * single {@code BundleActivator} in the Manifest file. Fragment bundles
- * must not have a {@code BundleActivator}. The form of the Manifest
+ * <code>BundleActivator</code> is specified through the
+ * <code>Bundle-Activator</code> Manifest header. A bundle can only specify a
+ * single <code>BundleActivator</code> in the Manifest file. Fragment bundles
+ * must not have a <code>BundleActivator</code>. The form of the Manifest
* header is:
*
* <p>
- * {@code Bundle-Activator: <i>class-name</i>}
+ * <code>Bundle-Activator: <i>class-name</i></code>
*
* <p>
- * where {@code <i>class-name</i>} is a fully qualified Java classname.
+ * where <code><i>class-name</i></code> is a fully qualified Java classname.
* <p>
- * The specified {@code BundleActivator} class must have a public
- * constructor that takes no parameters so that a {@code BundleActivator}
- * object can be created by {@code Class.newInstance()}.
+ * The specified <code>BundleActivator</code> class must have a public
+ * constructor that takes no parameters so that a <code>BundleActivator</code>
+ * object can be created by <code>Class.newInstance()</code>.
*
* @NotThreadSafe
- * @version $Id: 1b73057bd270ab07f0a16430dba16e5132eea24f $
+ * @version $Revision: 6361 $
*/
public interface BundleActivator {
@@ -69,7 +69,7 @@
/**
* Called when this bundle is stopped so the Framework can perform the
* bundle-specific activities necessary to stop the bundle. In general, this
- * method should undo the work that the {@code BundleActivator.start}
+ * method should undo the work that the <code>BundleActivator.start</code>
* method started. There should be no active threads that were started by
* this bundle when this bundle returns. A stopped bundle must not call any
* Framework objects.
diff --git a/framework/src/main/java/org/osgi/framework/BundleContext.java b/framework/src/main/java/org/osgi/framework/BundleContext.java
index c587d03..44b3801 100644
--- a/framework/src/main/java/org/osgi/framework/BundleContext.java
+++ b/framework/src/main/java/org/osgi/framework/BundleContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
import java.io.File;
import java.io.InputStream;
-import java.util.Collection;
import java.util.Dictionary;
/**
@@ -27,107 +26,100 @@
* Framework.
*
* <p>
- * {@code BundleContext} methods allow a bundle to:
+ * <code>BundleContext</code> methods allow a bundle to:
* <ul>
* <li>Subscribe to events published by the Framework.
* <li>Register service objects with the Framework service registry.
- * <li>Retrieve {@code ServiceReferences} from the Framework service registry.
+ * <li>Retrieve <code>ServiceReferences</code> from the Framework service
+ * registry.
* <li>Get and release service objects for a referenced service.
* <li>Install new bundles in the Framework.
* <li>Get the list of bundles installed in the Framework.
* <li>Get the {@link Bundle} object for a bundle.
- * <li>Create {@code File} objects for files in a persistent storage area
- * provided for the bundle by the Framework.
+ * <li>Create <code>File</code> objects for files in a persistent storage
+ * area provided for the bundle by the Framework.
* </ul>
*
* <p>
- * A {@code BundleContext} object will be created for a bundle when the bundle
- * is started. The {@code Bundle} object associated with a {@code BundleContext}
- * object is called the <em>context bundle</em>.
- *
- * <p>
- * The {@code BundleContext} object will be passed to the
- * {@link BundleActivator#start} method during activation of the context bundle.
- * The same {@code BundleContext} object will be passed to the
- * {@link BundleActivator#stop} method when the context bundle is stopped. A
- * {@code BundleContext} object is generally for the private use of its
+ * A <code>BundleContext</code> object will be created and provided to the
+ * bundle associated with this context when it is started using the
+ * {@link BundleActivator#start} method. The same <code>BundleContext</code>
+ * object will be passed to the bundle associated with this context when it is
+ * stopped using the {@link BundleActivator#stop} method. A
+ * <code>BundleContext</code> object is generally for the private use of its
* associated bundle and is not meant to be shared with other bundles in the
* OSGi environment.
*
* <p>
- * The {@code BundleContext} object is only valid during the execution of its
- * context bundle; that is, during the period from when the context bundle is in
- * the {@code STARTING}, {@code STOPPING}, and {@code ACTIVE} bundle states. If
- * the {@code BundleContext} object is used subsequently, an
- * {@code IllegalStateException} must be thrown. The {@code BundleContext}
- * object must never be reused after its context bundle is stopped.
+ * The <code>Bundle</code> object associated with a <code>BundleContext</code>
+ * object is called the <em>context bundle</em>.
*
* <p>
- * Two {@code BundleContext} objects are equal if they both refer to the same
- * execution context of a bundle. The Framework is the only entity that can
- * create {@code BundleContext} objects and they are only valid within the
- * Framework that created them.
+ * The <code>BundleContext</code> object is only valid during the execution of
+ * its context bundle; that is, during the period from when the context bundle
+ * is in the <code>STARTING</code>, <code>STOPPING</code>, and
+ * <code>ACTIVE</code> bundle states. If the <code>BundleContext</code>
+ * object is used subsequently, an <code>IllegalStateException</code> must be
+ * thrown. The <code>BundleContext</code> object must never be reused after
+ * its context bundle is stopped.
*
* <p>
- * A {@link Bundle} can be {@link Bundle#adapt(Class) adapted} to its
- * {@code BundleContext}. In order for this to succeed, the caller must have the
- * appropriate {@code AdminPermission[bundle,CONTEXT]} if the Java Runtime
- * Environment supports permissions.
+ * The Framework is the only entity that can create <code>BundleContext</code>
+ * objects and they are only valid within the Framework that created them.
*
* @ThreadSafe
- * @noimplement
- * @version $Id: 6d4b5967b9fe706b1dfbdd42b3d759028ed9826d $
+ * @version $Revision: 6781 $
*/
-public interface BundleContext extends BundleReference {
-
+public interface BundleContext {
/**
* Returns the value of the specified property. If the key is not found in
* the Framework properties, the system properties are then searched. The
- * method returns {@code null} if the property is not found.
+ * method returns <code>null</code> if the property is not found.
*
* <p>
* All bundles must have permission to read properties whose names start
* with "org.osgi.".
*
* @param key The name of the requested property.
- * @return The value of the requested property, or {@code null} if the
+ * @return The value of the requested property, or <code>null</code> if the
* property is undefined.
* @throws SecurityException If the caller does not have the appropriate
- * {@code PropertyPermission} to read the property, and the Java
- * Runtime Environment supports permissions.
+ * <code>PropertyPermission</code> to read the property, and the
+ * Java Runtime Environment supports permissions.
*/
- String getProperty(String key);
+ public String getProperty(String key);
/**
- * Returns the {@code Bundle} object associated with this
- * {@code BundleContext}. This bundle is called the context bundle.
+ * Returns the <code>Bundle</code> object associated with this
+ * <code>BundleContext</code>. This bundle is called the context bundle.
*
- * @return The {@code Bundle} object associated with this
- * {@code BundleContext}.
- * @throws IllegalStateException If this BundleContext is no longer valid.
+ * @return The <code>Bundle</code> object associated with this
+ * <code>BundleContext</code>.
+ * @throws IllegalStateException If this BundleContext is no
+ * longer valid.
*/
- Bundle getBundle();
+ public Bundle getBundle();
/**
- * Installs a bundle from the specified {@code InputStream} object.
+ * Installs a bundle from the specified <code>InputStream</code> object.
*
* <p>
- * If the specified {@code InputStream} is {@code null}, the Framework must
- * create the {@code InputStream} from which to read the bundle by
- * interpreting, in an implementation dependent manner, the specified
- * {@code location}.
+ * If the specified <code>InputStream</code> is <code>null</code>, the
+ * Framework must create the <code>InputStream</code> from which to read the
+ * bundle by interpreting, in an implementation dependent manner, the
+ * specified <code>location</code>.
*
* <p>
- * The specified {@code location} identifier will be used as the identity of
- * the bundle. Every installed bundle is uniquely identified by its location
- * identifier which is typically in the form of a URL.
+ * The specified <code>location</code> identifier will be used as the
+ * identity of the bundle. Every installed bundle is uniquely identified by
+ * its location identifier which is typically in the form of a URL.
*
* <p>
* The following steps are required to install a bundle:
* <ol>
* <li>If a bundle containing the same location identifier is already
- * installed, the {@code Bundle} object for that bundle is returned.
+ * installed, the <code>Bundle</code> object for that bundle is returned.
*
* <li>The bundle's content is read from the input stream. If this fails, a
* {@link BundleException} is thrown.
@@ -135,80 +127,71 @@
* <li>The bundle's associated resources are allocated. The associated
* resources minimally consist of a unique identifier and a persistent
* storage area if the platform has file system support. If this step fails,
- * a {@code BundleException} is thrown.
+ * a <code>BundleException</code> is thrown.
*
- * <li>The bundle's state is set to {@code INSTALLED}.
+ * <li>The bundle's state is set to <code>INSTALLED</code>.
*
* <li>A bundle event of type {@link BundleEvent#INSTALLED} is fired.
*
- * <li>The {@code Bundle} object for the newly or previously installed
+ * <li>The <code>Bundle</code> object for the newly or previously installed
* bundle is returned.
* </ol>
*
* <b>Postconditions, no exceptions thrown </b>
* <ul>
- * <li>{@code getState()} in { {@code INSTALLED}, {@code RESOLVED}
- * }.
+ * <li><code>getState()</code> in { <code>INSTALLED</code>,
+ * <code>RESOLVED</code> }.
* <li>Bundle has a unique ID.
* </ul>
* <b>Postconditions, when an exception is thrown </b>
* <ul>
- * <li>Bundle is not installed. If there was an existing bundle for the
- * specified location, then that bundle must still be in the state it was
- * prior to calling this method.</li>
+ * <li>Bundle is not installed and no trace of the bundle exists.
* </ul>
*
* @param location The location identifier of the bundle to install.
- * @param input The {@code InputStream} object from which this bundle will
- * be read or {@code null} to indicate the Framework must create the
- * input stream from the specified location identifier. The input
- * stream must always be closed when this method completes, even if
- * an exception is thrown.
- * @return The {@code Bundle} object of the installed bundle.
- * @throws BundleException If the installation failed. BundleException types
- * thrown by this method include: {@link BundleException#READ_ERROR}
- * , {@link BundleException#DUPLICATE_BUNDLE_ERROR},
- * {@link BundleException#MANIFEST_ERROR}, and
- * {@link BundleException#REJECTED_BY_HOOK}.
+ * @param input The <code>InputStream</code> object from which this bundle
+ * will be read or <code>null</code> to indicate the Framework must
+ * create the input stream from the specified location identifier.
+ * The input stream must always be closed when this method completes,
+ * even if an exception is thrown.
+ * @return The <code>Bundle</code> object of the installed bundle.
+ * @throws BundleException If the input stream cannot be read or the
+ * installation failed.
* @throws SecurityException If the caller does not have the appropriate
- * {@code AdminPermission[installed bundle,LIFECYCLE]}, and the Java
- * Runtime Environment supports permissions.
+ * <code>AdminPermission[installed bundle,LIFECYCLE]</code>, and the
+ * Java Runtime Environment supports permissions.
* @throws IllegalStateException If this BundleContext is no longer valid.
*/
- Bundle installBundle(String location, InputStream input)
+ public Bundle installBundle(String location, InputStream input)
throws BundleException;
/**
- * Installs a bundle from the specified {@code location} identifier.
+ * Installs a bundle from the specified <code>location</code> identifier.
*
* <p>
* This method performs the same function as calling
* {@link #installBundle(String,InputStream)} with the specified
- * {@code location} identifier and a {@code null} InputStream.
+ * <code>location</code> identifier and a <code>null</code> InputStream.
*
* @param location The location identifier of the bundle to install.
- * @return The {@code Bundle} object of the installed bundle.
- * @throws BundleException If the installation failed. BundleException types
- * thrown by this method include: {@link BundleException#READ_ERROR}
- * , {@link BundleException#DUPLICATE_BUNDLE_ERROR},
- * {@link BundleException#MANIFEST_ERROR}, and
- * {@link BundleException#REJECTED_BY_HOOK}.
+ * @return The <code>Bundle</code> object of the installed bundle.
+ * @throws BundleException If the installation failed.
* @throws SecurityException If the caller does not have the appropriate
- * {@code AdminPermission[installed bundle,LIFECYCLE]}, and the Java
- * Runtime Environment supports permissions.
+ * <code>AdminPermission[installed bundle,LIFECYCLE]</code>, and the
+ * Java Runtime Environment supports permissions.
* @throws IllegalStateException If this BundleContext is no longer valid.
* @see #installBundle(String, InputStream)
*/
- Bundle installBundle(String location) throws BundleException;
+ public Bundle installBundle(String location) throws BundleException;
/**
* Returns the bundle with the specified identifier.
*
* @param id The identifier of the bundle to retrieve.
- * @return A {@code Bundle} object or {@code null} if the identifier does
- * not match any installed bundle.
+ * @return A <code>Bundle</code> object or <code>null</code> if the
+ * identifier does not match any installed bundle.
*/
- Bundle getBundle(long id);
+ public Bundle getBundle(long id);
/**
* Returns a list of all installed bundles.
@@ -218,164 +201,179 @@
* Framework is a very dynamic environment, bundles can be installed or
* uninstalled at anytime.
*
- * @return An array of {@code Bundle} objects, one object per installed
- * bundle.
+ * @return An array of <code>Bundle</code> objects, one object per
+ * installed bundle.
*/
- Bundle[] getBundles();
+ public Bundle[] getBundles();
/**
- * Adds the specified {@code ServiceListener} object with the specified
- * {@code filter} to the context bundle's list of listeners. See
- * {@link Filter} for a description of the filter syntax.
- * {@code ServiceListener} objects are notified when a service has a
+ * Adds the specified <code>ServiceListener</code> object with the
+ * specified <code>filter</code> to the context bundle's list of
+ * listeners. See {@link Filter} for a description of the filter syntax.
+ * <code>ServiceListener</code> objects are notified when a service has a
* lifecycle state change.
*
* <p>
* If the context bundle's list of listeners already contains a listener
- * {@code l} such that {@code (l==listener)}, then this method replaces that
- * listener's filter (which may be {@code null}) with the specified one
- * (which may be {@code null}).
+ * <code>l</code> such that <code>(l==listener)</code>, then this
+ * method replaces that listener's filter (which may be <code>null</code>)
+ * with the specified one (which may be <code>null</code>).
*
* <p>
* The listener is called if the filter criteria is met. To filter based
* upon the class of the service, the filter should reference the
- * {@link Constants#OBJECTCLASS} property. If {@code filter} is {@code null}
- * , all services are considered to match the filter.
+ * {@link Constants#OBJECTCLASS} property. If <code>filter</code> is
+ * <code>null</code>, all services are considered to match the filter.
*
* <p>
- * When using a {@code filter}, it is possible that the {@code ServiceEvent}
- * s for the complete lifecycle of a service will not be delivered to the
- * listener. For example, if the {@code filter} only matches when the
- * property {@code x} has the value {@code 1}, the listener will not be
- * called if the service is registered with the property {@code x} not set
- * to the value {@code 1}. Subsequently, when the service is modified
- * setting property {@code x} to the value {@code 1}, the filter will match
- * and the listener will be called with a {@code ServiceEvent} of type
- * {@code MODIFIED}. Thus, the listener will not be called with a
- * {@code ServiceEvent} of type {@code REGISTERED}.
+ * When using a <code>filter</code>, it is possible that the
+ * <code>ServiceEvent</code>s for the complete lifecycle of a service
+ * will not be delivered to the listener. For example, if the
+ * <code>filter</code> only matches when the property <code>x</code> has
+ * the value <code>1</code>, the listener will not be called if the
+ * service is registered with the property <code>x</code> not set to the
+ * value <code>1</code>. Subsequently, when the service is modified
+ * setting property <code>x</code> to the value <code>1</code>, the
+ * filter will match and the listener will be called with a
+ * <code>ServiceEvent</code> of type <code>MODIFIED</code>. Thus, the
+ * listener will not be called with a <code>ServiceEvent</code> of type
+ * <code>REGISTERED</code>.
*
* <p>
* If the Java Runtime Environment supports permissions, the
- * {@code ServiceListener} object will be notified of a service event only
- * if the bundle that is registering it has the {@code ServicePermission} to
- * get the service using at least one of the named classes the service was
- * registered under.
+ * <code>ServiceListener</code> object will be notified of a service event
+ * only if the bundle that is registering it has the
+ * <code>ServicePermission</code> to get the service using at least one of
+ * the named classes the service was registered under.
*
- * @param listener The {@code ServiceListener} object to be added.
+ * @param listener The <code>ServiceListener</code> object to be added.
* @param filter The filter criteria.
- * @throws InvalidSyntaxException If {@code filter} contains an invalid
- * filter string that cannot be parsed.
- * @throws IllegalStateException If this BundleContext is no longer valid.
+ * @throws InvalidSyntaxException If <code>filter</code> contains an
+ * invalid filter string that cannot be parsed.
+ * @throws IllegalStateException If this BundleContext is no
+ * longer valid.
* @see ServiceEvent
* @see ServiceListener
* @see ServicePermission
*/
- void addServiceListener(ServiceListener listener, String filter)
+ public void addServiceListener(ServiceListener listener, String filter)
throws InvalidSyntaxException;
/**
- * Adds the specified {@code ServiceListener} object to the context bundle's
- * list of listeners.
+ * Adds the specified <code>ServiceListener</code> object to the context
+ * bundle's list of listeners.
*
* <p>
* This method is the same as calling
- * {@code BundleContext.addServiceListener(ServiceListener listener,
- * String filter)} with {@code filter} set to {@code null}.
+ * <code>BundleContext.addServiceListener(ServiceListener listener,
+ * String filter)</code>
+ * with <code>filter</code> set to <code>null</code>.
*
- * @param listener The {@code ServiceListener} object to be added.
- * @throws IllegalStateException If this BundleContext is no longer valid.
+ * @param listener The <code>ServiceListener</code> object to be added.
+ * @throws IllegalStateException If this BundleContext is no
+ * longer valid.
* @see #addServiceListener(ServiceListener, String)
*/
- void addServiceListener(ServiceListener listener);
+ public void addServiceListener(ServiceListener listener);
/**
- * Removes the specified {@code ServiceListener} object from the context
- * bundle's list of listeners.
+ * Removes the specified <code>ServiceListener</code> object from the
+ * context bundle's list of listeners.
*
* <p>
- * If {@code listener} is not contained in this context bundle's list of
- * listeners, this method does nothing.
+ * If <code>listener</code> is not contained in this context bundle's list
+ * of listeners, this method does nothing.
*
- * @param listener The {@code ServiceListener} to be removed.
- * @throws IllegalStateException If this BundleContext is no longer valid.
+ * @param listener The <code>ServiceListener</code> to be removed.
+ * @throws IllegalStateException If this BundleContext is no
+ * longer valid.
*/
- void removeServiceListener(ServiceListener listener);
+ public void removeServiceListener(ServiceListener listener);
/**
- * Adds the specified {@code BundleListener} object to the context bundle's
- * list of listeners if not already present. BundleListener objects are
- * notified when a bundle has a lifecycle state change.
+ * Adds the specified <code>BundleListener</code> object to the context
+ * bundle's list of listeners if not already present. BundleListener objects
+ * are notified when a bundle has a lifecycle state change.
*
* <p>
* If the context bundle's list of listeners already contains a listener
- * {@code l} such that {@code (l==listener)}, this method does nothing.
+ * <code>l</code> such that <code>(l==listener)</code>, this method
+ * does nothing.
*
- * @param listener The {@code BundleListener} to be added.
- * @throws IllegalStateException If this BundleContext is no longer valid.
+ * @param listener The <code>BundleListener</code> to be added.
+ * @throws IllegalStateException If this BundleContext is no
+ * longer valid.
* @throws SecurityException If listener is a
- * {@code SynchronousBundleListener} and the caller does not have
- * the appropriate {@code AdminPermission[context bundle,LISTENER]},
- * and the Java Runtime Environment supports permissions.
+ * <code>SynchronousBundleListener</code> and the caller does not
+ * have the appropriate
+ * <code>AdminPermission[context bundle,LISTENER]</code>, and the
+ * Java Runtime Environment supports permissions.
* @see BundleEvent
* @see BundleListener
*/
- void addBundleListener(BundleListener listener);
+ public void addBundleListener(BundleListener listener);
/**
- * Removes the specified {@code BundleListener} object from the context
- * bundle's list of listeners.
+ * Removes the specified <code>BundleListener</code> object from the
+ * context bundle's list of listeners.
*
* <p>
- * If {@code listener} is not contained in the context bundle's list of
- * listeners, this method does nothing.
+ * If <code>listener</code> is not contained in the context bundle's list
+ * of listeners, this method does nothing.
*
- * @param listener The {@code BundleListener} object to be removed.
- * @throws IllegalStateException If this BundleContext is no longer valid.
+ * @param listener The <code>BundleListener</code> object to be removed.
+ * @throws IllegalStateException If this BundleContext is no
+ * longer valid.
* @throws SecurityException If listener is a
- * {@code SynchronousBundleListener} and the caller does not have
- * the appropriate {@code AdminPermission[context bundle,LISTENER]},
- * and the Java Runtime Environment supports permissions.
+ * <code>SynchronousBundleListener</code> and the caller does not
+ * have the appropriate
+ * <code>AdminPermission[context bundle,LISTENER]</code>, and the
+ * Java Runtime Environment supports permissions.
*/
- void removeBundleListener(BundleListener listener);
+ public void removeBundleListener(BundleListener listener);
/**
- * Adds the specified {@code FrameworkListener} object to the context
+ * Adds the specified <code>FrameworkListener</code> object to the context
* bundle's list of listeners if not already present. FrameworkListeners are
* notified of general Framework events.
*
* <p>
* If the context bundle's list of listeners already contains a listener
- * {@code l} such that {@code (l==listener)}, this method does nothing.
+ * <code>l</code> such that <code>(l==listener)</code>, this method
+ * does nothing.
*
- * @param listener The {@code FrameworkListener} object to be added.
- * @throws IllegalStateException If this BundleContext is no longer valid.
+ * @param listener The <code>FrameworkListener</code> object to be added.
+ * @throws IllegalStateException If this BundleContext is no
+ * longer valid.
* @see FrameworkEvent
* @see FrameworkListener
*/
- void addFrameworkListener(FrameworkListener listener);
+ public void addFrameworkListener(FrameworkListener listener);
/**
- * Removes the specified {@code FrameworkListener} object from the context
- * bundle's list of listeners.
+ * Removes the specified <code>FrameworkListener</code> object from the
+ * context bundle's list of listeners.
*
* <p>
- * If {@code listener} is not contained in the context bundle's list of
- * listeners, this method does nothing.
+ * If <code>listener</code> is not contained in the context bundle's list
+ * of listeners, this method does nothing.
*
- * @param listener The {@code FrameworkListener} object to be removed.
- * @throws IllegalStateException If this BundleContext is no longer valid.
+ * @param listener The <code>FrameworkListener</code> object to be
+ * removed.
+ * @throws IllegalStateException If this BundleContext is no
+ * longer valid.
*/
- void removeFrameworkListener(FrameworkListener listener);
+ public void removeFrameworkListener(FrameworkListener listener);
/**
* Registers the specified service object with the specified properties
* under the specified class names into the Framework. A
- * {@code ServiceRegistration} object is returned. The
- * {@code ServiceRegistration} object is for the private use of the bundle
- * registering the service and should not be shared with other bundles. The
- * registering bundle is defined to be the context bundle. Other bundles can
- * locate the service by using either the {@link #getServiceReferences} or
- * {@link #getServiceReference} method.
+ * <code>ServiceRegistration</code> object is returned. The
+ * <code>ServiceRegistration</code> object is for the private use of the
+ * bundle registering the service and should not be shared with other
+ * bundles. The registering bundle is defined to be the context bundle.
+ * Other bundles can locate the service by using either the
+ * {@link #getServiceReferences} or {@link #getServiceReference} method.
*
* <p>
* A bundle can register a service object that implements the
@@ -385,57 +383,59 @@
* <p>
* The following steps are required to register a service:
* <ol>
- * <li>If {@code service} is not a {@code ServiceFactory}, an
- * {@code IllegalArgumentException} is thrown if {@code service} is not an
- * {@code instanceof} all the specified class names.
+ * <li>If <code>service</code> is not a <code>ServiceFactory</code>, an
+ * <code>IllegalArgumentException</code> is thrown if <code>service</code>
+ * is not an <code>instanceof</code> all the specified class names.
* <li>The Framework adds the following service properties to the service
- * properties from the specified {@code Dictionary} (which may be
- * {@code null}): <br/>
+ * properties from the specified <code>Dictionary</code> (which may be
+ * <code>null</code>): <br/>
* A property named {@link Constants#SERVICE_ID} identifying the
* registration number of the service <br/>
* A property named {@link Constants#OBJECTCLASS} containing all the
* specified classes. <br/>
- * Properties with these names in the specified {@code Dictionary} will be
- * ignored.
+ * Properties with these names in the specified <code>Dictionary</code> will
+ * be ignored.
* <li>The service is added to the Framework service registry and may now be
* used by other bundles.
* <li>A service event of type {@link ServiceEvent#REGISTERED} is fired.
- * <li>A {@code ServiceRegistration} object for this registration is
+ * <li>A <code>ServiceRegistration</code> object for this registration is
* returned.
* </ol>
*
* @param clazzes The class names under which the service can be located.
* The class names in this array will be stored in the service's
* properties under the key {@link Constants#OBJECTCLASS}.
- * @param service The service object or a {@code ServiceFactory} object.
+ * @param service The service object or a <code>ServiceFactory</code>
+ * object.
* @param properties The properties for this service. The keys in the
- * properties object must all be {@code String} objects. See
+ * properties object must all be <code>String</code> objects. See
* {@link Constants} for a list of standard service property keys.
* Changes should not be made to this object after calling this
* method. To update the service's properties the
* {@link ServiceRegistration#setProperties} method must be called.
- * The set of properties may be {@code null} if the service has no
- * properties.
- * @return A {@code ServiceRegistration} object for use by the bundle
+ * The set of properties may be <code>null</code> if the service has
+ * no properties.
+ * @return A <code>ServiceRegistration</code> object for use by the bundle
* registering the service to update the service's properties or to
* unregister the service.
* @throws IllegalArgumentException If one of the following is true:
* <ul>
- * <li>{@code service} is {@code null}. <li>{@code service} is not a
- * {@code ServiceFactory} object and is not an instance of all the
- * named classes in {@code clazzes}. <li> {@code properties}
- * contains case variants of the same key name.
+ * <li><code>service</code> is <code>null</code>. <li><code>service
+ * </code> is not a <code>ServiceFactory</code> object and is not an
+ * instance of all the named classes in <code>clazzes</code>. <li>
+ * <code>properties</code> contains case variants of the same key
+ * name.
* </ul>
* @throws SecurityException If the caller does not have the
- * {@code ServicePermission} to register the service for all the
- * named classes and the Java Runtime Environment supports
+ * <code>ServicePermission</code> to register the service for all
+ * the named classes and the Java Runtime Environment supports
* permissions.
* @throws IllegalStateException If this BundleContext is no longer valid.
* @see ServiceRegistration
* @see ServiceFactory
*/
- ServiceRegistration< ? > registerService(String[] clazzes, Object service,
- Dictionary<String, ? > properties);
+ public ServiceRegistration registerService(String[] clazzes,
+ Object service, Dictionary properties);
/**
* Registers the specified service object with the specified properties
@@ -444,53 +444,28 @@
* <p>
* This method is otherwise identical to
* {@link #registerService(String[], Object, Dictionary)} and is provided as
- * a convenience when {@code service} will only be registered under a single
- * class name. Note that even in this case the value of the service's
+ * a convenience when <code>service</code> will only be registered under a
+ * single class name. Note that even in this case the value of the service's
* {@link Constants#OBJECTCLASS} property will be an array of string, rather
* than just a single string.
*
* @param clazz The class name under which the service can be located.
- * @param service The service object or a {@code ServiceFactory} object.
+ * @param service The service object or a <code>ServiceFactory</code>
+ * object.
* @param properties The properties for this service.
- * @return A {@code ServiceRegistration} object for use by the bundle
+ * @return A <code>ServiceRegistration</code> object for use by the bundle
* registering the service to update the service's properties or to
* unregister the service.
* @throws IllegalStateException If this BundleContext is no longer valid.
* @see #registerService(String[], Object, Dictionary)
*/
- ServiceRegistration< ? > registerService(String clazz, Object service,
- Dictionary<String, ? > properties);
+ public ServiceRegistration registerService(String clazz, Object service,
+ Dictionary properties);
/**
- * Registers the specified service object with the specified properties
- * under the specified class name with the Framework.
- *
- * <p>
- * This method is otherwise identical to
- * {@link #registerService(String[], Object, Dictionary)} and is provided as
- * a convenience when {@code service} will only be registered under a single
- * class name. Note that even in this case the value of the service's
- * {@link Constants#OBJECTCLASS} property will be an array of string, rather
- * than just a single string.
- *
- * @param <S> Type of Service.
- * @param clazz The class name under which the service can be located.
- * @param service The service object or a {@code ServiceFactory} object.
- * @param properties The properties for this service.
- * @return A {@code ServiceRegistration} object for use by the bundle
- * registering the service to update the service's properties or to
- * unregister the service.
- * @throws IllegalStateException If this BundleContext is no longer valid.
- * @see #registerService(String[], Object, Dictionary)
- * @since 1.6
- */
- <S> ServiceRegistration<S> registerService(Class<S> clazz, S service,
- Dictionary<String, ? > properties);
-
- /**
- * Returns an array of {@code ServiceReference} objects. The returned array
- * of {@code ServiceReference} objects contains services that were
- * registered under the specified class, match the specified filter
+ * Returns an array of <code>ServiceReference</code> objects. The returned
+ * array of <code>ServiceReference</code> objects contains services that
+ * were registered under the specified class, match the specified filter
* expression, and the packages for the class names under which the services
* were registered match the context bundle's packages as defined in
* {@link ServiceReference#isAssignableTo(Bundle, String)}.
@@ -501,51 +476,53 @@
* unregistered at any time.
*
* <p>
- * The specified {@code filter} expression is used to select the registered
- * services whose service properties contain keys and values which satisfy
- * the filter expression. See {@link Filter} for a description of the filter
- * syntax. If the specified {@code filter} is {@code null}, all registered
- * services are considered to match the filter. If the specified
- * {@code filter} expression cannot be parsed, an
- * {@link InvalidSyntaxException} will be thrown with a human readable
+ * The specified <code>filter</code> expression is used to select the
+ * registered services whose service properties contain keys and values
+ * which satisfy the filter expression. See {@link Filter} for a description
+ * of the filter syntax. If the specified <code>filter</code> is
+ * <code>null</code>, all registered services are considered to match the
+ * filter. If the specified <code>filter</code> expression cannot be parsed,
+ * an {@link InvalidSyntaxException} will be thrown with a human readable
* message where the filter became unparsable.
*
* <p>
- * The result is an array of {@code ServiceReference} objects for all
+ * The result is an array of <code>ServiceReference</code> objects for all
* services that meet all of the following conditions:
* <ul>
- * <li>If the specified class name, {@code clazz}, is not {@code null}, the
- * service must have been registered with the specified class name. The
- * complete list of class names with which a service was registered is
- * available from the service's {@link Constants#OBJECTCLASS objectClass}
- * property.
- * <li>If the specified {@code filter} is not {@code null}, the filter
- * expression must match the service.
+ * <li>If the specified class name, <code>clazz</code>, is not
+ * <code>null</code>, the service must have been registered with the
+ * specified class name. The complete list of class names with which a
+ * service was registered is available from the service's
+ * {@link Constants#OBJECTCLASS objectClass} property.
+ * <li>If the specified <code>filter</code> is not <code>null</code>, the
+ * filter expression must match the service.
* <li>If the Java Runtime Environment supports permissions, the caller must
- * have {@code ServicePermission} with the {@code GET} action for at least
- * one of the class names under which the service was registered.
+ * have <code>ServicePermission</code> with the <code>GET</code> action for
+ * at least one of the class names under which the service was registered.
* <li>For each class name with which the service was registered, calling
* {@link ServiceReference#isAssignableTo(Bundle, String)} with the context
- * bundle and the class name on the service's {@code ServiceReference}
- * object must return {@code true}
+ * bundle and the class name on the service's <code>ServiceReference</code>
+ * object must return <code>true</code>
* </ul>
*
* @param clazz The class name with which the service was registered or
- * {@code null} for all services.
- * @param filter The filter expression or {@code null} for all services.
- * @return An array of {@code ServiceReference} objects or {@code null} if
- * no services are registered which satisfy the search.
- * @throws InvalidSyntaxException If the specified {@code filter} contains
- * an invalid filter expression that cannot be parsed.
+ * <code>null</code> for all services.
+ * @param filter The filter expression or <code>null</code> for all
+ * services.
+ * @return An array of <code>ServiceReference</code> objects or
+ * <code>null</code> if no services are registered which satisfy the
+ * search.
+ * @throws InvalidSyntaxException If the specified <code>filter</code>
+ * contains an invalid filter expression that cannot be parsed.
* @throws IllegalStateException If this BundleContext is no longer valid.
*/
- ServiceReference< ? >[] getServiceReferences(String clazz, String filter)
+ public ServiceReference[] getServiceReferences(String clazz, String filter)
throws InvalidSyntaxException;
/**
- * Returns an array of {@code ServiceReference} objects. The returned array
- * of {@code ServiceReference} objects contains services that were
- * registered under the specified class and match the specified filter
+ * Returns an array of <code>ServiceReference</code> objects. The returned
+ * array of <code>ServiceReference</code> objects contains services that
+ * were registered under the specified class and match the specified filter
* expression.
*
* <p>
@@ -554,91 +531,61 @@
* unregistered at any time.
*
* <p>
- * The specified {@code filter} expression is used to select the registered
- * services whose service properties contain keys and values which satisfy
- * the filter expression. See {@link Filter} for a description of the filter
- * syntax. If the specified {@code filter} is {@code null}, all registered
- * services are considered to match the filter. If the specified
- * {@code filter} expression cannot be parsed, an
- * {@link InvalidSyntaxException} will be thrown with a human readable
+ * The specified <code>filter</code> expression is used to select the
+ * registered services whose service properties contain keys and values
+ * which satisfy the filter expression. See {@link Filter} for a description
+ * of the filter syntax. If the specified <code>filter</code> is
+ * <code>null</code>, all registered services are considered to match the
+ * filter. If the specified <code>filter</code> expression cannot be parsed,
+ * an {@link InvalidSyntaxException} will be thrown with a human readable
* message where the filter became unparsable.
*
* <p>
- * The result is an array of {@code ServiceReference} objects for all
+ * The result is an array of <code>ServiceReference</code> objects for all
* services that meet all of the following conditions:
* <ul>
- * <li>If the specified class name, {@code clazz}, is not {@code null}, the
- * service must have been registered with the specified class name. The
- * complete list of class names with which a service was registered is
- * available from the service's {@link Constants#OBJECTCLASS objectClass}
- * property.
- * <li>If the specified {@code filter} is not {@code null}, the filter
- * expression must match the service.
+ * <li>If the specified class name, <code>clazz</code>, is not
+ * <code>null</code>, the service must have been registered with the
+ * specified class name. The complete list of class names with which a
+ * service was registered is available from the service's
+ * {@link Constants#OBJECTCLASS objectClass} property.
+ * <li>If the specified <code>filter</code> is not <code>null</code>, the
+ * filter expression must match the service.
* <li>If the Java Runtime Environment supports permissions, the caller must
- * have {@code ServicePermission} with the {@code GET} action for at least
- * one of the class names under which the service was registered.
+ * have <code>ServicePermission</code> with the <code>GET</code> action for
+ * at least one of the class names under which the service was registered.
* </ul>
*
* @param clazz The class name with which the service was registered or
- * {@code null} for all services.
- * @param filter The filter expression or {@code null} for all services.
- * @return An array of {@code ServiceReference} objects or {@code null} if
- * no services are registered which satisfy the search.
- * @throws InvalidSyntaxException If the specified {@code filter} contains
- * an invalid filter expression that cannot be parsed.
+ * <code>null</code> for all services.
+ * @param filter The filter expression or <code>null</code> for all
+ * services.
+ * @return An array of <code>ServiceReference</code> objects or
+ * <code>null</code> if no services are registered which satisfy the
+ * search.
+ * @throws InvalidSyntaxException If the specified <code>filter</code>
+ * contains an invalid filter expression that cannot be parsed.
* @throws IllegalStateException If this BundleContext is no longer valid.
* @since 1.3
*/
- ServiceReference< ? >[] getAllServiceReferences(String clazz, String filter)
- throws InvalidSyntaxException;
+ public ServiceReference[] getAllServiceReferences(String clazz,
+ String filter) throws InvalidSyntaxException;
/**
- * Returns a {@code ServiceReference} object for a service that implements
- * and was registered under the specified class.
+ * Returns a <code>ServiceReference</code> object for a service that
+ * implements and was registered under the specified class.
*
* <p>
- * The returned {@code ServiceReference} object is valid at the time of the
- * call to this method. However as the Framework is a very dynamic
+ * The returned <code>ServiceReference</code> object is valid at the time of
+ * the call to this method. However as the Framework is a very dynamic
* environment, services can be modified or unregistered at any time.
*
* <p>
* This method is the same as calling
- * {@link #getServiceReferences(String, String)} with a {@code null} filter
- * expression and then finding the reference with the highest priority. It
- * is provided as a convenience for when the caller is interested in any
- * service that implements the specified class.
- * <p>
- * If multiple such services exist, the service with the highest priority is
- * selected. This priority is defined as the service reference with the
- * highest ranking (as specified in its {@link Constants#SERVICE_RANKING}
- * property) is returned.
- * <p>
- * If there is a tie in ranking, the service with the lowest service ID (as
- * specified in its {@link Constants#SERVICE_ID} property); that is, the
- * service that was registered first is returned.
- *
- * @param clazz The class name with which the service was registered.
- * @return A {@code ServiceReference} object, or {@code null} if no services
- * are registered which implement the named class.
- * @throws IllegalStateException If this BundleContext is no longer valid.
- * @see #getServiceReferences(String, String)
- */
- ServiceReference< ? > getServiceReference(String clazz);
-
- /**
- * Returns a {@code ServiceReference} object for a service that implements
- * and was registered under the specified class.
- *
- * <p>
- * The returned {@code ServiceReference} object is valid at the time of the
- * call to this method. However as the Framework is a very dynamic
- * environment, services can be modified or unregistered at any time.
- *
- * <p>
- * This method is the same as calling
- * {@link #getServiceReferences(Class, String)} with a {@code null} filter
- * expression. It is provided as a convenience for when the caller is
- * interested in any service that implements the specified class.
+ * {@link BundleContext#getServiceReferences(String, String)} with a
+ * <code>null</code> filter expression. It is provided as a convenience for
+ * when the caller is interested in any service that implements the
+ * specified class.
* <p>
* If multiple such services exist, the service with the highest ranking (as
* specified in its {@link Constants#SERVICE_RANKING} property) is returned.
@@ -647,76 +594,17 @@
* specified in its {@link Constants#SERVICE_ID} property); that is, the
* service that was registered first is returned.
*
- * @param <S> Type of Service.
* @param clazz The class name with which the service was registered.
- * @return A {@code ServiceReference} object, or {@code null} if no services
- * are registered which implement the named class.
+ * @return A <code>ServiceReference</code> object, or <code>null</code> if
+ * no services are registered which implement the named class.
* @throws IllegalStateException If this BundleContext is no longer valid.
- * @see #getServiceReferences(Class, String)
- * @since 1.6
+ * @see #getServiceReferences(String, String)
*/
- <S> ServiceReference<S> getServiceReference(Class<S> clazz);
-
- /**
- * Returns a collection of {@code ServiceReference} objects. The returned
- * collection of {@code ServiceReference} objects contains services that
- * were registered under the specified class, match the specified filter
- * expression, and the packages for the class names under which the services
- * were registered match the context bundle's packages as defined in
- * {@link ServiceReference#isAssignableTo(Bundle, String)}.
- *
- * <p>
- * The collection is valid at the time of the call to this method. However
- * since the Framework is a very dynamic environment, services can be
- * modified or unregistered at any time.
- *
- * <p>
- * The specified {@code filter} expression is used to select the registered
- * services whose service properties contain keys and values which satisfy
- * the filter expression. See {@link Filter} for a description of the filter
- * syntax. If the specified {@code filter} is {@code null}, all registered
- * services are considered to match the filter. If the specified
- * {@code filter} expression cannot be parsed, an
- * {@link InvalidSyntaxException} will be thrown with a human readable
- * message where the filter became unparsable.
- *
- * <p>
- * The result is a collection of {@code ServiceReference} objects for all
- * services that meet all of the following conditions:
- * <ul>
- * <li>If the specified class name, {@code clazz}, is not {@code null}, the
- * service must have been registered with the specified class name. The
- * complete list of class names with which a service was registered is
- * available from the service's {@link Constants#OBJECTCLASS objectClass}
- * property.
- * <li>If the specified {@code filter} is not {@code null}, the filter
- * expression must match the service.
- * <li>If the Java Runtime Environment supports permissions, the caller must
- * have {@code ServicePermission} with the {@code GET} action for at least
- * one of the class names under which the service was registered.
- * <li>For each class name with which the service was registered, calling
- * {@link ServiceReference#isAssignableTo(Bundle, String)} with the context
- * bundle and the class name on the service's {@code ServiceReference}
- * object must return {@code true}
- * </ul>
- *
- * @param <S> Type of Service
- * @param clazz The class name with which the service was registered. Must
- * not be {@code null}.
- * @param filter The filter expression or {@code null} for all services.
- * @return A collection of {@code ServiceReference} objects. May be empty if
- * no services are registered which satisfy the search.
- * @throws InvalidSyntaxException If the specified {@code filter} contains
- * an invalid filter expression that cannot be parsed.
- * @throws IllegalStateException If this BundleContext is no longer valid.
- * @since 1.6
- */
- <S> Collection<ServiceReference<S>> getServiceReferences(Class<S> clazz,
- String filter) throws InvalidSyntaxException;
+ public ServiceReference getServiceReference(String clazz);
/**
* Returns the service object referenced by the specified
- * {@code ServiceReference} object.
+ * <code>ServiceReference</code> object.
* <p>
* A bundle's use of a service is tracked by the bundle's use count of that
* service. Each time a service's service object is returned by
@@ -729,59 +617,60 @@
* no longer use that service.
*
* <p>
- * This method will always return {@code null} when the service associated
- * with this {@code reference} has been unregistered.
+ * This method will always return <code>null</code> when the service
+ * associated with this <code>reference</code> has been unregistered.
*
* <p>
* The following steps are required to get the service object:
* <ol>
- * <li>If the service has been unregistered, {@code null} is returned.
- * <li>If the context bundle's use count for the service is currently zero
- * and the service was registered with an object implementing the
- * {@code ServiceFactory} interface, the
- * {@link ServiceFactory#getService(Bundle, ServiceRegistration)} method is
- * called to create a service object for the context bundle. If the service
- * object returned by the {@code ServiceFactory} object is {@code null}, not
- * an {@code instanceof} all the classes named when the service was
- * registered or the {@code ServiceFactory} object throws an exception or
- * will be recursively called for the context bundle, {@code null} is
- * returned and a Framework event of type {@link FrameworkEvent#ERROR}
- * containing a {@link ServiceException} describing the error is fired. <br>
- * This service object is cached by the Framework. While the context
- * bundle's use count for the service is greater than zero, subsequent calls
- * to get the services's service object for the context bundle will return
- * the cached service object.
+ * <li>If the service has been unregistered, <code>null</code> is returned.
* <li>The context bundle's use count for this service is incremented by
* one.
+ * <li>If the context bundle's use count for the service is currently one
+ * and the service was registered with an object implementing the
+ * <code>ServiceFactory</code> interface, the
+ * {@link ServiceFactory#getService(Bundle, ServiceRegistration)} method is
+ * called to create a service object for the context bundle. This service
+ * object is cached by the Framework. While the context bundle's use count
+ * for the service is greater than zero, subsequent calls to get the
+ * services's service object for the context bundle will return the cached
+ * service object. <br>
+ * If the service object returned by the <code>ServiceFactory</code> object
+ * is not an <code>instanceof</code> all the classes named when the service
+ * was registered or the <code>ServiceFactory</code> object throws an
+ * exception, <code>null</code> is returned and a Framework event of type
+ * {@link FrameworkEvent#ERROR} containing a {@link ServiceException}
+ * describing the error is fired.
* <li>The service object for the service is returned.
* </ol>
*
- * @param <S> Type of Service.
* @param reference A reference to the service.
* @return A service object for the service associated with
- * {@code reference} or {@code null} if the service is not
+ * <code>reference</code> or <code>null</code> if the service is not
* registered, the service object returned by a
- * {@code ServiceFactory} does not implement the classes under which
- * it was registered or the {@code ServiceFactory} threw an
- * exception.
+ * <code>ServiceFactory</code> does not implement the classes under
+ * which it was registered or the <code>ServiceFactory</code> threw
+ * an exception.
* @throws SecurityException If the caller does not have the
- * {@code ServicePermission} to get the service using at least one
- * of the named classes the service was registered under and the
+ * <code>ServicePermission</code> to get the service using at least
+ * one of the named classes the service was registered under and the
* Java Runtime Environment supports permissions.
- * @throws IllegalStateException If this BundleContext is no longer valid.
+ * @throws IllegalStateException If this BundleContext is no
+ * longer valid.
* @throws IllegalArgumentException If the specified
- * {@code ServiceReference} was not created by the same framework
- * instance as this {@code BundleContext}.
+ * <code>ServiceReference</code> was not created by the same
+ * framework instance as this <code>BundleContext</code>.
* @see #ungetService(ServiceReference)
* @see ServiceFactory
*/
- <S> S getService(ServiceReference<S> reference);
+ public Object getService(ServiceReference reference);
/**
* Releases the service object referenced by the specified
- * {@code ServiceReference} object. If the context bundle's use count for
- * the service is zero, this method returns {@code false}. Otherwise, the
- * context bundle's use count for the service is decremented by one.
+ * <code>ServiceReference</code> object. If the context bundle's use count
+ * for the service is zero, this method returns <code>false</code>.
+ * Otherwise, the context bundle's use count for the service is decremented
+ * by one.
*
* <p>
* The service's service object should no longer be used and all references
@@ -792,81 +681,76 @@
* The following steps are required to unget the service object:
* <ol>
* <li>If the context bundle's use count for the service is zero or the
- * service has been unregistered, {@code false} is returned.
+ * service has been unregistered, <code>false</code> is returned.
* <li>The context bundle's use count for this service is decremented by
* one.
* <li>If the context bundle's use count for the service is currently zero
- * and the service was registered with a {@code ServiceFactory} object, the
+ * and the service was registered with a <code>ServiceFactory</code> object,
+ * the
* {@link ServiceFactory#ungetService(Bundle, ServiceRegistration, Object)}
* method is called to release the service object for the context bundle.
- * <li>{@code true} is returned.
+ * <li><code>true</code> is returned.
* </ol>
*
* @param reference A reference to the service to be released.
- * @return {@code false} if the context bundle's use count for the service
- * is zero or if the service has been unregistered; {@code true}
- * otherwise.
- * @throws IllegalStateException If this BundleContext is no longer valid.
+ * @return <code>false</code> if the context bundle's use count for the
+ * service is zero or if the service has been unregistered;
+ * <code>true</code> otherwise.
+ * @throws IllegalStateException If this BundleContext is no
+ * longer valid.
* @throws IllegalArgumentException If the specified
- * {@code ServiceReference} was not created by the same framework
- * instance as this {@code BundleContext}.
+ * <code>ServiceReference</code> was not created by the same
+ * framework instance as this <code>BundleContext</code>.
* @see #getService
* @see ServiceFactory
*/
- boolean ungetService(ServiceReference< ? > reference);
+ public boolean ungetService(ServiceReference reference);
/**
- * Creates a {@code File} object for a file in the persistent storage area
- * provided for the bundle by the Framework. This method will return
- * {@code null} if the platform does not have file system support.
+ * Creates a <code>File</code> object for a file in the persistent storage
+ * area provided for the bundle by the Framework. This method will return
+ * <code>null</code> if the platform does not have file system support.
*
* <p>
- * A {@code File} object for the base directory of the persistent storage
- * area provided for the context bundle by the Framework can be obtained by
- * calling this method with an empty string as {@code filename}.
+ * A <code>File</code> object for the base directory of the persistent
+ * storage area provided for the context bundle by the Framework can be
+ * obtained by calling this method with an empty string as
+ * <code>filename</code>.
*
* <p>
* If the Java Runtime Environment supports permissions, the Framework will
- * ensure that the bundle has the {@code java.io.FilePermission} with
- * actions {@code read},{@code write},{@code delete} for all files
- * (recursively) in the persistent storage area provided for the context
- * bundle.
+ * ensure that the bundle has the <code>java.io.FilePermission</code> with
+ * actions <code>read</code>,<code>write</code>,<code>delete</code>
+ * for all files (recursively) in the persistent storage area provided for
+ * the context bundle.
*
* @param filename A relative name to the file to be accessed.
- * @return A {@code File} object that represents the requested file or
- * {@code null} if the platform does not have file system support.
- * @throws IllegalStateException If this BundleContext is no longer valid.
+ * @return A <code>File</code> object that represents the requested file
+ * or <code>null</code> if the platform does not have file system
+ * support.
+ * @throws IllegalStateException If this BundleContext is no
+ * longer valid.
*/
- File getDataFile(String filename);
+ public File getDataFile(String filename);
/**
- * Creates a {@code Filter} object. This {@code Filter} object may be used
- * to match a {@code ServiceReference} object or a {@code Dictionary}
- * object.
+ * Creates a <code>Filter</code> object. This <code>Filter</code> object may
+ * be used to match a <code>ServiceReference</code> object or a
+ * <code>Dictionary</code> object.
*
* <p>
* If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
* thrown with a human readable message where the filter became unparsable.
*
* @param filter The filter string.
- * @return A {@code Filter} object encapsulating the filter string.
- * @throws InvalidSyntaxException If {@code filter} contains an invalid
+ * @return A <code>Filter</code> object encapsulating the filter string.
+ * @throws InvalidSyntaxException If <code>filter</code> contains an invalid
* filter string that cannot be parsed.
- * @throws NullPointerException If {@code filter} is null.
+ * @throws NullPointerException If <code>filter</code> is null.
* @throws IllegalStateException If this BundleContext is no longer valid.
* @see "Framework specification for a description of the filter string syntax."
* @see FrameworkUtil#createFilter(String)
* @since 1.1
*/
- Filter createFilter(String filter) throws InvalidSyntaxException;
-
- /**
- * Returns the bundle with the specified location.
- *
- * @param location The location of the bundle to retrieve.
- * @return A {@code Bundle} object or {@code null} if the location does not
- * match any installed bundle.
- * @since 1.6
- */
- Bundle getBundle(String location);
+ public Filter createFilter(String filter) throws InvalidSyntaxException;
}
diff --git a/framework/src/main/java/org/osgi/framework/BundleEvent.java b/framework/src/main/java/org/osgi/framework/BundleEvent.java
index 13c68be..7a8fb8d 100644
--- a/framework/src/main/java/org/osgi/framework/BundleEvent.java
+++ b/framework/src/main/java/org/osgi/framework/BundleEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,8 +21,8 @@
/**
* An event from the Framework describing a bundle lifecycle change.
* <p>
- * {@code BundleEvent} objects are delivered to
- * {@code SynchronousBundleListener}s and {@code BundleListener}s
+ * <code>BundleEvent</code> objects are delivered to
+ * <code>SynchronousBundleListener</code>s and <code>BundleListener</code>s
* when a change occurs in a bundle's lifecycle. A type code is used to identify
* the event type for future extendability.
*
@@ -32,7 +32,7 @@
* @Immutable
* @see BundleListener
* @see SynchronousBundleListener
- * @version $Id: ed3c40cd707bed45681cadce114a6cc5db27a844 $
+ * @version $Revision: 6542 $
*/
public class BundleEvent extends EventObject {
@@ -113,7 +113,7 @@
* {@link BundleActivator#start(BundleContext) BundleActivator start} method
* is about to be called if the bundle has a bundle activator class. This
* event is only delivered to {@link SynchronousBundleListener}s. It is not
- * delivered to {@code BundleListener}s.
+ * delivered to <code>BundleListener</code>s.
*
* @see Bundle#start()
* @since 1.3
@@ -127,7 +127,7 @@
* {@link BundleActivator#stop(BundleContext) BundleActivator stop} method
* is about to be called if the bundle has a bundle activator class. This
* event is only delivered to {@link SynchronousBundleListener}s. It is not
- * delivered to {@code BundleListener}s.
+ * delivered to <code>BundleListener</code>s.
*
* @see Bundle#stop()
* @since 1.3
@@ -140,55 +140,25 @@
* The bundle has a {@link Constants#ACTIVATION_LAZY lazy activation policy}
* and is waiting to be activated. It is now in the
* {@link Bundle#STARTING STARTING} state and has a valid
- * {@code BundleContext}. This event is only delivered to
+ * <code>BundleContext</code>. This event is only delivered to
* {@link SynchronousBundleListener}s. It is not delivered to
- * {@code BundleListener}s.
+ * <code>BundleListener</code>s.
*
* @since 1.4
*/
public final static int LAZY_ACTIVATION = 0x00000200;
/**
- * Bundle that was the origin of the event. For install event type, this is
- * the bundle whose context was used to install the bundle. Otherwise it is
- * the bundle itself.
- *
- * @since 1.6
- */
- private final Bundle origin;
-
- /**
* Creates a bundle event of the specified type.
*
* @param type The event type.
* @param bundle The bundle which had a lifecycle change.
- * @param origin The bundle which is the origin of the event. For the event
- * type {@link #INSTALLED}, this is the bundle whose context was used
- * to install the bundle. Otherwise it is the bundle itself.
- * @since 1.6
*/
- public BundleEvent(int type, Bundle bundle, Bundle origin) {
- super(bundle);
- if (origin == null) {
- throw new IllegalArgumentException("null origin");
- }
- this.bundle = bundle;
- this.type = type;
- this.origin = origin;
- }
- /**
- * Creates a bundle event of the specified type.
- *
- * @param type The event type.
- * @param bundle The bundle which had a lifecycle change. This bundle is
- * used as the origin of the event.
- */
public BundleEvent(int type, Bundle bundle) {
super(bundle);
this.bundle = bundle;
this.type = type;
- this.origin = bundle;
}
/**
@@ -218,21 +188,8 @@
*
* @return The type of lifecycle event.
*/
+
public int getType() {
return type;
}
-
- /**
- * Returns the bundle that was the origin of the event.
- *
- * <p>
- * For the event type {@link #INSTALLED}, this is the bundle whose context
- * was used to install the bundle. Otherwise it is the bundle itself.
- *
- * @return The bundle that was the origin of the event.
- * @since 1.6
- */
- public Bundle getOrigin() {
- return origin;
- }
}
diff --git a/framework/src/main/java/org/osgi/framework/BundleException.java b/framework/src/main/java/org/osgi/framework/BundleException.java
index 9cae61a..500d147 100644
--- a/framework/src/main/java/org/osgi/framework/BundleException.java
+++ b/framework/src/main/java/org/osgi/framework/BundleException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,9 +21,9 @@
* occurred.
*
* <p>
- * A {@code BundleException} object is created by the Framework to denote
+ * A <code>BundleException</code> object is created by the Framework to denote
* an exception condition in the lifecycle of a bundle.
- * {@code BundleException}s should not be created by bundle developers.
+ * <code>BundleException</code>s should not be created by bundle developers.
* A type code is used to identify the exception type for future extendability.
*
* <p>
@@ -32,7 +32,7 @@
* <p>
* This exception conforms to the general purpose exception chaining mechanism.
*
- * @version $Id: 9e117ec9667b040f7752e342aa07d6c7d5bf0275 $
+ * @version $Revision: 6083 $
*/
public class BundleException extends Exception {
@@ -45,14 +45,13 @@
private final int type;
/**
- * No exception type is specified.
+ * No exception type is unspecified.
*
* @since 1.5
*/
public static final int UNSPECIFIED = 0;
/**
- * The operation was unsupported. This type can be used anywhere a
- * BundleException can be thrown.
+ * The operation was unsupported.
*
* @since 1.5
*/
@@ -103,12 +102,8 @@
public static final int NATIVECODE_ERROR = 8;
/**
- * The install or update operation failed because another already installed
- * bundle has the same symbolic name and version. This exception type will
- * only occur if the framework is configured to only allow a single bundle
- * to be installed for a given symbolic name and version.
- *
- * @see Constants#FRAMEWORK_BSNVERSION
+ * The install or update operation failed because another
+ * already installed bundle has the same symbolic name and version.
* @since 1.5
*/
public static final int DUPLICATE_BUNDLE_ERROR = 9;
@@ -122,22 +117,7 @@
public static final int START_TRANSIENT_ERROR = 10;
/**
- * The framework received an error while reading the input stream for a
- * bundle.
- *
- * @since 1.6
- */
- public static final int READ_ERROR = 11;
-
- /**
- * A framework hook rejected the operation.
- *
- * @since 1.6
- */
- public static final int REJECTED_BY_HOOK = 12;
-
- /**
- * Creates a {@code BundleException} with the specified message and
+ * Creates a <code>BundleException</code> with the specified message and
* exception cause.
*
* @param msg The associated message.
@@ -148,7 +128,7 @@
}
/**
- * Creates a {@code BundleException} with the specified message.
+ * Creates a <code>BundleException</code> with the specified message.
*
* @param msg The message.
*/
@@ -157,7 +137,7 @@
}
/**
- * Creates a {@code BundleException} with the specified message, type
+ * Creates a <code>BundleException</code> with the specified message, type
* and exception cause.
*
* @param msg The associated message.
@@ -171,7 +151,7 @@
}
/**
- * Creates a {@code BundleException} with the specified message and
+ * Creates a <code>BundleException</code> with the specified message and
* type.
*
* @param msg The message.
@@ -184,29 +164,29 @@
}
/**
- * Returns the cause of this exception or {@code null} if no cause was
+ * Returns the cause of this exception or <code>null</code> if no cause was
* specified when this exception was created.
*
* <p>
* This method predates the general purpose exception chaining mechanism.
- * The {@code getCause()} method is now the preferred means of
+ * The <code>getCause()</code> method is now the preferred means of
* obtaining this information.
*
- * @return The result of calling {@code getCause()}.
+ * @return The result of calling <code>getCause()</code>.
*/
public Throwable getNestedException() {
return getCause();
}
/**
- * Returns the cause of this exception or {@code null} if no cause was
+ * Returns the cause of this exception or <code>null</code> if no cause was
* set.
*
- * @return The cause of this exception or {@code null} if no cause was
+ * @return The cause of this exception or <code>null</code> if no cause was
* set.
* @since 1.3
*/
- public Throwable getCause() {
+ public Throwable getCause() {
return super.getCause();
}
@@ -226,7 +206,7 @@
}
/**
- * Returns the type for this exception or {@code UNSPECIFIED} if the
+ * Returns the type for this exception or <code>UNSPECIFIED</code> if the
* type was unspecified or unknown.
*
* @return The type of this exception.
diff --git a/framework/src/main/java/org/osgi/framework/BundleListener.java b/framework/src/main/java/org/osgi/framework/BundleListener.java
index d9bb54c..9dd7151 100644
--- a/framework/src/main/java/org/osgi/framework/BundleListener.java
+++ b/framework/src/main/java/org/osgi/framework/BundleListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,29 +19,29 @@
import java.util.EventListener;
/**
- * A {@code BundleEvent} listener. {@code BundleListener} is a
+ * A <code>BundleEvent</code> listener. <code>BundleListener</code> is a
* listener interface that may be implemented by a bundle developer. When a
- * {@code BundleEvent} is fired, it is asynchronously delivered to a
- * {@code BundleListener}. The Framework delivers
- * {@code BundleEvent} objects to a {@code BundleListener} in
- * order and must not concurrently call a {@code BundleListener}.
+ * <code>BundleEvent</code> is fired, it is asynchronously delivered to a
+ * <code>BundleListener</code>. The Framework delivers
+ * <code>BundleEvent</code> objects to a <code>BundleListener</code> in
+ * order and must not concurrently call a <code>BundleListener</code>.
* <p>
- * A {@code BundleListener} object is registered with the Framework using
+ * A <code>BundleListener</code> object is registered with the Framework using
* the {@link BundleContext#addBundleListener} method.
- * {@code BundleListener}s are called with a {@code BundleEvent}
+ * <code>BundleListener</code>s are called with a <code>BundleEvent</code>
* object when a bundle has been installed, resolved, started, stopped, updated,
* unresolved, or uninstalled.
*
* @see BundleEvent
* @NotThreadSafe
- * @version $Id: 77cdaebd3ac97c6798fc3043957abd1bd6d01ccb $
+ * @version $Revision: 5673 $
*/
public interface BundleListener extends EventListener {
/**
* Receives notification that a bundle has had a lifecycle change.
*
- * @param event The {@code BundleEvent}.
+ * @param event The <code>BundleEvent</code>.
*/
public void bundleChanged(BundleEvent event);
}
diff --git a/framework/src/main/java/org/osgi/framework/BundlePermission.java b/framework/src/main/java/org/osgi/framework/BundlePermission.java
index e6f9356..8677e69 100644
--- a/framework/src/main/java/org/osgi/framework/BundlePermission.java
+++ b/framework/src/main/java/org/osgi/framework/BundlePermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,12 +23,10 @@
import java.security.BasicPermission;
import java.security.Permission;
import java.security.PermissionCollection;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
-import java.util.List;
import java.util.Map;
/**
@@ -52,13 +50,13 @@
* </pre>
*
* <p>
- * {@code BundlePermission} has four actions: {@code provide},
- * {@code require},{@code host}, and {@code fragment}. The
- * {@code provide} action implies the {@code require} action.
+ * <code>BundlePermission</code> has four actions: <code>provide</code>,
+ * <code>require</code>,<code>host</code>, and <code>fragment</code>. The
+ * <code>provide</code> action implies the <code>require</code> action.
*
* @since 1.3
* @ThreadSafe
- * @version $Id: d30c9c987cc13007ed19d3a9fdd11b00739591c0 $
+ * @version $Revision: 6860 $
*/
public final class BundlePermission extends BasicPermission {
@@ -66,24 +64,24 @@
private static final long serialVersionUID = 3257846601685873716L;
/**
- * The action string {@code provide}. The {@code provide} action
- * implies the {@code require} action.
+ * The action string <code>provide</code>. The <code>provide</code> action
+ * implies the <code>require</code> action.
*/
public final static String PROVIDE = "provide";
/**
- * The action string {@code require}. The {@code require} action
- * is implied by the {@code provide} action.
+ * The action string <code>require</code>. The <code>require</code> action
+ * is implied by the <code>provide</code> action.
*/
public final static String REQUIRE = "require";
/**
- * The action string {@code host}.
+ * The action string <code>host</code>.
*/
public final static String HOST = "host";
/**
- * The action string {@code fragment}.
+ * The action string <code>fragment</code>.
*/
public final static String FRAGMENT = "fragment";
@@ -115,14 +113,14 @@
* Bundle Permissions are granted over all possible versions of a bundle.
*
* A bundle that needs to provide a bundle must have the appropriate
- * {@code BundlePermission} for the symbolic name; a bundle that
- * requires a bundle must have the appropriate {@code BundlePermssion}
+ * <code>BundlePermission</code> for the symbolic name; a bundle that
+ * requires a bundle must have the appropriate <code>BundlePermssion</code>
* for that symbolic name; a bundle that specifies a fragment host must have
- * the appropriate {@code BundlePermission} for that symbolic name.
+ * the appropriate <code>BundlePermission</code> for that symbolic name.
*
* @param symbolicName The bundle symbolic name.
- * @param actions {@code provide},{@code require},
- * {@code host},{@code fragment} (canonical order).
+ * @param actions <code>provide</code>,<code>require</code>,
+ * <code>host</code>,<code>fragment</code> (canonical order).
*/
public BundlePermission(String symbolicName, String actions) {
this(symbolicName, parseActions(actions));
@@ -280,9 +278,9 @@
*
* <p>
* This method checks that the symbolic name of the target is implied by the
- * symbolic name of this object. The list of {@code BundlePermission}
+ * symbolic name of this object. The list of <code>BundlePermission</code>
* actions must either match or allow for the list of the target object to
- * imply the target {@code BundlePermission} action.
+ * imply the target <code>BundlePermission</code> action.
* <p>
* The permission to provide a bundle implies the permission to require the
* named symbolic name.
@@ -295,8 +293,8 @@
* </pre>
*
* @param p The requested permission.
- * @return {@code true} if the specified {@code BundlePermission}
- * action is implied by this object; {@code false} otherwise.
+ * @return <code>true</code> if the specified <code>BundlePermission</code>
+ * action is implied by this object; <code>false</code> otherwise.
*/
public boolean implies(Permission p) {
if (!(p instanceof BundlePermission)) {
@@ -312,15 +310,15 @@
/**
* Returns the canonical string representation of the
- * {@code BundlePermission} actions.
+ * <code>BundlePermission</code> actions.
*
* <p>
- * Always returns present {@code BundlePermission} actions in the
- * following order: {@code provide}, {@code require},
- * {@code host}, {@code fragment}.
+ * Always returns present <code>BundlePermission</code> actions in the
+ * following order: <code>provide</code>, <code>require</code>,
+ * <code>host</code>, <code>fragment</code>.
*
- * @return Canonical string representation of the {@code BundlePermission
- * } actions.
+ * @return Canonical string representation of the <code>BundlePermission
+ * </code> actions.
*/
public String getActions() {
String result = actions;
@@ -359,28 +357,28 @@
}
/**
- * Returns a new {@code PermissionCollection} object suitable for
- * storing {@code BundlePermission} objects.
+ * Returns a new <code>PermissionCollection</code> object suitable for
+ * storing <code>BundlePermission</code> objects.
*
- * @return A new {@code PermissionCollection} object.
+ * @return A new <code>PermissionCollection</code> object.
*/
public PermissionCollection newPermissionCollection() {
return new BundlePermissionCollection();
}
/**
- * Determines the equality of two {@code BundlePermission} objects.
+ * Determines the equality of two <code>BundlePermission</code> objects.
*
* This method checks that specified bundle has the same bundle symbolic
- * name and {@code BundlePermission} actions as this
- * {@code BundlePermission} object.
+ * name and <code>BundlePermission</code> actions as this
+ * <code>BundlePermission</code> object.
*
* @param obj The object to test for equality with this
- * {@code BundlePermission} object.
- * @return {@code true} if {@code obj} is a
- * {@code BundlePermission}, and has the same bundle symbolic
- * name and actions as this {@code BundlePermission} object;
- * {@code false} otherwise.
+ * <code>BundlePermission</code> object.
+ * @return <code>true</code> if <code>obj</code> is a
+ * <code>BundlePermission</code>, and has the same bundle symbolic
+ * name and actions as this <code>BundlePermission</code> object;
+ * <code>false</code> otherwise.
*/
public boolean equals(Object obj) {
if (obj == this) {
@@ -410,7 +408,7 @@
/**
* WriteObject is called to save the state of the
- * {@code BundlePermission} object to a stream. The actions are
+ * <code>BundlePermission</code> object to a stream. The actions are
* serialized, and the superclass takes care of the name.
*/
private synchronized void writeObject(java.io.ObjectOutputStream s)
@@ -435,7 +433,7 @@
}
/**
- * Stores a set of {@code BundlePermission} permissions.
+ * Stores a set of <code>BundlePermission</code> permissions.
*
* @see java.security.Permission
* @see java.security.Permissions
@@ -450,7 +448,7 @@
*
* @GuardedBy this
*/
- private transient Map<String, BundlePermission> permissions;
+ private transient Map permissions;
/**
* Boolean saying if "*" is in the collection.
@@ -465,17 +463,17 @@
*
*/
public BundlePermissionCollection() {
- permissions = new HashMap<String, BundlePermission>();
+ permissions = new HashMap();
all_allowed = false;
}
/**
* Add a permission to this permission collection.
*
- * @param permission The {@code BundlePermission} object to add.
+ * @param permission The <code>BundlePermission</code> object to add.
* @throws IllegalArgumentException If the permission is not a
- * {@code BundlePermission} instance.
- * @throws SecurityException If this {@code BundlePermissionCollection}
+ * <code>BundlePermission</code> instance.
+ * @throws SecurityException If this <code>BundlePermissionCollection</code>
* object has been marked read-only.
*/
public void add(final Permission permission) {
@@ -490,8 +488,8 @@
final BundlePermission bp = (BundlePermission) permission;
final String name = bp.getName();
synchronized (this) {
- Map<String, BundlePermission> pc = permissions;
- BundlePermission existing = pc.get(name);
+ Map pc = permissions;
+ BundlePermission existing = (BundlePermission) pc.get(name);
if (existing != null) {
final int oldMask = existing.getActionsMask();
final int newMask = bp.getActionsMask();
@@ -514,12 +512,12 @@
/**
* Determines if the specified permissions implies the permissions expressed
- * in {@code permission}.
+ * in <code>permission</code>.
*
* @param permission The Permission object to compare with this
- * {@code BundlePermission} object.
- * @return {@code true} if {@code permission} is a proper subset
- * of a permission in the set; {@code false} otherwise.
+ * <code>BundlePermission</code> object.
+ * @return <code>true</code> if <code>permission</code> is a proper subset
+ * of a permission in the set; <code>false</code> otherwise.
*/
public boolean implies(final Permission permission) {
if (!(permission instanceof BundlePermission)) {
@@ -532,10 +530,10 @@
BundlePermission bp;
synchronized (this) {
- Map<String, BundlePermission> pc = permissions;
+ Map pc = permissions;
/* short circuit if the "*" Permission was added */
if (all_allowed) {
- bp = pc.get("*");
+ bp = (BundlePermission) pc.get("*");
if (bp != null) {
effective |= bp.getActionsMask();
if ((effective & desired) == desired) {
@@ -543,7 +541,7 @@
}
}
}
- bp = pc.get(requestedName);
+ bp = (BundlePermission) pc.get(requestedName);
// strategy:
// Check for full match first. Then work our way up the
// name looking for matches on a.b.*
@@ -559,7 +557,7 @@
int offset = requestedName.length() - 1;
while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
requestedName = requestedName.substring(0, last + 1) + "*";
- bp = pc.get(requestedName);
+ bp = (BundlePermission) pc.get(requestedName);
if (bp != null) {
effective |= bp.getActionsMask();
if ((effective & desired) == desired) {
@@ -575,14 +573,13 @@
}
/**
- * Returns an enumeration of all {@code BundlePermission} objects in
+ * Returns an enumeration of all <code>BundlePermission</code> objects in
* the container.
*
- * @return Enumeration of all {@code BundlePermission} objects.
+ * @return Enumeration of all <code>BundlePermission</code> objects.
*/
- public synchronized Enumeration<Permission> elements() {
- List<Permission> all = new ArrayList<Permission>(permissions.values());
- return Collections.enumeration(all);
+ public synchronized Enumeration elements() {
+ return Collections.enumeration(permissions.values());
}
/* serialization logic */
@@ -592,8 +589,7 @@
private synchronized void writeObject(ObjectOutputStream out)
throws IOException {
- Hashtable<String, BundlePermission> hashtable = new Hashtable<String, BundlePermission>(
- permissions);
+ Hashtable hashtable = new Hashtable(permissions);
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("permissions", hashtable);
pfields.put("all_allowed", all_allowed);
@@ -603,9 +599,8 @@
private synchronized void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField gfields = in.readFields();
- Hashtable<String, BundlePermission> hashtable = (Hashtable<String, BundlePermission>) gfields
- .get("permissions", null);
- permissions = new HashMap<String, BundlePermission>(hashtable);
+ Hashtable hashtable = (Hashtable) gfields.get("permissions", null);
+ permissions = new HashMap(hashtable);
all_allowed = gfields.get("all_allowed", false);
}
}
diff --git a/framework/src/main/java/org/osgi/framework/BundleReference.java b/framework/src/main/java/org/osgi/framework/BundleReference.java
index 97340f7..f9c4183 100644
--- a/framework/src/main/java/org/osgi/framework/BundleReference.java
+++ b/framework/src/main/java/org/osgi/framework/BundleReference.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2009, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,16 +21,15 @@
*
* @since 1.5
* @ThreadSafe
- * @noimplement
- * @version $Id: e61bd3e020264b04022a430fe09a85ee3aabf1a3 $
+ * @version $Revision: 6860 $
*/
public interface BundleReference {
/**
- * Returns the {@code Bundle} object associated with this
- * {@code BundleReference}.
+ * Returns the <code>Bundle</code> object associated with this
+ * <code>BundleReference</code>.
*
- * @return The {@code Bundle} object associated with this
- * {@code BundleReference}.
+ * @return The <code>Bundle</code> object associated with this
+ * <code>BundleReference</code>.
*/
public Bundle getBundle();
}
diff --git a/framework/src/main/java/org/osgi/framework/CapabilityPermission.java b/framework/src/main/java/org/osgi/framework/CapabilityPermission.java
deleted file mode 100644
index bcac790..0000000
--- a/framework/src/main/java/org/osgi/framework/CapabilityPermission.java
+++ /dev/null
@@ -1,807 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
- *
- * Licensed 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.osgi.framework;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.ObjectStreamField;
-import java.security.AccessController;
-import java.security.BasicPermission;
-import java.security.Permission;
-import java.security.PermissionCollection;
-import java.security.PrivilegedAction;
-import java.util.AbstractMap;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A bundle's authority to provide or require a capability.
- * <ul>
- * <li>The {@code provide} action allows a bundle to provide a capability
- * matching the specified filter.
- * <li>The {@code require} action allows a bundle to require a capability
- * matching the specified filter.
- * </ul>
- *
- * @ThreadSafe
- * @version $Id: bab1ac06b46613f6cff39b291295d8b3e51d58ce $
- * @since 1.6
- */
-
-public final class CapabilityPermission extends BasicPermission {
- static final long serialVersionUID = -7662148639076511574L;
- /**
- * The action string {@code require}.
- */
- public final static String REQUIRE = "require";
- /**
- * The action string {@code provide}.
- */
- public final static String PROVIDE = "provide";
-
- private final static int ACTION_REQUIRE = 0x00000001;
- private final static int ACTION_PROVIDE = 0x00000002;
- private final static int ACTION_ALL = ACTION_REQUIRE
- | ACTION_PROVIDE;
- final static int ACTION_NONE = 0;
-
- /**
- * The actions mask.
- */
- transient int action_mask;
-
- /**
- * The actions in canonical form.
- *
- * @serial
- */
- private volatile String actions = null;
-
- /**
- * The attributes of the requested capability. Must be null if not
- * constructed with attributes.
- */
- transient final Map<String, Object> attributes;
-
- /**
- * The bundle of the requested capability. Must be null if not constructed
- * with bundle.
- */
- transient final Bundle bundle;
-
- /**
- * If this CapabilityPermission was constructed with a filter, this holds a
- * Filter matching object used to evaluate the filter in implies.
- */
- transient Filter filter;
-
- /**
- * This map holds the properties of the permission, used to match a filter
- * in implies. This is not initialized until necessary, and then cached in
- * this object.
- */
- private transient volatile Map<String, Object> properties;
-
- /**
- * Create a new CapabilityPermission.
- *
- * <p>
- * The name is specified as a dot-separated string. Wildcards may be used.
- *
- * <pre>
- * name ::= <namespace> | <namespace ending in ".*"> | *
- * </pre>
- *
- * Examples:
- *
- * <pre>
- * com.acme.capability.*
- * org.foo.capability
- * *
- * </pre>
- *
- * For the {@code require} action, the name can also be a filter expression.
- * The filter gives access to the capability attributes as well as the
- * following attributes:
- * <ul>
- * <li>signer - A Distinguished Name chain used to sign the bundle providing
- * the capability. Wildcards in a DN are not matched according to the filter
- * string rules, but according to the rules defined for a DN chain.</li>
- * <li>location - The location of the bundle providing the capability.</li>
- * <li>id - The bundle ID of the bundle providing the capability.</li>
- * <li>name - The symbolic name of the bundle providing the capability.</li>
- * <li>capability.namespace - The name space of the required capability.</li>
- * </ul>
- * Since the above attribute names may conflict with attribute names of a
- * capability, you can prefix an attribute name with '@' in the filter
- * expression to match against the capability attributes and not one of the
- * above attributes. Filter attribute names are processed in a case
- * sensitive manner.
- *
- * <p>
- * There are two possible actions: {@code require} and {@code provide}. The
- * {@code require} permission allows the owner of this permission to require
- * a capability matching the attributes. The {@code provide} permission
- * allows the bundle to provide a capability in the specified capability
- * name space.
- *
- * @param name The capability name space or a filter over the attributes.
- * @param actions {@code require},{@code provide} (canonical order)
- * @throws IllegalArgumentException If the specified name is a filter
- * expression and either the specified action is not {@code require}
- * or the filter has an invalid syntax.
- */
- public CapabilityPermission(String name, String actions) {
- this(name, parseActions(actions));
- if ((this.filter != null)
- && ((action_mask & ACTION_ALL) != ACTION_REQUIRE)) {
- throw new IllegalArgumentException(
- "invalid action string for filter expression");
- }
- }
-
- /**
- * Creates a new requested {@code CapabilityPermission} object to be used by
- * code that must perform {@code checkPermission} for the {@code require}
- * action. {@code CapabilityPermission} objects created with this
- * constructor cannot be added to a {@code CapabilityPermission} permission
- * collection.
- *
- * @param namespace The requested capability name space.
- * @param attributes The requested capability attributes.
- * @param providingBundle The bundle providing the requested capability.
- * @param actions The action {@code require}.
- * @throws IllegalArgumentException If the specified action is not
- * {@code require} or attributes or providingBundle are {@code null}
- * .
- */
- public CapabilityPermission(String namespace, Map<String, ? > attributes,
- Bundle providingBundle, String actions) {
- super(namespace);
- setTransients(namespace, parseActions(actions));
- if (attributes == null) {
- throw new IllegalArgumentException("attributes must not be null");
- }
- if (providingBundle == null) {
- throw new IllegalArgumentException("bundle must not be null");
- }
- this.attributes = new HashMap<String, Object>(attributes);
- this.bundle = providingBundle;
- if ((action_mask & ACTION_ALL) != ACTION_REQUIRE) {
- throw new IllegalArgumentException("invalid action string");
- }
- }
-
- /**
- * Package private constructor used by CapabilityPermissionCollection.
- *
- * @param name class name
- * @param mask action mask
- */
- CapabilityPermission(String name, int mask) {
- super(name);
- setTransients(name, mask);
- this.attributes = null;
- this.bundle = null;
- }
-
- /**
- * Called by constructors and when deserialized.
- *
- * @param mask action mask
- */
- private void setTransients(String name, int mask) {
- if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
- throw new IllegalArgumentException("invalid action string");
- }
- action_mask = mask;
- filter = parseFilter(name);
- }
-
- /**
- * Parse action string into action mask.
- *
- * @param actions Action string.
- * @return action mask.
- */
- private static int parseActions(String actions) {
- boolean seencomma = false;
-
- int mask = ACTION_NONE;
-
- if (actions == null) {
- return mask;
- }
-
- char[] a = actions.toCharArray();
-
- int i = a.length - 1;
- if (i < 0)
- return mask;
-
- while (i != -1) {
- char c;
-
- // skip whitespace
- while ((i != -1)
- && ((c = a[i]) == ' ' || c == '\r' || c == '\n'
- || c == '\f' || c == '\t'))
- i--;
-
- // check for the known strings
- int matchlen;
-
- if (i >= 6 && (a[i - 6] == 'r' || a[i - 6] == 'R')
- && (a[i - 5] == 'e' || a[i - 5] == 'E')
- && (a[i - 4] == 'q' || a[i - 4] == 'Q')
- && (a[i - 3] == 'u' || a[i - 3] == 'U')
- && (a[i - 2] == 'i' || a[i - 2] == 'I')
- && (a[i - 1] == 'r' || a[i - 1] == 'R')
- && (a[i] == 'e' || a[i] == 'E')) {
- matchlen = 7;
- mask |= ACTION_REQUIRE;
- }
- else
- if (i >= 6 && (a[i - 6] == 'p' || a[i - 6] == 'P')
- && (a[i - 5] == 'r' || a[i - 5] == 'R')
- && (a[i - 4] == 'o' || a[i - 4] == 'O')
- && (a[i - 3] == 'v' || a[i - 3] == 'V')
- && (a[i - 2] == 'i' || a[i - 2] == 'I')
- && (a[i - 1] == 'd' || a[i - 1] == 'D')
- && (a[i] == 'e' || a[i] == 'E')) {
- matchlen = 7;
- mask |= ACTION_PROVIDE;
- }
- else {
- // parse error
- throw new IllegalArgumentException("invalid permission: "
- + actions);
- }
-
- // make sure we didn't just match the tail of a word
- // like "ackbarfprovide". Also, skip to the comma.
- seencomma = false;
- while (i >= matchlen && !seencomma) {
- switch (a[i - matchlen]) {
- case ',' :
- seencomma = true;
- /* FALLTHROUGH */
- case ' ' :
- case '\r' :
- case '\n' :
- case '\f' :
- case '\t' :
- break;
- default :
- throw new IllegalArgumentException(
- "invalid permission: " + actions);
- }
- i--;
- }
-
- // point i at the location of the comma minus one (or -1).
- i -= matchlen;
- }
-
- if (seencomma) {
- throw new IllegalArgumentException("invalid permission: " + actions);
- }
-
- return mask;
- }
-
- /**
- * Parse filter string into a Filter object.
- *
- * @param filterString The filter string to parse.
- * @return a Filter for this bundle. If the specified filterString is not a
- * filter expression, then {@code null} is returned.
- * @throws IllegalArgumentException If the filter syntax is invalid.
- */
- private static Filter parseFilter(String filterString) {
- filterString = filterString.trim();
- if (filterString.charAt(0) != '(') {
- return null;
- }
-
- try {
- return FrameworkUtil.createFilter(filterString);
- }
- catch (InvalidSyntaxException e) {
- IllegalArgumentException iae = new IllegalArgumentException(
- "invalid filter");
- iae.initCause(e);
- throw iae;
- }
- }
-
- /**
- * Determines if a {@code CapabilityPermission} object "implies" the
- * specified permission.
- *
- * @param p The target permission to check.
- * @return {@code true} if the specified permission is implied by this
- * object; {@code false} otherwise.
- */
- public boolean implies(Permission p) {
- if (!(p instanceof CapabilityPermission)) {
- return false;
- }
- CapabilityPermission requested = (CapabilityPermission) p;
- if (bundle != null) {
- return false;
- }
- // if requested permission has a filter, then it is an invalid argument
- if (requested.filter != null) {
- return false;
- }
- return implies0(requested, ACTION_NONE);
- }
-
- /**
- * Internal implies method. Used by the implies and the permission
- * collection implies methods.
- *
- * @param requested The requested CapabilityPermission which has already be
- * validated as a proper argument. The requested CapabilityPermission
- * must not have a filter expression.
- * @param effective The effective actions with which to start.
- * @return {@code true} if the specified permission is implied by this
- * object; {@code false} otherwise.
- */
- boolean implies0(CapabilityPermission requested, int effective) {
- /* check actions first - much faster */
- effective |= action_mask;
- final int desired = requested.action_mask;
- if ((effective & desired) != desired) {
- return false;
- }
- /* Get filter if any */
- Filter f = filter;
- if (f == null) {
- return super.implies(requested);
- }
- return f.matches(requested.getProperties());
- }
-
- /**
- * Returns the canonical string representation of the actions. Always
- * returns present actions in the following order: {@code require},
- * {@code provide}.
- *
- * @return The canonical string representation of the actions.
- */
- public String getActions() {
- String result = actions;
- if (result == null) {
- StringBuffer sb = new StringBuffer();
- boolean comma = false;
-
- int mask = action_mask;
- if ((mask & ACTION_REQUIRE) == ACTION_REQUIRE) {
- sb.append(REQUIRE);
- comma = true;
- }
-
- if ((mask & ACTION_PROVIDE) == ACTION_PROVIDE) {
- if (comma)
- sb.append(',');
- sb.append(PROVIDE);
- }
-
- actions = result = sb.toString();
- }
-
- return result;
- }
-
- /**
- * Returns a new {@code PermissionCollection} object for storing
- * {@code CapabilityPermission} objects.
- *
- * @return A new {@code PermissionCollection} object suitable for storing
- * {@code CapabilityPermission} objects.
- */
- public PermissionCollection newPermissionCollection() {
- return new CapabilityPermissionCollection();
- }
-
- /**
- * Determines the equality of two CapabilityPermission objects.
- *
- * Checks that specified object has the same name and action as this
- * {@code CapabilityPermission}.
- *
- * @param obj The object to test for equality.
- * @return true if obj is a {@code CapabilityPermission}, and has the same
- * name and actions as this {@code CapabilityPermission} object;
- * {@code false} otherwise.
- */
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
-
- if (!(obj instanceof CapabilityPermission)) {
- return false;
- }
-
- CapabilityPermission cp = (CapabilityPermission) obj;
-
- return (action_mask == cp.action_mask)
- && getName().equals(cp.getName())
- && ((attributes == cp.attributes) || ((attributes != null) && (attributes
- .equals(cp.attributes))))
- && ((bundle == cp.bundle) || ((bundle != null) && bundle
- .equals(cp.bundle)));
- }
-
- /**
- * Returns the hash code value for this object.
- *
- * @return Hash code value for this object.
- */
- public int hashCode() {
- int h = 31 * 17 + getName().hashCode();
- h = 31 * h + getActions().hashCode();
- if (attributes != null) {
- h = 31 * h + attributes.hashCode();
- }
- if (bundle != null) {
- h = 31 * h + bundle.hashCode();
- }
- return h;
- }
-
- /**
- * WriteObject is called to save the state of this permission to a stream.
- * The actions are serialized, and the superclass takes care of the name.
- */
- private synchronized void writeObject(java.io.ObjectOutputStream s)
- throws IOException {
- if (bundle != null) {
- throw new NotSerializableException("cannot serialize");
- }
- // Write out the actions. The superclass takes care of the name
- // call getActions to make sure actions field is initialized
- if (actions == null)
- getActions();
- s.defaultWriteObject();
- }
-
- /**
- * readObject is called to restore the state of this permission from a
- * stream.
- */
- private synchronized void readObject(java.io.ObjectInputStream s)
- throws IOException, ClassNotFoundException {
- // Read in the action, then initialize the rest
- s.defaultReadObject();
- setTransients(getName(), parseActions(actions));
- }
-
- /**
- * Called by {@code <@link CapabilityPermission#implies(Permission)>}. This
- * method is only called on a requested permission which cannot have a
- * filter set.
- *
- * @return a map of properties for this permission.
- */
- private Map<String, Object> getProperties() {
- Map<String, Object> result = properties;
- if (result != null) {
- return result;
- }
- final Map<String, Object> props = new HashMap<String, Object>(5);
- props.put("capability.namespace", getName());
- if (bundle == null) {
- return properties = props;
- }
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- props.put("id", new Long(bundle.getBundleId()));
- props.put("location", bundle.getLocation());
- String name = bundle.getSymbolicName();
- if (name != null) {
- props.put("name", name);
- }
- SignerProperty signer = new SignerProperty(bundle);
- if (signer.isBundleSigned()) {
- props.put("signer", signer);
- }
- return null;
- }
- });
- return properties = new Properties(props, attributes);
- }
-
- static private final class Properties extends AbstractMap<String, Object> {
- private final Map<String, Object> properties;
- private final Map<String, Object> attributes;
- private transient volatile Set<Map.Entry<String, Object>> entries;
-
- Properties(Map<String, Object> properties,
- Map<String, Object> attributes) {
- this.properties = properties;
- this.attributes = attributes;
- entries = null;
- }
-
- public Object get(Object k) {
- if (!(k instanceof String)) {
- return null;
- }
- String key = (String) k;
- if (key.charAt(0) == '@') {
- return attributes.get(key.substring(1));
- }
- Object value = properties.get(key);
- if (value != null) { // fall back to service properties
- return value;
- }
- return attributes.get(key);
- }
-
- public Set<Map.Entry<String, Object>> entrySet() {
- if (entries != null) {
- return entries;
- }
- Set<Map.Entry<String, Object>> all = new HashSet<Map.Entry<String, Object>>(
- attributes.size() + properties.size());
- all.addAll(attributes.entrySet());
- all.addAll(properties.entrySet());
- return entries = Collections.unmodifiableSet(all);
- }
- }
-}
-
-/**
- * Stores a set of CapabilityPermission permissions.
- *
- * @see java.security.Permission
- * @see java.security.Permissions
- * @see java.security.PermissionCollection
- */
-final class CapabilityPermissionCollection extends PermissionCollection {
- static final long serialVersionUID = -615322242639008920L;
-
- /**
- * Table of permissions.
- *
- * @serial
- * @GuardedBy this
- */
- private Map<String, CapabilityPermission> permissions;
-
- /**
- * Boolean saying if "*" is in the collection.
- *
- * @serial
- * @GuardedBy this
- */
- private boolean all_allowed;
-
- /**
- * Table of permissions with filter expressions.
- *
- * @serial
- * @GuardedBy this
- */
- private Map<String, CapabilityPermission> filterPermissions;
-
- /**
- * Creates an empty CapabilityPermissionCollection object.
- */
- public CapabilityPermissionCollection() {
- permissions = new HashMap<String, CapabilityPermission>();
- all_allowed = false;
- }
-
- /**
- * Adds a permission to this permission collection.
- *
- * @param permission The Permission object to add.
- * @throws IllegalArgumentException If the specified permission is not a
- * CapabilityPermission object.
- * @throws SecurityException If this {@code CapabilityPermissionCollection}
- * object has been marked read-only.
- */
- public void add(final Permission permission) {
- if (!(permission instanceof CapabilityPermission)) {
- throw new IllegalArgumentException("invalid permission: "
- + permission);
- }
- if (isReadOnly()) {
- throw new SecurityException("attempt to add a Permission to a "
- + "readonly PermissionCollection");
- }
-
- final CapabilityPermission cp = (CapabilityPermission) permission;
- if (cp.bundle != null) {
- throw new IllegalArgumentException("cannot add to collection: "
- + cp);
- }
-
- final String name = cp.getName();
- final Filter f = cp.filter;
- synchronized (this) {
- /* select the bucket for the permission */
- Map<String, CapabilityPermission> pc;
- if (f != null) {
- pc = filterPermissions;
- if (pc == null) {
- filterPermissions = pc = new HashMap<String, CapabilityPermission>();
- }
- }
- else {
- pc = permissions;
- }
- final CapabilityPermission existing = pc.get(name);
-
- if (existing != null) {
- final int oldMask = existing.action_mask;
- final int newMask = cp.action_mask;
- if (oldMask != newMask) {
- pc.put(name, new CapabilityPermission(name, oldMask
- | newMask));
- }
- }
- else {
- pc.put(name, cp);
- }
-
- if (!all_allowed) {
- if (name.equals("*")) {
- all_allowed = true;
- }
- }
- }
- }
-
- /**
- * Determines if a set of permissions implies the permissions expressed in
- * {@code permission}.
- *
- * @param permission The Permission object to compare.
- * @return {@code true} if {@code permission} is a proper subset of a
- * permission in the set; {@code false} otherwise.
- */
- public boolean implies(final Permission permission) {
- if (!(permission instanceof CapabilityPermission)) {
- return false;
- }
- final CapabilityPermission requested = (CapabilityPermission) permission;
- /* if requested permission has a filter, then it is an invalid argument */
- if (requested.filter != null) {
- return false;
- }
-
- String requestedName = requested.getName();
- final int desired = requested.action_mask;
- int effective = CapabilityPermission.ACTION_NONE;
-
- Collection<CapabilityPermission> perms;
- synchronized (this) {
- Map<String, CapabilityPermission> pc = permissions;
- CapabilityPermission cp;
- /* short circuit if the "*" Permission was added */
- if (all_allowed) {
- cp = pc.get("*");
- if (cp != null) {
- effective |= cp.action_mask;
- if ((effective & desired) == desired) {
- return true;
- }
- }
- }
-
- /*
- * strategy: Check for full match first. Then work our way up the
- * name looking for matches on a.b.*
- */
- cp = pc.get(requestedName);
- if (cp != null) {
- /* we have a direct hit! */
- effective |= cp.action_mask;
- if ((effective & desired) == desired) {
- return true;
- }
- }
- /* work our way up the tree... */
- int last;
- int offset = requestedName.length() - 1;
- while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
- requestedName = requestedName.substring(0, last + 1) + "*";
- cp = pc.get(requestedName);
- if (cp != null) {
- effective |= cp.action_mask;
- if ((effective & desired) == desired) {
- return true;
- }
- }
- offset = last - 1;
- }
- /*
- * we don't have to check for "*" as it was already checked before
- * we were called.
- */
- pc = filterPermissions;
- if (pc == null) {
- return false;
- }
- perms = pc.values();
- }
- /* iterate one by one over filteredPermissions */
- for (CapabilityPermission perm : perms) {
- if (perm.implies0(requested, effective)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns an enumeration of all the {@code CapabilityPermission} objects in
- * the container.
- *
- * @return Enumeration of all the CapabilityPermission objects.
- */
- public synchronized Enumeration<Permission> elements() {
- List<Permission> all = new ArrayList<Permission>(permissions.values());
- Map<String, CapabilityPermission> pc = filterPermissions;
- if (pc != null) {
- all.addAll(pc.values());
- }
- return Collections.enumeration(all);
- }
-
- /* serialization logic */
- private static final ObjectStreamField[] serialPersistentFields = {
- new ObjectStreamField("permissions", HashMap.class),
- new ObjectStreamField("all_allowed", Boolean.TYPE),
- new ObjectStreamField("filterPermissions", HashMap.class) };
-
- private synchronized void writeObject(ObjectOutputStream out)
- throws IOException {
- ObjectOutputStream.PutField pfields = out.putFields();
- pfields.put("permissions", permissions);
- pfields.put("all_allowed", all_allowed);
- pfields.put("filterPermissions", filterPermissions);
- out.writeFields();
- }
-
- private synchronized void readObject(java.io.ObjectInputStream in)
- throws IOException, ClassNotFoundException {
- ObjectInputStream.GetField gfields = in.readFields();
- HashMap<String, CapabilityPermission> p = (HashMap<String, CapabilityPermission>) gfields
- .get("permissions", null);
- permissions = p;
- all_allowed = gfields.get("all_allowed", false);
- HashMap<String, CapabilityPermission> fp = (HashMap<String, CapabilityPermission>) gfields
- .get("filterPermissions", null);
- filterPermissions = fp;
- }
-}
diff --git a/framework/src/main/java/org/osgi/framework/Configurable.java b/framework/src/main/java/org/osgi/framework/Configurable.java
index d82da9b..b30910c 100644
--- a/framework/src/main/java/org/osgi/framework/Configurable.java
+++ b/framework/src/main/java/org/osgi/framework/Configurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,20 +20,20 @@
* Supports a configuration object.
*
* <p>
- * {@code Configurable} is an interface that should be used by a bundle
+ * <code>Configurable</code> is an interface that should be used by a bundle
* developer in support of a configurable service. Bundles that need to
* configure a service may test to determine if the service object is an
- * {@code instanceof Configurable}.
+ * <code>instanceof Configurable</code>.
*
* @deprecated As of 1.2. Please use Configuration Admin service.
- * @version $Id: 29705c0c238aa456cda1b1a13458079bf1542771 $
+ * @version $Revision: 6361 $
*/
public interface Configurable {
/**
* Returns this service's configuration object.
*
* <p>
- * Services implementing {@code Configurable} should take care when
+ * Services implementing <code>Configurable</code> should take care when
* returning a service configuration object since this object is probably
* sensitive.
* <p>
diff --git a/framework/src/main/java/org/osgi/framework/Constants.java b/framework/src/main/java/org/osgi/framework/Constants.java
index b71a12d..16a10d8 100644
--- a/framework/src/main/java/org/osgi/framework/Constants.java
+++ b/framework/src/main/java/org/osgi/framework/Constants.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,19 +16,16 @@
package org.osgi.framework;
-import org.osgi.framework.launch.Framework;
-
/**
* Defines standard names for the OSGi environment system properties, service
* properties, and Manifest header attribute keys.
*
* <p>
- * The values associated with these keys are of type {@code String}, unless
- * otherwise indicated.
+ * The values associated with these keys are of type
+ * <code>String</code>, unless otherwise indicated.
*
* @since 1.1
- * @noimplement
- * @version $Id: 517c954ed7d34d2ee762933466f69fa03db7cd37 $
+ * @version $Revision: 6552 $
*/
public interface Constants {
@@ -36,7 +33,7 @@
* Location identifier of the OSGi <i>system bundle </i>, which is defined
* to be "System Bundle".
*/
- String SYSTEM_BUNDLE_LOCATION = "System Bundle";
+ public static final String SYSTEM_BUNDLE_LOCATION = "System Bundle";
/**
* Alias for the symbolic name of the OSGi <i>system bundle </i>. It is
@@ -44,50 +41,50 @@
*
* @since 1.3
*/
- String SYSTEM_BUNDLE_SYMBOLICNAME = "system.bundle";
+ public static final String SYSTEM_BUNDLE_SYMBOLICNAME = "system.bundle";
/**
* Manifest header identifying the bundle's category.
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*/
- String BUNDLE_CATEGORY = "Bundle-Category";
+ public static final String BUNDLE_CATEGORY = "Bundle-Category";
/**
* Manifest header identifying a list of directories and embedded JAR files,
* which are bundle resources used to extend the bundle's classpath.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*/
- String BUNDLE_CLASSPATH = "Bundle-ClassPath";
+ public static final String BUNDLE_CLASSPATH = "Bundle-ClassPath";
/**
* Manifest header identifying the bundle's copyright information.
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*/
- String BUNDLE_COPYRIGHT = "Bundle-Copyright";
+ public static final String BUNDLE_COPYRIGHT = "Bundle-Copyright";
/**
* Manifest header containing a brief description of the bundle's
* functionality.
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*/
- String BUNDLE_DESCRIPTION = "Bundle-Description";
+ public static final String BUNDLE_DESCRIPTION = "Bundle-Description";
/**
* Manifest header identifying the bundle's name.
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*/
- String BUNDLE_NAME = "Bundle-Name";
+ public static final String BUNDLE_NAME = "Bundle-Name";
/**
* Manifest header identifying a number of hardware environments and the
@@ -95,20 +92,20 @@
* these environments.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*/
- String BUNDLE_NATIVECODE = "Bundle-NativeCode";
+ public static final String BUNDLE_NATIVECODE = "Bundle-NativeCode";
/**
* Manifest header identifying the packages that the bundle offers to the
* Framework for export.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*/
- String EXPORT_PACKAGE = "Export-Package";
+ public static final String EXPORT_PACKAGE = "Export-Package";
/**
* Manifest header identifying the fully qualified class names of the
@@ -116,108 +113,108 @@
* only).
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*
* @deprecated As of 1.2.
*/
- String EXPORT_SERVICE = "Export-Service";
+ public static final String EXPORT_SERVICE = "Export-Service";
/**
* Manifest header identifying the packages on which the bundle depends.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*/
- String IMPORT_PACKAGE = "Import-Package";
+ public static final String IMPORT_PACKAGE = "Import-Package";
/**
* Manifest header identifying the packages that the bundle may dynamically
* import during execution.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*
* @since 1.2
*/
- String DYNAMICIMPORT_PACKAGE = "DynamicImport-Package";
+ public static final String DYNAMICIMPORT_PACKAGE = "DynamicImport-Package";
/**
* Manifest header identifying the fully qualified class names of the
* services that the bundle requires (used for informational purposes only).
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*
* @deprecated As of 1.2.
*/
- String IMPORT_SERVICE = "Import-Service";
+ public static final String IMPORT_SERVICE = "Import-Service";
/**
* Manifest header identifying the bundle's vendor.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*/
- String BUNDLE_VENDOR = "Bundle-Vendor";
+ public static final String BUNDLE_VENDOR = "Bundle-Vendor";
/**
* Manifest header identifying the bundle's version.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*/
- String BUNDLE_VERSION = "Bundle-Version";
+ public static final String BUNDLE_VERSION = "Bundle-Version";
/**
* Manifest header identifying the bundle's documentation URL, from which
* further information about the bundle may be obtained.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*/
- String BUNDLE_DOCURL = "Bundle-DocURL";
+ public static final String BUNDLE_DOCURL = "Bundle-DocURL";
/**
* Manifest header identifying the contact address where problems with the
* bundle may be reported; for example, an email address.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*/
- String BUNDLE_CONTACTADDRESS = "Bundle-ContactAddress";
+ public static final String BUNDLE_CONTACTADDRESS = "Bundle-ContactAddress";
/**
* Manifest header attribute identifying the bundle's activator class.
*
* <p>
* If present, this header specifies the name of the bundle resource class
- * that implements the {@code BundleActivator} interface and whose
- * {@code start} and {@code stop} methods are called by the Framework when
- * the bundle is started and stopped, respectively.
+ * that implements the <code>BundleActivator</code> interface and whose
+ * <code>start</code> and <code>stop</code> methods are called by the
+ * Framework when the bundle is started and stopped, respectively.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*/
- String BUNDLE_ACTIVATOR = "Bundle-Activator";
+ public static final String BUNDLE_ACTIVATOR = "Bundle-Activator";
/**
* Manifest header identifying the location from which a new bundle version
* is obtained during a bundle update operation.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*/
- String BUNDLE_UPDATELOCATION = "Bundle-UpdateLocation";
+ public static final String BUNDLE_UPDATELOCATION = "Bundle-UpdateLocation";
/**
* Manifest header attribute identifying the version of a package specified
@@ -226,7 +223,7 @@
* @deprecated As of 1.3. This has been replaced by
* {@link #VERSION_ATTRIBUTE}.
*/
- String PACKAGE_SPECIFICATION_VERSION = "specification-version";
+ public static final String PACKAGE_SPECIFICATION_VERSION = "specification-version";
/**
* Manifest header attribute identifying the processor required to run
@@ -242,7 +239,7 @@
*
* @see #BUNDLE_NATIVECODE
*/
- String BUNDLE_NATIVECODE_PROCESSOR = "processor";
+ public static final String BUNDLE_NATIVECODE_PROCESSOR = "processor";
/**
* Manifest header attribute identifying the operating system required to
@@ -258,7 +255,7 @@
*
* @see #BUNDLE_NATIVECODE
*/
- String BUNDLE_NATIVECODE_OSNAME = "osname";
+ public static final String BUNDLE_NATIVECODE_OSNAME = "osname";
/**
* Manifest header attribute identifying the operating system version
@@ -274,7 +271,7 @@
*
* @see #BUNDLE_NATIVECODE
*/
- String BUNDLE_NATIVECODE_OSVERSION = "osversion";
+ public static final String BUNDLE_NATIVECODE_OSVERSION = "osversion";
/**
* Manifest header attribute identifying the language in which the native
@@ -290,7 +287,7 @@
*
* @see #BUNDLE_NATIVECODE
*/
- String BUNDLE_NATIVECODE_LANGUAGE = "language";
+ public static final String BUNDLE_NATIVECODE_LANGUAGE = "language";
/**
* Manifest header identifying the required execution environment for the
@@ -299,28 +296,27 @@
* environments it implements.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*
* @since 1.2
- * @deprecated As of 1.6. Replaced by the {@code osgi.ee} capability.
*/
- String BUNDLE_REQUIREDEXECUTIONENVIRONMENT = "Bundle-RequiredExecutionEnvironment";
+ public static final String BUNDLE_REQUIREDEXECUTIONENVIRONMENT = "Bundle-RequiredExecutionEnvironment";
/**
* Manifest header identifying the bundle's symbolic name.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*
* @since 1.3
*/
- String BUNDLE_SYMBOLICNAME = "Bundle-SymbolicName";
+ public final static String BUNDLE_SYMBOLICNAME = "Bundle-SymbolicName";
/**
* Manifest header directive identifying whether a bundle is a singleton.
- * The default value is {@code false}.
+ * The default value is <code>false</code>.
*
* <p>
* The directive value is encoded in the Bundle-SymbolicName manifest header
@@ -330,10 +326,14 @@
* Bundle-SymbolicName: com.acme.module.test; singleton:=true
* </pre>
*
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ *
* @see #BUNDLE_SYMBOLICNAME
* @since 1.3
*/
- String SINGLETON_DIRECTIVE = "singleton";
+ public final static String SINGLETON_DIRECTIVE = "singleton";
/**
* Manifest header directive identifying if and when a fragment may attach
@@ -354,7 +354,7 @@
* @see #FRAGMENT_ATTACHMENT_NEVER
* @since 1.3
*/
- String FRAGMENT_ATTACHMENT_DIRECTIVE = "fragment-attachment";
+ public final static String FRAGMENT_ATTACHMENT_DIRECTIVE = "fragment-attachment";
/**
* Manifest header directive value identifying a fragment attachment type of
@@ -373,7 +373,7 @@
* @see #FRAGMENT_ATTACHMENT_DIRECTIVE
* @since 1.3
*/
- String FRAGMENT_ATTACHMENT_ALWAYS = "always";
+ public final static String FRAGMENT_ATTACHMENT_ALWAYS = "always";
/**
* Manifest header directive value identifying a fragment attachment type of
@@ -392,7 +392,7 @@
* @see #FRAGMENT_ATTACHMENT_DIRECTIVE
* @since 1.3
*/
- String FRAGMENT_ATTACHMENT_RESOLVETIME = "resolve-time";
+ public final static String FRAGMENT_ATTACHMENT_RESOLVETIME = "resolve-time";
/**
* Manifest header directive value identifying a fragment attachment type of
@@ -410,45 +410,46 @@
* @see #FRAGMENT_ATTACHMENT_DIRECTIVE
* @since 1.3
*/
- String FRAGMENT_ATTACHMENT_NEVER = "never";
+ public final static String FRAGMENT_ATTACHMENT_NEVER = "never";
/**
* Manifest header identifying the base name of the bundle's localization
* entries.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*
* @see #BUNDLE_LOCALIZATION_DEFAULT_BASENAME
* @since 1.3
*/
- String BUNDLE_LOCALIZATION = "Bundle-Localization";
+ public final static String BUNDLE_LOCALIZATION = "Bundle-Localization";
/**
- * Default value for the {@code Bundle-Localization} manifest header.
+ * Default value for the <code>Bundle-Localization</code> manifest header.
*
* @see #BUNDLE_LOCALIZATION
* @since 1.3
*/
- String BUNDLE_LOCALIZATION_DEFAULT_BASENAME = "OSGI-INF/l10n/bundle";
+ public final static String BUNDLE_LOCALIZATION_DEFAULT_BASENAME = "OSGI-INF/l10n/bundle";
/**
* Manifest header identifying the symbolic names of other bundles required
* by the bundle.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*
* @since 1.3
*/
- String REQUIRE_BUNDLE = "Require-Bundle";
+ public final static String REQUIRE_BUNDLE = "Require-Bundle";
/**
* Manifest header attribute identifying a range of versions for a bundle
- * specified in the {@code Require-Bundle} or {@code Fragment-Host} manifest
- * headers. The default value is {@code 0.0.0}.
+ * specified in the <code>Require-Bundle</code> or
+ * <code>Fragment-Host</code> manifest headers. The default value is
+ * <code>0.0.0</code>.
*
* <p>
* The attribute value is encoded in the Require-Bundle manifest header
@@ -468,19 +469,19 @@
* @see #REQUIRE_BUNDLE
* @since 1.3
*/
- String BUNDLE_VERSION_ATTRIBUTE = "bundle-version";
+ public static final String BUNDLE_VERSION_ATTRIBUTE = "bundle-version";
/**
* Manifest header identifying the symbolic name of another bundle for which
* that the bundle is a fragment.
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*
* @since 1.3
*/
- String FRAGMENT_HOST = "Fragment-Host";
+ public final static String FRAGMENT_HOST = "Fragment-Host";
/**
* Manifest header attribute is used for selection by filtering based upon
@@ -496,7 +497,7 @@
* @see #BUNDLE_NATIVECODE
* @since 1.3
*/
- String SELECTION_FILTER_ATTRIBUTE = "selection-filter";
+ public final static String SELECTION_FILTER_ATTRIBUTE = "selection-filter";
/**
* Manifest header identifying the bundle manifest version. A bundle
@@ -508,12 +509,12 @@
* specifically, by version 1.3 of the OSGi Core Specification is "2".
*
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*
* @since 1.3
*/
- String BUNDLE_MANIFESTVERSION = "Bundle-ManifestVersion";
+ public final static String BUNDLE_MANIFESTVERSION = "Bundle-ManifestVersion";
/**
* Manifest header attribute identifying the version of a package specified
@@ -524,14 +525,14 @@
* manifest header like:
*
* <pre>
- * Export-Package: org.osgi.framework; version="1.1"
+ * Import-Package: org.osgi.framework; version="1.1"
* </pre>
*
* @see #EXPORT_PACKAGE
* @see #IMPORT_PACKAGE
* @since 1.3
*/
- String VERSION_ATTRIBUTE = "version";
+ public final static String VERSION_ATTRIBUTE = "version";
/**
* Manifest header attribute identifying the symbolic name of a bundle that
@@ -548,96 +549,88 @@
* @see #IMPORT_PACKAGE
* @since 1.3
*/
- String BUNDLE_SYMBOLICNAME_ATTRIBUTE = "bundle-symbolic-name";
+ public final static String BUNDLE_SYMBOLICNAME_ATTRIBUTE = "bundle-symbolic-name";
/**
* Manifest header directive identifying the resolution type in the
- * Import-Package, Require-Bundle or Require-Capability manifest header. The
- * default value is {@link #RESOLUTION_MANDATORY mandatory}.
+ * Import-Package or Require-Bundle manifest header. The default value is
+ * {@link #RESOLUTION_MANDATORY mandatory}.
*
* <p>
- * The directive value is encoded in the Import-Package, Require-Bundle or
- * Require-Capability manifest header like:
+ * The directive value is encoded in the Import-Package or Require-Bundle
+ * manifest header like:
*
* <pre>
* Import-Package: org.osgi.framework; resolution:="optional"
* Require-Bundle: com.acme.module.test; resolution:="optional"
- * Require-Capability: com.acme.capability; resolution:="optional"
* </pre>
*
* @see #IMPORT_PACKAGE
* @see #REQUIRE_BUNDLE
- * @see #REQUIRE_CAPABILITY
* @see #RESOLUTION_MANDATORY
* @see #RESOLUTION_OPTIONAL
* @since 1.3
*/
- String RESOLUTION_DIRECTIVE = "resolution";
+ public final static String RESOLUTION_DIRECTIVE = "resolution";
/**
* Manifest header directive value identifying a mandatory resolution type.
- * A mandatory resolution type indicates that the import package, require
- * bundle or require capability must be resolved when the bundle is
- * resolved. If such an import, require bundle or require capability cannot
- * be resolved, the module fails to resolve.
+ * A mandatory resolution type indicates that the import package or require
+ * bundle must be resolved when the bundle is resolved. If such an import or
+ * require bundle cannot be resolved, the module fails to resolve.
*
* <p>
- * The directive value is encoded in the Import-Package, Require-Bundle or
- * Require-Capability manifest header like:
+ * The directive value is encoded in the Import-Package or Require-Bundle
+ * manifest header like:
*
* <pre>
- * Import-Package: org.osgi.framework; resolution:="mandatory"
- * Require-Bundle: com.acme.module.test; resolution:="mandatory"
- * Require-Capability: com.acme.capability; resolution:="mandatory"
+ * Import-Package: org.osgi.framework; resolution:="manditory"
+ * Require-Bundle: com.acme.module.test; resolution:="manditory"
* </pre>
*
* @see #RESOLUTION_DIRECTIVE
* @since 1.3
*/
- String RESOLUTION_MANDATORY = "mandatory";
+ public final static String RESOLUTION_MANDATORY = "mandatory";
/**
* Manifest header directive value identifying an optional resolution type.
- * An optional resolution type indicates that the import, require bundle or
- * require capability is optional and the bundle may be resolved without the
- * import, require bundle or require capability being resolved. If the
- * import, require bundle or require capability is not resolved when the
- * bundle is resolved, the import, require bundle or require capability may
- * not be resolved until the bundle is refreshed.
+ * An optional resolution type indicates that the import or require bundle
+ * is optional and the bundle may be resolved without the import or require
+ * bundle being resolved. If the import or require bundle is not resolved
+ * when the bundle is resolved, the import or require bundle may not be
+ * resolved before the bundle is refreshed.
*
* <p>
- * The directive value is encoded in the Import-Package, Require-Bundle or
- * Require-Capability manifest header like:
+ * The directive value is encoded in the Import-Package or Require-Bundle
+ * manifest header like:
*
* <pre>
* Import-Package: org.osgi.framework; resolution:="optional"
* Require-Bundle: com.acme.module.test; resolution:="optional"
- * Require-Capability: com.acme.capability; resolution:="optional"
* </pre>
*
* @see #RESOLUTION_DIRECTIVE
* @since 1.3
*/
- String RESOLUTION_OPTIONAL = "optional";
+ public final static String RESOLUTION_OPTIONAL = "optional";
/**
* Manifest header directive identifying a list of packages that an exported
- * package or provided capability uses.
+ * package uses.
*
* <p>
- * The directive value is encoded in the Export-Package or
- * Provide-Capability manifest header like:
+ * The directive value is encoded in the Export-Package manifest header
+ * like:
*
* <pre>
* Export-Package: org.osgi.util.tracker; uses:="org.osgi.framework"
- * Provide-Capability: com.acme.capability; uses:="com.acme.service"
* </pre>
*
* @see #EXPORT_PACKAGE
- * @see #PROVIDE_CAPABILITY
* @since 1.3
*/
- String USES_DIRECTIVE = "uses";
+ public final static String USES_DIRECTIVE = "uses";
/**
* Manifest header directive identifying a list of classes to include in the
@@ -667,7 +660,7 @@
* @see #BUNDLE_ACTIVATIONPOLICY
* @since 1.3
*/
- String INCLUDE_DIRECTIVE = "include";
+ public final static String INCLUDE_DIRECTIVE = "include";
/**
* Manifest header directive identifying a list of classes to exclude in the
@@ -696,7 +689,7 @@
* @see #BUNDLE_ACTIVATIONPOLICY
* @since 1.3
*/
- String EXCLUDE_DIRECTIVE = "exclude";
+ public final static String EXCLUDE_DIRECTIVE = "exclude";
/**
* Manifest header directive identifying names of matching attributes which
@@ -714,7 +707,7 @@
* @see #EXPORT_PACKAGE
* @since 1.3
*/
- String MANDATORY_DIRECTIVE = "mandatory";
+ public final static String MANDATORY_DIRECTIVE = "mandatory";
/**
* Manifest header directive identifying the visibility of a required bundle
@@ -734,7 +727,7 @@
* @see #VISIBILITY_REEXPORT
* @since 1.3
*/
- String VISIBILITY_DIRECTIVE = "visibility";
+ public final static String VISIBILITY_DIRECTIVE = "visibility";
/**
* Manifest header directive value identifying a private visibility type. A
@@ -753,7 +746,7 @@
* @see #VISIBILITY_DIRECTIVE
* @since 1.3
*/
- String VISIBILITY_PRIVATE = "private";
+ public final static String VISIBILITY_PRIVATE = "private";
/**
* Manifest header directive value identifying a reexport visibility type. A
@@ -773,7 +766,7 @@
* @see #VISIBILITY_DIRECTIVE
* @since 1.3
*/
- String VISIBILITY_REEXPORT = "reexport";
+ public final static String VISIBILITY_REEXPORT = "reexport";
/**
* Manifest header directive identifying the type of the extension fragment.
@@ -790,7 +783,7 @@
* @see #EXTENSION_BOOTCLASSPATH
* @since 1.3
*/
- String EXTENSION_DIRECTIVE = "extension";
+ public final static String EXTENSION_DIRECTIVE = "extension";
/**
* Manifest header directive value identifying the type of extension
@@ -807,7 +800,7 @@
* @see #EXTENSION_DIRECTIVE
* @since 1.3
*/
- String EXTENSION_FRAMEWORK = "framework";
+ public final static String EXTENSION_FRAMEWORK = "framework";
/**
* Manifest header directive value identifying the type of extension
@@ -824,20 +817,20 @@
* @see #EXTENSION_DIRECTIVE
* @since 1.3
*/
- String EXTENSION_BOOTCLASSPATH = "bootclasspath";
+ public final static String EXTENSION_BOOTCLASSPATH = "bootclasspath";
/**
* Manifest header identifying the bundle's activation policy.
* <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
*
* @since 1.4
* @see #ACTIVATION_LAZY
* @see #INCLUDE_DIRECTIVE
* @see #EXCLUDE_DIRECTIVE
*/
- String BUNDLE_ACTIVATIONPOLICY = "Bundle-ActivationPolicy";
+ public final static String BUNDLE_ACTIVATIONPOLICY = "Bundle-ActivationPolicy";
/**
* Bundle activation policy declaring the bundle must be activated when the
@@ -861,16 +854,16 @@
* @see Bundle#START_ACTIVATION_POLICY
* @since 1.4
*/
- String ACTIVATION_LAZY = "lazy";
+ public final static String ACTIVATION_LAZY = "lazy";
/**
* Framework environment property identifying the Framework version.
*
* <p>
* The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
+ * <code>BundleContext.getProperty</code> method.
*/
- String FRAMEWORK_VERSION = "org.osgi.framework.version";
+ public static final String FRAMEWORK_VERSION = "org.osgi.framework.version";
/**
* Framework environment property identifying the Framework implementation
@@ -878,79 +871,79 @@
*
* <p>
* The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
+ * <code>BundleContext.getProperty</code> method.
*/
- String FRAMEWORK_VENDOR = "org.osgi.framework.vendor";
+ public static final String FRAMEWORK_VENDOR = "org.osgi.framework.vendor";
/**
- * Framework launching property identifying the Framework implementation
+ * Framework environment property identifying the Framework implementation
* language (see ISO 639 for possible values).
*
* <p>
* The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
+ * <code>BundleContext.getProperty</code> method.
*/
- String FRAMEWORK_LANGUAGE = "org.osgi.framework.language";
+ public static final String FRAMEWORK_LANGUAGE = "org.osgi.framework.language";
/**
- * Framework launching property identifying the Framework host-computer's
+ * Framework environment property identifying the Framework host-computer's
* operating system.
*
* <p>
* The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
+ * <code>BundleContext.getProperty</code> method.
*/
- String FRAMEWORK_OS_NAME = "org.osgi.framework.os.name";
+ public static final String FRAMEWORK_OS_NAME = "org.osgi.framework.os.name";
/**
- * Framework launching property identifying the Framework host-computer's
+ * Framework environment property identifying the Framework host-computer's
* operating system version number.
*
* <p>
* The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
+ * <code>BundleContext.getProperty</code> method.
*/
- String FRAMEWORK_OS_VERSION = "org.osgi.framework.os.version";
+ public static final String FRAMEWORK_OS_VERSION = "org.osgi.framework.os.version";
/**
- * Framework launching property identifying the Framework host-computer's
+ * Framework environment property identifying the Framework host-computer's
* processor name.
*
* <p>
* The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
+ * <code>BundleContext.getProperty</code> method.
*/
- String FRAMEWORK_PROCESSOR = "org.osgi.framework.processor";
+ public static final String FRAMEWORK_PROCESSOR = "org.osgi.framework.processor";
/**
- * Framework launching property identifying execution environments provided
- * by the Framework.
+ * Framework environment property identifying execution environments
+ * provided by the Framework.
*
* <p>
* The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
+ * <code>BundleContext.getProperty</code> method.
*
* @since 1.2
- * @deprecated As of 1.6. Replaced by the {@code osgi.ee} capability.
*/
- String FRAMEWORK_EXECUTIONENVIRONMENT = "org.osgi.framework.executionenvironment";
+ public static final String FRAMEWORK_EXECUTIONENVIRONMENT = "org.osgi.framework.executionenvironment";
/**
- * Framework launching property identifying packages for which the Framework
- * must delegate class loading to the parent class loader of the bundle.
+ * Framework environment property identifying packages for which the
+ * Framework must delegate class loading to the parent class loader of the
+ * bundle.
*
* <p>
* The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
+ * <code>BundleContext.getProperty</code> method.
*
* @see #FRAMEWORK_BUNDLE_PARENT
* @since 1.3
*/
- String FRAMEWORK_BOOTDELEGATION = "org.osgi.framework.bootdelegation";
+ public static final String FRAMEWORK_BOOTDELEGATION = "org.osgi.framework.bootdelegation";
/**
- * Framework launching property identifying packages which the system bundle
- * must export.
+ * Framework environment property identifying packages which the system
+ * bundle must export.
*
* <p>
* If this property is not specified then the framework must calculate a
@@ -958,15 +951,15 @@
*
* <p>
* The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
+ * <code>BundleContext.getProperty</code> method.
*
* @since 1.3
*/
- String FRAMEWORK_SYSTEMPACKAGES = "org.osgi.framework.system.packages";
+ public static final String FRAMEWORK_SYSTEMPACKAGES = "org.osgi.framework.system.packages";
/**
- * Framework launching property identifying extra packages which the system
- * bundle must export from the current execution environment.
+ * Framework environment property identifying extra packages which the
+ * system bundle must export from the current execution environment.
*
* <p>
* This property is useful for configuring extra system packages in addition
@@ -974,84 +967,84 @@
*
* <p>
* The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
+ * <code>BundleContext.getProperty</code> method.
*
* @see #FRAMEWORK_SYSTEMPACKAGES
* @since 1.5
*/
- String FRAMEWORK_SYSTEMPACKAGES_EXTRA = "org.osgi.framework.system.packages.extra";
+ public static final String FRAMEWORK_SYSTEMPACKAGES_EXTRA = "org.osgi.framework.system.packages.extra";
/**
* Framework environment property identifying whether the Framework supports
* framework extension bundles.
*
* <p>
- * As of version 1.4, the value of this property must be {@code true}. The
- * Framework must support framework extension bundles.
+ * As of version 1.4, the value of this property must be <code>true</code>.
+ * The Framework must support framework extension bundles.
*
* <p>
* The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
+ * <code>BundleContext.getProperty</code> method.
*
* @since 1.3
*/
- String SUPPORTS_FRAMEWORK_EXTENSION = "org.osgi.supports.framework.extension";
+ public static final String SUPPORTS_FRAMEWORK_EXTENSION = "org.osgi.supports.framework.extension";
/**
* Framework environment property identifying whether the Framework supports
* bootclasspath extension bundles.
*
* <p>
- * If the value of this property is {@code true}, then the Framework
+ * If the value of this property is <code>true</code>, then the Framework
* supports bootclasspath extension bundles. The default value is
- * {@code false}.
+ * <code>false</code>.
* <p>
* The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
+ * <code>BundleContext.getProperty</code> method.
*
* @since 1.3
*/
- String SUPPORTS_BOOTCLASSPATH_EXTENSION = "org.osgi.supports.bootclasspath.extension";
+ public static final String SUPPORTS_BOOTCLASSPATH_EXTENSION = "org.osgi.supports.bootclasspath.extension";
/**
* Framework environment property identifying whether the Framework supports
* fragment bundles.
*
* <p>
- * As of version 1.4, the value of this property must be {@code true}. The
- * Framework must support fragment bundles.
+ * As of version 1.4, the value of this property must be <code>true</code>.
+ * The Framework must support fragment bundles.
* <p>
* The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
+ * <code>BundleContext.getProperty</code> method.
*
* @since 1.3
*/
- String SUPPORTS_FRAMEWORK_FRAGMENT = "org.osgi.supports.framework.fragment";
+ public static final String SUPPORTS_FRAMEWORK_FRAGMENT = "org.osgi.supports.framework.fragment";
/**
* Framework environment property identifying whether the Framework supports
* the {@link #REQUIRE_BUNDLE Require-Bundle} manifest header.
*
* <p>
- * As of version 1.4, the value of this property must be {@code true}. The
- * Framework must support the {@code Require-Bundle} manifest header.
+ * As of version 1.4, the value of this property must be <code>true</code>.
+ * The Framework must support the <code>Require-Bundle</code> manifest
+ * header.
* <p>
* The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
+ * <code>BundleContext.getProperty</code> method.
*
* @since 1.3
*/
- String SUPPORTS_FRAMEWORK_REQUIREBUNDLE = "org.osgi.supports.framework.requirebundle";
+ public static final String SUPPORTS_FRAMEWORK_REQUIREBUNDLE = "org.osgi.supports.framework.requirebundle";
/**
- * Framework launching property specifying the type of security manager the
- * framework must use. If not specified then the framework will not set the
- * VM security manager.
+ * Specifies the type of security manager the framework must use. If not
+ * specified then the framework will not set the VM security manager.
*
* @see #FRAMEWORK_SECURITY_OSGI
* @since 1.5
*/
- String FRAMEWORK_SECURITY = "org.osgi.framework.security";
+ public final static String FRAMEWORK_SECURITY = "org.osgi.framework.security";
/**
* Specifies that a security manager that supports all security aspects of
@@ -1060,40 +1053,39 @@
*
* <p>
* If this value is specified and there is a security manager already
- * installed, then a {@code SecurityException} must be thrown when the
+ * installed, then a <code>SecurityException</code> must be thrown when the
* Framework is initialized.
*
* @see #FRAMEWORK_SECURITY
* @since 1.5
*/
- String FRAMEWORK_SECURITY_OSGI = "osgi";
+ public final static String FRAMEWORK_SECURITY_OSGI = "osgi";
/**
- * Framework launching property specifying the persistent storage area used
- * by the framework. The value of this property must be a valid file path in
- * the file system to a directory. If the specified directory does not exist
- * then the framework will create the directory. If the specified path
- * exists but is not a directory or if the framework fails to create the
- * storage directory, then framework initialization must fail. The framework
- * is free to use this directory as it sees fit. This area can not be shared
- * with anything else.
+ * Specified the persistent storage area used by the framework. The value of
+ * this property must be a valid file path in the file system to a
+ * directory. If the specified directory does not exist then the framework
+ * will create the directory. If the specified path exists but is not a
+ * directory or if the framework fails to create the storage directory, then
+ * framework initialization must fail. The framework is free to use this
+ * directory as it sees fit. This area can not be shared with anything else.
* <p>
* If this property is not set, the framework should use a reasonable
* platform default for the persistent storage area.
*
* @since 1.5
*/
- String FRAMEWORK_STORAGE = "org.osgi.framework.storage";
+ public final static String FRAMEWORK_STORAGE = "org.osgi.framework.storage";
/**
- * Framework launching property specifying if and when the persistent
- * storage area for the framework should be cleaned. If this property is not
- * set, then the framework storage area must not be cleaned.
+ * Specifies if and when the persistent storage area for the framework
+ * should be cleaned. If this property is not set, then the framework
+ * storage area must not be cleaned.
*
* @see #FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT
* @since 1.5
*/
- String FRAMEWORK_STORAGE_CLEAN = "org.osgi.framework.storage.clean";
+ public final static String FRAMEWORK_STORAGE_CLEAN = "org.osgi.framework.storage.clean";
/**
* Specifies that the framework storage area must be cleaned before the
@@ -1103,29 +1095,29 @@
*
* @since 1.5
*/
- String FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT = "onFirstInit";
+ public final static String FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT = "onFirstInit";
/**
- * Framework launching property specifying a comma separated list of
- * additional library file extensions that must be used when a bundle's
- * class loader is searching for native libraries. If this property is not
- * set, then only the library name returned by
- * {@code System.mapLibraryName(String)} will be used to search. This is
- * needed for certain operating systems which allow more than one extension
- * for a library. For example, AIX allows library extensions of {@code .a}
- * and {@code .so}, but {@code System.mapLibraryName(String)} will only
- * return names with the {@code .a} extension.
+ * Specifies a comma separated list of additional library file extensions
+ * that must be used when a bundle's class loader is searching for native
+ * libraries. If this property is not set, then only the library name
+ * returned by <code>System.mapLibraryName(String)</code> will be used to
+ * search. This is needed for certain operating systems which allow more
+ * than one extension for a library. For example, AIX allows library
+ * extensions of <code>.a</code> and <code>.so</code>, but
+ * <code>System.mapLibraryName(String)</code> will only return names with
+ * the <code>.a</code> extension.
*
* @since 1.5
*/
- String FRAMEWORK_LIBRARY_EXTENSIONS = "org.osgi.framework.library.extensions";
+ public final static String FRAMEWORK_LIBRARY_EXTENSIONS = "org.osgi.framework.library.extensions";
/**
- * Framework launching property specifying an optional OS specific command
- * to set file permissions on extracted native code. On some operating
- * systems, it is required that native libraries be set to executable. This
- * optional property allows you to specify the command. For example, on a
- * UNIX style OS, this property could have the following value.
+ * Specifies an optional OS specific command to set file permissions on
+ * extracted native code. On some operating systems, it is required that
+ * native libraries be set to executable. This optional property allows you
+ * to specify the command. For example, on a UNIX style OS, this property
+ * could have the following value.
*
* <pre>
* chmod +rx ${abspath}
@@ -1136,24 +1128,16 @@
*
* @since 1.5
*/
- String FRAMEWORK_EXECPERMISSION = "org.osgi.framework.command.execpermission";
+ public final static String FRAMEWORK_EXECPERMISSION = "org.osgi.framework.command.execpermission";
/**
- * Specified the substitution string for the absolute path of a file.
- *
- * @see #FRAMEWORK_EXECPERMISSION
- * @since 1.6
- */
- String FRAMEWORK_COMMAND_ABSPATH = "abspath";
-
- /**
- * Framework launching property specifying the trust repositories used by
- * the framework. The value is a {@code java.io.File.pathSeparator}
- * separated list of valid file paths to files that contain key stores of
- * type {@code JKS}. The framework will use the key stores as trust
- * repositories to authenticate certificates of trusted signers. The key
- * stores are only used as read-only trust repositories to access public
- * keys. No passwords are required to access the key stores' public keys.
+ * Specifies the trust repositories used by the framework. The value is a
+ * <code>java.io.File.pathSeparator</code> separated list of valid file
+ * paths to files that contain key stores of type <code>JKS</code>. The
+ * framework will use the key stores as trust repositories to authenticate
+ * certificates of trusted signers. The key stores are only used as
+ * read-only trust repositories to access public keys. No passwords are
+ * required to access the key stores' public keys.
* <p>
* Note that framework implementations are allowed to use other trust
* repositories in addition to the trust repositories specified by this
@@ -1162,29 +1146,27 @@
*
* @since 1.5
*/
- String FRAMEWORK_TRUST_REPOSITORIES = "org.osgi.framework.trust.repositories";
+ public final static String FRAMEWORK_TRUST_REPOSITORIES = "org.osgi.framework.trust.repositories";
/**
- * Framework launching property specifying the current windowing system. The
- * framework should provide a reasonable default if this is not set.
+ * Specifies the current windowing system. The framework should provide a
+ * reasonable default if this is not set.
*
* @since 1.5
*/
- String FRAMEWORK_WINDOWSYSTEM = "org.osgi.framework.windowsystem";
+ public final static String FRAMEWORK_WINDOWSYSTEM = "org.osgi.framework.windowsystem";
/**
- * Framework launching property specifying the beginning start level of the
- * framework.
+ * Specifies the beginning start level of the framework.
*
- * @see "Core Specification, Starting the Framework."
+ * @see "Core Specification, section 8.2.3."
* @since 1.5
*/
- String FRAMEWORK_BEGINNING_STARTLEVEL = "org.osgi.framework.startlevel.beginning";
+ public final static String FRAMEWORK_BEGINNING_STARTLEVEL = "org.osgi.framework.startlevel.beginning";
/**
- * Framework launching property specifying the parent class loader type for
- * all bundle class loaders. Default value is
- * {@link #FRAMEWORK_BUNDLE_PARENT_BOOT boot}.
+ * Specifies the parent class loader type for all bundle class loaders.
+ * Default value is {@link #FRAMEWORK_BUNDLE_PARENT_BOOT boot}.
*
* @see #FRAMEWORK_BUNDLE_PARENT_BOOT
* @see #FRAMEWORK_BUNDLE_PARENT_EXT
@@ -1192,7 +1174,7 @@
* @see #FRAMEWORK_BUNDLE_PARENT_FRAMEWORK
* @since 1.5
*/
- String FRAMEWORK_BUNDLE_PARENT = "org.osgi.framework.bundle.parent";
+ public final static String FRAMEWORK_BUNDLE_PARENT = "org.osgi.framework.bundle.parent";
/**
* Specifies to use of the boot class loader as the parent class loader for
@@ -1201,7 +1183,7 @@
* @since 1.5
* @see #FRAMEWORK_BUNDLE_PARENT
*/
- String FRAMEWORK_BUNDLE_PARENT_BOOT = "boot";
+ public final static String FRAMEWORK_BUNDLE_PARENT_BOOT = "boot";
/**
* Specifies to use the extension class loader as the parent class loader
@@ -1210,48 +1192,48 @@
* @since 1.5
* @see #FRAMEWORK_BUNDLE_PARENT
*/
- String FRAMEWORK_BUNDLE_PARENT_EXT = "ext";
+ public final static String FRAMEWORK_BUNDLE_PARENT_EXT = "ext";
/**
* Specifies to use the application class loader as the parent class loader
- * for all bundle class loaders. Depending on how the framework is launched,
- * this may refer to the same class loader as
+ * for all bundle class loaders. Depending on how the framework is
+ * launched, this may refer to the same class loader as
* {@link #FRAMEWORK_BUNDLE_PARENT_FRAMEWORK}.
*
* @since 1.5
* @see #FRAMEWORK_BUNDLE_PARENT
*/
- String FRAMEWORK_BUNDLE_PARENT_APP = "app";
+ public final static String FRAMEWORK_BUNDLE_PARENT_APP = "app";
/**
* Specifies to use the framework class loader as the parent class loader
* for all bundle class loaders. The framework class loader is the class
- * loader used to load the framework implementation. Depending on how the
- * framework is launched, this may refer to the same class loader as
+ * loader used to load the framework implementation. Depending on how the
+ * framework is launched, this may refer to the same class loader as
* {@link #FRAMEWORK_BUNDLE_PARENT_APP}.
*
* @since 1.5
* @see #FRAMEWORK_BUNDLE_PARENT
*/
- String FRAMEWORK_BUNDLE_PARENT_FRAMEWORK = "framework";
+ public final static String FRAMEWORK_BUNDLE_PARENT_FRAMEWORK = "framework";
/*
* Service properties.
*/
-
+
/**
* Service property identifying all of the class names under which a service
* was registered in the Framework. The value of this property must be of
- * type {@code String[]}.
+ * type <code>String[]</code>.
*
* <p>
* This property is set by the Framework when a service is registered.
*/
- String OBJECTCLASS = "objectClass";
+ public static final String OBJECTCLASS = "objectClass";
/**
* Service property identifying a service's registration number. The value
- * of this property must be of type {@code Long}.
+ * of this property must be of type <code>Long</code>.
*
* <p>
* The value of this property is assigned by the Framework when a service is
@@ -1259,426 +1241,72 @@
* previously assigned values since the Framework was started. These values
* are NOT persistent across restarts of the Framework.
*/
- String SERVICE_ID = "service.id";
+ public static final String SERVICE_ID = "service.id";
/**
* Service property identifying a service's persistent identifier.
*
* <p>
- * This property may be supplied in the {@code properties}
- * {@code Dictionary} object passed to the
- * {@code BundleContext.registerService} method. The value of this property
- * must be of type {@code String}, {@code String[]}, or {@code Collection}
- * of {@code String}.
+ * This property may be supplied in the <code>properties</code>
+ * <code>Dictionary</code> object passed to the
+ * <code>BundleContext.registerService</code> method. The value of this
+ * property must be of type <code>String</code>, <code>String[]</code>, or
+ * <code>Collection</code> of <code>String</code>.
*
* <p>
* A service's persistent identifier uniquely identifies the service and
* persists across multiple Framework invocations.
*
* <p>
- * By convention, every bundle has its own unique name space, starting with
+ * By convention, every bundle has its own unique namespace, starting with
* the bundle's identifier (see {@link Bundle#getBundleId}) and followed by
* a dot (.). A bundle may use this as the prefix of the persistent
* identifiers for the services it registers.
*/
- String SERVICE_PID = "service.pid";
+ public static final String SERVICE_PID = "service.pid";
/**
* Service property identifying a service's ranking number.
*
* <p>
- * This property may be supplied in the {@code properties
- * Dictionary} object passed to the {@code BundleContext.registerService}
- * method. The value of this property must be of type {@code Integer}.
+ * This property may be supplied in the <code>properties
+ * Dictionary</code> object passed to the
+ * <code>BundleContext.registerService</code> method. The value of this
+ * property must be of type <code>Integer</code>.
*
* <p>
* The service ranking is used by the Framework to determine the <i>natural
- * order</i> of services, see {@link ServiceReference#compareTo}, and the
- * <i>default</i> service to be returned from a call to the
+ * order</i> of services, see {@link ServiceReference#compareTo(Object)},
+ * and the <i>default</i> service to be returned from a call to the
* {@link BundleContext#getServiceReference} method.
*
* <p>
* The default ranking is zero (0). A service with a ranking of
- * {@code Integer.MAX_VALUE} is very likely to be returned as the default
- * service, whereas a service with a ranking of {@code Integer.MIN_VALUE} is
- * very unlikely to be returned.
+ * <code>Integer.MAX_VALUE</code> is very likely to be returned as the
+ * default service, whereas a service with a ranking of
+ * <code>Integer.MIN_VALUE</code> is very unlikely to be returned.
*
* <p>
- * If the supplied property value is not of type {@code Integer}, it is
+ * If the supplied property value is not of type <code>Integer</code>, it is
* deemed to have a ranking value of zero.
*/
- String SERVICE_RANKING = "service.ranking";
+ public static final String SERVICE_RANKING = "service.ranking";
/**
* Service property identifying a service's vendor.
*
* <p>
- * This property may be supplied in the properties {@code Dictionary} object
- * passed to the {@code BundleContext.registerService} method.
+ * This property may be supplied in the properties <code>Dictionary</code>
+ * object passed to the <code>BundleContext.registerService</code> method.
*/
- String SERVICE_VENDOR = "service.vendor";
+ public static final String SERVICE_VENDOR = "service.vendor";
/**
* Service property identifying a service's description.
*
* <p>
- * This property may be supplied in the properties {@code Dictionary} object
- * passed to the {@code BundleContext.registerService} method.
+ * This property may be supplied in the properties <code>Dictionary</code>
+ * object passed to the <code>BundleContext.registerService</code> method.
*/
- String SERVICE_DESCRIPTION = "service.description";
-
- /**
- * Framework environment property identifying the Framework's universally
- * unique identifier (UUID). A UUID represents a 128-bit value. A new UUID
- * is generated by the {@link Framework#init()} method each time a framework
- * is initialized. The value of this property must conform to the UUID
- * string representation specified in <a
- * href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>.
- *
- * <p>
- * The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
- *
- * @since 1.6
- */
- String FRAMEWORK_UUID = "org.osgi.framework.uuid";
-
- /**
- * Service property identifying the configuration types supported by a
- * distribution provider. Registered by the distribution provider on one of
- * its services to indicate the supported configuration types.
- *
- * <p>
- * The value of this property must be of type {@code String},
- * {@code String[]}, or {@code Collection} of {@code String}.
- *
- * @since 1.6
- * @see "Remote Services Specification"
- */
- String REMOTE_CONFIGS_SUPPORTED = "remote.configs.supported";
-
- /**
- * Service property identifying the intents supported by a distribution
- * provider. Registered by the distribution provider on one of its services
- * to indicate the vocabulary of implemented intents.
- *
- * <p>
- * The value of this property must be of type {@code String},
- * {@code String[]}, or {@code Collection} of {@code String}.
- *
- * @since 1.6
- * @see "Remote Services Specification"
- */
- String REMOTE_INTENTS_SUPPORTED = "remote.intents.supported";
-
- /**
- * Service property identifying the configuration types that should be used
- * to export the service. Each configuration type represents the
- * configuration parameters for an endpoint. A distribution provider should
- * create an endpoint for each configuration type that it supports.
- *
- * <p>
- * This property may be supplied in the {@code properties}
- * {@code Dictionary} object passed to the
- * {@code BundleContext.registerService} method. The value of this property
- * must be of type {@code String}, {@code String[]}, or {@code Collection}
- * of {@code String}.
- *
- * @since 1.6
- * @see "Remote Services Specification"
- */
- String SERVICE_EXPORTED_CONFIGS = "service.exported.configs";
-
- /**
- * Service property identifying the intents that the distribution provider
- * must implement to distribute the service. Intents listed in this property
- * are reserved for intents that are critical for the code to function
- * correctly, for example, ordering of messages. These intents should not be
- * configurable.
- *
- * <p>
- * This property may be supplied in the {@code properties}
- * {@code Dictionary} object passed to the
- * {@code BundleContext.registerService} method. The value of this property
- * must be of type {@code String}, {@code String[]}, or {@code Collection}
- * of {@code String}.
- *
- * @since 1.6
- * @see "Remote Services Specification"
- */
- String SERVICE_EXPORTED_INTENTS = "service.exported.intents";
-
- /**
- * Service property identifying the extra intents that the distribution
- * provider must implement to distribute the service. This property is
- * merged with the {@code service.exported.intents} property before the
- * distribution provider interprets the listed intents; it has therefore the
- * same semantics but the property should be configurable so the
- * administrator can choose the intents based on the topology. Bundles
- * should therefore make this property configurable, for example through the
- * Configuration Admin service.
- *
- * <p>
- * This property may be supplied in the {@code properties}
- * {@code Dictionary} object passed to the
- * {@code BundleContext.registerService} method. The value of this property
- * must be of type {@code String}, {@code String[]}, or {@code Collection}
- * of {@code String}.
- *
- * @since 1.6
- * @see "Remote Services Specification"
- */
- String SERVICE_EXPORTED_INTENTS_EXTRA = "service.exported.intents.extra";
-
- /**
- * Service property marking the service for export. It defines the
- * interfaces under which this service can be exported. This list must be a
- * subset of the types under which the service was registered. The single
- * value of an asterisk ("*", \u002A) indicates all the
- * interface types under which the service was registered excluding the
- * non-interface types. It is strongly recommended to only export interface
- * types and not concrete classes due to the complexity of creating proxies
- * for some type of concrete classes.
- *
- * <p>
- * This property may be supplied in the {@code properties}
- * {@code Dictionary} object passed to the
- * {@code BundleContext.registerService} method. The value of this property
- * must be of type {@code String}, {@code String[]}, or {@code Collection}
- * of {@code String}.
- *
- * @since 1.6
- * @see "Remote Services Specification"
- */
- String SERVICE_EXPORTED_INTERFACES = "service.exported.interfaces";
-
- /**
- * Service property identifying the service as imported. This service
- * property must be set by a distribution provider to any value when it
- * registers the endpoint proxy as an imported service. A bundle can use
- * this property to filter out imported services.
- *
- * <p>
- * The value of this property may be of any type.
- *
- * @since 1.6
- * @see "Remote Services Specification"
- */
- String SERVICE_IMPORTED = "service.imported";
-
- /**
- * Service property identifying the configuration types used to import the
- * service. Any associated properties for this configuration types must be
- * properly mapped to the importing system. For example, a URL in these
- * properties must point to a valid resource when used in the importing
- * framework. If multiple configuration types are listed in this property,
- * then they must be synonyms for exactly the same remote endpoint that is
- * used to export this service.
- *
- * <p>
- * The value of this property must be of type {@code String},
- * {@code String[]}, or {@code Collection} of {@code String}.
- *
- * @since 1.6
- * @see "Remote Services Specification"
- * @see #SERVICE_EXPORTED_CONFIGS
- */
- String SERVICE_IMPORTED_CONFIGS = "service.imported.configs";
-
- /**
- * Service property identifying the intents that this service implement.
- * This property has a dual purpose:
- * <ul>
- * <li>A bundle can use this service property to notify the distribution
- * provider that these intents are already implemented by the exported
- * service object.</li>
- * <li>A distribution provider must use this property to convey the combined
- * intents of: the exporting service, the intents that the exporting
- * distribution provider adds, and the intents that the importing
- * distribution provider adds.</li>
- * </ul>
- *
- * To export a service, a distribution provider must expand any qualified
- * intents. Both the exporting and importing distribution providers must
- * recognize all intents before a service can be distributed.
- *
- * <p>
- * The value of this property must be of type {@code String},
- * {@code String[]}, or {@code Collection} of {@code String}.
- *
- * @since 1.6
- * @see "Remote Services Specification"
- */
- String SERVICE_INTENTS = "service.intents";
-
- /**
- * Manifest header identifying the capabilities that the bundle offers to
- * provide to other bundles.
- *
- * <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
- *
- * @since 1.6
- */
- String PROVIDE_CAPABILITY = "Provide-Capability";
-
- /**
- * Manifest header identifying the capabilities on which the bundle depends.
- *
- * <p>
- * The header value may be retrieved from the {@code Dictionary} object
- * returned by the {@code Bundle.getHeaders} method.
- *
- * @since 1.6
- */
- String REQUIRE_CAPABILITY = "Require-Capability";
-
- /**
- * Manifest header directive identifying the effective time of the provided
- * capability. The default value is {@link #EFFECTIVE_RESOLVE resolve}.
- *
- * <p>
- * The directive value is encoded in the Provide-Capability manifest header
- * like:
- *
- * <pre>
- * Provide-Capability: com.acme.capability; effective:="resolve"
- * </pre>
- *
- * @see #PROVIDE_CAPABILITY
- * @see #EFFECTIVE_RESOLVE
- * @see #EFFECTIVE_ACTIVE
- * @since 1.6
- */
- String EFFECTIVE_DIRECTIVE = "effective";
-
- /**
- * Manifest header directive value identifying a capability that is
- * effective at resolve time. Capabilities with an effective time of resolve
- * are the only capabilities which are processed by the resolver.
- *
- * <p>
- * The directive value is encoded in the Provide-Capability manifest header
- * like:
- *
- * <pre>
- * Provide-Capability: com.acme.capability; effective:="resolve"
- * </pre>
- *
- * @see #EFFECTIVE_DIRECTIVE
- * @since 1.6
- */
- String EFFECTIVE_RESOLVE = "resolve";
-
- /**
- * Manifest header directive value identifying a capability that is
- * effective at active time. Capabilities with an effective time of active
- * are ignored by the resolver.
- *
- * <p>
- * The directive value is encoded in the Provide-Capability manifest header
- * like:
- *
- * <pre>
- * Provide-Capability: com.acme.capability; effective:="active"
- * </pre>
- *
- * @see #EFFECTIVE_DIRECTIVE
- * @since 1.6
- */
- String EFFECTIVE_ACTIVE = "active";
-
- /**
- * Manifest header directive identifying the capability filter specified in
- * the Require-Capability manifest header.
- *
- * <p>
- * The directive value is encoded in the Require-Capability manifest header
- * like:
- *
- * <pre>
- * Require-Capability: com.acme.capability; filter:="(someattr=somevalue)"
- * </pre>
- *
- * @see #REQUIRE_CAPABILITY
- * @since 1.6
- */
- String FILTER_DIRECTIVE = "filter";
-
- /**
- * Framework launching property identifying capabilities which the system
- * bundle must provide.
- *
- * <p>
- * If this property is not specified then the framework must calculate a
- * reasonable default value for the current execution environment.
- *
- * <p>
- * The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
- *
- * @since 1.6
- */
- String FRAMEWORK_SYSTEMCAPABILITIES = "org.osgi.framework.system.capabilities";
-
- /**
- * Framework launching property identifying extra capabilities which the
- * system bundle must additionally provide.
- *
- * <p>
- * This property is useful for configuring extra system capabilities in
- * addition to the system capabilities calculated by the framework.
- *
- * <p>
- * The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
- *
- * @see #FRAMEWORK_SYSTEMCAPABILITIES
- * @since 1.6
- */
- String FRAMEWORK_SYSTEMCAPABILITIES_EXTRA = "org.osgi.framework.system.capabilities.extra";
-
- /**
- * Framework launching property specifying whether multiple bundles having
- * the same {@link #BUNDLE_SYMBOLICNAME symbolic name} and
- * {@link #BUNDLE_VERSION version} may be installed.
- *
- * <p>
- * Default value is {@link #FRAMEWORK_BSNVERSION_SINGLE single} in this
- * release of the specification. This default may change to
- * {@link #FRAMEWORK_BSNVERSION_MULTIPLE multiple} in a future specification
- * release. Therefore, code must not assume the default behavior is
- * {@code single} and should interrogate the value of this property to
- * determine the behavior.
- *
- * <p>
- * The value of this property may be retrieved by calling the
- * {@code BundleContext.getProperty} method.
- *
- * @see #FRAMEWORK_BSNVERSION_MULTIPLE
- * @see #FRAMEWORK_BSNVERSION_SINGLE
- * @since 1.6
- */
- String FRAMEWORK_BSNVERSION = "org.osgi.framework.bsnversion";
-
- /**
- * Specifies the framework will allow multiple bundles to be installed
- * having the same symbolic name and version.
- *
- * @since 1.6
- * @see #FRAMEWORK_BSNVERSION
- */
- String FRAMEWORK_BSNVERSION_MULTIPLE = "multiple";
-
- /**
- * Specifies the framework will only allow a single bundle to be installed
- * for a given symbolic name and version. It will be an error to install a
- * bundle or update a bundle to have the same symbolic name and version as
- * another installed bundle.
- *
- * @since 1.6
- * @see #FRAMEWORK_BSNVERSION
- */
- String FRAMEWORK_BSNVERSION_SINGLE = "single";
+ public static final String SERVICE_DESCRIPTION = "service.description";
}
diff --git a/framework/src/main/java/org/osgi/framework/Filter.java b/framework/src/main/java/org/osgi/framework/Filter.java
index a9bb6c3..81c3e5b 100644
--- a/framework/src/main/java/org/osgi/framework/Filter.java
+++ b/framework/src/main/java/org/osgi/framework/Filter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,17 @@
package org.osgi.framework;
import java.util.Dictionary;
-import java.util.Map;
/**
- * An <a href="http://www.ietf.org/rfc/rfc1960.txt">RFC 1960</a>-based Filter.
+ * An RFC 1960-based Filter.
* <p>
- * {@code Filter}s can be created by calling {@link BundleContext#createFilter}
- * or {@link FrameworkUtil#createFilter} with a filter string.
+ * <code>Filter</code>s can be created by calling
+ * {@link BundleContext#createFilter} or {@link FrameworkUtil#createFilter} with
+ * a filter string.
* <p>
- * A {@code Filter} can be used numerous times to determine if the match
- * argument matches the filter string that was used to create the {@code Filter}.
+ * A <code>Filter</code> can be used numerous times to determine if the match
+ * argument matches the filter string that was used to create the
+ * <code>Filter</code>.
* <p>
* Some examples of LDAP filters are:
*
@@ -37,100 +38,86 @@
* </pre>
*
* @since 1.1
- * @see "Core Specification, Filters, for a description of the filter string syntax."
+ * @see "Core Specification, section 5.5, for a description of the filter string syntax."
* @ThreadSafe
- * @noimplement
- * @version $Id: 4d21267f4b85d1912d73f7e2c049cc968c4237f9 $
+ * @version $Revision: 6860 $
*/
public interface Filter {
/**
* Filter using a service's properties.
* <p>
- * This {@code Filter} is executed using the keys and values of the
- * referenced service's properties. The keys are looked up in a case
- * insensitive manner.
+ * This <code>Filter</code> is executed using the keys and values of the
+ * referenced service's properties. The keys are case insensitively matched
+ * with this <code>Filter</code>.
*
* @param reference The reference to the service whose properties are used
* in the match.
- * @return {@code true} if the service's properties match this
- * {@code Filter}; {@code false} otherwise.
+ * @return <code>true</code> if the service's properties match this
+ * <code>Filter</code>; <code>false</code> otherwise.
*/
- boolean match(ServiceReference< ? > reference);
+ public boolean match(ServiceReference reference);
/**
- * Filter using a {@code Dictionary} with case insensitive key lookup. This
- * {@code Filter} is executed using the specified {@code Dictionary}'s keys
- * and values. The keys are looked up in a case insensitive manner.
+ * Filter using a <code>Dictionary</code>. This <code>Filter</code> is
+ * executed using the specified <code>Dictionary</code>'s keys and values.
+ * The keys are case insensitively matched with this <code>Filter</code>.
*
- * @param dictionary The {@code Dictionary} whose key/value pairs are used
- * in the match.
- * @return {@code true} if the {@code Dictionary}'s values match this
- * filter; {@code false} otherwise.
- * @throws IllegalArgumentException If {@code dictionary} contains case
+ * @param dictionary The <code>Dictionary</code> whose keys are used in the
+ * match.
+ * @return <code>true</code> if the <code>Dictionary</code>'s keys and
+ * values match this filter; <code>false</code> otherwise.
+ * @throws IllegalArgumentException If <code>dictionary</code> contains case
* variants of the same key name.
*/
- boolean match(Dictionary<String, ? > dictionary);
+ public boolean match(Dictionary dictionary);
/**
- * Returns this {@code Filter}'s filter string.
+ * Returns this <code>Filter</code>'s filter string.
* <p>
* The filter string is normalized by removing whitespace which does not
* affect the meaning of the filter.
*
- * @return This {@code Filter}'s filter string.
+ * @return This <code>Filter</code>'s filter string.
*/
- String toString();
+ public String toString();
/**
- * Compares this {@code Filter} to another {@code Filter}.
+ * Compares this <code>Filter</code> to another <code>Filter</code>.
*
* <p>
- * This implementation returns the result of calling
- * {@code this.toString().equals(obj.toString())}.
+ * This method returns the result of calling
+ * <code>this.toString().equals(obj.toString())</code>.
*
- * @param obj The object to compare against this {@code Filter}.
- * @return If the other object is a {@code Filter} object, then returns
+ * @param obj The object to compare against this <code>Filter</code>.
+ * @return If the other object is a <code>Filter</code> object, then returns
* the result of calling
- * {@code this.toString().equals(obj.toString())};
- * {@code false} otherwise.
+ * <code>this.toString().equals(obj.toString())</code>;
+ * <code>false</code> otherwise.
*/
- boolean equals(Object obj);
+ public boolean equals(Object obj);
/**
- * Returns the hashCode for this {@code Filter}.
+ * Returns the hashCode for this <code>Filter</code>.
*
* <p>
- * This implementation returns the result of calling
- * {@code this.toString().hashCode()}.
+ * This method returns the result of calling
+ * <code>this.toString().hashCode()</code>.
*
- * @return The hashCode of this {@code Filter}.
+ * @return The hashCode of this <code>Filter</code>.
*/
- int hashCode();
+ public int hashCode();
/**
- * Filter using a {@code Dictionary}. This {@code Filter} is executed using
- * the specified {@code Dictionary}'s keys and values. The keys are looked
- * up in a normal manner respecting case.
+ * Filter with case sensitivity using a <code>Dictionary</code>. This
+ * <code>Filter</code> is executed using the specified
+ * <code>Dictionary</code>'s keys and values. The keys are case sensitively
+ * matched with this <code>Filter</code>.
*
- * @param dictionary The {@code Dictionary} whose key/value pairs are used
- * in the match.
- * @return {@code true} if the {@code Dictionary}'s values match this
- * filter; {@code false} otherwise.
+ * @param dictionary The <code>Dictionary</code> whose keys are used in the
+ * match.
+ * @return <code>true</code> if the <code>Dictionary</code>'s keys and
+ * values match this filter; <code>false</code> otherwise.
* @since 1.3
*/
- boolean matchCase(Dictionary<String, ? > dictionary);
-
- /**
- * Filter using a {@code Map}. This {@code Filter} is executed using the
- * specified {@code Map}'s keys and values. The keys are looked up in a
- * normal manner respecting case.
- *
- * @param map The {@code Map} whose key/value pairs are used in the match.
- * Maps with {@code null} key or values are not supported. A
- * {@code null} value is considered not present to the filter.
- * @return {@code true} if the {@code Map}'s values match this filter;
- * {@code false} otherwise.
- * @since 1.6
- */
- boolean matches(Map<String, ? > map);
+ public boolean matchCase(Dictionary dictionary);
}
diff --git a/framework/src/main/java/org/osgi/framework/FrameworkEvent.java b/framework/src/main/java/org/osgi/framework/FrameworkEvent.java
index d309699..747b249 100644
--- a/framework/src/main/java/org/osgi/framework/FrameworkEvent.java
+++ b/framework/src/main/java/org/osgi/framework/FrameworkEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,15 +18,12 @@
import java.util.EventObject;
-import org.osgi.framework.startlevel.FrameworkStartLevel;
-import org.osgi.framework.wiring.FrameworkWiring;
-
/**
* A general event from the Framework.
*
* <p>
- * {@code FrameworkEvent} objects are delivered to
- * {@code FrameworkListener}s when a general event occurs within the OSGi
+ * <code>FrameworkEvent</code> objects are delivered to
+ * <code>FrameworkListener</code>s when a general event occurs within the OSGi
* environment. A type code is used to identify the event type for future
* extendability.
*
@@ -35,7 +32,7 @@
*
* @Immutable
* @see FrameworkListener
- * @version $Id: e05c6ffd542fa432835961882bf6b15b0620ffb6 $
+ * @version $Revision: 6542 $
*/
public class FrameworkEvent extends EventObject {
@@ -64,7 +61,7 @@
* has reached the initial start level. The source of this event is the
* System Bundle.
*
- * @see "The Start Level Specification"
+ * @see "The Start Level Service"
*/
public final static int STARTED = 0x00000001;
@@ -77,21 +74,20 @@
public final static int ERROR = 0x00000002;
/**
- * A FrameworkWiring.refreshBundles operation has completed.
+ * A PackageAdmin.refreshPackage operation has completed.
*
* <p>
- * This event is fired when the Framework has completed the refresh bundles
- * operation initiated by a call to the FrameworkWiring.refreshBundles
- * method. The source of this event is the System Bundle.
+ * This event is fired when the Framework has completed the refresh packages
+ * operation initiated by a call to the PackageAdmin.refreshPackages method.
+ * The source of this event is the System Bundle.
*
* @since 1.2
- * @see FrameworkWiring#refreshBundles(java.util.Collection,
- * FrameworkListener...)
+ * @see "<code>PackageAdmin.refreshPackages</code>"
*/
public final static int PACKAGES_REFRESHED = 0x00000004;
/**
- * A FrameworkStartLevel.setStartLevel operation has completed.
+ * A StartLevel.setStartLevel operation has completed.
*
* <p>
* This event is fired when the Framework has completed changing the active
@@ -99,7 +95,7 @@
* The source of this event is the System Bundle.
*
* @since 1.2
- * @see FrameworkStartLevel#setStartLevel(int, FrameworkListener...)
+ * @see "The Start Level Service"
*/
public final static int STARTLEVEL_CHANGED = 0x00000008;
@@ -174,7 +170,7 @@
* Creates a Framework event.
*
* @param type The event type.
- * @param source The event source object. This may not be {@code null}.
+ * @param source The event source object. This may not be <code>null</code>.
* @deprecated As of 1.2. This constructor is deprecated in favor of using
* the other constructor with the System Bundle as the event
* source.
@@ -192,7 +188,7 @@
* @param type The event type.
* @param bundle The event source.
* @param throwable The related exception. This argument may be
- * {@code null} if there is no related exception.
+ * <code>null</code> if there is no related exception.
*/
public FrameworkEvent(int type, Bundle bundle, Throwable throwable) {
super(bundle);
@@ -204,7 +200,7 @@
/**
* Returns the exception related to this event.
*
- * @return The related exception or {@code null} if none.
+ * @return The related exception or <code>null</code> if none.
*/
public Throwable getThrowable() {
return throwable;
diff --git a/framework/src/main/java/org/osgi/framework/FrameworkListener.java b/framework/src/main/java/org/osgi/framework/FrameworkListener.java
index 5d73fb9..c96c490 100644
--- a/framework/src/main/java/org/osgi/framework/FrameworkListener.java
+++ b/framework/src/main/java/org/osgi/framework/FrameworkListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,31 +19,31 @@
import java.util.EventListener;
/**
- * A {@code FrameworkEvent} listener. {@code FrameworkListener} is
+ * A <code>FrameworkEvent</code> listener. <code>FrameworkListener</code> is
* a listener interface that may be implemented by a bundle developer. When a
- * {@code FrameworkEvent} is fired, it is asynchronously delivered to a
- * {@code FrameworkListener}. The Framework delivers
- * {@code FrameworkEvent} objects to a {@code FrameworkListener}
- * in order and must not concurrently call a {@code FrameworkListener}.
+ * <code>FrameworkEvent</code> is fired, it is asynchronously delivered to a
+ * <code>FrameworkListener</code>. The Framework delivers
+ * <code>FrameworkEvent</code> objects to a <code>FrameworkListener</code>
+ * in order and must not concurrently call a <code>FrameworkListener</code>.
*
* <p>
- * A {@code FrameworkListener} object is registered with the Framework
+ * A <code>FrameworkListener</code> object is registered with the Framework
* using the {@link BundleContext#addFrameworkListener} method.
- * {@code FrameworkListener} objects are called with a
- * {@code FrameworkEvent} objects when the Framework starts and when
+ * <code>FrameworkListener</code> objects are called with a
+ * <code>FrameworkEvent</code> objects when the Framework starts and when
* asynchronous errors occur.
*
* @see FrameworkEvent
* @NotThreadSafe
- * @version $Id: a32e7599ea09d3510759d77e824cb8d9eff67f9d $
+ * @version $Revision: 5673 $
*/
public interface FrameworkListener extends EventListener {
/**
- * Receives notification of a general {@code FrameworkEvent} object.
+ * Receives notification of a general <code>FrameworkEvent</code> object.
*
- * @param event The {@code FrameworkEvent} object.
+ * @param event The <code>FrameworkEvent</code> object.
*/
public void frameworkEvent(FrameworkEvent event);
}
diff --git a/framework/src/main/java/org/osgi/framework/FrameworkUtil.java b/framework/src/main/java/org/osgi/framework/FrameworkUtil.java
index 0e89999..4a53bd3 100644
--- a/framework/src/main/java/org/osgi/framework/FrameworkUtil.java
+++ b/framework/src/main/java/org/osgi/framework/FrameworkUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,15 +21,12 @@
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
import javax.security.auth.x500.X500Principal;
@@ -42,7 +39,7 @@
*
* @since 1.3
* @ThreadSafe
- * @version $Id: a902bc156ea997ed244831c7fab0f290a08ac0c1 $
+ * @version $Revision: 7761 $
*/
public class FrameworkUtil {
/**
@@ -53,9 +50,9 @@
}
/**
- * Creates a {@code Filter} object. This {@code Filter} object may
- * be used to match a {@code ServiceReference} object or a
- * {@code Dictionary} object.
+ * Creates a <code>Filter</code> object. This <code>Filter</code> object may
+ * be used to match a <code>ServiceReference</code> object or a
+ * <code>Dictionary</code> object.
*
* <p>
* If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
@@ -67,16 +64,16 @@
* by {@link BundleContext#createFilter(String)}.
*
* @param filter The filter string.
- * @return A {@code Filter} object encapsulating the filter string.
- * @throws InvalidSyntaxException If {@code filter} contains an invalid
+ * @return A <code>Filter</code> object encapsulating the filter string.
+ * @throws InvalidSyntaxException If <code>filter</code> contains an invalid
* filter string that cannot be parsed.
- * @throws NullPointerException If {@code filter} is null.
+ * @throws NullPointerException If <code>filter</code> is null.
*
* @see Filter
*/
public static Filter createFilter(String filter)
throws InvalidSyntaxException {
- return FilterImpl.newInstance(filter);
+ return new org.apache.felix.framework.FilterImpl(filter);
}
/**
@@ -105,8 +102,8 @@
* wildcard can also replace the first list of RDNs of a DN. The first RDNs
* are the least significant. Such lists of matched RDNs can be empty.
* <p>
- * For example, a match pattern with a wildcard that matches all DNs that
- * end with RDNs of o=ACME and c=US would look like this:
+ * For example, a match pattern with a wildcard that matches all all DNs
+ * that end with RDNs of o=ACME and c=US would look like this:
*
* <pre>
* *, o=ACME, c=US
@@ -179,36 +176,34 @@
*
* @param matchPattern The pattern against which to match the DN chain.
* @param dnChain The DN chain to match against the specified pattern. Each
- * element of the chain must be of type {@code String} and use the
- * format defined in <a
- * href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>.
- * @return {@code true} If the pattern matches the DN chain; otherwise
- * {@code false} is returned.
+ * element of the chain must be of type <code>String</code> and use
+ * the format defined in RFC 2253.
+ * @return <code>true</code> If the pattern matches the DN chain; otherwise
+ * <code>false</code> is returned.
* @throws IllegalArgumentException If the specified match pattern or DN
* chain is invalid.
* @since 1.5
*/
public static boolean matchDistinguishedNameChain(String matchPattern,
- List<String> dnChain) {
+ List /* <String> */dnChain) {
return DNChainMatching.match(matchPattern, dnChain);
}
/**
- * Return a {@code Bundle} for the specified bundle class. The returned
- * {@code Bundle} is the bundle associated with the bundle class loader
+ * Return a <code>Bundle</code> for the specified bundle class. The returned
+ * <code>Bundle</code> is the bundle associated with the bundle class loader
* which defined the specified class.
*
* @param classFromBundle A class defined by a bundle class loader.
- * @return A {@code Bundle} for the specified bundle class or
- * {@code null} if the specified class was not defined by a
+ * @return A <code>Bundle</code> for the specified bundle class or
+ * <code>null</code> if the specified class was not defined by a
* bundle class loader.
* @since 1.5
*/
- public static Bundle getBundle(final Class< ? > classFromBundle) {
+ public static Bundle getBundle(final Class classFromBundle) {
// We use doPriv since the caller may not have permission
// to call getClassLoader.
- Object cl = AccessController
- .doPrivileged(new PrivilegedAction<Object>() {
+ Object cl = AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return classFromBundle.getClassLoader();
}
@@ -221,1518 +216,6 @@
}
/**
- * RFC 1960-based Filter. Filter objects can be created by calling the
- * constructor with the desired filter string. A Filter object can be called
- * numerous times to determine if the match argument matches the filter
- * string that was used to create the Filter object.
- *
- * <p>
- * The syntax of a filter string is the string representation of LDAP search
- * filters as defined in RFC 1960: <i>A String Representation of LDAP Search
- * Filters</i> (available at http://www.ietf.org/rfc/rfc1960.txt). It should
- * be noted that RFC 2254: <i>A String Representation of LDAP Search
- * Filters</i> (available at http://www.ietf.org/rfc/rfc2254.txt) supersedes
- * RFC 1960 but only adds extensible matching and is not applicable for this
- * API.
- *
- * <p>
- * The string representation of an LDAP search filter is defined by the
- * following grammar. It uses a prefix format.
- *
- * <pre>
- * <filter> ::= '(' <filtercomp> ')'
- * <filtercomp> ::= <and> | <or> | <not> | <item>
- * <and> ::= '&' <filterlist>
- * <or> ::= '|' <filterlist>
- * <not> ::= '!' <filter>
- * <filterlist> ::= <filter> | <filter> <filterlist>
- * <item> ::= <simple> | <present> | <substring>
- * <simple> ::= <attr> <filtertype> <value>
- * <filtertype> ::= <equal> | <approx> | <greater> | <less>
- * <equal> ::= '='
- * <approx> ::= '˜='
- * <greater> ::= '>='
- * <less> ::= '<='
- * <present> ::= <attr> '=*'
- * <substring> ::= <attr> '=' <initial> <any> <final>
- * <initial> ::= NULL | <value>
- * <any> ::= '*' <starval>
- * <starval> ::= NULL | <value> '*' <starval>
- * <final> ::= NULL | <value>
- * </pre>
- *
- * {@code <attr>} is a string representing an attribute, or key,
- * in the properties objects of the registered services. Attribute names are
- * not case sensitive; that is cn and CN both refer to the same attribute.
- * {@code <value>} is a string representing the value, or part of
- * one, of a key in the properties objects of the registered services. If a
- * {@code <value>} must contain one of the characters '
- * {@code *}' or '{@code (}' or '{@code )}', these characters
- * should be escaped by preceding them with the backslash '{@code \}'
- * character. Note that although both the {@code <substring>} and
- * {@code <present>} productions can produce the {@code 'attr=*'}
- * construct, this construct is used only to denote a presence filter.
- *
- * <p>
- * Examples of LDAP filters are:
- *
- * <pre>
- * "(cn=Babs Jensen)"
- * "(!(cn=Tim Howes))"
- * "(&(" + Constants.OBJECTCLASS + "=Person)(|(sn=Jensen)(cn=Babs J*)))"
- * "(o=univ*of*mich*)"
- * </pre>
- *
- * <p>
- * The approximate match ({@code ~=}) is implementation specific but
- * should at least ignore case and white space differences. Optional are
- * codes like soundex or other smart "closeness" comparisons.
- *
- * <p>
- * Comparison of values is not straightforward. Strings are compared
- * differently than numbers and it is possible for a key to have multiple
- * values. Note that that keys in the match argument must always be strings.
- * The comparison is defined by the object type of the key's value. The
- * following rules apply for comparison:
- *
- * <blockquote>
- * <TABLE BORDER=0>
- * <TR>
- * <TD><b>Property Value Type </b></TD>
- * <TD><b>Comparison Type</b></TD>
- * </TR>
- * <TR>
- * <TD>String</TD>
- * <TD>String comparison</TD>
- * </TR>
- * <TR valign=top>
- * <TD>Integer, Long, Float, Double, Byte, Short, BigInteger, BigDecimal</TD>
- * <TD>numerical comparison</TD>
- * </TR>
- * <TR>
- * <TD>Character</TD>
- * <TD>character comparison</TD>
- * </TR>
- * <TR>
- * <TD>Boolean</TD>
- * <TD>equality comparisons only</TD>
- * </TR>
- * <TR>
- * <TD>[] (array)</TD>
- * <TD>recursively applied to values</TD>
- * </TR>
- * <TR>
- * <TD>Collection</TD>
- * <TD>recursively applied to values</TD>
- * </TR>
- * </TABLE>
- * Note: arrays of primitives are also supported. </blockquote>
- *
- * A filter matches a key that has multiple values if it matches at least
- * one of those values. For example,
- *
- * <pre>
- * Dictionary d = new Hashtable();
- * d.put("cn", new String[] {"a", "b", "c"});
- * </pre>
- *
- * d will match {@code (cn=a)} and also {@code (cn=b)}
- *
- * <p>
- * A filter component that references a key having an unrecognizable data
- * type will evaluate to {@code false} .
- */
- static private final class FilterImpl implements Filter {
- /* filter operators */
- private static final int EQUAL = 1;
- private static final int APPROX = 2;
- private static final int GREATER = 3;
- private static final int LESS = 4;
- private static final int PRESENT = 5;
- private static final int SUBSTRING = 6;
- private static final int AND = 7;
- private static final int OR = 8;
- private static final int NOT = 9;
-
- /** filter operation */
- private final int op;
- /** filter attribute or null if operation AND, OR or NOT */
- private final String attr;
- /** filter operands */
- private final Object value;
-
- /* normalized filter string for Filter object */
- private transient String filterString;
-
- /**
- * Constructs a {@link FilterImpl} object. This filter object may be
- * used to match a {@link ServiceReference} or a Dictionary.
- *
- * <p>
- * If the filter cannot be parsed, an {@link InvalidSyntaxException}
- * will be thrown with a human readable message where the filter became
- * unparsable.
- *
- * @param filterString the filter string.
- * @throws InvalidSyntaxException If the filter parameter contains an
- * invalid filter string that cannot be parsed.
- */
- static FilterImpl newInstance(String filterString)
- throws InvalidSyntaxException {
- return new Parser(filterString).parse();
- }
-
- FilterImpl(int operation, String attr, Object value) {
- this.op = operation;
- this.attr = attr;
- this.value = value;
- filterString = null;
- }
-
- /**
- * Filter using a service's properties.
- * <p>
- * This {@code Filter} is executed using the keys and values of the
- * referenced service's properties. The keys are looked up in a case
- * insensitive manner.
- *
- * @param reference The reference to the service whose properties are
- * used in the match.
- * @return {@code true} if the service's properties match this
- * {@code Filter}; {@code false} otherwise.
- */
- public boolean match(ServiceReference< ? > reference) {
- return matches(new ServiceReferenceMap(reference));
- }
-
- /**
- * Filter using a {@code Dictionary} with case insensitive key lookup.
- * This {@code Filter} is executed using the specified
- * {@code Dictionary}'s keys and values. The keys are looked up in a
- * case insensitive manner.
- *
- * @param dictionary The {@code Dictionary} whose key/value pairs are
- * used in the match.
- * @return {@code true} if the {@code Dictionary}'s values match this
- * filter; {@code false} otherwise.
- * @throws IllegalArgumentException If {@code dictionary} contains case
- * variants of the same key name.
- */
- public boolean match(Dictionary<String, ? > dictionary) {
- return matches(new CaseInsensitiveMap(dictionary));
- }
-
- /**
- * Filter using a {@code Dictionary}. This {@code Filter} is executed
- * using the specified {@code Dictionary}'s keys and values. The keys
- * are looked up in a normal manner respecting case.
- *
- * @param dictionary The {@code Dictionary} whose key/value pairs are
- * used in the match.
- * @return {@code true} if the {@code Dictionary}'s values match this
- * filter; {@code false} otherwise.
- * @since 1.3
- */
- public boolean matchCase(Dictionary<String, ? > dictionary) {
- switch (op) {
- case AND : {
- FilterImpl[] filters = (FilterImpl[]) value;
- for (FilterImpl f : filters) {
- if (!f.matchCase(dictionary)) {
- return false;
- }
- }
- return true;
- }
-
- case OR : {
- FilterImpl[] filters = (FilterImpl[]) value;
- for (FilterImpl f : filters) {
- if (f.matchCase(dictionary)) {
- return true;
- }
- }
- return false;
- }
-
- case NOT : {
- FilterImpl filter = (FilterImpl) value;
- return !filter.matchCase(dictionary);
- }
-
- case SUBSTRING :
- case EQUAL :
- case GREATER :
- case LESS :
- case APPROX : {
- Object prop = (dictionary == null) ? null : dictionary
- .get(attr);
- return compare(op, prop, value);
- }
-
- case PRESENT : {
- Object prop = (dictionary == null) ? null : dictionary
- .get(attr);
- return prop != null;
- }
- }
-
- return false;
- }
-
- /**
- * Filter using a {@code Map}. This {@code Filter} is executed using the
- * specified {@code Map}'s keys and values. The keys are looked up in a
- * normal manner respecting case.
- *
- * @param map The {@code Map} whose key/value pairs are used in the
- * match. Maps with {@code null} key or values are not supported.
- * A {@code null} value is considered not present to the filter.
- * @return {@code true} if the {@code Map}'s values match this filter;
- * {@code false} otherwise.
- * @since 1.6
- */
- public boolean matches(Map<String, ? > map) {
- switch (op) {
- case AND : {
- FilterImpl[] filters = (FilterImpl[]) value;
- for (FilterImpl f : filters) {
- if (!f.matches(map)) {
- return false;
- }
- }
- return true;
- }
-
- case OR : {
- FilterImpl[] filters = (FilterImpl[]) value;
- for (FilterImpl f : filters) {
- if (f.matches(map)) {
- return true;
- }
- }
- return false;
- }
-
- case NOT : {
- FilterImpl filter = (FilterImpl) value;
- return !filter.matches(map);
- }
-
- case SUBSTRING :
- case EQUAL :
- case GREATER :
- case LESS :
- case APPROX : {
- Object prop = (map == null) ? null : map.get(attr);
- return compare(op, prop, value);
- }
-
- case PRESENT : {
- Object prop = (map == null) ? null : map.get(attr);
- return prop != null;
- }
- }
-
- return false;
- }
-
- /**
- * Returns this {@code Filter}'s filter string.
- * <p>
- * The filter string is normalized by removing whitespace which does not
- * affect the meaning of the filter.
- *
- * @return This {@code Filter}'s filter string.
- */
- public String toString() {
- String result = filterString;
- if (result == null) {
- filterString = result = normalize().toString();
- }
- return result;
- }
-
- /**
- * Returns this {@code Filter}'s normalized filter string.
- * <p>
- * The filter string is normalized by removing whitespace which does not
- * affect the meaning of the filter.
- *
- * @return This {@code Filter}'s filter string.
- */
- private StringBuffer normalize() {
- StringBuffer sb = new StringBuffer();
- sb.append('(');
-
- switch (op) {
- case AND : {
- sb.append('&');
-
- FilterImpl[] filters = (FilterImpl[]) value;
- for (FilterImpl f : filters) {
- sb.append(f.normalize());
- }
-
- break;
- }
-
- case OR : {
- sb.append('|');
-
- FilterImpl[] filters = (FilterImpl[]) value;
- for (FilterImpl f : filters) {
- sb.append(f.normalize());
- }
-
- break;
- }
-
- case NOT : {
- sb.append('!');
- FilterImpl filter = (FilterImpl) value;
- sb.append(filter.normalize());
-
- break;
- }
-
- case SUBSTRING : {
- sb.append(attr);
- sb.append('=');
-
- String[] substrings = (String[]) value;
-
- for (String substr : substrings) {
- if (substr == null) /* * */{
- sb.append('*');
- }
- else /* xxx */{
- sb.append(encodeValue(substr));
- }
- }
-
- break;
- }
- case EQUAL : {
- sb.append(attr);
- sb.append('=');
- sb.append(encodeValue((String) value));
-
- break;
- }
- case GREATER : {
- sb.append(attr);
- sb.append(">=");
- sb.append(encodeValue((String) value));
-
- break;
- }
- case LESS : {
- sb.append(attr);
- sb.append("<=");
- sb.append(encodeValue((String) value));
-
- break;
- }
- case APPROX : {
- sb.append(attr);
- sb.append("~=");
- sb.append(encodeValue(approxString((String) value)));
-
- break;
- }
-
- case PRESENT : {
- sb.append(attr);
- sb.append("=*");
-
- break;
- }
- }
-
- sb.append(')');
-
- return sb;
- }
-
- /**
- * Compares this {@code Filter} to another {@code Filter}.
- *
- * <p>
- * This implementation returns the result of calling
- * {@code this.toString().equals(obj.toString()}.
- *
- * @param obj The object to compare against this {@code Filter}.
- * @return If the other object is a {@code Filter} object, then
- * returns the result of calling
- * {@code this.toString().equals(obj.toString()};
- * {@code false} otherwise.
- */
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
-
- if (!(obj instanceof Filter)) {
- return false;
- }
-
- return this.toString().equals(obj.toString());
- }
-
- /**
- * Returns the hashCode for this {@code Filter}.
- *
- * <p>
- * This implementation returns the result of calling
- * {@code this.toString().hashCode()}.
- *
- * @return The hashCode of this {@code Filter}.
- */
- public int hashCode() {
- return this.toString().hashCode();
- }
-
- /**
- * Encode the value string such that '(', '*', ')' and '\' are escaped.
- *
- * @param value unencoded value string.
- * @return encoded value string.
- */
- private static String encodeValue(String value) {
- boolean encoded = false;
- int inlen = value.length();
- int outlen = inlen << 1; /* inlen 2 */
-
- char[] output = new char[outlen];
- value.getChars(0, inlen, output, inlen);
-
- int cursor = 0;
- for (int i = inlen; i < outlen; i++) {
- char c = output[i];
-
- switch (c) {
- case '(' :
- case '*' :
- case ')' :
- case '\\' : {
- output[cursor] = '\\';
- cursor++;
- encoded = true;
-
- break;
- }
- }
-
- output[cursor] = c;
- cursor++;
- }
-
- return encoded ? new String(output, 0, cursor) : value;
- }
-
- private boolean compare(int operation, Object value1, Object value2) {
- if (value1 == null) {
- return false;
- }
- if (value1 instanceof String) {
- return compare_String(operation, (String) value1, value2);
- }
-
- Class< ? > clazz = value1.getClass();
- if (clazz.isArray()) {
- Class< ? > type = clazz.getComponentType();
- if (type.isPrimitive()) {
- return compare_PrimitiveArray(operation, type, value1,
- value2);
- }
- return compare_ObjectArray(operation, (Object[]) value1, value2);
- }
- if (value1 instanceof Collection< ? >) {
- return compare_Collection(operation, (Collection< ? >) value1,
- value2);
- }
- if (value1 instanceof Integer) {
- return compare_Integer(operation,
- ((Integer) value1).intValue(), value2);
- }
- if (value1 instanceof Long) {
- return compare_Long(operation, ((Long) value1).longValue(),
- value2);
- }
- if (value1 instanceof Byte) {
- return compare_Byte(operation, ((Byte) value1).byteValue(),
- value2);
- }
- if (value1 instanceof Short) {
- return compare_Short(operation, ((Short) value1).shortValue(),
- value2);
- }
- if (value1 instanceof Character) {
- return compare_Character(operation, ((Character) value1)
- .charValue(), value2);
- }
- if (value1 instanceof Float) {
- return compare_Float(operation, ((Float) value1).floatValue(),
- value2);
- }
- if (value1 instanceof Double) {
- return compare_Double(operation, ((Double) value1)
- .doubleValue(), value2);
- }
- if (value1 instanceof Boolean) {
- return compare_Boolean(operation, ((Boolean) value1)
- .booleanValue(), value2);
- }
- if (value1 instanceof Comparable< ? >) {
- Comparable<Object> comparable = (Comparable<Object>) value1;
- return compare_Comparable(operation, comparable, value2);
- }
- return compare_Unknown(operation, value1, value2);
- }
-
- private boolean compare_Collection(int operation,
- Collection< ? > collection, Object value2) {
- for (Object value1 : collection) {
- if (compare(operation, value1, value2)) {
- return true;
- }
- }
- return false;
- }
-
- private boolean compare_ObjectArray(int operation, Object[] array,
- Object value2) {
- for (Object value1 : array) {
- if (compare(operation, value1, value2)) {
- return true;
- }
- }
- return false;
- }
-
- private boolean compare_PrimitiveArray(int operation, Class< ? > type,
- Object primarray, Object value2) {
- if (Integer.TYPE.isAssignableFrom(type)) {
- int[] array = (int[]) primarray;
- for (int value1 : array) {
- if (compare_Integer(operation, value1, value2)) {
- return true;
- }
- }
- return false;
- }
- if (Long.TYPE.isAssignableFrom(type)) {
- long[] array = (long[]) primarray;
- for (long value1 : array) {
- if (compare_Long(operation, value1, value2)) {
- return true;
- }
- }
- return false;
- }
- if (Byte.TYPE.isAssignableFrom(type)) {
- byte[] array = (byte[]) primarray;
- for (byte value1 : array) {
- if (compare_Byte(operation, value1, value2)) {
- return true;
- }
- }
- return false;
- }
- if (Short.TYPE.isAssignableFrom(type)) {
- short[] array = (short[]) primarray;
- for (short value1 : array) {
- if (compare_Short(operation, value1, value2)) {
- return true;
- }
- }
- return false;
- }
- if (Character.TYPE.isAssignableFrom(type)) {
- char[] array = (char[]) primarray;
- for (char value1 : array) {
- if (compare_Character(operation, value1, value2)) {
- return true;
- }
- }
- return false;
- }
- if (Float.TYPE.isAssignableFrom(type)) {
- float[] array = (float[]) primarray;
- for (float value1 : array) {
- if (compare_Float(operation, value1, value2)) {
- return true;
- }
- }
- return false;
- }
- if (Double.TYPE.isAssignableFrom(type)) {
- double[] array = (double[]) primarray;
- for (double value1 : array) {
- if (compare_Double(operation, value1, value2)) {
- return true;
- }
- }
- return false;
- }
- if (Boolean.TYPE.isAssignableFrom(type)) {
- boolean[] array = (boolean[]) primarray;
- for (boolean value1 : array) {
- if (compare_Boolean(operation, value1, value2)) {
- return true;
- }
- }
- return false;
- }
- return false;
- }
-
- private boolean compare_String(int operation, String string,
- Object value2) {
- switch (operation) {
- case SUBSTRING : {
- String[] substrings = (String[]) value2;
- int pos = 0;
- for (int i = 0, size = substrings.length; i < size; i++) {
- String substr = substrings[i];
-
- if (i + 1 < size) /* if this is not that last substr */{
- if (substr == null) /* * */{
- String substr2 = substrings[i + 1];
-
- if (substr2 == null) /* ** */
- continue; /* ignore first star */
- /* xxx */
- int index = string.indexOf(substr2, pos);
- if (index == -1) {
- return false;
- }
-
- pos = index + substr2.length();
- if (i + 2 < size) // if there are more
- // substrings, increment
- // over the string we just
- // matched; otherwise need
- // to do the last substr
- // check
- i++;
- }
- else /* xxx */{
- int len = substr.length();
- if (string.regionMatches(pos, substr, 0, len)) {
- pos += len;
- }
- else {
- return false;
- }
- }
- }
- else /* last substr */{
- if (substr == null) /* * */{
- return true;
- }
- /* xxx */
- return string.endsWith(substr);
- }
- }
-
- return true;
- }
- case EQUAL : {
- return string.equals(value2);
- }
- case APPROX : {
- string = approxString(string);
- String string2 = approxString((String) value2);
-
- return string.equalsIgnoreCase(string2);
- }
- case GREATER : {
- return string.compareTo((String) value2) >= 0;
- }
- case LESS : {
- return string.compareTo((String) value2) <= 0;
- }
- }
- return false;
- }
-
- private boolean compare_Integer(int operation, int intval, Object value2) {
- if (operation == SUBSTRING) {
- return false;
- }
- int intval2;
- try {
- intval2 = Integer.parseInt(((String) value2).trim());
- }
- catch (IllegalArgumentException e) {
- return false;
- }
- switch (operation) {
- case APPROX :
- case EQUAL : {
- return intval == intval2;
- }
- case GREATER : {
- return intval >= intval2;
- }
- case LESS : {
- return intval <= intval2;
- }
- }
- return false;
- }
-
- private boolean compare_Long(int operation, long longval, Object value2) {
- if (operation == SUBSTRING) {
- return false;
- }
- long longval2;
- try {
- longval2 = Long.parseLong(((String) value2).trim());
- }
- catch (IllegalArgumentException e) {
- return false;
- }
-
- switch (operation) {
- case APPROX :
- case EQUAL : {
- return longval == longval2;
- }
- case GREATER : {
- return longval >= longval2;
- }
- case LESS : {
- return longval <= longval2;
- }
- }
- return false;
- }
-
- private boolean compare_Byte(int operation, byte byteval, Object value2) {
- if (operation == SUBSTRING) {
- return false;
- }
- byte byteval2;
- try {
- byteval2 = Byte.parseByte(((String) value2).trim());
- }
- catch (IllegalArgumentException e) {
- return false;
- }
-
- switch (operation) {
- case APPROX :
- case EQUAL : {
- return byteval == byteval2;
- }
- case GREATER : {
- return byteval >= byteval2;
- }
- case LESS : {
- return byteval <= byteval2;
- }
- }
- return false;
- }
-
- private boolean compare_Short(int operation, short shortval,
- Object value2) {
- if (operation == SUBSTRING) {
- return false;
- }
- short shortval2;
- try {
- shortval2 = Short.parseShort(((String) value2).trim());
- }
- catch (IllegalArgumentException e) {
- return false;
- }
-
- switch (operation) {
- case APPROX :
- case EQUAL : {
- return shortval == shortval2;
- }
- case GREATER : {
- return shortval >= shortval2;
- }
- case LESS : {
- return shortval <= shortval2;
- }
- }
- return false;
- }
-
- private boolean compare_Character(int operation, char charval,
- Object value2) {
- if (operation == SUBSTRING) {
- return false;
- }
- char charval2;
- try {
- charval2 = ((String) value2).charAt(0);
- }
- catch (IndexOutOfBoundsException e) {
- return false;
- }
-
- switch (operation) {
- case EQUAL : {
- return charval == charval2;
- }
- case APPROX : {
- return (charval == charval2)
- || (Character.toUpperCase(charval) == Character
- .toUpperCase(charval2))
- || (Character.toLowerCase(charval) == Character
- .toLowerCase(charval2));
- }
- case GREATER : {
- return charval >= charval2;
- }
- case LESS : {
- return charval <= charval2;
- }
- }
- return false;
- }
-
- private boolean compare_Boolean(int operation, boolean boolval,
- Object value2) {
- if (operation == SUBSTRING) {
- return false;
- }
- boolean boolval2 = Boolean.valueOf(((String) value2).trim())
- .booleanValue();
- switch (operation) {
- case APPROX :
- case EQUAL :
- case GREATER :
- case LESS : {
- return boolval == boolval2;
- }
- }
- return false;
- }
-
- private boolean compare_Float(int operation, float floatval,
- Object value2) {
- if (operation == SUBSTRING) {
- return false;
- }
- float floatval2;
- try {
- floatval2 = Float.parseFloat(((String) value2).trim());
- }
- catch (IllegalArgumentException e) {
- return false;
- }
-
- switch (operation) {
- case APPROX :
- case EQUAL : {
- return Float.compare(floatval, floatval2) == 0;
- }
- case GREATER : {
- return Float.compare(floatval, floatval2) >= 0;
- }
- case LESS : {
- return Float.compare(floatval, floatval2) <= 0;
- }
- }
- return false;
- }
-
- private boolean compare_Double(int operation, double doubleval,
- Object value2) {
- if (operation == SUBSTRING) {
- return false;
- }
- double doubleval2;
- try {
- doubleval2 = Double.parseDouble(((String) value2).trim());
- }
- catch (IllegalArgumentException e) {
- return false;
- }
-
- switch (operation) {
- case APPROX :
- case EQUAL : {
- return Double.compare(doubleval, doubleval2) == 0;
- }
- case GREATER : {
- return Double.compare(doubleval, doubleval2) >= 0;
- }
- case LESS : {
- return Double.compare(doubleval, doubleval2) <= 0;
- }
- }
- return false;
- }
-
- private static final Class< ? >[] constructorType = new Class[] {String.class};
-
- private boolean compare_Comparable(int operation,
- Comparable<Object> value1, Object value2) {
- if (operation == SUBSTRING) {
- return false;
- }
- Constructor< ? > constructor;
- try {
- constructor = value1.getClass().getConstructor(constructorType);
- }
- catch (NoSuchMethodException e) {
- return false;
- }
- try {
- if (!constructor.isAccessible())
- AccessController.doPrivileged(new SetAccessibleAction(
- constructor));
- value2 = constructor
- .newInstance(new Object[] {((String) value2).trim()});
- }
- catch (IllegalAccessException e) {
- return false;
- }
- catch (InvocationTargetException e) {
- return false;
- }
- catch (InstantiationException e) {
- return false;
- }
-
- try {
- switch (operation) {
- case APPROX :
- case EQUAL : {
- return value1.compareTo(value2) == 0;
- }
- case GREATER : {
- return value1.compareTo(value2) >= 0;
- }
- case LESS : {
- return value1.compareTo(value2) <= 0;
- }
- }
- }
- catch (Exception e) {
- // if the compareTo method throws an exception; return false
- return false;
- }
- return false;
- }
-
- private boolean compare_Unknown(int operation, Object value1,
- Object value2) {
- if (operation == SUBSTRING) {
- return false;
- }
- Constructor< ? > constructor;
- try {
- constructor = value1.getClass().getConstructor(constructorType);
- }
- catch (NoSuchMethodException e) {
- return false;
- }
- try {
- if (!constructor.isAccessible())
- AccessController.doPrivileged(new SetAccessibleAction(
- constructor));
- value2 = constructor
- .newInstance(new Object[] {((String) value2).trim()});
- }
- catch (IllegalAccessException e) {
- return false;
- }
- catch (InvocationTargetException e) {
- return false;
- }
- catch (InstantiationException e) {
- return false;
- }
-
- try {
- switch (operation) {
- case APPROX :
- case EQUAL :
- case GREATER :
- case LESS : {
- return value1.equals(value2);
- }
- }
- }
- catch (Exception e) {
- // if the equals method throws an exception; return false
- return false;
- }
- return false;
- }
-
- /**
- * Map a string for an APPROX (~=) comparison.
- *
- * This implementation removes white spaces. This is the minimum
- * implementation allowed by the OSGi spec.
- *
- * @param input Input string.
- * @return String ready for APPROX comparison.
- */
- private static String approxString(String input) {
- boolean changed = false;
- char[] output = input.toCharArray();
- int cursor = 0;
- for (char c : output) {
- if (Character.isWhitespace(c)) {
- changed = true;
- continue;
- }
-
- output[cursor] = c;
- cursor++;
- }
-
- return changed ? new String(output, 0, cursor) : input;
- }
-
- /**
- * Parser class for OSGi filter strings. This class parses the complete
- * filter string and builds a tree of Filter objects rooted at the
- * parent.
- */
- static private final class Parser {
- private final String filterstring;
- private final char[] filterChars;
- private int pos;
-
- Parser(String filterstring) {
- this.filterstring = filterstring;
- filterChars = filterstring.toCharArray();
- pos = 0;
- }
-
- FilterImpl parse() throws InvalidSyntaxException {
- FilterImpl filter;
- try {
- filter = parse_filter();
- }
- catch (ArrayIndexOutOfBoundsException e) {
- throw new InvalidSyntaxException("Filter ended abruptly",
- filterstring, e);
- }
-
- if (pos != filterChars.length) {
- throw new InvalidSyntaxException(
- "Extraneous trailing characters: "
- + filterstring.substring(pos), filterstring);
- }
- return filter;
- }
-
- private FilterImpl parse_filter() throws InvalidSyntaxException {
- FilterImpl filter;
- skipWhiteSpace();
-
- if (filterChars[pos] != '(') {
- throw new InvalidSyntaxException("Missing '(': "
- + filterstring.substring(pos), filterstring);
- }
-
- pos++;
-
- filter = parse_filtercomp();
-
- skipWhiteSpace();
-
- if (filterChars[pos] != ')') {
- throw new InvalidSyntaxException("Missing ')': "
- + filterstring.substring(pos), filterstring);
- }
-
- pos++;
-
- skipWhiteSpace();
-
- return filter;
- }
-
- private FilterImpl parse_filtercomp() throws InvalidSyntaxException {
- skipWhiteSpace();
-
- char c = filterChars[pos];
-
- switch (c) {
- case '&' : {
- pos++;
- return parse_and();
- }
- case '|' : {
- pos++;
- return parse_or();
- }
- case '!' : {
- pos++;
- return parse_not();
- }
- }
- return parse_item();
- }
-
- private FilterImpl parse_and() throws InvalidSyntaxException {
- int lookahead = pos;
- skipWhiteSpace();
-
- if (filterChars[pos] != '(') {
- pos = lookahead - 1;
- return parse_item();
- }
-
- List<FilterImpl> operands = new ArrayList<FilterImpl>(10);
-
- while (filterChars[pos] == '(') {
- FilterImpl child = parse_filter();
- operands.add(child);
- }
-
- return new FilterImpl(FilterImpl.AND, null, operands
- .toArray(new FilterImpl[operands.size()]));
- }
-
- private FilterImpl parse_or() throws InvalidSyntaxException {
- int lookahead = pos;
- skipWhiteSpace();
-
- if (filterChars[pos] != '(') {
- pos = lookahead - 1;
- return parse_item();
- }
-
- List<FilterImpl> operands = new ArrayList<FilterImpl>(10);
-
- while (filterChars[pos] == '(') {
- FilterImpl child = parse_filter();
- operands.add(child);
- }
-
- return new FilterImpl(FilterImpl.OR, null, operands
- .toArray(new FilterImpl[operands.size()]));
- }
-
- private FilterImpl parse_not() throws InvalidSyntaxException {
- int lookahead = pos;
- skipWhiteSpace();
-
- if (filterChars[pos] != '(') {
- pos = lookahead - 1;
- return parse_item();
- }
-
- FilterImpl child = parse_filter();
-
- return new FilterImpl(FilterImpl.NOT, null, child);
- }
-
- private FilterImpl parse_item() throws InvalidSyntaxException {
- String attr = parse_attr();
-
- skipWhiteSpace();
-
- switch (filterChars[pos]) {
- case '~' : {
- if (filterChars[pos + 1] == '=') {
- pos += 2;
- return new FilterImpl(FilterImpl.APPROX, attr,
- parse_value());
- }
- break;
- }
- case '>' : {
- if (filterChars[pos + 1] == '=') {
- pos += 2;
- return new FilterImpl(FilterImpl.GREATER, attr,
- parse_value());
- }
- break;
- }
- case '<' : {
- if (filterChars[pos + 1] == '=') {
- pos += 2;
- return new FilterImpl(FilterImpl.LESS, attr,
- parse_value());
- }
- break;
- }
- case '=' : {
- if (filterChars[pos + 1] == '*') {
- int oldpos = pos;
- pos += 2;
- skipWhiteSpace();
- if (filterChars[pos] == ')') {
- return new FilterImpl(FilterImpl.PRESENT, attr,
- null);
- }
- pos = oldpos;
- }
-
- pos++;
- Object string = parse_substring();
-
- if (string instanceof String) {
- return new FilterImpl(FilterImpl.EQUAL, attr,
- string);
- }
- return new FilterImpl(FilterImpl.SUBSTRING, attr,
- string);
- }
- }
-
- throw new InvalidSyntaxException("Invalid operator: "
- + filterstring.substring(pos), filterstring);
- }
-
- private String parse_attr() throws InvalidSyntaxException {
- skipWhiteSpace();
-
- int begin = pos;
- int end = pos;
-
- char c = filterChars[pos];
-
- while (c != '~' && c != '<' && c != '>' && c != '=' && c != '('
- && c != ')') {
- pos++;
-
- if (!Character.isWhitespace(c)) {
- end = pos;
- }
-
- c = filterChars[pos];
- }
-
- int length = end - begin;
-
- if (length == 0) {
- throw new InvalidSyntaxException("Missing attr: "
- + filterstring.substring(pos), filterstring);
- }
-
- return new String(filterChars, begin, length);
- }
-
- private String parse_value() throws InvalidSyntaxException {
- StringBuffer sb = new StringBuffer(filterChars.length - pos);
-
- parseloop: while (true) {
- char c = filterChars[pos];
-
- switch (c) {
- case ')' : {
- break parseloop;
- }
-
- case '(' : {
- throw new InvalidSyntaxException("Invalid value: "
- + filterstring.substring(pos), filterstring);
- }
-
- case '\\' : {
- pos++;
- c = filterChars[pos];
- /* fall through into default */
- }
-
- default : {
- sb.append(c);
- pos++;
- break;
- }
- }
- }
-
- if (sb.length() == 0) {
- throw new InvalidSyntaxException("Missing value: "
- + filterstring.substring(pos), filterstring);
- }
-
- return sb.toString();
- }
-
- private Object parse_substring() throws InvalidSyntaxException {
- StringBuffer sb = new StringBuffer(filterChars.length - pos);
-
- List<String> operands = new ArrayList<String>(10);
-
- parseloop: while (true) {
- char c = filterChars[pos];
-
- switch (c) {
- case ')' : {
- if (sb.length() > 0) {
- operands.add(sb.toString());
- }
-
- break parseloop;
- }
-
- case '(' : {
- throw new InvalidSyntaxException("Invalid value: "
- + filterstring.substring(pos), filterstring);
- }
-
- case '*' : {
- if (sb.length() > 0) {
- operands.add(sb.toString());
- }
-
- sb.setLength(0);
-
- operands.add(null);
- pos++;
-
- break;
- }
-
- case '\\' : {
- pos++;
- c = filterChars[pos];
- /* fall through into default */
- }
-
- default : {
- sb.append(c);
- pos++;
- break;
- }
- }
- }
-
- int size = operands.size();
-
- if (size == 0) {
- return "";
- }
-
- if (size == 1) {
- Object single = operands.get(0);
-
- if (single != null) {
- return single;
- }
- }
-
- return operands.toArray(new String[size]);
- }
-
- private void skipWhiteSpace() {
- for (int length = filterChars.length; (pos < length)
- && Character.isWhitespace(filterChars[pos]);) {
- pos++;
- }
- }
- }
- }
-
- /**
- * This Map is used for case-insensitive key lookup during filter
- * evaluation. This Map implementation only supports the get operation using
- * a String key as no other operations are used by the Filter
- * implementation.
- */
- static private final class CaseInsensitiveMap extends
- AbstractMap<String, Object>
- implements Map<String, Object> {
- private final Dictionary<String, ? > dictionary;
- private final String[] keys;
-
- /**
- * Create a case insensitive map from the specified dictionary.
- *
- * @param dictionary
- * @throws IllegalArgumentException If {@code dictionary} contains case
- * variants of the same key name.
- */
- CaseInsensitiveMap(Dictionary<String, ? > dictionary) {
- if (dictionary == null) {
- this.dictionary = null;
- this.keys = new String[0];
- return;
- }
- this.dictionary = dictionary;
- List<String> keyList = new ArrayList<String>(dictionary.size());
- for (Enumeration<?> e = dictionary.keys(); e.hasMoreElements();) {
- Object k = e.nextElement();
- if (k instanceof String) {
- String key = (String) k;
- for (String i : keyList) {
- if (key.equalsIgnoreCase(i)) {
- throw new IllegalArgumentException();
- }
- }
- keyList.add(key);
- }
- }
- this.keys = keyList.toArray(new String[keyList.size()]);
- }
-
- public Object get(Object o) {
- String k = (String) o;
- for (String key : keys) {
- if (key.equalsIgnoreCase(k)) {
- return dictionary.get(key);
- }
- }
- return null;
- }
-
- public Set<java.util.Map.Entry<String, Object>> entrySet() {
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * This Map is used for key lookup from a ServiceReference during filter
- * evaluation. This Map implementation only supports the get operation using
- * a String key as no other operations are used by the Filter
- * implementation.
- */
- static private final class ServiceReferenceMap extends
- AbstractMap<String, Object> implements Map<String, Object> {
- private final ServiceReference< ? > reference;
-
- ServiceReferenceMap(ServiceReference< ? > reference) {
- this.reference = reference;
- }
-
- public Object get(Object key) {
- if (reference == null) {
- return null;
- }
- return reference.getProperty((String) key);
- }
-
- public Set<java.util.Map.Entry<String, Object>> entrySet() {
- throw new UnsupportedOperationException();
- }
- }
-
- static private final class SetAccessibleAction implements
- PrivilegedAction<Object> {
- private final AccessibleObject accessible;
-
- SetAccessibleAction(AccessibleObject accessible) {
- this.accessible = accessible;
- }
-
- public Object run() {
- accessible.setAccessible(true);
- return null;
- }
- }
-
- /**
* This class contains a method to match a distinguished name (DN) chain
* against and DN chain pattern.
* <p>
@@ -1746,12 +229,12 @@
* cn=ben+ou=research,o=ACME,c=us;ou=Super CA,c=CA
* </pre>
*
- * is made up of two DNs: "{@code cn=ben+ou=research,o=ACME,c=us}
- * " and " {@code ou=Super CA,c=CA}
+ * is made up of two DNs: "<code>cn=ben+ou=research,o=ACME,c=us</code>
+ * " and " <code>ou=Super CA,c=CA</code>
* ". The first DN is made of of three RDNs: "
- * {@code cn=ben+ou=research}" and "{@code o=ACME}" and "
- * {@code c=us}". The first RDN has two name value pairs: "
- * {@code cn=ben}" and "{@code ou=research}".
+ * <code>cn=ben+ou=research</code>" and "<code>o=ACME</code>" and "
+ * <code>c=us</code>". The first RDN has two name value pairs: "
+ * <code>cn=ben</code>" and "<code>ou=research</code>".
* <p>
* A chain pattern makes use of wildcards ('*' or '-') to match against DNs,
* and wildcards ('*') to match againts DN prefixes, and value. If a DN in a
@@ -1763,7 +246,7 @@
* removed). If a value of a name/value pair is a wildcard ("*"), the value
* will match any value for that name.
*/
- static private final class DNChainMatching {
+ private static class DNChainMatching {
private static final String MINUS_WILDCARD = "-";
private static final String STAR_WILDCARD = "*";
@@ -1774,7 +257,7 @@
* @param rdnPattern List of name value pattern pairs.
* @return true if the list of name value pairs match the pattern.
*/
- private static boolean rdnmatch(List< ? > rdn, List< ? > rdnPattern) {
+ private static boolean rdnmatch(List rdn, List rdnPattern) {
if (rdn.size() != rdnPattern.size()) {
return false;
}
@@ -1798,7 +281,7 @@
return true;
}
- private static boolean dnmatch(List< ? > dn, List< ? > dnPattern) {
+ private static boolean dnmatch(List dn, List dnPattern) {
int dnStart = 0;
int patStart = 0;
int patLen = dnPattern.size();
@@ -1825,8 +308,7 @@
}
}
for (int i = 0; i < patLen; i++) {
- if (!rdnmatch((List< ? >) dn.get(i + dnStart),
- (List< ? >) dnPattern
+ if (!rdnmatch((List) dn.get(i + dnStart), (List) dnPattern
.get(i + patStart))) {
return false;
}
@@ -1847,12 +329,12 @@
* @return a list of DNs.
* @throws IllegalArgumentException
*/
- private static List<Object> parseDNchainPattern(String dnChain) {
+ private static List parseDNchainPattern(String dnChain) {
if (dnChain == null) {
throw new IllegalArgumentException(
"The DN chain must not be null.");
}
- List<Object> parsed = new ArrayList<Object>();
+ List parsed = new ArrayList();
int startIndex = 0;
startIndex = skipSpaces(dnChain, startIndex);
while (startIndex < dnChain.length()) {
@@ -1880,15 +362,22 @@
startIndex = endIndex + 1;
startIndex = skipSpaces(dnChain, startIndex);
}
+ return parseDNchain(parsed);
+ }
+ private static List parseDNchain(List chain) {
+ if (chain == null) {
+ throw new IllegalArgumentException("DN chain must not be null.");
+ }
+ chain = new ArrayList(chain);
// Now we parse is a list of strings, lets make List of rdn out
// of them
- for (int i = 0; i < parsed.size(); i++) {
- String dn = (String) parsed.get(i);
+ for (int i = 0; i < chain.size(); i++) {
+ String dn = (String) chain.get(i);
if (dn.equals(STAR_WILDCARD) || dn.equals(MINUS_WILDCARD)) {
continue;
}
- List<Object> rdns = new ArrayList<Object>();
+ List rdns = new ArrayList();
if (dn.charAt(0) == '*') {
if (dn.charAt(1) != ',') {
throw new IllegalArgumentException(
@@ -1903,32 +392,12 @@
}
// Now dn is a nice CANONICAL DN
parseDN(dn, rdns);
- parsed.set(i, rdns);
+ chain.set(i, rdns);
}
- if (parsed.size() == 0) {
+ if (chain.size() == 0) {
throw new IllegalArgumentException("empty DN chain");
}
- return parsed;
- }
-
- private static List<Object> parseDNchain(List<String> chain) {
- if (chain == null) {
- throw new IllegalArgumentException("DN chain must not be null.");
- }
- List<Object> result = new ArrayList<Object>(chain.size());
- // Now we parse is a list of strings, lets make List of rdn out
- // of them
- for (String dn : chain) {
- dn = new X500Principal(dn).getName(X500Principal.CANONICAL);
- // Now dn is a nice CANONICAL DN
- List<Object> rdns = new ArrayList<Object>();
- parseDN(dn, rdns);
- result.add(rdns);
- }
- if (result.size() == 0) {
- throw new IllegalArgumentException("empty DN chain");
- }
- return result;
+ return chain;
}
/**
@@ -1951,10 +420,10 @@
* @param rdn the list to fill in with RDNs extracted from the dn
* @throws IllegalArgumentException if a formatting error is found.
*/
- private static void parseDN(String dn, List<Object> rdn) {
+ private static void parseDN(String dn, List rdn) {
int startIndex = 0;
char c = '\0';
- List<String> nameValues = new ArrayList<String>();
+ List nameValues = new ArrayList();
while (startIndex < dn.length()) {
int endIndex;
for (endIndex = startIndex; endIndex < dn.length(); endIndex++) {
@@ -1974,7 +443,7 @@
if (c != '+') {
rdn.add(nameValues);
if (endIndex != dn.length()) {
- nameValues = new ArrayList<String>();
+ nameValues = new ArrayList();
}
else {
nameValues = null;
@@ -1992,7 +461,7 @@
* This method will return an 'index' which points to a non-wildcard DN
* or the end-of-list.
*/
- private static int skipWildCards(List<Object> dnChainPattern,
+ private static int skipWildCards(List dnChainPattern,
int dnChainPatternIndex) {
int i;
for (i = dnChainPatternIndex; i < dnChainPattern.size(); i++) {
@@ -2006,7 +475,7 @@
// otherwise continue skipping over wild cards
}
else {
- if (dnPattern instanceof List< ? >) {
+ if (dnPattern instanceof List) {
// if its a list then we have our 'non-wildcard' DN
break;
}
@@ -2027,9 +496,8 @@
* where DNChain is of the format: "DN;DN;DN;" and DNChainPattern is of
* the format: "DNPattern;*;DNPattern" (or combinations of this)
*/
- private static boolean dnChainMatch(List<Object> dnChain,
- int dnChainIndex, List<Object> dnChainPattern,
- int dnChainPatternIndex)
+ private static boolean dnChainMatch(List dnChain, int dnChainIndex,
+ List dnChainPattern, int dnChainPatternIndex)
throws IllegalArgumentException {
if (dnChainIndex >= dnChain.size()) {
return false;
@@ -2083,12 +551,12 @@
// failure
}
else {
- if (dnPattern instanceof List< ? >) {
+ if (dnPattern instanceof List) {
// here we have to do a deeper check for each DN in the
// pattern until we hit a wild card
do {
- if (!dnmatch((List< ? >) dnChain.get(dnChainIndex),
- (List< ? >) dnPattern)) {
+ if (!dnmatch((List) dnChain.get(dnChainIndex),
+ (List) dnPattern)) {
return false;
}
// go to the next set of DN's in both chains
@@ -2130,7 +598,7 @@
dnChainPattern, dnChainPatternIndex);
}
else {
- if (!(dnPattern instanceof List< ? >)) {
+ if (!(dnPattern instanceof List)) {
throw new IllegalArgumentException(
"expected String or List in DN Pattern");
}
@@ -2183,9 +651,9 @@
* @return true if dnChain matches the pattern.
* @throws IllegalArgumentException
*/
- static boolean match(String pattern, List<String> dnChain) {
- List<Object> parsedDNChain;
- List<Object> parsedDNPattern;
+ static boolean match(String pattern, List/* <String> */dnChain) {
+ List parsedDNChain;
+ List parsedDNPattern;
try {
parsedDNChain = parseDNchain(dnChain);
}
@@ -2207,12 +675,12 @@
return dnChainMatch(parsedDNChain, 0, parsedDNPattern, 0);
}
- private static String toString(List< ? > dnChain) {
+ private static String toString(List dnChain) {
if (dnChain == null) {
return null;
}
StringBuffer sb = new StringBuffer();
- for (Iterator< ? > iChain = dnChain.iterator(); iChain.hasNext();) {
+ for (Iterator iChain = dnChain.iterator(); iChain.hasNext();) {
sb.append(iChain.next());
if (iChain.hasNext()) {
sb.append("; ");
diff --git a/framework/src/main/java/org/osgi/framework/InvalidSyntaxException.java b/framework/src/main/java/org/osgi/framework/InvalidSyntaxException.java
index 46d6d20..f67fd43 100644
--- a/framework/src/main/java/org/osgi/framework/InvalidSyntaxException.java
+++ b/framework/src/main/java/org/osgi/framework/InvalidSyntaxException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,14 +21,14 @@
* syntax.
*
* <p>
- * An {@code InvalidSyntaxException} object indicates that a filter
+ * An <code>InvalidSyntaxException</code> object indicates that a filter
* string parameter has an invalid syntax and cannot be parsed. See
* {@link Filter} for a description of the filter string syntax.
*
* <p>
* This exception conforms to the general purpose exception chaining mechanism.
*
- * @version $Id: adb84e3bc0b82b842e4da84542057fdf53e2ca6a $
+ * @version $Revision: 6083 $
*/
public class InvalidSyntaxException extends Exception {
@@ -39,10 +39,10 @@
private final String filter;
/**
- * Creates an exception of type {@code InvalidSyntaxException}.
+ * Creates an exception of type <code>InvalidSyntaxException</code>.
*
* <p>
- * This method creates an {@code InvalidSyntaxException} object with
+ * This method creates an <code>InvalidSyntaxException</code> object with
* the specified message and the filter string which generated the
* exception.
*
@@ -55,10 +55,10 @@
}
/**
- * Creates an exception of type {@code InvalidSyntaxException}.
+ * Creates an exception of type <code>InvalidSyntaxException</code>.
*
* <p>
- * This method creates an {@code InvalidSyntaxException} object with
+ * This method creates an <code>InvalidSyntaxException</code> object with
* the specified message and the filter string which generated the
* exception.
*
@@ -74,7 +74,7 @@
/**
* Returns the filter string that generated the
- * {@code InvalidSyntaxException} object.
+ * <code>InvalidSyntaxException</code> object.
*
* @return The invalid filter string.
* @see BundleContext#getServiceReferences
@@ -85,10 +85,10 @@
}
/**
- * Returns the cause of this exception or {@code null} if no cause was
+ * Returns the cause of this exception or <code>null</code> if no cause was
* set.
*
- * @return The cause of this exception or {@code null} if no cause was
+ * @return The cause of this exception or <code>null</code> if no cause was
* set.
* @since 1.3
*/
diff --git a/framework/src/main/java/org/osgi/framework/PackagePermission.java b/framework/src/main/java/org/osgi/framework/PackagePermission.java
index b6697a5..da2f540 100644
--- a/framework/src/main/java/org/osgi/framework/PackagePermission.java
+++ b/framework/src/main/java/org/osgi/framework/PackagePermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,9 +29,11 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -49,35 +51,35 @@
* </pre>
*
* <p>
- * {@code PackagePermission} has three actions: {@code exportonly},
- * {@code import} and {@code export}. The {@code export} action,
- * which is deprecated, implies the {@code import} action.
+ * <code>PackagePermission</code> has three actions: <code>exportonly</code>,
+ * <code>import</code> and <code>export</code>. The <code>export</code> action,
+ * which is deprecated, implies the <code>import</code> action.
*
* @ThreadSafe
- * @version $Id: a286af94405e583f8bedc2ff5d7c818198f8caaf $
+ * @version $Revision: 7189 $
*/
public final class PackagePermission extends BasicPermission {
static final long serialVersionUID = -5107705877071099135L;
/**
- * The action string {@code export}. The {@code export} action
- * implies the {@code import} action.
+ * The action string <code>export</code>. The <code>export</code> action
+ * implies the <code>import</code> action.
*
- * @deprecated Since 1.5. Use {@code exportonly} instead.
+ * @deprecated Since 1.5. Use <code>exportonly</code> instead.
*/
public final static String EXPORT = "export";
/**
- * The action string {@code exportonly}. The {@code exportonly}
- * action does not imply the {@code import} action.
+ * The action string <code>exportonly</code>. The <code>exportonly</code>
+ * action does not imply the <code>import</code> action.
*
* @since 1.5
*/
public final static String EXPORTONLY = "exportonly";
/**
- * The action string {@code import}.
+ * The action string <code>import</code>.
*/
public final static String IMPORT = "import";
@@ -111,14 +113,14 @@
transient Filter filter;
/**
- * This map holds the properties of the permission, used to match a filter
- * in implies. This is not initialized until necessary, and then cached in
- * this object.
+ * This dictionary holds the properties of the permission, used to match a
+ * filter in implies. This is not initialized until necessary, and then
+ * cached in this object.
*/
- private transient volatile Map<String, Object> properties;
+ private transient volatile Dictionary properties;
/**
- * Creates a new {@code PackagePermission} object.
+ * Creates a new <code>PackagePermission</code> object.
*
* <p>
* The name is specified as a normal Java package name: a dot-separated
@@ -136,7 +138,7 @@
* *
* </pre>
*
- * For the {@code import} action, the name can also be a filter
+ * For the <code>import</code> action, the name can also be a filter
* expression. The filter gives access to the following attributes:
* <ul>
* <li>signer - A Distinguished Name chain used to sign the exporting
@@ -153,19 +155,19 @@
* Package Permissions are granted over all possible versions of a package.
*
* A bundle that needs to export a package must have the appropriate
- * {@code PackagePermission} for that package; similarly, a bundle that
+ * <code>PackagePermission</code> for that package; similarly, a bundle that
* needs to import a package must have the appropriate
- * {@code PackagePermssion} for that package.
+ * <code>PackagePermssion</code> for that package.
* <p>
* Permission is granted for both classes and resources.
*
* @param name Package name or filter expression. A filter expression can
- * only be specified if the specified action is {@code import}.
- * @param actions {@code exportonly},{@code import} (canonical
+ * only be specified if the specified action is <code>import</code>.
+ * @param actions <code>exportonly</code>,<code>import</code> (canonical
* order).
* @throws IllegalArgumentException If the specified name is a filter
* expression and either the specified action is not
- * {@code import} or the filter has an invalid syntax.
+ * <code>import</code> or the filter has an invalid syntax.
*/
public PackagePermission(String name, String actions) {
this(name, parseActions(actions));
@@ -177,17 +179,17 @@
}
/**
- * Creates a new requested {@code PackagePermission} object to be used
- * by code that must perform {@code checkPermission} for the
- * {@code import} action. {@code PackagePermission} objects
+ * Creates a new requested <code>PackagePermission</code> object to be used
+ * by code that must perform <code>checkPermission</code> for the
+ * <code>import</code> action. <code>PackagePermission</code> objects
* created with this constructor cannot be added to a
- * {@code PackagePermission} permission collection.
+ * <code>PackagePermission</code> permission collection.
*
* @param name The name of the requested package to import.
* @param exportingBundle The bundle exporting the requested package.
- * @param actions The action {@code import}.
+ * @param actions The action <code>import</code>.
* @throws IllegalArgumentException If the specified action is not
- * {@code import} or the name is a filter expression.
+ * <code>import</code> or the name is a filter expression.
* @since 1.5
*/
public PackagePermission(String name, Bundle exportingBundle, String actions) {
@@ -343,7 +345,7 @@
*
* @param filterString The filter string to parse.
* @return a Filter for this bundle. If the specified filterString is not a
- * filter expression, then {@code null} is returned.
+ * filter expression, then <code>null</code> is returned.
* @throws IllegalArgumentException If the filter syntax is invalid.
*/
private static Filter parseFilter(String filterString) {
@@ -368,9 +370,9 @@
*
* <p>
* This method checks that the package name of the target is implied by the
- * package name of this object. The list of {@code PackagePermission}
+ * package name of this object. The list of <code>PackagePermission</code>
* actions must either match or allow for the list of the target object to
- * imply the target {@code PackagePermission} action.
+ * imply the target <code>PackagePermission</code> action.
* <p>
* The permission to export a package implies the permission to import the
* named package.
@@ -383,8 +385,8 @@
* </pre>
*
* @param p The requested permission.
- * @return {@code true} if the specified permission is implied by this
- * object; {@code false} otherwise.
+ * @return <code>true</code> if the specified permission is implied by this
+ * object; <code>false</code> otherwise.
*/
public boolean implies(Permission p) {
if (!(p instanceof PackagePermission)) {
@@ -409,8 +411,8 @@
* validated as a proper argument. The requested PackagePermission
* must not have a filter expression.
* @param effective The effective actions with which to start.
- * @return {@code true} if the specified permission is implied by this
- * object; {@code false} otherwise.
+ * @return <code>true</code> if the specified permission is implied by this
+ * object; <code>false</code> otherwise.
*/
boolean implies0(PackagePermission requested, int effective) {
/* check actions first - much faster */
@@ -424,19 +426,19 @@
if (f == null) {
return super.implies(requested);
}
- return f.matches(requested.getProperties());
+ return f.matchCase(requested.getProperties());
}
/**
* Returns the canonical string representation of the
- * {@code PackagePermission} actions.
+ * <code>PackagePermission</code> actions.
*
* <p>
- * Always returns present {@code PackagePermission} actions in the
- * following order: {@code EXPORTONLY},{@code IMPORT}.
+ * Always returns present <code>PackagePermission</code> actions in the
+ * following order: <code>EXPORTONLY</code>,<code>IMPORT</code>.
*
* @return Canonical string representation of the
- * {@code PackagePermission} actions.
+ * <code>PackagePermission</code> actions.
*/
public String getActions() {
String result = actions;
@@ -462,28 +464,28 @@
}
/**
- * Returns a new {@code PermissionCollection} object suitable for
- * storing {@code PackagePermission} objects.
+ * Returns a new <code>PermissionCollection</code> object suitable for
+ * storing <code>PackagePermission</code> objects.
*
- * @return A new {@code PermissionCollection} object.
+ * @return A new <code>PermissionCollection</code> object.
*/
public PermissionCollection newPermissionCollection() {
return new PackagePermissionCollection();
}
/**
- * Determines the equality of two {@code PackagePermission} objects.
+ * Determines the equality of two <code>PackagePermission</code> objects.
*
* This method checks that specified package has the same package name and
- * {@code PackagePermission} actions as this
- * {@code PackagePermission} object.
+ * <code>PackagePermission</code> actions as this
+ * <code>PackagePermission</code> object.
*
* @param obj The object to test for equality with this
- * {@code PackagePermission} object.
- * @return {@code true} if {@code obj} is a
- * {@code PackagePermission}, and has the same package name and
- * actions as this {@code PackagePermission} object;
- * {@code false} otherwise.
+ * <code>PackagePermission</code> object.
+ * @return <code>true</code> if <code>obj</code> is a
+ * <code>PackagePermission</code>, and has the same package name and
+ * actions as this <code>PackagePermission</code> object;
+ * <code>false</code> otherwise.
*/
public boolean equals(Object obj) {
if (obj == this) {
@@ -545,42 +547,42 @@
}
/**
- * Called by {@code <@link PackagePermission#implies(Permission)>}. This
- * method is only called on a requested permission which cannot have a
- * filter set.
+ * Called by <code><@link PackagePermission#implies(Permission)></code>.
*
- * @return a map of properties for this permission.
+ * @return a dictionary of properties for this permission.
*/
- private Map<String, Object> getProperties() {
- Map<String, Object> result = properties;
+ private Dictionary getProperties() {
+ Dictionary result = properties;
if (result != null) {
return result;
}
- final Map<String, Object> map = new HashMap<String, Object>(5);
- map.put("package.name", getName());
+ final Dictionary dict = new Hashtable(5);
+ if (filter == null) {
+ dict.put("package.name", getName());
+ }
if (bundle != null) {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
- map.put("id", new Long(bundle.getBundleId()));
- map.put("location", bundle.getLocation());
+ dict.put("id", new Long(bundle.getBundleId()));
+ dict.put("location", bundle.getLocation());
String name = bundle.getSymbolicName();
if (name != null) {
- map.put("name", name);
+ dict.put("name", name);
}
SignerProperty signer = new SignerProperty(bundle);
if (signer.isBundleSigned()) {
- map.put("signer", signer);
+ dict.put("signer", signer);
}
return null;
}
});
}
- return properties = map;
+ return properties = dict;
}
}
/**
- * Stores a set of {@code PackagePermission} permissions.
+ * Stores a set of <code>PackagePermission</code> permissions.
*
* @see java.security.Permission
* @see java.security.Permissions
@@ -594,7 +596,7 @@
*
* @GuardedBy this
*/
- private transient Map<String, PackagePermission> permissions;
+ private transient Map permissions;
/**
* Boolean saying if "*" is in the collection.
@@ -610,25 +612,25 @@
* @serial
* @GuardedBy this
*/
- private Map<String, PackagePermission> filterPermissions;
+ private Map filterPermissions;
/**
* Create an empty PackagePermissions object.
*/
public PackagePermissionCollection() {
- permissions = new HashMap<String, PackagePermission>();
+ permissions = new HashMap();
all_allowed = false;
}
/**
* Adds a permission to this permission collection.
*
- * @param permission The {@code PackagePermission} object to add.
+ * @param permission The <code>PackagePermission</code> object to add.
* @throws IllegalArgumentException If the specified permission is not a
- * {@code PackagePermission} instance or was constructed with a
+ * <code>PackagePermission</code> instance or was constructed with a
* Bundle object.
* @throws SecurityException If this
- * {@code PackagePermissionCollection} object has been marked
+ * <code>PackagePermissionCollection</code> object has been marked
* read-only.
*/
public void add(final Permission permission) {
@@ -651,18 +653,18 @@
final Filter f = pp.filter;
synchronized (this) {
/* select the bucket for the permission */
- Map<String, PackagePermission> pc;
+ Map pc;
if (f != null) {
pc = filterPermissions;
if (pc == null) {
- filterPermissions = pc = new HashMap<String, PackagePermission>();
+ filterPermissions = pc = new HashMap();
}
}
else {
pc = permissions;
}
- final PackagePermission existing = pc.get(name);
+ final PackagePermission existing = (PackagePermission) pc.get(name);
if (existing != null) {
final int oldMask = existing.action_mask;
final int newMask = pp.action_mask;
@@ -687,12 +689,12 @@
/**
* Determines if the specified permissions implies the permissions expressed
- * in {@code permission}.
+ * in <code>permission</code>.
*
* @param permission The Permission object to compare with this
- * {@code PackagePermission} object.
- * @return {@code true} if {@code permission} is a proper subset
- * of a permission in the set; {@code false} otherwise.
+ * <code>PackagePermission</code> object.
+ * @return <code>true</code> if <code>permission</code> is a proper subset
+ * of a permission in the set; <code>false</code> otherwise.
*/
public boolean implies(final Permission permission) {
if (!(permission instanceof PackagePermission)) {
@@ -707,13 +709,13 @@
final int desired = requested.action_mask;
int effective = PackagePermission.ACTION_NONE;
- Collection<PackagePermission> perms;
+ Collection perms;
synchronized (this) {
- Map<String, PackagePermission> pc = permissions;
+ Map pc = permissions;
PackagePermission pp;
/* short circuit if the "*" Permission was added */
if (all_allowed) {
- pp = pc.get("*");
+ pp = (PackagePermission) pc.get("*");
if (pp != null) {
effective |= pp.action_mask;
if ((effective & desired) == desired) {
@@ -725,7 +727,7 @@
* strategy: Check for full match first. Then work our way up the
* name looking for matches on a.b.*
*/
- pp = pc.get(requestedName);
+ pp = (PackagePermission) pc.get(requestedName);
if (pp != null) {
/* we have a direct hit! */
effective |= pp.action_mask;
@@ -738,7 +740,7 @@
int offset = requestedName.length() - 1;
while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
requestedName = requestedName.substring(0, last + 1) + "*";
- pp = pc.get(requestedName);
+ pp = (PackagePermission) pc.get(requestedName);
if (pp != null) {
effective |= pp.action_mask;
if ((effective & desired) == desired) {
@@ -758,8 +760,9 @@
perms = pc.values();
}
/* iterate one by one over filteredPermissions */
- for (PackagePermission perm : perms) {
- if (perm.implies0(requested, effective)) {
+ for (Iterator iter = perms.iterator(); iter.hasNext();) {
+ if (((PackagePermission) iter.next())
+ .implies0(requested, effective)) {
return true;
}
}
@@ -767,14 +770,14 @@
}
/**
- * Returns an enumeration of all {@code PackagePermission} objects in
+ * Returns an enumeration of all <code>PackagePermission</code> objects in
* the container.
*
- * @return Enumeration of all {@code PackagePermission} objects.
+ * @return Enumeration of all <code>PackagePermission</code> objects.
*/
- public synchronized Enumeration<Permission> elements() {
- List<Permission> all = new ArrayList<Permission>(permissions.values());
- Map<String, PackagePermission> pc = filterPermissions;
+ public synchronized Enumeration elements() {
+ List all = new ArrayList(permissions.values());
+ Map pc = filterPermissions;
if (pc != null) {
all.addAll(pc.values());
}
@@ -789,8 +792,7 @@
private synchronized void writeObject(ObjectOutputStream out)
throws IOException {
- Hashtable<String, PackagePermission> hashtable = new Hashtable<String, PackagePermission>(
- permissions);
+ Hashtable hashtable = new Hashtable(permissions);
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("permissions", hashtable);
pfields.put("all_allowed", all_allowed);
@@ -801,12 +803,9 @@
private synchronized void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField gfields = in.readFields();
- Hashtable<String, PackagePermission> hashtable = (Hashtable<String, PackagePermission>) gfields
- .get("permissions", null);
- permissions = new HashMap<String, PackagePermission>(hashtable);
+ Hashtable hashtable = (Hashtable) gfields.get("permissions", null);
+ permissions = new HashMap(hashtable);
all_allowed = gfields.get("all_allowed", false);
- HashMap<String, PackagePermission> fp = (HashMap<String, PackagePermission>) gfields
- .get("filterPermissions", null);
- filterPermissions = fp;
+ filterPermissions = (HashMap) gfields.get("filterPermissions", null);
}
}
diff --git a/framework/src/main/java/org/osgi/framework/ServiceEvent.java b/framework/src/main/java/org/osgi/framework/ServiceEvent.java
index 82ec899..b7c9928 100644
--- a/framework/src/main/java/org/osgi/framework/ServiceEvent.java
+++ b/framework/src/main/java/org/osgi/framework/ServiceEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,8 +22,8 @@
/**
* An event from the Framework describing a service lifecycle change.
* <p>
- * {@code ServiceEvent} objects are delivered to
- * {@code ServiceListener}s and {@code AllServiceListener}s when a
+ * <code>ServiceEvent</code> objects are delivered to
+ * <code>ServiceListener</code>s and <code>AllServiceListener</code>s when a
* change occurs in this service's lifecycle. A type code is used to identify
* the event type for future extendability.
*
@@ -33,7 +33,7 @@
* @Immutable
* @see ServiceListener
* @see AllServiceListener
- * @version $Id: 2b9458d90004411b6ca0cb4b361bc282b04c85eb $
+ * @version $Revision: 6542 $
*/
public class ServiceEvent extends EventObject {
@@ -41,7 +41,7 @@
/**
* Reference to the service that had a change occur in its lifecycle.
*/
- private final ServiceReference< ? > reference;
+ private final ServiceReference reference;
/**
* Type of service lifecycle change.
@@ -75,7 +75,7 @@
* has completed unregistering.
*
* <p>
- * If a bundle is using a service that is {@code UNREGISTERING}, the
+ * If a bundle is using a service that is <code>UNREGISTERING</code>, the
* bundle should release its use of the service when it receives this event.
* If the bundle does not release its use of the service when it receives
* this event, the Framework will automatically release the bundle's use of
@@ -92,7 +92,7 @@
* <p>
* This event is synchronously delivered <strong>after</strong> the service
* properties have been modified. This event is only delivered to listeners
- * which were added with a non-{@code null} filter where the filter
+ * which were added with a non-<code>null</code> filter where the filter
* matched the service properties prior to the modification but the filter
* does not match the modified service properties.
*
@@ -105,10 +105,10 @@
* Creates a new service event object.
*
* @param type The event type.
- * @param reference A {@code ServiceReference} object to the service
+ * @param reference A <code>ServiceReference</code> object to the service
* that had a lifecycle change.
*/
- public ServiceEvent(int type, ServiceReference< ? > reference) {
+ public ServiceEvent(int type, ServiceReference reference) {
super(reference);
this.reference = reference;
this.type = type;
@@ -122,7 +122,7 @@
*
* @return Reference to the service that had a lifecycle change.
*/
- public ServiceReference< ? > getServiceReference() {
+ public ServiceReference getServiceReference() {
return reference;
}
diff --git a/framework/src/main/java/org/osgi/framework/ServiceException.java b/framework/src/main/java/org/osgi/framework/ServiceException.java
index d8ed3bd..4cf04a0 100644
--- a/framework/src/main/java/org/osgi/framework/ServiceException.java
+++ b/framework/src/main/java/org/osgi/framework/ServiceException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2007, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2007, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,18 +20,18 @@
* A service exception used to indicate that a service problem occurred.
*
* <p>
- * A {@code ServiceException} object is created by the Framework or
+ * A <code>ServiceException</code> object is created by the Framework or
* service implementation to denote an exception condition in the service. A
* type code is used to identify the exception type for future extendability.
* Service implementations may also create subclasses of
- * {@code ServiceException}. When subclassing, the subclass should set
+ * <code>ServiceException</code>. When subclassing, the subclass should set
* the type to {@link #SUBCLASSED} to indicate that
- * {@code ServiceException} has been subclassed.
+ * <code>ServiceException</code> has been subclassed.
*
* <p>
* This exception conforms to the general purpose exception chaining mechanism.
*
- * @version $Id: 453b6021eed4543f754e20696b9f8b33a7e121ee $
+ * @version $Revision: 6518 $
* @since 1.5
*/
@@ -68,16 +68,9 @@
* An error occurred invoking a remote service.
*/
public static final int REMOTE = 5;
- /**
- * The service factory resulted in a recursive call to itself for the
- * requesting bundle.
- *
- * @since 1.6
- */
- public static final int FACTORY_RECURSION = 6;
/**
- * Creates a {@code ServiceException} with the specified message and
+ * Creates a <code>ServiceException</code> with the specified message and
* exception cause.
*
* @param msg The associated message.
@@ -88,7 +81,7 @@
}
/**
- * Creates a {@code ServiceException} with the specified message.
+ * Creates a <code>ServiceException</code> with the specified message.
*
* @param msg The message.
*/
@@ -97,7 +90,7 @@
}
/**
- * Creates a {@code ServiceException} with the specified message,
+ * Creates a <code>ServiceException</code> with the specified message,
* type and exception cause.
*
* @param msg The associated message.
@@ -110,7 +103,7 @@
}
/**
- * Creates a {@code ServiceException} with the specified message and
+ * Creates a <code>ServiceException</code> with the specified message and
* type.
*
* @param msg The message.
@@ -122,7 +115,7 @@
}
/**
- * Returns the type for this exception or {@code UNSPECIFIED} if the
+ * Returns the type for this exception or <code>UNSPECIFIED</code> if the
* type was unspecified or unknown.
*
* @return The type of this exception.
diff --git a/framework/src/main/java/org/osgi/framework/ServiceFactory.java b/framework/src/main/java/org/osgi/framework/ServiceFactory.java
index 6383b22..c8f6bf3 100644
--- a/framework/src/main/java/org/osgi/framework/ServiceFactory.java
+++ b/framework/src/main/java/org/osgi/framework/ServiceFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,73 +21,65 @@
* environment.
*
* <p>
- * When registering a service, a {@code ServiceFactory} object can be used
- * instead of a service object, so that the bundle developer can gain control of
- * the specific service object granted to a bundle that is using the service.
+ * When registering a service, a <code>ServiceFactory</code> object can be
+ * used instead of a service object, so that the bundle developer can gain
+ * control of the specific service object granted to a bundle that is using the
+ * service.
*
* <p>
- * When this happens, the {@code BundleContext.getService(ServiceReference)}
- * method calls the {@code ServiceFactory.getService} method to create a service
- * object specifically for the requesting bundle. The service object returned by
- * the {@code ServiceFactory} is cached by the Framework until the bundle
+ * When this happens, the
+ * <code>BundleContext.getService(ServiceReference)</code> method calls the
+ * <code>ServiceFactory.getService</code> method to create a service object
+ * specifically for the requesting bundle. The service object returned by the
+ * <code>ServiceFactory</code> is cached by the Framework until the bundle
* releases its use of the service.
*
* <p>
- * When the bundle's use count for the service is decremented to zero (including
- * the bundle stopping or the service being unregistered), the
- * {@code ServiceFactory.ungetService} method is called.
+ * When the bundle's use count for the service equals zero (including the bundle
+ * stopping or the service being unregistered), the
+ * <code>ServiceFactory.ungetService</code> method is called.
*
* <p>
- * {@code ServiceFactory} objects are only used by the Framework and are not
- * made available to other bundles in the OSGi environment. The Framework may
- * concurrently call a {@code ServiceFactory}.
+ * <code>ServiceFactory</code> objects are only used by the Framework and are
+ * not made available to other bundles in the OSGi environment. The Framework
+ * may concurrently call a <code>ServiceFactory</code>.
*
- * @param <S> Type of Service
* @see BundleContext#getService
* @ThreadSafe
- * @version $Id: 94cd1a0127aaad9beb484f557342a8fbd0be2322 $
+ * @version $Revision: 5967 $
*/
-public interface ServiceFactory<S> {
+public interface ServiceFactory {
/**
* Creates a new service object.
*
* <p>
* The Framework invokes this method the first time the specified
- * {@code bundle} requests a service object using the
- * {@code BundleContext.getService(ServiceReference)} method. The service
- * factory can then return a specific service object for each bundle.
+ * <code>bundle</code> requests a service object using the
+ * <code>BundleContext.getService(ServiceReference)</code> method. The
+ * service factory can then return a specific service object for each
+ * bundle.
*
* <p>
- * The Framework must check that the returned service object is valid. If
- * the returned service object is {@code null} or is not an
- * {@code instanceof} all the classes named when the service was registered,
- * a framework event of type {@link FrameworkEvent#ERROR} is fired
- * containing a service exception of type
- * {@link ServiceException#FACTORY_ERROR} and {@code null} is returned to
- * the bundle. If this method throws an exception, a framework event of type
- * {@link FrameworkEvent#ERROR} is fired containing a service exception of
- * type {@link ServiceException#FACTORY_EXCEPTION} with the thrown exception
- * as the cause and {@code null} is returned to the bundle. If this method
- * is recursively called for the specified bundle, a framework event of type
- * {@link FrameworkEvent#ERROR} is fired containing a service exception of
- * type {@link ServiceException#FACTORY_RECURSION} and {@code null} is
- * returned to the bundle.
+ * The Framework caches the value returned (unless it is <code>null</code>),
+ * and will return the same service object on any future call to
+ * <code>BundleContext.getService</code> for the same bundle. This means the
+ * Framework must not allow this method to be concurrently called for the
+ * same bundle.
*
* <p>
- * The Framework caches the valid service object and will return the same
- * service object on any future call to {@code BundleContext.getService} for
- * the specified bundle. This means the Framework must not allow this method
- * to be concurrently called for the specified bundle.
+ * The Framework will check if the returned service object is an instance of
+ * all the classes named when the service was registered. If not, then
+ * <code>null</code> is returned to the bundle.
*
- * @param bundle The bundle requesting the service.
- * @param registration The {@code ServiceRegistration} object for the
- * requested service.
+ * @param bundle The bundle using the service.
+ * @param registration The <code>ServiceRegistration</code> object for the
+ * service.
* @return A service object that <strong>must</strong> be an instance of all
* the classes named when the service was registered.
* @see BundleContext#getService
*/
- public S getService(Bundle bundle, ServiceRegistration<S> registration);
+ public Object getService(Bundle bundle, ServiceRegistration registration);
/**
* Releases a service object.
@@ -96,20 +88,13 @@
* The Framework invokes this method when a service has been released by a
* bundle. The service object may then be destroyed.
*
- * <p>
- * If this method throws an exception, a framework event of type
- * {@link FrameworkEvent#ERROR} is fired containing a service exception of
- * type {@link ServiceException#FACTORY_EXCEPTION} with the thrown exception
- * as the cause.
- *
* @param bundle The bundle releasing the service.
- * @param registration The {@code ServiceRegistration} object for the
- * service being released.
+ * @param registration The <code>ServiceRegistration</code> object for the
+ * service.
* @param service The service object returned by a previous call to the
- * {@link #getService(Bundle, ServiceRegistration) getService}
- * method.
+ * <code>ServiceFactory.getService</code> method.
* @see BundleContext#ungetService
*/
- public void ungetService(Bundle bundle, ServiceRegistration<S> registration,
- S service);
+ public void ungetService(Bundle bundle, ServiceRegistration registration,
+ Object service);
}
diff --git a/framework/src/main/java/org/osgi/framework/ServiceListener.java b/framework/src/main/java/org/osgi/framework/ServiceListener.java
index dc6a159..ec08560 100644
--- a/framework/src/main/java/org/osgi/framework/ServiceListener.java
+++ b/framework/src/main/java/org/osgi/framework/ServiceListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,46 +19,46 @@
import java.util.EventListener;
/**
- * A {@code ServiceEvent} listener. {@code ServiceListener} is a
+ * A <code>ServiceEvent</code> listener. <code>ServiceListener</code> is a
* listener interface that may be implemented by a bundle developer. When a
- * {@code ServiceEvent} is fired, it is synchronously delivered to a
- * {@code ServiceListener}. The Framework may deliver
- * {@code ServiceEvent} objects to a {@code ServiceListener} out
+ * <code>ServiceEvent</code> is fired, it is synchronously delivered to a
+ * <code>ServiceListener</code>. The Framework may deliver
+ * <code>ServiceEvent</code> objects to a <code>ServiceListener</code> out
* of order and may concurrently call and/or reenter a
- * {@code ServiceListener}.
+ * <code>ServiceListener</code>.
*
* <p>
- * A {@code ServiceListener} object is registered with the Framework
- * using the {@code BundleContext.addServiceListener} method.
- * {@code ServiceListener} objects are called with a
- * {@code ServiceEvent} object when a service is registered, modified, or
+ * A <code>ServiceListener</code> object is registered with the Framework
+ * using the <code>BundleContext.addServiceListener</code> method.
+ * <code>ServiceListener</code> objects are called with a
+ * <code>ServiceEvent</code> object when a service is registered, modified, or
* is in the process of unregistering.
*
* <p>
- * {@code ServiceEvent} object delivery to {@code ServiceListener}
+ * <code>ServiceEvent</code> object delivery to <code>ServiceListener</code>
* objects is filtered by the filter specified when the listener was registered.
* If the Java Runtime Environment supports permissions, then additional
- * filtering is done. {@code ServiceEvent} objects are only delivered to
+ * filtering is done. <code>ServiceEvent</code> objects are only delivered to
* the listener if the bundle which defines the listener object's class has the
- * appropriate {@code ServicePermission} to get the service using at
+ * appropriate <code>ServicePermission</code> to get the service using at
* least one of the named classes under which the service was registered.
*
* <p>
- * {@code ServiceEvent} object delivery to {@code ServiceListener}
+ * <code>ServiceEvent</code> object delivery to <code>ServiceListener</code>
* objects is further filtered according to package sources as defined in
* {@link ServiceReference#isAssignableTo(Bundle, String)}.
*
* @see ServiceEvent
* @see ServicePermission
* @ThreadSafe
- * @version $Id: d73f8e9b4babc8b53b5d1cbe7b17b732f54bb2a3 $
+ * @version $Revision: 5673 $
*/
public interface ServiceListener extends EventListener {
/**
* Receives notification that a service has had a lifecycle change.
*
- * @param event The {@code ServiceEvent} object.
+ * @param event The <code>ServiceEvent</code> object.
*/
public void serviceChanged(ServiceEvent event);
}
diff --git a/framework/src/main/java/org/osgi/framework/ServicePermission.java b/framework/src/main/java/org/osgi/framework/ServicePermission.java
index b7a9956..d2f3c31 100644
--- a/framework/src/main/java/org/osgi/framework/ServicePermission.java
+++ b/framework/src/main/java/org/osgi/framework/ServicePermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,43 +26,42 @@
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
-import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
/**
* A bundle's authority to register or get a service.
* <ul>
- * <li>The {@code register} action allows a bundle to register a service on
+ * <li>The <code>register</code> action allows a bundle to register a service on
* the specified names.
- * <li>The {@code get} action allows a bundle to detect a service and get
+ * <li>The <code>get</code> action allows a bundle to detect a service and get
* it.
* </ul>
* Permission to get a service is required in order to detect events regarding
* the service. Untrusted bundles should not be able to detect the presence of
* certain services unless they have the appropriate
- * {@code ServicePermission} to get the specific service.
+ * <code>ServicePermission</code> to get the specific service.
*
* @ThreadSafe
- * @version $Id: 1b6ee9543f4cbc16add8dc8c40dfa9a6dfee7aa2 $
+ * @version $Revision: 7189 $
*/
public final class ServicePermission extends BasicPermission {
static final long serialVersionUID = -7662148639076511574L;
/**
- * The action string {@code get}.
+ * The action string <code>get</code>.
*/
public final static String GET = "get";
/**
- * The action string {@code register}.
+ * The action string <code>register</code>.
*/
public final static String REGISTER = "register";
@@ -88,7 +87,7 @@
* The service used by this ServicePermission. Must be null if not
* constructed with a service.
*/
- transient final ServiceReference< ? > service;
+ transient final ServiceReference service;
/**
* The object classes for this ServicePermission. Must be null if not
@@ -103,11 +102,11 @@
transient Filter filter;
/**
- * This map holds the properties of the permission, used to match a filter
- * in implies. This is not initialized until necessary, and then cached in
- * this object.
+ * This dictionary holds the properties of the permission, used to match a
+ * filter in implies. This is not initialized until necessary, and then
+ * cached in this object.
*/
- private transient volatile Map<String, Object> properties;
+ private transient volatile Dictionary properties;
/**
* True if constructed with a name and the name is "*" or ends with ".*".
@@ -139,7 +138,7 @@
* *
* </pre>
*
- * For the {@code get} action, the name can also be a filter
+ * For the <code>get</code> action, the name can also be a filter
* expression. The filter gives access to the service properties as well as
* the following attributes:
* <ul>
@@ -159,17 +158,17 @@
* Service properties names are case insensitive.
*
* <p>
- * There are two possible actions: {@code get} and
- * {@code register}. The {@code get} permission allows the owner
+ * There are two possible actions: <code>get</code> and
+ * <code>register</code>. The <code>get</code> permission allows the owner
* of this permission to obtain a service with this name. The
- * {@code register} permission allows the bundle to register a service
+ * <code>register</code> permission allows the bundle to register a service
* under that name.
*
* @param name The service class name
- * @param actions {@code get},{@code register} (canonical order)
+ * @param actions <code>get</code>,<code>register</code> (canonical order)
* @throws IllegalArgumentException If the specified name is a filter
* expression and either the specified action is not
- * {@code get} or the filter has an invalid syntax.
+ * <code>get</code> or the filter has an invalid syntax.
*/
public ServicePermission(String name, String actions) {
this(name, parseActions(actions));
@@ -181,19 +180,19 @@
}
/**
- * Creates a new requested {@code ServicePermission} object to be used
- * by code that must perform {@code checkPermission} for the
- * {@code get} action. {@code ServicePermission} objects created
- * with this constructor cannot be added to a {@code ServicePermission}
+ * Creates a new requested <code>ServicePermission</code> object to be used
+ * by code that must perform <code>checkPermission</code> for the
+ * <code>get</code> action. <code>ServicePermission</code> objects created
+ * with this constructor cannot be added to a <code>ServicePermission</code>
* permission collection.
*
* @param reference The requested service.
- * @param actions The action {@code get}.
+ * @param actions The action <code>get</code>.
* @throws IllegalArgumentException If the specified action is not
- * {@code get} or reference is {@code null}.
+ * <code>get</code> or reference is <code>null</code>.
* @since 1.5
*/
- public ServicePermission(ServiceReference< ? > reference, String actions) {
+ public ServicePermission(ServiceReference reference, String actions) {
super(createName(reference));
setTransients(null, parseActions(actions));
this.service = reference;
@@ -210,7 +209,7 @@
* @param reference ServiceReference to use to create permission name.
* @return permission name.
*/
- private static String createName(ServiceReference< ? > reference) {
+ private static String createName(ServiceReference reference) {
if (reference == null) {
throw new IllegalArgumentException("reference must not be null");
}
@@ -352,7 +351,7 @@
*
* @param filterString The filter string to parse.
* @return a Filter for this bundle. If the specified filterString is not a
- * filter expression, then {@code null} is returned.
+ * filter expression, then <code>null</code> is returned.
* @throws IllegalArgumentException If the filter syntax is invalid.
*/
private static Filter parseFilter(String filterString) {
@@ -373,12 +372,12 @@
}
/**
- * Determines if a {@code ServicePermission} object "implies" the
+ * Determines if a <code>ServicePermission</code> object "implies" the
* specified permission.
*
* @param p The target permission to check.
- * @return {@code true} if the specified permission is implied by this
- * object; {@code false} otherwise.
+ * @return <code>true</code> if the specified permission is implied by this
+ * object; <code>false</code> otherwise.
*/
public boolean implies(Permission p) {
if (!(p instanceof ServicePermission)) {
@@ -403,8 +402,8 @@
* validated as a proper argument. The requested ServicePermission
* must not have a filter expression.
* @param effective The effective actions with which to start.
- * @return {@code true} if the specified permission is implied by this
- * object; {@code false} otherwise.
+ * @return <code>true</code> if the specified permission is implied by this
+ * object; <code>false</code> otherwise.
*/
boolean implies0(ServicePermission requested, int effective) {
/* check actions first - much faster */
@@ -420,7 +419,7 @@
/* if we have a filter */
Filter f = filter;
if (f != null) {
- return f.matches(requested.getProperties());
+ return f.matchCase(requested.getProperties());
}
/* if requested permission not created with ServiceReference */
String[] requestedNames = requested.objectClass;
@@ -451,8 +450,8 @@
/**
* Returns the canonical string representation of the actions. Always
- * returns present actions in the following order: {@code get},
- * {@code register}.
+ * returns present actions in the following order: <code>get</code>,
+ * <code>register</code>.
*
* @return The canonical string representation of the actions.
*/
@@ -481,11 +480,11 @@
}
/**
- * Returns a new {@code PermissionCollection} object for storing
- * {@code ServicePermission} objects.
- *
- * @return A new {@code PermissionCollection} object suitable for storing
- * {@code ServicePermission} objects.
+ * Returns a new <code>PermissionCollection</code> object for storing
+ * <code>ServicePermission<code> objects.
+ *
+ * @return A new <code>PermissionCollection</code> object suitable for storing
+ * <code>ServicePermission</code> objects.
*/
public PermissionCollection newPermissionCollection() {
return new ServicePermissionCollection();
@@ -495,12 +494,12 @@
* Determines the equality of two ServicePermission objects.
*
* Checks that specified object has the same class name and action as this
- * {@code ServicePermission}.
+ * <code>ServicePermission</code>.
*
* @param obj The object to test for equality.
- * @return true if obj is a {@code ServicePermission}, and has the same
- * class name and actions as this {@code ServicePermission}
- * object; {@code false} otherwise.
+ * @return true if obj is a <code>ServicePermission</code>, and has the same
+ * class name and actions as this <code>ServicePermission</code>
+ * object; <code>false</code> otherwise.
*/
public boolean equals(Object obj) {
if (obj == this) {
@@ -559,28 +558,27 @@
s.defaultReadObject();
setTransients(parseFilter(getName()), parseActions(actions));
}
-
/**
- * Called by {@code <@link ServicePermission#implies(Permission)>}. This
- * method is only called on a requested permission which cannot have a
- * filter set.
+ * Called by <code><@link ServicePermission#implies(Permission)></code>.
*
- * @return a map of properties for this permission.
+ * @return a dictionary of properties for this permission.
*/
- private Map<String, Object> getProperties() {
- Map<String, Object> result = properties;
+ private Dictionary getProperties() {
+ Dictionary result = properties;
if (result != null) {
return result;
}
if (service == null) {
- result = new HashMap<String, Object>(1);
- result.put(Constants.OBJECTCLASS, new String[] {getName()});
+ result = new Hashtable(1);
+ if (filter == null) {
+ result.put(Constants.OBJECTCLASS, new String[] {getName()});
+ }
return properties = result;
}
- final Map<String, Object> props = new HashMap<String, Object>(4);
+ final Map props = new HashMap(4);
final Bundle bundle = service.getBundle();
if (bundle != null) {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
props.put("id", new Long(bundle.getBundleId()));
props.put("location", bundle.getLocation());
@@ -599,15 +597,13 @@
return properties = new Properties(props, service);
}
- static private final class Properties extends AbstractMap<String, Object> {
- private final Map<String, Object> properties;
- private final ServiceReference< ? > service;
- private transient volatile Set<Map.Entry<String, Object>> entries;
+ private static class Properties extends Dictionary {
+ private final Map properties;
+ private final ServiceReference service;
- Properties(Map<String, Object> properties, ServiceReference< ? > service) {
+ Properties(Map properties, ServiceReference service) {
this.properties = properties;
this.service = service;
- entries = null;
}
public Object get(Object k) {
@@ -625,64 +621,57 @@
return service.getProperty(key);
}
- public Set<Map.Entry<String, Object>> entrySet() {
- if (entries != null) {
- return entries;
- }
- Set<Map.Entry<String, Object>> all = new HashSet<Map.Entry<String, Object>>(
- properties.entrySet());
- add: for (String key : service.getPropertyKeys()) {
- for (String k : properties.keySet()) {
- if (key.equalsIgnoreCase(k)) {
+ public int size() {
+ return properties.size() + service.getPropertyKeys().length;
+ }
+
+ public boolean isEmpty() {
+ // we can return false because this must never be empty
+ return false;
+ }
+
+ public Enumeration keys() {
+ Collection pk = properties.keySet();
+ String spk[] = service.getPropertyKeys();
+ List all = new ArrayList(pk.size() + spk.length);
+ all.addAll(pk);
+ add:
+ for (int i = 0, length = spk.length; i < length; i++) {
+ String key = spk[i];
+ for (Iterator iter = pk.iterator(); iter.hasNext();) {
+ if (key.equalsIgnoreCase((String) iter.next())) {
continue add;
}
}
- all.add(new Entry(key, service.getProperty(key)));
+ all.add(key);
}
- return entries = Collections.unmodifiableSet(all);
+ return Collections.enumeration(all);
}
-
- static private final class Entry implements Map.Entry<String, Object> {
- private final String k;
- private final Object v;
- Entry(String key, Object value) {
- this.k = key;
- this.v = value;
- }
- public String getKey() {
- return k;
- }
- public Object getValue() {
- return v;
- }
- public Object setValue(Object value) {
- throw new UnsupportedOperationException();
- }
- public String toString() {
- return k + "=" + v;
- }
- public int hashCode() {
- return ((k == null) ? 0 : k.hashCode())
- ^ ((v == null) ? 0 : v.hashCode());
- }
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (!(obj instanceof Map.Entry)) {
- return false;
- }
- Map.Entry< ? , ? > e = (Map.Entry< ? , ? >) obj;
- final Object key = e.getKey();
- if ((k == key) || ((k != null) && k.equals(key))) {
- final Object value = e.getValue();
- if ((v == value) || ((v != null) && v.equals(value))) {
- return true;
+ public Enumeration elements() {
+ Collection pk = properties.keySet();
+ String spk[] = service.getPropertyKeys();
+ List all = new ArrayList(pk.size() + spk.length);
+ all.addAll(properties.values());
+ add:
+ for (int i = 0, length = spk.length; i < length; i++) {
+ String key = spk[i];
+ for (Iterator iter = pk.iterator(); iter.hasNext();) {
+ if (key.equalsIgnoreCase((String) iter.next())) {
+ continue add;
}
}
- return false;
+ all.add(service.getProperty(key));
}
+ return Collections.enumeration(all);
+ }
+
+ public Object put(Object key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object remove(Object key) {
+ throw new UnsupportedOperationException();
}
}
}
@@ -701,7 +690,7 @@
*
* @GuardedBy this
*/
- private transient Map<String, ServicePermission> permissions;
+ private transient Map permissions;
/**
* Boolean saying if "*" is in the collection.
@@ -717,13 +706,13 @@
* @serial
* @GuardedBy this
*/
- private Map<String, ServicePermission> filterPermissions;
+ private Map filterPermissions;
/**
* Creates an empty ServicePermissions object.
*/
public ServicePermissionCollection() {
- permissions = new HashMap<String, ServicePermission>();
+ permissions = new HashMap();
all_allowed = false;
}
@@ -734,7 +723,7 @@
* @throws IllegalArgumentException If the specified permission is not a
* ServicePermission object.
* @throws SecurityException If this
- * {@code ServicePermissionCollection} object has been marked
+ * <code>ServicePermissionCollection</code> object has been marked
* read-only.
*/
public void add(final Permission permission) {
@@ -757,17 +746,17 @@
final Filter f = sp.filter;
synchronized (this) {
/* select the bucket for the permission */
- Map<String, ServicePermission> pc;
+ Map pc;
if (f != null) {
pc = filterPermissions;
if (pc == null) {
- filterPermissions = pc = new HashMap<String, ServicePermission>();
+ filterPermissions = pc = new HashMap();
}
}
else {
pc = permissions;
}
- final ServicePermission existing = pc.get(name);
+ final ServicePermission existing = (ServicePermission) pc.get(name);
if (existing != null) {
final int oldMask = existing.action_mask;
@@ -792,11 +781,11 @@
/**
* Determines if a set of permissions implies the permissions expressed in
- * {@code permission}.
+ * <code>permission</code>.
*
* @param permission The Permission object to compare.
- * @return {@code true} if {@code permission} is a proper
- * subset of a permission in the set; {@code false}
+ * @return <code>true</code> if <code>permission</code> is a proper
+ * subset of a permission in the set; <code>false</code>
* otherwise.
*/
public boolean implies(final Permission permission) {
@@ -810,12 +799,12 @@
}
int effective = ServicePermission.ACTION_NONE;
- Collection<ServicePermission> perms;
+ Collection perms;
synchronized (this) {
final int desired = requested.action_mask;
/* short circuit if the "*" Permission was added */
if (all_allowed) {
- ServicePermission sp = permissions.get("*");
+ ServicePermission sp = (ServicePermission) permissions.get("*");
if (sp != null) {
effective |= sp.action_mask;
if ((effective & desired) == desired) {
@@ -840,7 +829,7 @@
}
}
}
- Map<String, ServicePermission> pc = filterPermissions;
+ Map pc = filterPermissions;
if (pc == null) {
return false;
}
@@ -848,8 +837,9 @@
}
/* iterate one by one over filteredPermissions */
- for (ServicePermission perm : perms) {
- if (perm.implies0(requested, effective)) {
+ for (Iterator iter = perms.iterator(); iter.hasNext();) {
+ if (((ServicePermission) iter.next())
+ .implies0(requested, effective)) {
return true;
}
}
@@ -867,8 +857,8 @@
*/
private int effective(String requestedName, final int desired,
int effective) {
- final Map<String, ServicePermission> pc = permissions;
- ServicePermission sp = pc.get(requestedName);
+ final Map pc = permissions;
+ ServicePermission sp = (ServicePermission) pc.get(requestedName);
// strategy:
// Check for full match first. Then work our way up the
// name looking for matches on a.b.*
@@ -884,7 +874,7 @@
int offset = requestedName.length() - 1;
while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
requestedName = requestedName.substring(0, last + 1) + "*";
- sp = pc.get(requestedName);
+ sp = (ServicePermission) pc.get(requestedName);
if (sp != null) {
effective |= sp.action_mask;
if ((effective & desired) == desired) {
@@ -901,14 +891,14 @@
}
/**
- * Returns an enumeration of all the {@code ServicePermission}
+ * Returns an enumeration of all the <code>ServicePermission</code>
* objects in the container.
*
* @return Enumeration of all the ServicePermission objects.
*/
- public synchronized Enumeration<Permission> elements() {
- List<Permission> all = new ArrayList<Permission>(permissions.values());
- Map<String, ServicePermission> pc = filterPermissions;
+ public synchronized Enumeration elements() {
+ List all = new ArrayList(permissions.values());
+ Map pc = filterPermissions;
if (pc != null) {
all.addAll(pc.values());
}
@@ -923,8 +913,7 @@
private synchronized void writeObject(ObjectOutputStream out)
throws IOException {
- Hashtable<String, ServicePermission> hashtable = new Hashtable<String, ServicePermission>(
- permissions);
+ Hashtable hashtable = new Hashtable(permissions);
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("permissions", hashtable);
pfields.put("all_allowed", all_allowed);
@@ -935,12 +924,9 @@
private synchronized void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField gfields = in.readFields();
- Hashtable<String, ServicePermission> hashtable = (Hashtable<String, ServicePermission>) gfields
- .get("permissions", null);
- permissions = new HashMap<String, ServicePermission>(hashtable);
+ Hashtable hashtable = (Hashtable) gfields.get("permissions", null);
+ permissions = new HashMap(hashtable);
all_allowed = gfields.get("all_allowed", false);
- HashMap<String, ServicePermission> fp = (HashMap<String, ServicePermission>) gfields
- .get("filterPermissions", null);
- filterPermissions = fp;
+ filterPermissions = (HashMap) gfields.get("filterPermissions", null);
}
}
diff --git a/framework/src/main/java/org/osgi/framework/ServiceReference.java b/framework/src/main/java/org/osgi/framework/ServiceReference.java
index ad38df7..a6dd9bd 100644
--- a/framework/src/main/java/org/osgi/framework/ServiceReference.java
+++ b/framework/src/main/java/org/osgi/framework/ServiceReference.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,40 +22,38 @@
* A reference to a service.
*
* <p>
- * The Framework returns {@code ServiceReference} objects from the
- * {@code BundleContext.getServiceReference} and
- * {@code BundleContext.getServiceReferences} methods.
+ * The Framework returns <code>ServiceReference</code> objects from the
+ * <code>BundleContext.getServiceReference</code> and
+ * <code>BundleContext.getServiceReferences</code> methods.
* <p>
- * A {@code ServiceReference} object may be shared between bundles and can
- * be used to examine the properties of the service and to get the service
+ * A <code>ServiceReference</code> object may be shared between bundles and
+ * can be used to examine the properties of the service and to get the service
* object.
* <p>
* Every service registered in the Framework has a unique
- * {@code ServiceRegistration} object and may have multiple, distinct
- * {@code ServiceReference} objects referring to it.
- * {@code ServiceReference} objects associated with a
- * {@code ServiceRegistration} object have the same {@code hashCode}
- * and are considered equal (more specifically, their {@code equals()}
- * method will return {@code true} when compared).
+ * <code>ServiceRegistration</code> object and may have multiple, distinct
+ * <code>ServiceReference</code> objects referring to it.
+ * <code>ServiceReference</code> objects associated with a
+ * <code>ServiceRegistration</code> object have the same <code>hashCode</code>
+ * and are considered equal (more specifically, their <code>equals()</code>
+ * method will return <code>true</code> when compared).
* <p>
* If the same service object is registered multiple times,
- * {@code ServiceReference} objects associated with different
- * {@code ServiceRegistration} objects are not equal.
+ * <code>ServiceReference</code> objects associated with different
+ * <code>ServiceRegistration</code> objects are not equal.
*
- * @param <S> Type of Service.
* @see BundleContext#getServiceReference
* @see BundleContext#getServiceReferences
* @see BundleContext#getService
* @ThreadSafe
- * @noimplement
- * @version $Id: 771b9b4d4f65dbe593154d02912edba51a085b0c $
+ * @version $Revision: 6374 $
*/
-public interface ServiceReference<S> extends Comparable<Object> {
+public interface ServiceReference extends Comparable {
/**
* Returns the property value to which the specified property key is mapped
- * in the properties {@code Dictionary} object of the service
- * referenced by this {@code ServiceReference} object.
+ * in the properties <code>Dictionary</code> object of the service
+ * referenced by this <code>ServiceReference</code> object.
*
* <p>
* Property keys are case-insensitive.
@@ -63,30 +61,30 @@
* <p>
* This method must continue to return property values after the service has
* been unregistered. This is so references to unregistered services (for
- * example, {@code ServiceReference} objects stored in the log) can
+ * example, <code>ServiceReference</code> objects stored in the log) can
* still be interrogated.
*
* @param key The property key.
- * @return The property value to which the key is mapped; {@code null}
+ * @return The property value to which the key is mapped; <code>null</code>
* if there is no property named after the key.
*/
public Object getProperty(String key);
/**
- * Returns an array of the keys in the properties {@code Dictionary}
- * object of the service referenced by this {@code ServiceReference}
+ * Returns an array of the keys in the properties <code>Dictionary</code>
+ * object of the service referenced by this <code>ServiceReference</code>
* object.
*
* <p>
* This method will continue to return the keys after the service has been
* unregistered. This is so references to unregistered services (for
- * example, {@code ServiceReference} objects stored in the log) can
+ * example, <code>ServiceReference</code> objects stored in the log) can
* still be interrogated.
*
* <p>
* This method is <i>case-preserving </i>; this means that every key in the
* returned array must have the same case as the corresponding key in the
- * properties {@code Dictionary} that was passed to the
+ * properties <code>Dictionary</code> that was passed to the
* {@link BundleContext#registerService(String[],Object,Dictionary)} or
* {@link ServiceRegistration#setProperties} methods.
*
@@ -96,15 +94,15 @@
/**
* Returns the bundle that registered the service referenced by this
- * {@code ServiceReference} object.
+ * <code>ServiceReference</code> object.
*
* <p>
- * This method must return {@code null} when the service has been
+ * This method must return <code>null</code> when the service has been
* unregistered. This can be used to determine if the service has been
* unregistered.
*
* @return The bundle that registered the service referenced by this
- * {@code ServiceReference} object; {@code null} if that
+ * <code>ServiceReference</code> object; <code>null</code> if that
* service has already been unregistered.
* @see BundleContext#registerService(String[],Object,Dictionary)
*/
@@ -112,12 +110,12 @@
/**
* Returns the bundles that are using the service referenced by this
- * {@code ServiceReference} object. Specifically, this method returns
+ * <code>ServiceReference</code> object. Specifically, this method returns
* the bundles whose usage count for that service is greater than zero.
*
* @return An array of bundles whose usage count for the service referenced
- * by this {@code ServiceReference} object is greater than
- * zero; {@code null} if no bundles are currently using that
+ * by this <code>ServiceReference</code> object is greater than
+ * zero; <code>null</code> if no bundles are currently using that
* service.
*
* @since 1.1
@@ -126,60 +124,60 @@
/**
* Tests if the bundle that registered the service referenced by this
- * {@code ServiceReference} and the specified bundle use the same
+ * <code>ServiceReference</code> and the specified bundle use the same
* source for the package of the specified class name.
* <p>
* This method performs the following checks:
* <ol>
* <li>Get the package name from the specified class name.</li>
* <li>For the bundle that registered the service referenced by this
- * {@code ServiceReference} (registrant bundle); find the source for
- * the package. If no source is found then return {@code true} if the
+ * <code>ServiceReference</code> (registrant bundle); find the source for
+ * the package. If no source is found then return <code>true</code> if the
* registrant bundle is equal to the specified bundle; otherwise return
- * {@code false}.</li>
+ * <code>false</code>.</li>
* <li>If the package source of the registrant bundle is equal to the
- * package source of the specified bundle then return {@code true};
- * otherwise return {@code false}.</li>
+ * package source of the specified bundle then return <code>true</code>;
+ * otherwise return <code>false</code>.</li>
* </ol>
*
- * @param bundle The {@code Bundle} object to check.
+ * @param bundle The <code>Bundle</code> object to check.
* @param className The class name to check.
- * @return {@code true} if the bundle which registered the service
- * referenced by this {@code ServiceReference} and the
+ * @return <code>true</code> if the bundle which registered the service
+ * referenced by this <code>ServiceReference</code> and the
* specified bundle use the same source for the package of the
- * specified class name. Otherwise {@code false} is returned.
- * @throws IllegalArgumentException If the specified {@code Bundle} was
+ * specified class name. Otherwise <code>false</code> is returned.
+ * @throws IllegalArgumentException If the specified <code>Bundle</code> was
* not created by the same framework instance as this
- * {@code ServiceReference}.
+ * <code>ServiceReference</code>.
* @since 1.3
*/
public boolean isAssignableTo(Bundle bundle, String className);
/**
- * Compares this {@code ServiceReference} with the specified
- * {@code ServiceReference} for order.
+ * Compares this <code>ServiceReference</code> with the specified
+ * <code>ServiceReference</code> for order.
*
* <p>
- * If this {@code ServiceReference} and the specified
- * {@code ServiceReference} have the same {@link Constants#SERVICE_ID
- * service id} they are equal. This {@code ServiceReference} is less
- * than the specified {@code ServiceReference} if it has a lower
+ * If this <code>ServiceReference</code> and the specified
+ * <code>ServiceReference</code> have the same {@link Constants#SERVICE_ID
+ * service id} they are equal. This <code>ServiceReference</code> is less
+ * than the specified <code>ServiceReference</code> if it has a lower
* {@link Constants#SERVICE_RANKING service ranking} and greater if it has a
- * higher service ranking. Otherwise, if this {@code ServiceReference}
- * and the specified {@code ServiceReference} have the same
+ * higher service ranking. Otherwise, if this <code>ServiceReference</code>
+ * and the specified <code>ServiceReference</code> have the same
* {@link Constants#SERVICE_RANKING service ranking}, this
- * {@code ServiceReference} is less than the specified
- * {@code ServiceReference} if it has a higher
+ * <code>ServiceReference</code> is less than the specified
+ * <code>ServiceReference</code> if it has a higher
* {@link Constants#SERVICE_ID service id} and greater if it has a lower
* service id.
*
- * @param reference The {@code ServiceReference} to be compared.
+ * @param reference The <code>ServiceReference</code> to be compared.
* @return Returns a negative integer, zero, or a positive integer if this
- * {@code ServiceReference} is less than, equal to, or greater
- * than the specified {@code ServiceReference}.
+ * <code>ServiceReference</code> is less than, equal to, or greater
+ * than the specified <code>ServiceReference</code>.
* @throws IllegalArgumentException If the specified
- * {@code ServiceReference} was not created by the same
- * framework instance as this {@code ServiceReference}.
+ * <code>ServiceReference</code> was not created by the same
+ * framework instance as this <code>ServiceReference</code>.
* @since 1.4
*/
public int compareTo(Object reference);
diff --git a/framework/src/main/java/org/osgi/framework/ServiceRegistration.java b/framework/src/main/java/org/osgi/framework/ServiceRegistration.java
index e4cfc0e..9186cf7 100644
--- a/framework/src/main/java/org/osgi/framework/ServiceRegistration.java
+++ b/framework/src/main/java/org/osgi/framework/ServiceRegistration.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,35 +22,33 @@
* A registered service.
*
* <p>
- * The Framework returns a {@code ServiceRegistration} object when a
- * {@code BundleContext.registerService} method invocation is successful.
- * The {@code ServiceRegistration} object is for the private use of the
+ * The Framework returns a <code>ServiceRegistration</code> object when a
+ * <code>BundleContext.registerService</code> method invocation is successful.
+ * The <code>ServiceRegistration</code> object is for the private use of the
* registering bundle and should not be shared with other bundles.
* <p>
- * The {@code ServiceRegistration} object may be used to update the
+ * The <code>ServiceRegistration</code> object may be used to update the
* properties of the service or to unregister the service.
*
- * @param <S> Type of Service.
* @see BundleContext#registerService(String[],Object,Dictionary)
* @ThreadSafe
- * @noimplement
- * @version $Id: dc742ff3749821529f9ae62e05d9bd5d8eca00d7 $
+ * @version $Revision: 6361 $
*/
-public interface ServiceRegistration<S> {
+public interface ServiceRegistration {
/**
- * Returns a {@code ServiceReference} object for a service being
+ * Returns a <code>ServiceReference</code> object for a service being
* registered.
* <p>
- * The {@code ServiceReference} object may be shared with other
+ * The <code>ServiceReference</code> object may be shared with other
* bundles.
*
* @throws IllegalStateException If this
- * {@code ServiceRegistration} object has already been
+ * <code>ServiceRegistration</code> object has already been
* unregistered.
- * @return {@code ServiceReference} object.
+ * @return <code>ServiceReference</code> object.
*/
- public ServiceReference<S> getReference();
+ public ServiceReference getReference();
/**
* Updates the properties associated with a service.
@@ -72,17 +70,17 @@
* be made to this object after calling this method. To update the
* service's properties this method should be called again.
*
- * @throws IllegalStateException If this {@code ServiceRegistration}
+ * @throws IllegalStateException If this <code>ServiceRegistration</code>
* object has already been unregistered.
- * @throws IllegalArgumentException If {@code properties} contains
+ * @throws IllegalArgumentException If <code>properties</code> contains
* case variants of the same key name.
*/
- public void setProperties(Dictionary<String, ? > properties);
+ public void setProperties(Dictionary properties);
/**
- * Unregisters a service. Remove a {@code ServiceRegistration} object
- * from the Framework service registry. All {@code ServiceReference}
- * objects associated with this {@code ServiceRegistration} object
+ * Unregisters a service. Remove a <code>ServiceRegistration</code> object
+ * from the Framework service registry. All <code>ServiceReference</code>
+ * objects associated with this <code>ServiceRegistration</code> object
* can no longer be used to interact with the service once unregistration is
* complete.
*
@@ -94,18 +92,18 @@
* <li>A service event of type {@link ServiceEvent#UNREGISTERING} is fired
* so that bundles using this service can release their use of the service.
* Once delivery of the service event is complete, the
- * {@code ServiceReference} objects for the service may no longer be
+ * <code>ServiceReference</code> objects for the service may no longer be
* used to get a service object for the service.
* <li>For each bundle whose use count for this service is greater than
* zero: <br>
* The bundle's use count for this service is set to zero. <br>
* If the service was registered with a {@link ServiceFactory} object, the
- * {@code ServiceFactory.ungetService} method is called to release
+ * <code>ServiceFactory.ungetService</code> method is called to release
* the service object for the bundle.
* </ol>
*
* @throws IllegalStateException If this
- * {@code ServiceRegistration} object has already been
+ * <code>ServiceRegistration</code> object has already been
* unregistered.
* @see BundleContext#ungetService
* @see ServiceFactory#ungetService
diff --git a/framework/src/main/java/org/osgi/framework/SignerProperty.java b/framework/src/main/java/org/osgi/framework/SignerProperty.java
index 8b357c1..2ba0389 100644
--- a/framework/src/main/java/org/osgi/framework/SignerProperty.java
+++ b/framework/src/main/java/org/osgi/framework/SignerProperty.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2009, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
import java.security.cert.X509Certificate;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -26,9 +27,9 @@
* during filter expression evaluation in the permission implies method.
*
* @Immutable
- * @version $Id: 3589831a7594cf36e645a51ab9b9ae5ebfd80beb $
+ * @version $Revision: 6479 $
*/
-final class SignerProperty {
+class SignerProperty {
private final Bundle bundle;
private final String pattern;
@@ -70,21 +71,19 @@
SignerProperty other = (SignerProperty) o;
Bundle matchBundle = bundle != null ? bundle : other.bundle;
String matchPattern = bundle != null ? other.pattern : pattern;
- Map<X509Certificate, List<X509Certificate>> signers = matchBundle
+ Map/* <X509Certificate, List<X509Certificate>> */signers = matchBundle
.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
- for (List<X509Certificate> signerCerts : signers.values()) {
- List<String> dnChain = new ArrayList<String>(signerCerts.size());
- for (X509Certificate signerCert : signerCerts) {
- dnChain.add(signerCert.getSubjectDN().getName());
+ for (Iterator iSigners = signers.values().iterator(); iSigners
+ .hasNext();) {
+ List/* <X509Certificate> */signerCerts = (List) iSigners.next();
+ List/* <String> */dnChain = new ArrayList(signerCerts.size());
+ for (Iterator iCerts = signerCerts.iterator(); iCerts.hasNext();) {
+ dnChain.add(((X509Certificate) iCerts.next()).getSubjectDN()
+ .getName());
}
- try {
- if (FrameworkUtil.matchDistinguishedNameChain(matchPattern,
- dnChain)) {
- return true;
- }
- }
- catch (IllegalArgumentException e) {
- continue; // bad pattern
+ if (FrameworkUtil
+ .matchDistinguishedNameChain(matchPattern, dnChain)) {
+ return true;
}
}
return false;
@@ -107,7 +106,7 @@
if (bundle == null) {
return false;
}
- Map<X509Certificate, List<X509Certificate>> signers = bundle
+ Map/* <X509Certificate, List<X509Certificate>> */signers = bundle
.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
return !signers.isEmpty();
}
diff --git a/framework/src/main/java/org/osgi/framework/SynchronousBundleListener.java b/framework/src/main/java/org/osgi/framework/SynchronousBundleListener.java
index 227dc59..9104f04 100644
--- a/framework/src/main/java/org/osgi/framework/SynchronousBundleListener.java
+++ b/framework/src/main/java/org/osgi/framework/SynchronousBundleListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2001, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,48 +17,35 @@
package org.osgi.framework;
/**
- * A synchronous {@code BundleEvent} listener.
- * {@code SynchronousBundleListener} is a listener interface that may be
- * implemented by a bundle developer. When a {@code BundleEvent} is fired,
- * it is synchronously delivered to a {@code SynchronousBundleListener}.
- * The Framework may deliver {@code BundleEvent} objects to a
- * {@code SynchronousBundleListener} out of order and may concurrently call
- * and/or reenter a {@code SynchronousBundleListener}.
- *
+ * A synchronous <code>BundleEvent</code> listener.
+ * <code>SynchronousBundleListener</code> is a listener interface that may be
+ * implemented by a bundle developer. When a <code>BundleEvent</code> is
+ * fired, it is synchronously delivered to a
+ * <code>SynchronousBundleListener</code>. The Framework may deliver
+ * <code>BundleEvent</code> objects to a
+ * <code>SynchronousBundleListener</code> out of order and may concurrently
+ * call and/or reenter a <code>SynchronousBundleListener</code>.
* <p>
- * For {@code BundleEvent} types {@link BundleEvent#STARTED STARTED} and
- * {@link BundleEvent#LAZY_ACTIVATION LAZY_ACTIVATION}, the Framework must not
- * hold the referenced bundle's "state change" lock when the
- * {@code BundleEvent} is delivered to a
- * {@code SynchronousBundleListener}. For the other
- * {@code BundleEvent} types, the Framework must hold the referenced
- * bundle's "state change" lock when the {@code BundleEvent} is
- * delivered to a {@code SynchronousBundleListener}. A
- * {@code SynchronousBundleListener} cannot directly call life cycle
- * methods on the referenced bundle when the Framework is holding the referenced
- * bundle's "state change" lock.
- *
- * <p>
- * A {@code SynchronousBundleListener} object is registered with the
+ * A <code>SynchronousBundleListener</code> object is registered with the
* Framework using the {@link BundleContext#addBundleListener} method.
- * {@code SynchronousBundleListener} objects are called with a
- * {@code BundleEvent} object when a bundle has been installed, resolved,
+ * <code>SynchronousBundleListener</code> objects are called with a
+ * <code>BundleEvent</code> object when a bundle has been installed, resolved,
* starting, started, stopping, stopped, updated, unresolved, or uninstalled.
* <p>
- * Unlike normal {@code BundleListener} objects,
- * {@code SynchronousBundleListener}s are synchronously called during
+ * Unlike normal <code>BundleListener</code> objects,
+ * <code>SynchronousBundleListener</code>s are synchronously called during
* bundle lifecycle processing. The bundle lifecycle processing will not proceed
- * until all {@code SynchronousBundleListener}s have completed.
- * {@code SynchronousBundleListener} objects will be called prior to
- * {@code BundleListener} objects.
+ * until all <code>SynchronousBundleListener</code>s have completed.
+ * <code>SynchronousBundleListener</code> objects will be called prior to
+ * <code>BundleListener</code> objects.
* <p>
- * {@code AdminPermission[bundle,LISTENER]} is required to add or remove a
- * {@code SynchronousBundleListener} object.
+ * <code>AdminPermission[bundle,LISTENER]</code> is required to add or remove
+ * a <code>SynchronousBundleListener</code> object.
*
* @since 1.1
* @see BundleEvent
* @ThreadSafe
- * @version $Id: b22484f48ebdcb2141da9bba9eb65f5c40e0f520 $
+ * @version $Revision: 5673 $
*/
public interface SynchronousBundleListener extends BundleListener {
diff --git a/framework/src/main/java/org/osgi/framework/Version.java b/framework/src/main/java/org/osgi/framework/Version.java
index fd2484e..7317495 100644
--- a/framework/src/main/java/org/osgi/framework/Version.java
+++ b/framework/src/main/java/org/osgi/framework/Version.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,25 +28,24 @@
* <li>Major version. A non-negative integer.</li>
* <li>Minor version. A non-negative integer.</li>
* <li>Micro version. A non-negative integer.</li>
- * <li>Qualifier. A text string. See {@code Version(String)} for the
+ * <li>Qualifier. A text string. See <code>Version(String)</code> for the
* format of the qualifier string.</li>
* </ol>
*
* <p>
- * {@code Version} objects are immutable.
+ * <code>Version</code> objects are immutable.
*
* @since 1.3
* @Immutable
- * @version $Id: a71e2e2d7685e65b5bbe375efdf97fda16eff0a5 $
+ * @version $Revision: 6860 $
*/
-public class Version implements Comparable<Version> {
+public class Version implements Comparable {
private final int major;
private final int minor;
private final int micro;
private final String qualifier;
- private static final String SEPARATOR = ".";
- private transient String versionString;
+ private static final String SEPARATOR = "."; //$NON-NLS-1$
/**
* The empty version "0.0.0".
@@ -76,21 +75,20 @@
* @param minor Minor component of the version identifier.
* @param micro Micro component of the version identifier.
* @param qualifier Qualifier component of the version identifier. If
- * {@code null} is specified, then the qualifier will be set to
+ * <code>null</code> is specified, then the qualifier will be set to
* the empty string.
* @throws IllegalArgumentException If the numerical components are negative
* or the qualifier string is invalid.
*/
public Version(int major, int minor, int micro, String qualifier) {
if (qualifier == null) {
- qualifier = "";
+ qualifier = ""; //$NON-NLS-1$
}
this.major = major;
this.minor = minor;
this.micro = micro;
this.qualifier = qualifier;
- versionString = null;
validate();
}
@@ -113,51 +111,46 @@
* There must be no whitespace in version.
*
* @param version String representation of the version identifier.
- * @throws IllegalArgumentException If {@code version} is improperly
+ * @throws IllegalArgumentException If <code>version</code> is improperly
* formatted.
*/
public Version(String version) {
int maj = 0;
int min = 0;
int mic = 0;
- String qual = "";
+ String qual = ""; //$NON-NLS-1$
try {
StringTokenizer st = new StringTokenizer(version, SEPARATOR, true);
maj = Integer.parseInt(st.nextToken());
- if (st.hasMoreTokens()) { // minor
+ if (st.hasMoreTokens()) {
st.nextToken(); // consume delimiter
min = Integer.parseInt(st.nextToken());
- if (st.hasMoreTokens()) { // micro
+ if (st.hasMoreTokens()) {
st.nextToken(); // consume delimiter
mic = Integer.parseInt(st.nextToken());
- if (st.hasMoreTokens()) { // qualifier
+ if (st.hasMoreTokens()) {
st.nextToken(); // consume delimiter
- qual = st.nextToken(""); // remaining string
+ qual = st.nextToken();
- if (st.hasMoreTokens()) { // fail safe
- throw new IllegalArgumentException(
- "invalid format: " + version);
+ if (st.hasMoreTokens()) {
+ throw new IllegalArgumentException("invalid format"); //$NON-NLS-1$
}
}
}
}
}
catch (NoSuchElementException e) {
- IllegalArgumentException iae = new IllegalArgumentException(
- "invalid format: " + version);
- iae.initCause(e);
- throw iae;
+ throw new IllegalArgumentException("invalid format"); //$NON-NLS-1$
}
major = maj;
minor = min;
micro = mic;
qualifier = qual;
- versionString = null;
validate();
}
@@ -169,13 +162,13 @@
*/
private void validate() {
if (major < 0) {
- throw new IllegalArgumentException("negative major");
+ throw new IllegalArgumentException("negative major"); //$NON-NLS-1$
}
if (minor < 0) {
- throw new IllegalArgumentException("negative minor");
+ throw new IllegalArgumentException("negative minor"); //$NON-NLS-1$
}
if (micro < 0) {
- throw new IllegalArgumentException("negative micro");
+ throw new IllegalArgumentException("negative micro"); //$NON-NLS-1$
}
char[] chars = qualifier.toCharArray();
for (int i = 0, length = chars.length; i < length; i++) {
@@ -192,8 +185,8 @@
if ((ch == '_') || (ch == '-')) {
continue;
}
- throw new IllegalArgumentException("invalid qualifier: "
- + qualifier);
+ throw new IllegalArgumentException(
+ "invalid qualifier: " + qualifier); //$NON-NLS-1$
}
}
@@ -201,15 +194,15 @@
* Parses a version identifier from the specified string.
*
* <p>
- * See {@code Version(String)} for the format of the version string.
+ * See <code>Version(String)</code> for the format of the version string.
*
* @param version String representation of the version identifier. Leading
* and trailing whitespace will be ignored.
- * @return A {@code Version} object representing the version
- * identifier. If {@code version} is {@code null} or
- * the empty string then {@code emptyVersion} will be
+ * @return A <code>Version</code> object representing the version
+ * identifier. If <code>version</code> is <code>null</code> or
+ * the empty string then <code>emptyVersion</code> will be
* returned.
- * @throws IllegalArgumentException If {@code version} is improperly
+ * @throws IllegalArgumentException If <code>version</code> is improperly
* formatted.
*/
public static Version parseVersion(String version) {
@@ -265,16 +258,13 @@
* Returns the string representation of this version identifier.
*
* <p>
- * The format of the version string will be {@code major.minor.micro}
+ * The format of the version string will be <code>major.minor.micro</code>
* if qualifier is the empty string or
- * {@code major.minor.micro.qualifier} otherwise.
+ * <code>major.minor.micro.qualifier</code> otherwise.
*
* @return The string representation of this version identifier.
*/
public String toString() {
- if (versionString != null) {
- return versionString;
- }
int q = qualifier.length();
StringBuffer result = new StringBuffer(20 + q);
result.append(major);
@@ -286,7 +276,7 @@
result.append(SEPARATOR);
result.append(qualifier);
}
- return versionString = result.toString();
+ return result.toString();
}
/**
@@ -300,17 +290,17 @@
}
/**
- * Compares this {@code Version} object to another object.
+ * Compares this <code>Version</code> object to another object.
*
* <p>
* A version is considered to be <b>equal to </b> another version if the
* major, minor and micro components are equal and the qualifier component
- * is equal (using {@code String.equals}).
+ * is equal (using <code>String.equals</code>).
*
- * @param object The {@code Version} object to be compared.
- * @return {@code true} if {@code object} is a
- * {@code Version} and is equal to this object;
- * {@code false} otherwise.
+ * @param object The <code>Version</code> object to be compared.
+ * @return <code>true</code> if <code>object</code> is a
+ * <code>Version</code> and is equal to this object;
+ * <code>false</code> otherwise.
*/
public boolean equals(Object object) {
if (object == this) { // quicktest
@@ -327,7 +317,7 @@
}
/**
- * Compares this {@code Version} object to another {@code Version}.
+ * Compares this <code>Version</code> object to another object.
*
* <p>
* A version is considered to be <b>less than </b> another version if its
@@ -337,25 +327,27 @@
* and its micro component is less than the other version's micro component,
* or the major, minor and micro components are equal and it's qualifier
* component is less than the other version's qualifier component (using
- * {@code String.compareTo}).
+ * <code>String.compareTo</code>).
*
* <p>
* A version is considered to be <b>equal to</b> another version if the
* major, minor and micro components are equal and the qualifier component
- * is equal (using {@code String.compareTo}).
+ * is equal (using <code>String.compareTo</code>).
*
- * @param other The {@code Version} object to be compared.
- * @return A negative integer, zero, or a positive integer if this version
- * is less than, equal to, or greater than the specified
- * {@code Version} object.
+ * @param object The <code>Version</code> object to be compared.
+ * @return A negative integer, zero, or a positive integer if this object is
+ * less than, equal to, or greater than the specified
+ * <code>Version</code> object.
* @throws ClassCastException If the specified object is not a
- * {@code Version} object.
+ * <code>Version</code>.
*/
- public int compareTo(Version other) {
- if (other == this) { // quicktest
+ public int compareTo(Object object) {
+ if (object == this) { // quicktest
return 0;
}
+ Version other = (Version) object;
+
int result = major - other.major;
if (result != 0) {
return result;
diff --git a/framework/src/main/java/org/osgi/framework/startlevel/BundleStartLevel.java b/framework/src/main/java/org/osgi/framework/startlevel/BundleStartLevel.java
deleted file mode 100644
index d22d3ef..0000000
--- a/framework/src/main/java/org/osgi/framework/startlevel/BundleStartLevel.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
- *
- * Licensed 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.osgi.framework.startlevel;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleReference;
-
-/**
- * Query and modify the start level information for a bundle. The start level
- * object for a bundle can be obtained by calling {@link Bundle#adapt(Class)
- * bundle.adapt(BundleStartLevel.class)} on the bundle.
- *
- * <p>
- * The bundle associated with this BundleStartLevel object can be obtained by
- * calling {@link BundleReference#getBundle()}.
- *
- * @ThreadSafe
- * @noimplement
- * @version $Id: 9a000be191fe3cb4ae82535a30940db0340d5356 $
- */
-public interface BundleStartLevel extends BundleReference {
- /**
- * Return the assigned start level value for the bundle.
- *
- * @return The start level value of the bundle.
- * @see #setStartLevel(int)
- * @throws IllegalStateException If the bundle has been uninstalled.
- */
- int getStartLevel();
-
- /**
- * Assign a start level value to the bundle.
- *
- * <p>
- * The bundle will be assigned the specified start level. The start level
- * value assigned to the bundle will be persistently recorded by the
- * Framework.
- * <p>
- * If the new start level for the bundle is lower than or equal to the
- * active start level of the Framework and the bundle's autostart setting
- * indicates this bundle must be started, the Framework will start the
- * bundle as described in the {@link Bundle#start(int)} method using the
- * {@link Bundle#START_TRANSIENT} option. The
- * {@link Bundle#START_ACTIVATION_POLICY} option must also be used if
- * {@link #isActivationPolicyUsed()} returns {@code true}. The actual
- * starting of the bundle must occur asynchronously.
- * <p>
- * If the new start level for the bundle is higher than the active start
- * level of the Framework, the Framework will stop the bundle as described
- * in the {@link Bundle#stop(int)} method using the
- * {@link Bundle#STOP_TRANSIENT} option. The actual stopping of the bundle
- * must occur asynchronously.
- *
- * @param startlevel The new start level for the bundle.
- * @throws IllegalArgumentException If the specified start level is less
- * than or equal to zero, or if the bundle is the system bundle.
- * @throws IllegalStateException If the bundle has been uninstalled.
- * @throws SecurityException If the caller does not have
- * {@code AdminPermission[bundle,EXECUTE]} and the Java runtime
- * environment supports permissions.
- */
- void setStartLevel(int startlevel);
-
- /**
- * Returns whether the bundle's autostart setting indicates it must be
- * started.
- * <p>
- * The autostart setting of a bundle indicates whether the bundle is to be
- * started when its start level is reached.
- *
- * @return {@code true} if the autostart setting of the bundle indicates it
- * is to be started. {@code false} otherwise.
- * @throws IllegalStateException If this bundle has been uninstalled.
- * @see Bundle#START_TRANSIENT
- */
- boolean isPersistentlyStarted();
-
- /**
- * Returns whether the bundle's autostart setting indicates that the
- * activation policy declared in the bundle manifest must be used.
- * <p>
- * The autostart setting of a bundle indicates whether the bundle's declared
- * activation policy is to be used when the bundle is started.
- *
- * @return {@code true} if the bundle's autostart setting indicates the
- * activation policy declared in the manifest must be used.
- * {@code false} if the bundle must be eagerly activated.
- * @throws IllegalStateException If the bundle has been uninstalled.
- * @see Bundle#START_ACTIVATION_POLICY
- */
- boolean isActivationPolicyUsed();
-}
diff --git a/framework/src/main/java/org/osgi/framework/startlevel/FrameworkStartLevel.java b/framework/src/main/java/org/osgi/framework/startlevel/FrameworkStartLevel.java
deleted file mode 100644
index adb51ec..0000000
--- a/framework/src/main/java/org/osgi/framework/startlevel/FrameworkStartLevel.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2002, 2010). All Rights Reserved.
- *
- * Licensed 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.osgi.framework.startlevel;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleReference;
-import org.osgi.framework.FrameworkListener;
-
-/**
- * Query and modify the start level information for the framework. The start
- * level object for the framework can be obtained by calling
- * {@link Bundle#adapt(Class) bundle.adapt(FrameworkStartLevel.class)} on the
- * system bundle. Only the system bundle can be adapted to a FrameworkStartLevel
- * object.
- *
- * <p>
- * The system bundle associated with this FrameworkStartLevel object can be
- * obtained by calling {@link BundleReference#getBundle()}.
- *
- * @ThreadSafe
- * @noimplement
- * @version $Id: 2bca22671674ba50b8c6801d5d1df8e291fe2a9d $
- */
-public interface FrameworkStartLevel extends BundleReference {
- /**
- * Return the active start level value of the Framework.
- *
- * If the Framework is in the process of changing the start level this
- * method must return the active start level if this differs from the
- * requested start level.
- *
- * @return The active start level value of the Framework.
- */
- int getStartLevel();
-
- /**
- * Modify the active start level of the Framework and notify when complete.
- *
- * <p>
- * The Framework will move to the requested start level. This method will
- * return immediately to the caller and the start level change will occur
- * asynchronously on another thread. The specified {@code FrameworkListener}
- * s are notified, in the order specified, when the start level change is
- * complete. When the start level change completes normally, each specified
- * {@code FrameworkListener} will be called with a Framework event of type
- * {@code FrameworkEvent.STARTLEVEL_CHANGED}. If the start level change does
- * not complete normally, each specified {@code FrameworkListener} will be
- * called with a Framework event of type {@code FrameworkEvent.ERROR}.
- *
- * <p>
- * If the specified start level is higher than the active start level, the
- * Framework will continue to increase the start level until the Framework
- * has reached the specified start level.
- *
- * At each intermediate start level value on the way to and including the
- * target start level, the Framework must:
- * <ol>
- * <li>Change the active start level to the intermediate start level value.
- * <li>Start bundles at the intermediate start level whose autostart setting
- * indicate they must be started. They are started as described in the
- * {@link Bundle#start(int)} method using the {@link Bundle#START_TRANSIENT}
- * option. The {@link Bundle#START_ACTIVATION_POLICY} option must also be
- * used if {@link BundleStartLevel#isActivationPolicyUsed()} returns
- * {@code true} for the bundle.
- * </ol>
- * When this process completes after the specified start level is reached,
- * the Framework will fire a Framework event of type
- * {@code FrameworkEvent.STARTLEVEL_CHANGED} to announce it has moved to the
- * specified start level.
- *
- * <p>
- * If the specified start level is lower than the active start level, the
- * Framework will continue to decrease the start level until the Framework
- * has reached the specified start level.
- *
- * At each intermediate start level value on the way to and including the
- * specified start level, the framework must:
- * <ol>
- * <li>Stop bundles at the intermediate start level as described in the
- * {@link Bundle#stop(int)} method using the {@link Bundle#STOP_TRANSIENT}
- * option.
- * <li>Change the active start level to the intermediate start level value.
- * </ol>
- * When this process completes after the specified start level is reached,
- * the Framework will fire a Framework event of type
- * {@code FrameworkEvent.STARTLEVEL_CHANGED} to announce it has moved to the
- * specified start level.
- *
- * <p>
- * If the specified start level is equal to the active start level, then no
- * bundles are started or stopped, however, the Framework must fire a
- * Framework event of type {@code FrameworkEvent.STARTLEVEL_CHANGED} to
- * announce it has finished moving to the specified start level. This event
- * may arrive before this method returns.
- *
- * @param startlevel The requested start level for the Framework.
- * @param listeners Zero or more listeners to be notified when the start
- * level change has been completed. The specified listeners do not
- * need to be otherwise registered with the framework. If a specified
- * listener is already registered with the framework, it will be
- * notified twice.
- * @throws IllegalArgumentException If the specified start level is less
- * than or equal to zero.
- * @throws SecurityException If the caller does not have
- * {@code AdminPermission[System Bundle,STARTLEVEL]} and the Java
- * runtime environment supports permissions.
- */
- void setStartLevel(int startlevel, FrameworkListener... listeners);
-
- /**
- * Return the initial start level value that is assigned to a Bundle when it
- * is first installed.
- *
- * @return The initial start level value for Bundles.
- * @see #setInitialBundleStartLevel
- */
- int getInitialBundleStartLevel();
-
- /**
- * Set the initial start level value that is assigned to a Bundle when it is
- * first installed.
- *
- * <p>
- * The initial bundle start level will be set to the specified start level.
- * The initial bundle start level value will be persistently recorded by the
- * Framework.
- *
- * <p>
- * When a Bundle is installed via {@code BundleContext.installBundle}, it is
- * assigned the initial bundle start level value.
- *
- * <p>
- * The default initial bundle start level value is 1 unless this method has
- * been called to assign a different initial bundle start level value.
- *
- * <p>
- * This method does not change the start level values of installed bundles.
- *
- * @param startlevel The initial start level for newly installed bundles.
- * @throws IllegalArgumentException If the specified start level is less
- * than or equal to zero.
- * @throws SecurityException If the caller does not have
- * {@code AdminPermission[System Bundle,STARTLEVEL]} and the Java
- * runtime environment supports permissions.
- */
- void setInitialBundleStartLevel(int startlevel);
-}
diff --git a/framework/src/main/java/org/osgi/framework/wiring/BundleCapability.java b/framework/src/main/java/org/osgi/framework/wiring/BundleCapability.java
deleted file mode 100644
index c49f0ac..0000000
--- a/framework/src/main/java/org/osgi/framework/wiring/BundleCapability.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
- *
- * Licensed 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.osgi.framework.wiring;
-
-import java.util.Map;
-
-/**
- * A capability that has been declared from a {@link BundleRevision bundle
- * revision}.
- *
- * @ThreadSafe
- * @noimplement
- * @version $Id: 0fde13c3228af1aa97872b37ccf0aa6e23123b11 $
- */
-public interface BundleCapability {
- /**
- * Returns the name space of this capability.
- *
- * @return The name space of this capability.
- */
- String getNamespace();
-
- /**
- * Returns the directives of this capability.
- *
- * @return An unmodifiable map of directive names to directive values for
- * this capability, or an empty map if this capability has no
- * directives.
- */
- Map<String, String> getDirectives();
-
- /**
- * Returns the attributes of this capability.
- *
- * @return An unmodifiable map of attribute names to attribute values for
- * this capability, or an empty map if this capability has no
- * attributes.
- */
- Map<String, Object> getAttributes();
-
- /**
- * Returns the bundle revision declaring this capability.
- *
- * @return The bundle revision declaring this capability.
- */
- BundleRevision getRevision();
-}
diff --git a/framework/src/main/java/org/osgi/framework/wiring/BundleRequirement.java b/framework/src/main/java/org/osgi/framework/wiring/BundleRequirement.java
deleted file mode 100644
index bd637e6..0000000
--- a/framework/src/main/java/org/osgi/framework/wiring/BundleRequirement.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
- *
- * Licensed 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.osgi.framework.wiring;
-
-import java.util.Map;
-
-/**
- * A requirement that has been declared from a {@link BundleRevision bundle
- * revision}.
- *
- * @ThreadSafe
- * @noimplement
- * @version $Id: 659132c1fac7526240df377ead0e1bc8d4af2e77 $
- */
-public interface BundleRequirement {
- /**
- * Returns the name space of this requirement.
- *
- * @return The name space of this requirement.
- */
- String getNamespace();
-
- /**
- * Returns the directives of this requirement.
- *
- * @return An unmodifiable map of directive names to directive values for
- * this requirement, or an empty map if this requirement has no
- * directives.
- */
- Map<String, String> getDirectives();
-
- /**
- * Returns the attributes of this requirement.
- *
- * @return An unmodifiable map of attribute names to attribute values for
- * this requirement, or an empty map if this requirement has no
- * attributes.
- */
- Map<String, Object> getAttributes();
-
- /**
- * Returns the bundle revision declaring this requirement.
- *
- * @return The bundle revision declaring this requirement.
- */
- BundleRevision getRevision();
-
- /**
- * Returns whether the specified capability matches this requirement.
- *
- * @param capability The capability to match to this requirement.
- * @return {@code true} if the specified capability has the same
- * {@link #getNamespace() name space} as this requirement and the
- * filter for this requirement matches the
- * {@link BundleCapability#getAttributes() attributes of the
- * specified capability}; {@code false} otherwise.
- */
- boolean matches(BundleCapability capability);
-}
diff --git a/framework/src/main/java/org/osgi/framework/wiring/BundleRevision.java b/framework/src/main/java/org/osgi/framework/wiring/BundleRevision.java
deleted file mode 100644
index 5924dc1..0000000
--- a/framework/src/main/java/org/osgi/framework/wiring/BundleRevision.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
- *
- * Licensed 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.osgi.framework.wiring;
-
-import java.util.List;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleReference;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-
-/**
- * Bundle Revision. When a bundle is installed and each time a bundle is
- * updated, a new bundle revision of the bundle is created. Since a bundle
- * update can change the entries in a bundle, different bundle wirings for the
- * same bundle can be associated with different bundle revisions.
- *
- * <p>
- * For a bundle that has not been uninstalled, the most recent bundle revision
- * is defined to be the current bundle revision. A bundle in the UNINSTALLED
- * state does not have a current revision. The current bundle revision for a
- * bundle can be obtained by calling {@link Bundle#adapt(Class) bundle.adapt}
- * (BundleRevision.class). Since a bundle in the UNINSTALLED state does not have
- * a current revision, adapting such a bundle returns {@code null}.
- *
- * <p>
- * The framework defines name spaces for {@link #PACKAGE_NAMESPACE package},
- * {@link #BUNDLE_NAMESPACE bundle} and {@link #HOST_NAMESPACE host}
- * capabilities and requirements. These name spaces are defined only to express
- * wiring information by the framework. They must not be used in
- * {@link Constants#PROVIDE_CAPABILITY Provide-Capability} and
- * {@link Constants#REQUIRE_CAPABILITY Require-Capability} manifest headers.
- *
- * @ThreadSafe
- * @noimplement
- * @version $Id: 139b3046ebd46c48b03dda8d36f2f9d79e2e616d $
- */
-public interface BundleRevision extends BundleReference {
- /**
- * Returns the symbolic name for this bundle revision.
- *
- * @return The symbolic name for this bundle revision.
- * @see Bundle#getSymbolicName()
- */
- String getSymbolicName();
-
- /**
- * Returns the version for this bundle revision.
- *
- * @return The version for this bundle revision, or
- * {@link Version#emptyVersion} if this bundle revision has no
- * version information.
- * @see Bundle#getVersion()
- */
- Version getVersion();
-
- /**
- * Returns the capabilities declared by this bundle revision.
- *
- * @param namespace The name space of the declared capabilities to return or
- * {@code null} to return the declared capabilities from all name
- * spaces.
- * @return A list containing a snapshot of the declared
- * {@link BundleCapability}s, or an empty list if this bundle
- * revision declares no capabilities in the specified name space.
- * The list contains the declared capabilities in the order they are
- * specified in the manifest.
- */
- List<BundleCapability> getDeclaredCapabilities(String namespace);
-
- /**
- * Returns the requirements declared by this bundle revision.
- *
- * @param namespace The name space of the declared requirements to return or
- * {@code null} to return the declared requirements from all name
- * spaces.
- * @return A list containing a snapshot of the declared
- * {@link BundleRequirement}s, or an empty list if this bundle
- * revision declares no requirements in the specified name space.
- * The list contains the declared requirements in the order they are
- * specified in the manifest.
- */
- List<BundleRequirement> getDeclaredRequirements(String namespace);
-
- /**
- * Name space for package capabilities and requirements.
- *
- * <p>
- * The name of the package is stored in the capability attribute of the same
- * name as this name space (osgi.wiring.package). The other
- * directives and attributes of the package, from the
- * {@link Constants#EXPORT_PACKAGE Export-Package} manifest header, can be
- * found in the cabability's {@link BundleCapability#getDirectives()
- * directives} and {@link BundleCapability#getAttributes() attributes}. The
- * {@link Constants#VERSION_ATTRIBUTE version} capability attribute must
- * contain the {@link Version} of the package if one is specified or
- * {@link Version#emptyVersion} if not specified. The
- * {@link Constants#BUNDLE_SYMBOLICNAME_ATTRIBUTE bundle-symbolic-name}
- * capability attribute must contain the
- * {@link BundleRevision#getSymbolicName() symbolic name} of the provider if
- * one is specified. The {@link Constants#BUNDLE_VERSION_ATTRIBUTE
- * bundle-version} capability attribute must contain the
- * {@link BundleRevision#getVersion() version} of the provider if one is
- * specified or {@link Version#emptyVersion} if not specified.
- *
- * <p>
- * The package capabilities provided by the system bundle, that is the
- * bundle with id zero, must include the package specified by the
- * {@link Constants#FRAMEWORK_SYSTEMPACKAGES} and
- * {@link Constants#FRAMEWORK_SYSTEMPACKAGES_EXTRA} framework properties as
- * well as any other package exported by the framework implementation.
- *
- * <p>
- * A bundle revision {@link BundleRevision#getDeclaredCapabilities(String)
- * declares} zero or more package capabilities (this is, exported packages)
- * and {@link BundleRevision#getDeclaredRequirements(String) declares} zero
- * or more package requirements.
- * <p>
- * A bundle wiring {@link BundleWiring#getCapabilities(String) provides}
- * zero or more resolved package capabilities (that is, exported packages)
- * and {@link BundleWiring#getRequiredWires(String) requires} zero or more
- * resolved package requirements (that is, imported packages). The number of
- * package wires required by a bundle wiring may change as the bundle wiring
- * may dynamically import additional packages.
- */
- String PACKAGE_NAMESPACE = "osgi.wiring.package";
-
- /**
- * Name space for bundle capabilities and requirements.
- *
- * <p>
- * The bundle symbolic name of the bundle is stored in the capability
- * attribute of the same name as this name space (osgi.wiring.bundle).
- * The other directives and attributes of the bundle, from the
- * {@link Constants#BUNDLE_SYMBOLICNAME Bundle-SymbolicName} manifest
- * header, can be found in the cabability's
- * {@link BundleCapability#getDirectives() directives} and
- * {@link BundleCapability#getAttributes() attributes}. The
- * {@link Constants#BUNDLE_VERSION_ATTRIBUTE bundle-version} capability
- * attribute must contain the {@link Version} of the bundle from the
- * {@link Constants#BUNDLE_VERSION Bundle-Version} manifest header if one is
- * specified or {@link Version#emptyVersion} if not specified.
- *
- * <p>
- * A non-fragment revision
- * {@link BundleRevision#getDeclaredCapabilities(String) declares} exactly
- * one<sup>†</sup> bundle capability (that is, the bundle can be
- * required by another bundle). A fragment revision must not declare a
- * bundle capability.
- *
- * <p>
- * A bundle wiring for a non-fragment revision
- * {@link BundleWiring#getCapabilities(String) provides} exactly
- * one<sup>†</sup> bundle capability (that is, the bundle can be
- * required by another bundle) and
- * {@link BundleWiring#getRequiredWires(String) requires} zero or more
- * bundle capabilities (that is, requires other bundles).
- *
- * <p>
- * † A bundle with no bundle symbolic name (that is, a bundle with
- * {@link Constants#BUNDLE_MANIFESTVERSION Bundle-ManifestVersion}
- * {@literal <} 2) must not provide a bundle capability.
- */
- String BUNDLE_NAMESPACE = "osgi.wiring.bundle";
-
- /**
- * Name space for host capabilities and requirements.
- *
- * <p>
- * The bundle symbolic name of the bundle is stored in the capability
- * attribute of the same name as this name space (osgi.wiring.host).
- * The other directives and attributes of the bundle, from the
- * {@link Constants#BUNDLE_SYMBOLICNAME Bundle-SymbolicName} manifest
- * header, can be found in the cabability's
- * {@link BundleCapability#getDirectives() directives} and
- * {@link BundleCapability#getAttributes() attributes}. The
- * {@link Constants#BUNDLE_VERSION_ATTRIBUTE bundle-version} capability
- * attribute must contain the {@link Version} of the bundle from the
- * {@link Constants#BUNDLE_VERSION Bundle-Version} manifest header if one is
- * specified or {@link Version#emptyVersion} if not specified.
- *
- * <p>
- * A non-fragment revision
- * {@link BundleRevision#getDeclaredCapabilities(String) declares} zero or
- * one<sup>†</sup> host capability if the bundle
- * {@link Constants#FRAGMENT_ATTACHMENT_DIRECTIVE allows fragments to be
- * attached}. A fragment revision must
- * {@link BundleRevision#getDeclaredRequirements(String) declare} exactly
- * one host requirement.
- *
- * <p>
- * A bundle wiring for a non-fragment revision
- * {@link BundleWiring#getCapabilities(String) provides} zero or
- * one<sup>†</sup> host capability if the bundle
- * {@link Constants#FRAGMENT_ATTACHMENT_DIRECTIVE allows fragments to be
- * attached}. A bundle wiring for a fragment revision
- * {@link BundleWiring#getRequiredWires(String) requires} a host capability
- * for each host to which it is attached.
- *
- * <p>
- * † A bundle with no bundle symbolic name (that is, a bundle with
- * {@link Constants#BUNDLE_MANIFESTVERSION Bundle-ManifestVersion}
- * {@literal <} 2) must not provide a host capability.
- */
- String HOST_NAMESPACE = "osgi.wiring.host";
-
- /**
- * Returns the special types of this bundle revision. The bundle revision
- * type values are:
- * <ul>
- * <li>{@link #TYPE_FRAGMENT}
- * </ul>
- *
- * A bundle revision may be more than one type at a time. A type code is
- * used to identify the bundle revision type for future extendability.
- *
- * <p>
- * If this bundle revision is not one or more of the defined types then 0 is
- * returned.
- *
- * @return The special types of this bundle revision. The type values are
- * ORed together.
- */
- int getTypes();
-
- /**
- * Bundle revision type indicating the bundle revision is a fragment.
- *
- * @see #getTypes()
- */
- int TYPE_FRAGMENT = 0x00000001;
-
- /**
- * Returns the bundle wiring which is using this bundle revision.
- *
- * @return The bundle wiring which is using this bundle revision or
- * {@code null} if no bundle wiring is using this bundle revision.
- * @see BundleWiring#getRevision()
- */
- BundleWiring getWiring();
-}
diff --git a/framework/src/main/java/org/osgi/framework/wiring/BundleRevisions.java b/framework/src/main/java/org/osgi/framework/wiring/BundleRevisions.java
deleted file mode 100644
index a619dbb..0000000
--- a/framework/src/main/java/org/osgi/framework/wiring/BundleRevisions.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
- *
- * Licensed 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.osgi.framework.wiring;
-
-import java.util.List;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleReference;
-
-/**
- * The {@link BundleRevision bundle revisions} of a bundle. When a bundle is
- * installed and each time a bundle is updated, a new bundle revision of the
- * bundle is created. For a bundle that has not been uninstalled, the most
- * recent bundle revision is defined to be the current bundle revision. A bundle
- * in the UNINSTALLED state does not have a current revision. An in use bundle
- * revision is associated with an {@link BundleWiring#isInUse() in use}
- * {@link BundleWiring}. The current bundle revision, if there is one, and all
- * in use bundle revisions are returned.
- *
- * <p>
- * The bundle revisions for a bundle can be obtained by calling
- * {@link Bundle#adapt(Class) bundle.adapt}({@link BundleRevisions}.class).
- * {@link #getRevisions()} on the bundle.
- *
- * @ThreadSafe
- * @noimplement
- * @version $Id: 1d95ad10f0f08b100f8ee2485bdd34120032c7af $
- */
-public interface BundleRevisions extends BundleReference {
- /**
- * Return the bundle revisions for the {@link BundleReference#getBundle()
- * referenced} bundle.
- *
- * <p>
- * The result is a list containing the current bundle revision, if there is
- * one, and all in use bundle revisions. The list may also contain
- * intermediate bundle revisions which are not in use.
- *
- * <p>
- * The list is ordered in reverse chronological order such that the first
- * item is the most recent bundle revision and last item is the oldest
- * bundle revision.
- *
- * <p>
- * Generally the list will have at least one bundle revision for the bundle:
- * the current bundle revision. However, for an uninstalled bundle with no
- * in use bundle revisions, the list may be empty.
- *
- * @return A list containing a snapshot of the {@link BundleRevision}s for
- * the referenced bundle.
- */
- List<BundleRevision> getRevisions();
-}
diff --git a/framework/src/main/java/org/osgi/framework/wiring/BundleWire.java b/framework/src/main/java/org/osgi/framework/wiring/BundleWire.java
deleted file mode 100644
index 1b19e4c..0000000
--- a/framework/src/main/java/org/osgi/framework/wiring/BundleWire.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
- *
- * Licensed 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.osgi.framework.wiring;
-
-/**
- * A wire connecting a {@link BundleCapability} to a {@link BundleRequirement}.
- *
- * @ThreadSafe
- * @noimplement
- * @version $Id: 4f936a84065762ec3267a44f86ae01b0150e44ce $
- */
-public interface BundleWire {
- /**
- * Returns the {@link BundleCapability} for this wire.
- *
- * @return The {@link BundleCapability} for this wire.
- */
- BundleCapability getCapability();
-
- /**
- * Return the {@link BundleRequirement} for this wire.
- *
- * @return The {@link BundleRequirement} for this wire.
- */
- BundleRequirement getRequirement();
-
- /**
- * Returns the bundle wiring {@link BundleWiring#getProvidedWires(String)
- * providing} the {@link #getCapability() capability}.
- *
- * <p>
- * The bundle revision referenced by the returned bundle wiring may differ
- * from the bundle revision reference by the {@link #getCapability()
- * capability}.
- *
- * @return The bundle wiring providing the capability. If the bundle wiring
- * providing the capability is not {@link BundleWiring#isInUse() in
- * use}, {@code null} will be returned.
- */
- BundleWiring getProviderWiring();
-
- /**
- * Returns the bundle wiring who
- * {@link BundleWiring#getRequiredWires(String) requires} the
- * {@link #getCapability() capability}.
- *
- * <p>
- * The bundle revision referenced by the returned bundle wiring may differ
- * from the bundle revision reference by the {@link #getRequirement()
- * requirement}.
- *
- * @return The bundle wiring whose requirement is wired to the capability.
- * If the bundle wiring requiring the capability is not
- * {@link BundleWiring#isInUse() in use}, {@code null} will be
- * returned.
- */
- BundleWiring getRequirerWiring();
-}
diff --git a/framework/src/main/java/org/osgi/framework/wiring/BundleWiring.java b/framework/src/main/java/org/osgi/framework/wiring/BundleWiring.java
deleted file mode 100644
index 8d8956a..0000000
--- a/framework/src/main/java/org/osgi/framework/wiring/BundleWiring.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
- *
- * Licensed 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.osgi.framework.wiring;
-
-import java.net.URL;
-import java.util.Collection;
-import java.util.List;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleReference;
-
-/**
- * A wiring for a bundle. Each time a bundle is resolved, a new bundle wiring
- * for the bundle is created. A bundle wiring is associated with a bundle
- * revision and represents the dependencies with other bundle wirings.
- *
- * <p>
- * The bundle wiring for a bundle is the {@link #isCurrent() current} bundle
- * wiring if it is the most recent bundle wiring for the current bundle
- * revision. A bundle wiring is {@link #isInUse() in use} if it is the current
- * bundle wiring or if some other in use bundle wiring is dependent upon it. For
- * example, another bundle wiring is wired to a capability provided by the
- * bundle wiring. An in use bundle wiring for a non-fragment bundle has a class
- * loader. All bundles with non-current, in use bundle wirings are considered
- * removal pending. Once a bundle wiring is no longer in use, it is considered
- * stale and is discarded by the framework.
- *
- * <p>
- * The current bundle wiring for a bundle can be obtained by calling
- * {@link Bundle#adapt(Class) bundle.adapt}(BundleWiring.class). A bundle in the
- * INSTALLED or UNINSTALLED state does not have a current wiring, adapting such
- * a bundle returns {@code null}.
- *
- * @ThreadSafe
- * @noimplement
- * @version $Id: 58b8ec3bb9649387d4ccba1070f034f217d06ea2 $
- */
-public interface BundleWiring extends BundleReference {
- /**
- * Returns {@code true} if this bundle wiring is the current bundle wiring.
- * The bundle wiring for a bundle is the current bundle wiring if it is the
- * most recent bundle wiring for the current bundle revision. All bundles
- * with non-current, in use bundle wirings are considered
- * {@link FrameworkWiring#getRemovalPendingBundles() removal pending}.
- *
- * @return {@code true} if this bundle wiring is the current bundle wiring;
- * {@code false} otherwise.
- */
- boolean isCurrent();
-
- /**
- * Returns {@code true} if this bundle wiring is in use. A bundle wiring is
- * in use if it is the {@link #isCurrent() current} wiring or if some other
- * in use bundle wiring is dependent upon it. Once a bundle wiring is no
- * longer in use, it is considered stale and is discarded by the framework.
- *
- * @return {@code true} if this bundle wiring is in use; {@code false}
- * otherwise.
- */
- boolean isInUse();
-
- /**
- * Returns the capabilities provided by this bundle wiring.
- *
- * <p>
- * A capability may not be required by any bundle wiring and thus there may
- * be no {@link #getProvidedWires(String) wires} for the capability.
- *
- * <p>
- * A bundle wiring for a non-fragment revision provides a subset of the
- * declared capabilities from the bundle revision and all attached fragment
- * revisions. Not all declared capabilities may be provided since some may
- * be discarded. For example, if a package is declared to be exported and
- * import, only one is selected and the other is discarded.
- *
- * @param namespace The name space of the capabilities to return or
- * {@code null} to return the capabilities from all name spaces.
- * @return A list containing a snapshot of the {@link BundleCapability}s, or
- * an empty list if this bundle wiring provides no capabilities in
- * the specified name space. If this bundle wiring is not
- * {@link #isInUse() in use}, {@code null} will be returned. For a
- * given name space, the list contains the wires in the order the
- * capabilities were specified in the manifests of the
- * {@link #getRevision() bundle revision} and the attached fragments
- * of this bundle wiring. There is no ordering defined between
- * capabilities in different name spaces.
- */
- List<BundleCapability> getCapabilities(String namespace);
-
- /**
- * Returns the requirements of this bundle wiring.
- *
- * <p>
- * A bundle wiring for a non-fragment revision has a subset of the declared
- * requirements from the bundle revision and all attached fragment
- * revisions. Not all declared requirements may be present since some may be
- * discarded. For example, if a package is declared to be optionally
- * imported and is not actually imported, the requirement must be discarded.
- *
- * @param namespace The name space of the requirements to return or
- * {@code null} to return the requirements from all name spaces.
- * @return A list containing a snapshot of the {@link BundleRequirement}s,
- * or an empty list if this bundle wiring uses no requirements in
- * the specified name space. If this bundle wiring is not
- * {@link #isInUse() in use}, {@code null} will be returned. For a
- * given name space, the list contains the wires in the order the
- * requirements were specified in the manifests of the
- * {@link #getRevision() bundle revision} and the attached fragments
- * of this bundle wiring. There is no ordering defined between
- * requirements in different name spaces.
- */
- List<BundleRequirement> getRequirements(String namespace);
-
- /**
- * Returns the {@link BundleWire}s to the provided {@link BundleCapability
- * capabilities} of this bundle wiring.
- *
- * @param namespace The name space of the capabilities for which to return
- * wires or {@code null} to return the wires for the capabilities in
- * all name spaces.
- * @return A list containing a snapshot of the {@link BundleWire}s for the
- * {@link BundleCapability capabilities} of this bundle wiring, or
- * an empty list if this bundle wiring has no capabilities in the
- * specified name space. If this bundle wiring is not
- * {@link #isInUse() in use}, {@code null} will be returned. For a
- * given name space, the list contains the wires in the order the
- * capabilities were specified in the manifests of the
- * {@link #getRevision() bundle revision} and the attached fragments
- * of this bundle wiring. There is no ordering defined between
- * capabilities in different name spaces.
- */
- List<BundleWire> getProvidedWires(String namespace);
-
- /**
- * Returns the {@link BundleWire}s to the {@link BundleRequirement
- * requirements} in use by this bundle wiring.
- *
- * <p>
- * This method may return different results if this bundle wiring adds wires
- * to more requirements. For example, dynamically importing a package will
- * establish a new wire to the dynamically imported package.
- *
- * @param namespace The name space of the requirements for which to return
- * wires or {@code null} to return the wires for the requirements in
- * all name spaces.
- * @return A list containing a snapshot of the {@link BundleWire}s for the
- * {@link BundleRequirement requirements} of this bundle wiring, or
- * an empty list if this bundle wiring has no requirements in the
- * specified name space. If this bundle wiring is not
- * {@link #isInUse() in use}, {@code null} will be returned. For a
- * given name space, the list contains the wires in the order the
- * requirements were specified in the manifests of the
- * {@link #getRevision() bundle revision} and the attached fragments
- * of this bundle wiring. There is no ordering defined between
- * requirements in different name spaces.
- */
- List<BundleWire> getRequiredWires(String namespace);
-
- /**
- * Returns the bundle revision for the bundle in this bundle wiring. Since a
- * bundle update can change the entries in a bundle, different bundle
- * wirings for the same bundle can have different bundle revisions.
- *
- * <p>
- * The bundle object {@link BundleReference#getBundle() referenced} by the
- * returned {@code BundleRevision} may return different information than the
- * returned {@code BundleRevision} since the returned {@code BundleRevision}
- * may refer to an older revision of the bundle.
- *
- * @return The bundle revision for this bundle wiring.
- * @see BundleRevision#getWiring()
- */
- BundleRevision getRevision();
-
- /**
- * Returns the class loader for this bundle wiring. Since a bundle refresh
- * creates a new bundle wiring for a bundle, different bundle wirings for
- * the same bundle will have different class loaders.
- *
- * @return The class loader for this bundle wiring. If this bundle wiring is
- * not {@link #isInUse() in use} or this bundle wiring is for a
- * fragment revision, {@code null} will be returned.
- * @throws SecurityException If the caller does not have the appropriate
- * {@code RuntimePermission("getClassLoader")}, and the Java Runtime
- * Environment supports permissions.
- */
- ClassLoader getClassLoader();
-
- /**
- * Returns entries in this bundle wiring's {@link #getRevision() bundle
- * revision} and its attached fragment revisions. This bundle wiring's class
- * loader is not used to search for entries. Only the contents of this
- * bundle wiring's bundle revision and its attached fragment revisions are
- * searched for the specified entries.
- *
- * <p>
- * This method takes into account that the "contents" of this
- * bundle wiring can have attached fragments. This "bundle space"
- * is not a name space with unique members; the same entry name can be
- * present multiple times. This method therefore returns a list of URL
- * objects. These URLs can come from different JARs but have the same path
- * name. This method can either return only entries in the specified path or
- * recurse into subdirectories returning entries in the directory tree
- * beginning at the specified path.
- *
- * <p>
- * Note: Jar and zip files are not required to include directory entries.
- * URLs to directory entries will not be returned if the bundle contents do
- * not contain directory entries.
- *
- * @param path The path name in which to look. The path is always relative
- * to the root of this bundle wiring and may begin with
- * "/". A path value of "/" indicates the root of
- * this bundle wiring.
- * @param filePattern The file name pattern for selecting entries in the
- * specified path. The pattern is only matched against the last
- * element of the entry path. If the entry is a directory then the
- * trailing "/" is not used for pattern matching. Substring
- * matching is supported, as specified in the Filter specification,
- * using the wildcard character ("*"). If {@code null} is
- * specified, this is equivalent to "*" and matches all
- * files.
- * @param options The options for listing resource names. See
- * {@link #FINDENTRIES_RECURSE}. The method must ignore unrecognized
- * options.
- * @return An unmodifiable list of URL objects for each matching entry, or
- * an empty list if no matching entry could be found, if this bundle
- * wiring is for a fragment revision or if the caller does not have
- * the appropriate {@code AdminPermission[bundle,RESOURCE]} and the
- * Java Runtime Environment supports permissions. The list is
- * ordered such that entries from the {@link #getRevision() bundle
- * revision} are returned first followed by the entries from
- * attached fragment revisions in attachment order. If this bundle
- * wiring is not {@link #isInUse() in use}, {@code null} must be
- * returned.
- * @see Bundle#findEntries(String, String, boolean)
- */
- List<URL> findEntries(String path, String filePattern, int options);
-
- /**
- * The find entries operation must recurse into subdirectories.
- *
- * <p>
- * This bit may be set when calling
- * {@link #findEntries(String, String, int)} to specify the result must
- * include the matching entries from the specified path and its
- * subdirectories. If this bit is not set, then the result must only include
- * matching entries from the specified path.
- *
- * @see #findEntries(String, String, int)
- */
- int FINDENTRIES_RECURSE = 0x00000001;
-
- /**
- * Returns the names of resources visible to this bundle wiring's
- * {@link #getClassLoader() class loader}. The returned names can be used to
- * access the resources via this bundle wiring's class loader.
- *
- * <ul>
- * <li>Only the resource names for resources in bundle wirings will be
- * returned. The names of resources visible to a bundle wiring's parent
- * class loader, such as the bootstrap class loader, must not be included in
- * the result.
- * <li>Only established wires will be examined for resources. This method
- * must not cause new wires for dynamic imports to be established.
- * </ul>
- *
- * @param path The path name in which to look. The path is always relative
- * to the root of this bundle wiring's class loader and may begin
- * with "/". A path value of "/" indicates the
- * root of this bundle wiring's class loader.
- * @param filePattern The file name pattern for selecting resource names in
- * the specified path. The pattern is only matched against the last
- * element of the resource path. If the resource is a directory then
- * the trailing "/" is not used for pattern matching.
- * Substring matching is supported, as specified in the Filter
- * specification, using the wildcard character ("*"). If
- * {@code null} is specified, this is equivalent to "*" and
- * matches all files.
- * @param options The options for listing resource names. See
- * {@link #LISTRESOURCES_LOCAL} and {@link #LISTRESOURCES_RECURSE}.
- * This method must ignore unrecognized options.
- * @return An unmodifiable collection of resource names for each matching
- * resource, or an empty collection if no matching resource could be
- * found, if this bundle wiring is for a fragment revision or if the
- * caller does not have the appropriate
- * {@code AdminPermission[bundle,RESOURCE]} and the Java Runtime
- * Environment supports permissions. The collection is unordered and
- * must contain no duplicate resource names. If this bundle wiring
- * is not {@link #isInUse() in use}, {@code null} must be returned.
- */
- Collection<String> listResources(String path, String filePattern,
- int options);
-
- /**
- * The list resource names operation must recurse into subdirectories.
- *
- * <p>
- * This bit may be set when calling
- * {@link #listResources(String, String, int)} to specify the result must
- * include the names of matching resources from the specified path and its
- * subdirectories. If this bit is not set, then the result must only include
- * names of matching resources from the specified path.
- *
- * @see #listResources(String, String, int)
- */
- int LISTRESOURCES_RECURSE = 0x00000001;
-
- /**
- * The list resource names operation must limit the result to the names of
- * matching resources contained in this bundle wiring's
- * {@link #getRevision() bundle revision} and its attached fragment
- * revisions. The result must not include resource names for resources in
- * {@link BundleRevision#PACKAGE_NAMESPACE package} names which are
- * {@link #getRequiredWires(String) imported} by this wiring.
- *
- * <p>
- * This bit may be set when calling
- * {@link #listResources(String, String, int)} to specify the result must
- * only include the names of matching resources contained in this bundle
- * wiring's bundle revision and its attached fragment revisions. If this bit
- * is not set, then the result must include the names of matching resources
- * reachable from this bundle wiring's class loader which may include the
- * names of matching resources contained in imported packages and required
- * bundles.
- *
- * @see #listResources(String, String, int)
- */
- int LISTRESOURCES_LOCAL = 0x00000002;
-}
diff --git a/framework/src/main/java/org/osgi/framework/wiring/FrameworkWiring.java b/framework/src/main/java/org/osgi/framework/wiring/FrameworkWiring.java
deleted file mode 100644
index 046a6c2..0000000
--- a/framework/src/main/java/org/osgi/framework/wiring/FrameworkWiring.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2001, 2010). All Rights Reserved.
- *
- * Licensed 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.osgi.framework.wiring;
-
-import java.util.Collection;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleReference;
-import org.osgi.framework.FrameworkListener;
-
-/**
- * Query and modify wiring information for the framework. The framework wiring
- * object for the framework can be obtained by calling
- * {@link Bundle#adapt(Class) bundle.adapt(FrameworkWiring.class)} on the system
- * bundle. Only the system bundle can be adapted to a FrameworkWiring object.
- *
- * <p>
- * The system bundle associated with this FrameworkWiring object can be obtained
- * by calling {@link BundleReference#getBundle()}.
- *
- * @ThreadSafe
- * @noimplement
- * @version $Id: f9f3f89b5b8d369453d645a52a482a385a2bd520 $
- */
-public interface FrameworkWiring extends BundleReference {
- /**
- * Refreshes the specified bundles. This forces the update (replacement) or
- * removal of packages exported by the specified bundles.
- *
- * <p>
- * The technique by which the framework refreshes bundles may vary among
- * different framework implementations. A permissible implementation is to
- * stop and restart the framework.
- *
- * <p>
- * This method returns to the caller immediately and then performs the
- * following steps on a separate thread:
- *
- * <ol>
- * <li>Compute the {@link #getDependencyClosure(Collection) dependency
- * closure} of the specified bundles. If no bundles are specified, compute
- * the dependency closure of the {@link #getRemovalPendingBundles() removal
- * pending} bundles.
- *
- * <li>Each bundle in the dependency closure that is in the {@code ACTIVE}
- * state will be stopped as described in the {@code Bundle.stop} method.
- *
- * <li>Each bundle in the dependency closure that is in the {@code RESOLVED}
- * state is unresolved and thus moved to the {@code INSTALLED} state. The
- * effect of this step is that bundles in the dependency closure are no
- * longer {@code RESOLVED}.
- *
- * <li>Each bundle in the dependency closure that is in the
- * {@code UNINSTALLED} state is removed from the dependency closure and is
- * now completely removed from the Framework.
- *
- * <li>Each bundle in the dependency closure that was in the {@code ACTIVE}
- * state prior to Step 2 is started as described in the {@code Bundle.start}
- * method, causing all bundles required for the restart to be resolved. It
- * is possible that, as a result of the previous steps, packages that were
- * previously exported no longer are. Therefore, some bundles may be
- * unresolvable until bundles satisfying the dependencies have been
- * installed in the Framework.
- * </ol>
- *
- * <p>
- * For any exceptions that are thrown during any of these steps, a framework
- * event of type {@code FrameworkEvent.ERROR} is fired containing the
- * exception. The source bundle for these events should be the specific
- * bundle to which the exception is related. If no specific bundle can be
- * associated with the exception then the System Bundle must be used as the
- * source bundle for the event. All framework events fired by this method
- * are also delivered to the specified {@code FrameworkListener}s in the
- * order they are specified.
- *
- * <p>
- * When this process completes after the bundles are refreshed, the
- * Framework will fire a Framework event of type
- * {@code FrameworkEvent.PACKAGES_REFRESHED} to announce it has completed
- * the bundle refresh. The specified {@code FrameworkListener}s are notified
- * in the order specified. Each specified {@code FrameworkListener} will be
- * called with a Framework event of type
- * {@code FrameworkEvent.PACKAGES_REFRESHED}.
- *
- * @param bundles The bundles to be refreshed, or {@code null} to refresh
- * the {@link #getRemovalPendingBundles() removal pending} bundles.
- * @param listeners Zero or more listeners to be notified when the bundle
- * refresh has been completed. The specified listeners do not need to
- * be otherwise registered with the framework. If a specified
- * listener is already registered with the framework, it will be
- * notified twice.
- * @throws IllegalArgumentException If the specified {@code Bundle}s were
- * not created by the same framework instance associated with this
- * FrameworkWiring.
- * @throws SecurityException If the caller does not have
- * {@code AdminPermission[System Bundle,RESOLVE]} and the Java
- * runtime environment supports permissions.
- */
- void refreshBundles(Collection<Bundle> bundles,
- FrameworkListener... listeners);
-
- /**
- * Resolves the specified bundles. The Framework must attempt to resolve the
- * specified bundles that are unresolved. Additional bundles that are not
- * included in the specified bundles may be resolved as a result of calling
- * this method. A permissible implementation of this method is to attempt to
- * resolve all unresolved bundles installed in the framework.
- *
- * <p>
- * If no bundles are specified, then the Framework will attempt to resolve
- * all unresolved bundles. This method must not cause any bundle to be
- * refreshed, stopped, or started. This method will not return until the
- * operation has completed.
- *
- * @param bundles The bundles to resolve or {@code null} to resolve all
- * unresolved bundles installed in the Framework.
- * @return {@code true} if all specified bundles are resolved; {@code false}
- * otherwise.
- * @throws IllegalArgumentException If the specified {@code Bundle}s were
- * not created by the same framework instance associated with this
- * FrameworkWiring.
- * @throws SecurityException If the caller does not have
- * {@code AdminPermission[System Bundle,RESOLVE]} and the Java
- * runtime environment supports permissions.
- */
- boolean resolveBundles(Collection<Bundle> bundles);
-
- /**
- * Returns the bundles that have {@link BundleWiring#isCurrent()
- * non-current}, {@link BundleWiring#isInUse() in use} bundle wirings. This
- * is typically the bundles which have been updated or uninstalled since the
- * last call to {@link #refreshBundles(Collection, FrameworkListener...)}.
- *
- * @return A collection containing a snapshot of the {@code Bundle}s which
- * have non-current, in use {@code BundleWiring}s, or an empty
- * collection if there are no such bundles.
- */
- Collection<Bundle> getRemovalPendingBundles();
-
- /**
- * Returns the dependency closure for the specified bundles.
- *
- * <p>
- * A graph of bundles is computed starting with the specified bundles. The
- * graph is expanded by adding any bundle that is either wired to a package
- * that is currently exported by a bundle in the graph or requires a bundle
- * in the graph. The graph is fully constructed when there is no bundle
- * outside the graph that is wired to a bundle in the graph. The graph may
- * contain {@code UNINSTALLED} bundles that are
- * {@link #getRemovalPendingBundles() removal pending}.
- *
- * @param bundles The initial bundles for which to generate the dependency
- * closure.
- * @return A collection containing a snapshot of the dependency closure of
- * the specified bundles, or an empty collection if there were no
- * specified bundles.
- * @throws IllegalArgumentException If the specified {@code Bundle}s were
- * not created by the same framework instance associated with this
- * FrameworkWiring.
- */
- Collection<Bundle> getDependencyClosure(Collection<Bundle> bundles);
-}