You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2010/03/03 16:04:42 UTC
svn commit: r918500 [2/4] - in
/felix/trunk/framework/src/main/java/org/apache/felix: framework/
framework/capabilityset/ framework/resolver/ framework/searchpolicy/
moduleloader/
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java?rev=918500&r1=918499&r2=918500&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java Wed Mar 3 15:04:41 2010
@@ -18,8 +18,9 @@
*/
package org.apache.felix.framework;
-import org.apache.felix.framework.searchpolicy.*;
-import org.apache.felix.moduleloader.*;
+import org.apache.felix.framework.resolver.ResourceNotFoundException;
+import org.apache.felix.framework.resolver.Content;
+import org.apache.felix.framework.capabilityset.SimpleFilter;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
@@ -31,7 +32,7 @@
import java.security.ProtectionDomain;
import java.security.SecureClassLoader;
import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
@@ -42,29 +43,37 @@
import java.util.Vector;
import org.apache.felix.framework.Felix.FelixResolver;
import org.apache.felix.framework.cache.JarContent;
+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.capabilityset.Requirement;
+import org.apache.felix.framework.resolver.Wire;
+import org.apache.felix.framework.resolver.ResolveException;
+import org.apache.felix.framework.resolver.WireImpl;
+import org.apache.felix.framework.resolver.WireModuleImpl;
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.Capability;
+import org.apache.felix.framework.util.manifestparser.CapabilityImpl;
import org.apache.felix.framework.util.manifestparser.ManifestParser;
import org.apache.felix.framework.util.manifestparser.R4Library;
-import org.apache.felix.framework.util.manifestparser.Requirement;
+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.InvalidSyntaxException;
import org.osgi.framework.Version;
-public class ModuleImpl implements IModule
+public class ModuleImpl implements Module
{
private final Logger m_logger;
private final Map m_configMap;
private final FelixResolver m_resolver;
private final String m_id;
- private final IContent m_content;
+ private final Content m_content;
private final Map m_headerMap;
private final URLStreamHandler m_streamHandler;
@@ -73,28 +82,28 @@
private final String m_symbolicName;
private final Version m_version;
- private final ICapability[] m_capabilities;
- private ICapability[] m_cachedCapabilities = null;
- private final IRequirement[] m_requirements;
- private IRequirement[] m_cachedRequirements = null;
- private final IRequirement[] m_dynamicRequirements;
- private IRequirement[] m_cachedDynamicRequirements = null;
- private final R4Library[] m_nativeLibraries;
+ 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 String[] m_activationIncludes;
- private final String[] m_activationExcludes;
+ private final List<String> m_activationIncludes;
+ private final List<String> m_activationExcludes;
private final Bundle m_bundle;
- private IModule[] m_fragments = null;
- private IWire[] m_wires = null;
- private IModule[] m_dependentHosts = new IModule[0];
- private IModule[] m_dependentImporters = new IModule[0];
- private IModule[] m_dependentRequirers = new IModule[0];
+ private List<Module> m_fragments = null;
+ private List<Wire> m_wires = null;
+ private List<Module> m_dependentHosts = new ArrayList<Module>(0);
+ 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 IContent[] m_contentPath;
- private IContent[] m_fragmentContents = null;
+ private Content[] m_contentPath;
+ private Content[] m_fragmentContents = null;
private ModuleClassLoader m_classLoader;
private boolean m_isActivationTriggered = false;
private ProtectionDomain m_protectionDomain = null;
@@ -184,7 +193,7 @@
public ModuleImpl(
Logger logger, Map configMap, FelixResolver resolver,
- Bundle bundle, String id, Map headerMap, IContent content,
+ Bundle bundle, String id, Map headerMap, Content content,
URLStreamHandler streamHandler, String[] bootPkgs,
boolean[] bootPkgWildcards)
throws BundleException
@@ -269,163 +278,110 @@
return m_version;
}
- public synchronized ICapability[] getCapabilities()
+ public synchronized List<Capability> getCapabilities()
{
if (m_cachedCapabilities == null)
{
List capList = (m_capabilities == null)
- ? new ArrayList() : new ArrayList(Arrays.asList(m_capabilities));
+ ? new ArrayList<Capability>()
+ : new ArrayList<Capability>(m_capabilities);
for (int fragIdx = 0;
- (m_fragments != null) && (fragIdx < m_fragments.length);
+ (m_fragments != null) && (fragIdx < m_fragments.size());
fragIdx++)
{
- ICapability[] caps = m_fragments[fragIdx].getCapabilities();
+ List<Capability> caps = m_fragments.get(fragIdx).getCapabilities();
for (int capIdx = 0;
- (caps != null) && (capIdx < caps.length);
+ (caps != null) && (capIdx < caps.size());
capIdx++)
{
- if (caps[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+ if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
capList.add(
- new Capability(
+ new CapabilityImpl(
this,
- caps[capIdx].getNamespace(),
- ((Capability) caps[capIdx]).getDirectives(),
- ((Capability) caps[capIdx]).getAttributes()));
+ caps.get(capIdx).getNamespace(),
+ caps.get(capIdx).getDirectives(),
+ caps.get(capIdx).getAttributes()));
}
}
}
- m_cachedCapabilities = (ICapability[])
- capList.toArray(new ICapability[capList.size()]);
+ m_cachedCapabilities = Collections.unmodifiableList(capList);
}
return m_cachedCapabilities;
}
- public synchronized IRequirement[] getRequirements()
+ public synchronized List<Requirement> getRequirements()
{
if (m_cachedRequirements == null)
{
- List allReqs = new ArrayList();
- Map pkgMap = new HashMap();
- Map rbMap = new HashMap();
- for (int i = 0; (m_requirements != null) && i < m_requirements.length; i++)
- {
- if (m_requirements[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
- {
- pkgMap.put(
- ((Requirement) m_requirements[i]).getTargetName(),
- m_requirements[i]);
- }
- else if (m_requirements[i].getNamespace().equals(ICapability.MODULE_NAMESPACE))
- {
- rbMap.put(
- ((Requirement) m_requirements[i]).getTargetName(),
- m_requirements[i]);
- }
- else
- {
- allReqs.add(m_requirements[i]);
- }
- }
-
- // Aggregate host and fragment bundle and package requirements.
+ List<Requirement> reqList = (m_requirements == null)
+ ? new ArrayList() : new ArrayList(m_requirements);
for (int fragIdx = 0;
- (m_fragments != null) && (fragIdx < m_fragments.length);
+ (m_fragments != null) && (fragIdx < m_fragments.size());
fragIdx++)
{
- IRequirement[] reqs = m_fragments[fragIdx].getRequirements();
+ List<Requirement> reqs = m_fragments.get(fragIdx).getRequirements();
for (int reqIdx = 0;
- (reqs != null) && (reqIdx < reqs.length);
+ (reqs != null) && (reqIdx < reqs.size());
reqIdx++)
{
- if (reqs[reqIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
- {
- // If the current fragment requirement overlaps a previously
- // added requirement, then calculate a new intersecting requirement.
- Requirement req = (Requirement) pkgMap.get(
- ((Requirement) reqs[reqIdx]).getTargetName());
- if (req != null)
- {
- req = FelixResolverState.calculateVersionIntersection(
- req, (Requirement) reqs[reqIdx]);
- }
- else
- {
- req = (Requirement) reqs[reqIdx];
- }
- pkgMap.put(req.getTargetName(), req);
- }
- else if (reqs[reqIdx].getNamespace().equals(ICapability.MODULE_NAMESPACE))
+ if (reqs.get(reqIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+ || reqs.get(reqIdx).getNamespace().equals(Capability.MODULE_NAMESPACE))
{
- // If the current fragment requirement overlaps a previously
- // added requirement, then calculate a new intersecting requirement.
- Requirement req = (Requirement) pkgMap.get(
- ((Requirement) reqs[reqIdx]).getTargetName());
- if (req != null)
- {
- req = FelixResolverState.calculateVersionIntersection(
- req, (Requirement) reqs[reqIdx]);
- }
- else
- {
- req = (Requirement) reqs[reqIdx];
- }
- rbMap.put(req.getTargetName(), req);
+ reqList.add(
+ new FragmentRequirement(
+ reqs.get(reqIdx), m_fragments.get(fragIdx)));
}
}
}
- allReqs.addAll(pkgMap.values());
- allReqs.addAll(rbMap.values());
- m_cachedRequirements = (IRequirement[])
- allReqs.toArray(new IRequirement[allReqs.size()]);
+ m_cachedRequirements = Collections.unmodifiableList(reqList);
}
return m_cachedRequirements;
}
- public synchronized IRequirement[] getDynamicRequirements()
+ public synchronized List<Requirement> getDynamicRequirements()
{
if (m_cachedDynamicRequirements == null)
{
- List reqList = (m_dynamicRequirements == null)
- ? new ArrayList() : new ArrayList(Arrays.asList(m_dynamicRequirements));
+ List<Requirement> reqList = (m_dynamicRequirements == null)
+ ? new ArrayList() : new ArrayList(m_dynamicRequirements);
for (int fragIdx = 0;
- (m_fragments != null) && (fragIdx < m_fragments.length);
+ (m_fragments != null) && (fragIdx < m_fragments.size());
fragIdx++)
{
- IRequirement[] reqs = m_fragments[fragIdx].getDynamicRequirements();
+ List<Requirement> reqs = m_fragments.get(fragIdx).getDynamicRequirements();
for (int reqIdx = 0;
- (reqs != null) && (reqIdx < reqs.length);
+ (reqs != null) && (reqIdx < reqs.size());
reqIdx++)
{
- if (reqs[reqIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+ if (reqs.get(reqIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
- reqList.add(reqs[reqIdx]);
+ reqList.add(reqs.get(reqIdx));
}
}
}
- m_cachedDynamicRequirements = (IRequirement[])
- reqList.toArray(new IRequirement[reqList.size()]);
+ m_cachedDynamicRequirements = Collections.unmodifiableList(reqList);
}
return m_cachedDynamicRequirements;
}
- public synchronized R4Library[] getNativeLibraries()
+ public synchronized List<R4Library> getNativeLibraries()
{
- R4Library[] result = null;
+ List<R4Library> result = null;
if (m_isResolved)
{
- List nativeList = (m_nativeLibraries == null)
- ? new ArrayList() : new ArrayList(Arrays.asList(m_nativeLibraries));
+ List<R4Library> nativeList = (m_nativeLibraries == null)
+ ? new ArrayList() : new ArrayList(m_nativeLibraries);
for (int fragIdx = 0;
- (m_fragments != null) && (fragIdx < m_fragments.length);
+ (m_fragments != null) && (fragIdx < m_fragments.size());
fragIdx++)
{
- R4Library[] libs = m_fragments[fragIdx].getNativeLibraries();
+ List<R4Library> libs = m_fragments.get(fragIdx).getNativeLibraries();
for (int reqIdx = 0;
- (libs != null) && (reqIdx < libs.length);
+ (libs != null) && (reqIdx < libs.size());
reqIdx++)
{
- nativeList.add(libs[reqIdx]);
+ nativeList.add(libs.get(reqIdx));
}
}
@@ -434,7 +390,7 @@
// could not be found when resolving the bundle.
result = (nativeList.size() == 0)
? null
- : (R4Library[]) nativeList.toArray(new R4Library[nativeList.size()]);
+ : Collections.unmodifiableList(nativeList);
}
else
{
@@ -465,20 +421,20 @@
// by default, otherwise try to find one match.
boolean included = (m_activationIncludes == null);
for (int i = 0;
- (!included) && (m_activationIncludes != null) && (i < m_activationIncludes.length);
+ (!included) && (m_activationIncludes != null) && (i < m_activationIncludes.size());
i++)
{
- included = m_activationIncludes[i].equals(pkgName);
+ 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.length);
+ (!excluded) && (m_activationExcludes != null) && (i < m_activationExcludes.size());
i++)
{
- excluded = m_activationExcludes[i].equals(pkgName);
+ excluded = m_activationExcludes.get(i).equals(pkgName);
}
return included && !excluded;
}
@@ -497,40 +453,40 @@
return m_id;
}
- public synchronized IWire[] getWires()
+ public synchronized List<Wire> getWires()
{
return m_wires;
}
- public synchronized void setWires(IWire[] wires)
+ public synchronized void setWires(List<Wire> wires)
{
// 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; (m_wires != null) && (i < m_wires.length); i++)
+ for (int i = 0; (m_wires != null) && (i < m_wires.size()); i++)
{
- if (m_wires[i].getCapability().getNamespace().equals(ICapability.MODULE_NAMESPACE))
+ if (m_wires.get(i).getCapability().getNamespace().equals(Capability.MODULE_NAMESPACE))
{
- ((ModuleImpl) m_wires[i].getExporter()).removeDependentRequirer(this);
+ ((ModuleImpl) m_wires.get(i).getExporter()).removeDependentRequirer(this);
}
- else if (m_wires[i].getCapability().getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+ else if (m_wires.get(i).getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
- ((ModuleImpl) m_wires[i].getExporter()).removeDependentImporter(this);
+ ((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; (m_wires != null) && (i < m_wires.length); i++)
+ for (int i = 0; (m_wires != null) && (i < m_wires.size()); i++)
{
- if (m_wires[i].getCapability().getNamespace().equals(ICapability.MODULE_NAMESPACE))
+ if (m_wires.get(i).getCapability().getNamespace().equals(Capability.MODULE_NAMESPACE))
{
- ((ModuleImpl) m_wires[i].getExporter()).addDependentRequirer(this);
+ ((ModuleImpl) m_wires.get(i).getExporter()).addDependentRequirer(this);
}
- else if (m_wires[i].getCapability().getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+ else if (m_wires.get(i).getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
- ((ModuleImpl) m_wires[i].getExporter()).addDependentImporter(this);
+ ((ModuleImpl) m_wires.get(i).getExporter()).addDependentImporter(this);
}
}
}
@@ -549,12 +505,12 @@
// Content access methods.
//
- public IContent getContent()
+ public Content getContent()
{
return m_content;
}
- private synchronized IContent[] getContentPath()
+ private synchronized Content[] getContentPath()
{
if (m_contentPath == null)
{
@@ -570,19 +526,19 @@
return m_contentPath;
}
- private IContent[] initializeContentPath() throws Exception
+ 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[i], m_fragmentContents[i], contentList, false);
+ calculateContentPath(m_fragments.get(i), m_fragmentContents[i], contentList, false);
}
- return (IContent[]) contentList.toArray(new IContent[contentList.size()]);
+ return (Content[]) contentList.toArray(new Content[contentList.size()]);
}
private List calculateContentPath(
- IModule module, IContent content, List contentList, boolean searchFragments)
+ Module module, Content content, List contentList, boolean searchFragments)
throws Exception
{
// Creating the content path entails examining the bundle's
@@ -596,25 +552,25 @@
// Find class path meta-data.
String classPath = (String) module.getHeaders().get(FelixConstants.BUNDLE_CLASSPATH);
// Parse the class path into strings.
- String[] classPathStrings = ManifestParser.parseDelimitedString(
+ List<String> classPathStrings = ManifestParser.parseDelimitedString(
classPath, FelixConstants.CLASS_PATH_SEPARATOR);
if (classPathStrings == null)
{
- classPathStrings = new String[0];
+ classPathStrings = new ArrayList<String>(0);
}
// Create the bundles class path.
- for (int i = 0; i < classPathStrings.length; i++)
+ 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[i] = (classPathStrings[i].startsWith("/"))
- ? classPathStrings[i].substring(1)
- : classPathStrings[i];
+ 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[i].equals(FelixConstants.CLASS_PATH_DOT))
+ if (classPathStrings.get(i).equals(FelixConstants.CLASS_PATH_DOT))
{
localContentList.add(content);
}
@@ -622,7 +578,7 @@
{
// Try to find the embedded class path entry in the current
// content.
- IContent embeddedContent = content.getEntryAsContent(classPathStrings[i]);
+ 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.
@@ -631,7 +587,8 @@
&& (m_fragmentContents != null) && (fragIdx < m_fragmentContents.length);
fragIdx++)
{
- embeddedContent = m_fragmentContents[fragIdx].getEntryAsContent(classPathStrings[i]);
+ embeddedContent =
+ m_fragmentContents[fragIdx].getEntryAsContent(classPathStrings.get(i));
}
// If we found the embedded content, then add it to the
// class path content list.
@@ -645,7 +602,7 @@
// need to create an "Eventer" class like "Logger" perhaps.
m_logger.log(Logger.LOG_INFO,
"Class path entry not found: "
- + classPathStrings[i]);
+ + classPathStrings.get(i));
}
}
}
@@ -840,7 +797,7 @@
}
// Check the module class path.
- IContent[] contentPath = getContentPath();
+ Content[] contentPath = getContentPath();
for (int i = 0;
(url == null) &&
(i < contentPath.length); i++)
@@ -936,15 +893,15 @@
// Note that the search may be aborted if this method throws an
// exception, otherwise it continues if a null is returned.
- IWire[] wires = getWires();
- for (int i = 0; (wires != null) && (i < wires.length); i++)
+ List<Wire> wires = getWires();
+ for (int i = 0; (wires != null) && (i < wires.size()); i++)
{
- if (wires[i] instanceof R4Wire)
+ if (wires.get(i) instanceof WireImpl)
{
try
{
// If we find the class or resource, then return it.
- urls = wires[i].getResources(name);
+ urls = wires.get(i).getResources(name);
}
catch (ResourceNotFoundException ex)
{
@@ -962,14 +919,14 @@
// 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.length); i++)
+ for (int i = 0; (wires != null) && (i < wires.size()); i++)
{
- if (wires[i] instanceof R4WireModule)
+ if (wires.get(i) instanceof WireModuleImpl)
{
try
{
// If we find the class or resource, then add it.
- urls = wires[i].getResources(name);
+ urls = wires.get(i).getResources(name);
}
catch (ResourceNotFoundException ex)
{
@@ -996,10 +953,10 @@
// 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.
- IWire wire = null;
+ Wire wire = null;
try
{
- wire = m_resolver.resolveDynamicImport(this, pkgName);
+ wire = m_resolver.resolve(this, pkgName);
}
catch (ResolveException ex)
{
@@ -1033,7 +990,7 @@
// 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 IContent[] contentPath = getContentPath();
+ final Content[] contentPath = getContentPath();
if (name.equals("/"))
{
for (int i = 0; i < contentPath.length; i++)
@@ -1139,8 +1096,8 @@
try
{
- return m_secureAction.createURL(null,
- FelixConstants.BUNDLE_URL_PROTOCOL + "://" +
+ return m_secureAction.createURL(null,
+ FelixConstants.BUNDLE_URL_PROTOCOL + "://" +
m_id + ":" + port + path, m_streamHandler);
}
catch (MalformedURLException ex)
@@ -1157,19 +1114,19 @@
// Fragment and dependency management methods.
//
- public synchronized IModule[] getFragments()
+ public synchronized List<Module> getFragments()
{
return m_fragments;
}
- public synchronized void attachFragments(IModule[] fragments) throws Exception
+ public synchronized void attachFragments(List<Module> fragments) throws Exception
{
// Remove module from old fragment dependencies.
// We will generally only remove module fragment
// dependencies when we are uninstalling the module.
- for (int i = 0; (m_fragments != null) && (i < m_fragments.length); i++)
+ for (int i = 0; (m_fragments != null) && (i < m_fragments.size()); i++)
{
- ((ModuleImpl) m_fragments[i]).removeDependentHost(this);
+ ((ModuleImpl) m_fragments.get(i)).removeDependentHost(this);
}
// Remove cached capabilities and requirements.
@@ -1185,12 +1142,12 @@
// to attach to our content loader.
if (m_fragments != null)
{
- IContent[] fragmentContents = new IContent[m_fragments.length];
- for (int i = 0; (m_fragments != null) && (i < m_fragments.length); i++)
+ Content[] fragmentContents = new Content[m_fragments.size()];
+ for (int i = 0; (m_fragments != null) && (i < m_fragments.size()); i++)
{
- ((ModuleImpl) m_fragments[i]).addDependentHost(this);
+ ((ModuleImpl) m_fragments.get(i)).addDependentHost(this);
fragmentContents[i] =
- m_fragments[i].getContent()
+ m_fragments.get(i).getContent()
.getEntryAsContent(FelixConstants.CLASS_PATH_DOT);
}
// Now attach the fragment contents to our content loader.
@@ -1199,7 +1156,7 @@
}
// This must be called holding the object lock.
- private void attachFragmentContents(IContent[] fragmentContents)
+ private void attachFragmentContents(Content[] fragmentContents)
throws Exception
{
// Close existing fragment contents.
@@ -1222,121 +1179,68 @@
m_contentPath = initializeContentPath();
}
- public synchronized IModule[] getDependentHosts()
+ public synchronized List<Module> getDependentHosts()
{
return m_dependentHosts;
}
- public synchronized void addDependentHost(IModule module)
+ public synchronized void addDependentHost(Module module)
{
- m_dependentHosts = addDependent(m_dependentHosts, module);
+ if (!m_dependentHosts.contains(module))
+ {
+ m_dependentHosts.add(module);
+ }
}
- public synchronized void removeDependentHost(IModule module)
+ public synchronized void removeDependentHost(Module module)
{
- m_dependentHosts = removeDependent(m_dependentHosts, module);
+ m_dependentHosts.remove(module);
}
- public synchronized IModule[] getDependentImporters()
+ public synchronized List<Module> getDependentImporters()
{
return m_dependentImporters;
}
- public synchronized void addDependentImporter(IModule module)
+ public synchronized void addDependentImporter(Module module)
{
- m_dependentImporters = addDependent(m_dependentImporters, module);
+ if (!m_dependentImporters.contains(module))
+ {
+ m_dependentImporters.add(module);
+ }
}
- public synchronized void removeDependentImporter(IModule module)
+ public synchronized void removeDependentImporter(Module module)
{
- m_dependentImporters = removeDependent(m_dependentImporters, module);
+ m_dependentImporters.remove(module);
}
- public synchronized IModule[] getDependentRequirers()
+ public synchronized List<Module> getDependentRequirers()
{
return m_dependentRequirers;
}
- public synchronized void addDependentRequirer(IModule module)
+ public synchronized void addDependentRequirer(Module module)
{
- m_dependentRequirers = addDependent(m_dependentRequirers, module);
- }
-
- public synchronized void removeDependentRequirer(IModule module)
- {
- m_dependentRequirers = removeDependent(m_dependentRequirers, module);
- }
-
- public synchronized IModule[] getDependents()
- {
- IModule[] dependents = new IModule[
- m_dependentHosts.length + m_dependentImporters.length + m_dependentRequirers.length];
- System.arraycopy(
- m_dependentHosts,
- 0,
- dependents,
- 0,
- m_dependentHosts.length);
- System.arraycopy(
- m_dependentImporters,
- 0,
- dependents,
- m_dependentHosts.length,
- m_dependentImporters.length);
- System.arraycopy(
- m_dependentRequirers,
- 0,
- dependents,
- m_dependentHosts.length + m_dependentImporters.length,
- m_dependentRequirers.length);
- return dependents;
- }
-
- private static IModule[] addDependent(IModule[] modules, IModule module)
- {
- // Make sure the dependent module is not already present.
- for (int i = 0; i < modules.length; i++)
+ if (!m_dependentRequirers.contains(module))
{
- if (modules[i].equals(module))
- {
- return modules;
- }
+ m_dependentRequirers.add(module);
}
- IModule[] tmp = new IModule[modules.length + 1];
- System.arraycopy(modules, 0, tmp, 0, modules.length);
- tmp[modules.length] = module;
- return tmp;
}
- private static IModule[] removeDependent(IModule[] modules, IModule module)
+ public synchronized void removeDependentRequirer(Module module)
{
- IModule[] tmp = modules;
-
- // Make sure the dependent module is present.
- for (int i = 0; i < modules.length; i++)
- {
- if (modules[i].equals(module))
- {
- // If this is the module, then point to empty list.
- if ((modules.length - 1) == 0)
- {
- tmp = new IModule[0];
- }
- // Otherwise, we need to do some array copying.
- else
- {
- tmp = new IModule[modules.length - 1];
- System.arraycopy(modules, 0, tmp, 0, i);
- if (i < tmp.length)
- {
- System.arraycopy(modules, i + 1, tmp, i, tmp.length - i);
- }
- }
- break;
- }
- }
+ m_dependentRequirers.remove(module);
+ }
- return tmp;
+ public synchronized List<Module> getDependents()
+ {
+ List<Module> dependents = new ArrayList<Module>
+ (m_dependentHosts.size() + m_dependentImporters.size() + m_dependentRequirers.size());
+ dependents.addAll(m_dependentHosts);
+ dependents.addAll(m_dependentImporters);
+ dependents.addAll(m_dependentRequirers);
+ return dependents;
}
public synchronized void close()
@@ -1433,13 +1337,13 @@
throws ClassNotFoundException, ResourceNotFoundException
{
// We delegate to the module's wires to find the class or resource.
- IWire[] wires = getWires();
- for (int i = 0; (wires != null) && (i < wires.length); i++)
+ 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) wires[i].getClass(name)
- : (Object) wires[i].getResource(name);
+ ? (Object) wires.get(i).getClass(name)
+ : (Object) wires.get(i).getResource(name);
if (result != null)
{
return result;
@@ -1456,10 +1360,10 @@
// 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.
- IWire wire = null;
+ Wire wire = null;
try
{
- wire = m_resolver.resolveDynamicImport(this, pkgName);
+ wire = m_resolver.resolve(this, pkgName);
}
catch (ResolveException ex)
{
@@ -1772,8 +1676,8 @@
byte[] bytes = null;
// Check the module class path.
- IContent[] contentPath = getContentPath();
- IContent content = null;
+ Content[] contentPath = getContentPath();
+ Content content = null;
for (int i = 0;
(bytes == null) &&
(i < contentPath.length); i++)
@@ -1799,7 +1703,7 @@
int activationPolicy =
((BundleImpl) getBundle()).isDeclaredActivationPolicyUsed()
? ((BundleImpl) getBundle()).getCurrentModule().getDeclaredActivationPolicy()
- : IModule.EAGER_ACTIVATION;
+ : Module.EAGER_ACTIVATION;
// If the module is using deferred activation, then if
// we load this class from this module we need to activate
@@ -1810,7 +1714,7 @@
? false : isActivationTrigger(pkgName);
if (!m_isActivationTriggered
&& isTriggerClass
- && (activationPolicy == IModule.LAZY_ACTIVATION)
+ && (activationPolicy == Module.LAZY_ACTIVATION)
&& (getBundle().getState() == Bundle.STARTING))
{
List deferredList = (List) m_deferredActivation.get();
@@ -2027,14 +1931,14 @@
// native library.
if (result == null)
{
- R4Library[] libs = getNativeLibraries();
- for (int libIdx = 0; (libs != null) && (libIdx < libs.length); libIdx++)
+ List<R4Library> libs = getNativeLibraries();
+ for (int libIdx = 0; (libs != null) && (libIdx < libs.size()); libIdx++)
{
- if (libs[libIdx].match(m_configMap, name))
+ if (libs.get(libIdx).match(m_configMap, name))
{
// Search bundle content first for native library.
result = getContent().getEntryAsNativeLibrary(
- libs[libIdx].getEntryName());
+ libs.get(libIdx).getEntryName());
// If not found, then search fragments in order.
for (int i = 0;
(result == null) && (m_fragmentContents != null)
@@ -2042,7 +1946,7 @@
i++)
{
result = m_fragmentContents[i].getEntryAsNativeLibrary(
- libs[libIdx].getEntryName());
+ libs.get(libIdx).getEntryName());
}
}
}
@@ -2084,13 +1988,13 @@
String importer = module.getBundle().toString();
// Next, check to see if the module imports the package.
- IWire[] wires = module.getWires();
- for (int i = 0; (wires != null) && (i < wires.length); i++)
+ List<Wire> wires = module.getWires();
+ for (int i = 0; (wires != null) && (i < wires.size()); i++)
{
- if (wires[i].getCapability().getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
- wires[i].getCapability().getProperties().get(ICapability.PACKAGE_PROPERTY).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[i].getExporter().getBundle().toString();
+ String exporter = wires.get(i).getExporter().getBundle().toString();
StringBuffer sb = new StringBuffer("*** Package '");
sb.append(pkgName);
@@ -2114,7 +2018,7 @@
// Next, check to see if the package was optionally imported and
// whether or not there is an exporter available.
- IRequirement[] reqs = module.getRequirements();
+ List<Requirement> reqs = module.getRequirements();
/*
* TODO: RB - Fix diagnostic message for optional imports.
for (int i = 0; (reqs != null) && (i < reqs.length); i++)
@@ -2174,7 +2078,9 @@
}
*/
// Next, check to see if the package is dynamically imported by the module.
- IRequirement pkgReq = Resolver.findAllowedDynamicImport(module, pkgName);
+// TODO: FELIX3 - Add Resolver.findAllowedDynamicImport().
+/*
+ Requirement pkgReq = Resolver.findAllowedDynamicImport(module, pkgName);
if (pkgReq != null)
{
// Try to see if there is an exporter available.
@@ -2228,22 +2134,14 @@
return sb.toString();
}
-
+*/
// Next, check to see if there are any exporters for the package at all.
- pkgReq = null;
- try
- {
- pkgReq = new Requirement(ICapability.PACKAGE_NAMESPACE, "(package=" + pkgName + ")");
- }
- catch (InvalidSyntaxException ex)
- {
- // This should never happen.
- }
- List exports =
- resolver.getResolvedCandidates(pkgReq, module);
- exports = (exports.size() == 0)
- ? resolver.getUnresolvedCandidates(pkgReq, module)
- : exports;
+ Requirement pkgReq = null;
+ List<Attribute> attrs = new ArrayList(1);
+ attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
+ pkgReq = new RequirementImpl(
+ Capability.PACKAGE_NAMESPACE, new ArrayList<Directive>(0), attrs);
+ Set<Capability> exports = resolver.getCandidates(module, pkgReq, false);
if (exports.size() > 0)
{
boolean classpath = false;
@@ -2261,7 +2159,7 @@
// Ignore
}
- String exporter = ((ICapability) exports.get(0)).getModule().getBundle().toString();
+ String exporter = exports.iterator().next().getModule().getBundle().toString();
StringBuffer sb = new StringBuffer("*** Class '");
sb.append(name);
@@ -2345,4 +2243,46 @@
return sb.toString();
}
-}
+
+ static class FragmentRequirement implements Requirement
+ {
+ private final Requirement m_req;
+ private final Module m_fragment;
+
+ public FragmentRequirement(Requirement req, Module fragment)
+ {
+ m_req = req;
+ m_fragment = fragment;
+ }
+
+ public Module getFragment()
+ {
+ return m_fragment;
+ }
+
+ public String getNamespace()
+ {
+ return m_req.getNamespace();
+ }
+
+ public SimpleFilter getFilter()
+ {
+ return m_req.getFilter();
+ }
+
+ public boolean isOptional()
+ {
+ return m_req.isOptional();
+ }
+
+ public Directive getDirective(String name)
+ {
+ return m_req.getDirective(name);
+ }
+
+ public List<Directive> getDirectives()
+ {
+ return m_req.getDirectives();
+ }
+ }
+}
\ No newline at end of file
Added: felix/trunk/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java?rev=918500&view=auto
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java (added)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java Wed Mar 3 15:04:41 2010
@@ -0,0 +1,499 @@
+/*
+ * 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.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+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.Set;
+
+public class CapabilitySet
+{
+ private final Map<String, Map<Object, Set<Capability>>> m_indices =
+ new HashMap<String, Map<Object, Set<Capability>>>();
+ private final Set<Capability> m_capList = new HashSet<Capability>();
+
+ public CapabilitySet(List<String> indexProps)
+ {
+ for (int i = 0; (indexProps != null) && (i < indexProps.size()); i++)
+ {
+ m_indices.put(indexProps.get(i), new HashMap<Object, Set<Capability>>());
+ }
+ }
+
+ public void addCapability(Capability cap)
+ {
+ m_capList.add(cap);
+
+ // Index capability.
+ for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
+ {
+ Attribute capAttr = cap.getAttribute(entry.getKey());
+ if (capAttr != null)
+ {
+ Object capValue = capAttr.getValue();
+ if (capValue.getClass().isArray())
+ {
+ capValue = convertArrayToList(capValue);
+ }
+
+ Map<Object, Set<Capability>> index = entry.getValue();
+
+ if (capValue instanceof Collection)
+ {
+ Collection c = (Collection) capValue;
+ for (Object o : c)
+ {
+ indexCapability(index, cap, o);
+ }
+ }
+ else
+ {
+ indexCapability(index, cap, capValue);
+ }
+ }
+ }
+
+// System.out.println("+++ INDICES " + m_indices);
+ }
+
+ private void indexCapability(
+ Map<Object, Set<Capability>> index, Capability cap, Object capValue)
+ {
+ Set<Capability> caps = index.get(capValue);
+ if (caps == null)
+ {
+ caps = new HashSet<Capability>();
+ index.put(capValue, caps);
+ }
+ caps.add(cap);
+ }
+
+ public void removeCapability(Capability cap)
+ {
+ if (m_capList.remove(cap))
+ {
+ for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
+ {
+ Attribute capAttr = cap.getAttribute(entry.getKey());
+ if (capAttr != null)
+ {
+ Object capValue = capAttr.getValue();
+ if (capValue.getClass().isArray())
+ {
+ capValue = convertArrayToList(capValue);
+ }
+
+ Map<Object, Set<Capability>> index = entry.getValue();
+
+ if (capValue instanceof Collection)
+ {
+ Collection c = (Collection) capValue;
+ for (Object o : c)
+ {
+ deindexCapability(index, cap, o);
+ }
+ }
+ else
+ {
+ deindexCapability(index, cap, capValue);
+ }
+ }
+ }
+
+// System.out.println("+++ INDICES " + m_indices);
+ }
+ }
+
+ private void deindexCapability(
+ Map<Object, Set<Capability>> index, Capability cap, Object capValue)
+ {
+ Set<Capability> caps = index.get(capValue);
+ caps.remove(cap);
+ if (caps.size() == 0)
+ {
+ index.remove(capValue);
+ }
+ }
+
+ public Set<Capability> match(SimpleFilter sf, boolean obeyMandatory)
+ {
+ Set<Capability> matches = match(m_capList, sf);
+ return (obeyMandatory)
+ ? matchMandatory(matches, sf)
+ : matches;
+ }
+
+ private Set<Capability> match(Set<Capability> caps, SimpleFilter sf)
+ {
+//System.out.println("+++ SF " + sf);
+ Set<Capability> matches = new HashSet<Capability>();
+
+ if (sf.getOperation() == SimpleFilter.AND)
+ {
+ // Evaluate each subfilter against the remaining capabilities.
+ // For AND we calculate the intersection of each subfilter.
+ // We can short-circuit the AND operation if there are no
+ // remaining capabilities.
+ List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+ for (int i = 0; (caps.size() > 0) && (i < sfs.size()); i++)
+ {
+//System.out.println("+++ REMAINING " + caps);
+ matches = match(caps, sfs.get(i));
+//System.out.println("+++ CURRENT " + matches);
+ caps = matches;
+ }
+ }
+ else if (sf.getOperation() == SimpleFilter.OR)
+ {
+ // Evaluate each subfilter against the remaining capabilities.
+ // For OR we calculate the union of each subfilter.
+ List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+ for (int i = 0; i < sfs.size(); i++)
+ {
+ matches.addAll(match(caps, sfs.get(i)));
+ }
+ }
+ else if (sf.getOperation() == SimpleFilter.NOT)
+ {
+ // Evaluate each subfilter against the remaining capabilities.
+ // For OR we calculate the union of each subfilter.
+ matches.addAll(caps);
+ List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+ for (int i = 0; i < sfs.size(); i++)
+ {
+ matches.removeAll(match(caps, sfs.get(i)));
+ }
+ }
+ else
+ {
+ Map<Object, Set<Capability>> index = m_indices.get(sf.getName());
+ if ((sf.getOperation() == SimpleFilter.EQ) && (index != null))
+ {
+ Set<Capability> existingCaps = index.get(sf.getValue());
+ if (existingCaps != null)
+ {
+ matches.addAll(existingCaps);
+//System.out.println("NARROWED " + caps.size() + " TO " + existingCaps.size());
+ matches.retainAll(caps);
+ }
+ }
+ else
+ {
+// System.out.println("+++ SEARCHING " + caps.size() + " CAPABILITIES");
+ for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
+ {
+ 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);
+ }
+ }
+ }
+ }
+ }
+
+ return matches;
+ }
+
+ public static boolean matches(Capability cap, SimpleFilter sf)
+ {
+ return matchesInternal(cap, sf) && matchMandatory(cap, sf);
+ }
+
+ private static boolean matchesInternal(Capability cap, SimpleFilter sf)
+ {
+ boolean matched = true;
+
+ if (sf.getOperation() == SimpleFilter.AND)
+ {
+ // Evaluate each subfilter against the remaining capabilities.
+ // For AND we calculate the intersection of each subfilter.
+ // We can short-circuit the AND operation if there are no
+ // remaining capabilities.
+ List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+ for (int i = 0; matched && (i < sfs.size()); i++)
+ {
+ matched = matchesInternal(cap, sfs.get(i));
+ }
+ }
+ else if (sf.getOperation() == SimpleFilter.OR)
+ {
+ // Evaluate each subfilter against the remaining capabilities.
+ // For OR we calculate the union of each subfilter.
+ matched = false;
+ List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+ for (int i = 0; !matched && (i < sfs.size()); i++)
+ {
+ matched = matchesInternal(cap, sfs.get(i));
+ }
+ }
+ else if (sf.getOperation() == SimpleFilter.NOT)
+ {
+ // Evaluate each subfilter against the remaining capabilities.
+ // For OR we calculate the union of each subfilter.
+ List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+ for (int i = 0; i < sfs.size(); i++)
+ {
+ matched = !(matchesInternal(cap, sfs.get(i)));
+ }
+ }
+ else
+ {
+ matched = false;
+ Attribute attr = cap.getAttribute(sf.getName());
+ if (attr != null)
+ {
+ Object lhs = attr.getValue();
+ matched = compare(lhs, sf.getValue(), sf.getOperation());
+ }
+ }
+
+ return matched;
+ }
+
+ private static Set<Capability> matchMandatory(Set<Capability> caps, SimpleFilter sf)
+ {
+ for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
+ {
+ Capability cap = it.next();
+ if (!matchMandatory(cap, sf))
+ {
+ it.remove();
+ }
+ }
+ return caps;
+ }
+
+ private static boolean matchMandatory(Capability cap, SimpleFilter sf)
+ {
+ List<Attribute> attrs = cap.getAttributes();
+ for (int attrIdx = 0; attrIdx < attrs.size(); attrIdx++)
+ {
+ if (attrs.get(attrIdx).isMandatory()
+ && !matchMandatory(attrs.get(attrIdx), sf))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static boolean matchMandatory(Attribute attr, SimpleFilter sf)
+ {
+ if ((sf.getName() != null) && sf.getName().equals(attr.getName()))
+ {
+ return true;
+ }
+ else if (sf.getOperation() == SimpleFilter.AND)
+ {
+ List list = (List) sf.getValue();
+ for (int i = 0; i < list.size(); i++)
+ {
+ SimpleFilter sf2 = (SimpleFilter) list.get(i);
+ if ((sf2.getName() != null)
+ && sf2.getName().equals(attr.getName()))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static final Class[] STRING_CLASS = new Class[] { String.class };
+
+ private static boolean compare(Object lhs, Object rhsUnknown, int op)
+ {
+ // If the type is comparable, then we can just return the
+ // result immediately.
+ if (lhs instanceof Comparable)
+ {
+ // The substring operator only works on string values, so if the
+ // lhs is not a string, then do an equality comparison using the
+ // original string containing wildcards.
+ if ((op == SimpleFilter.SUBSTRING) && !(lhs instanceof String))
+ {
+ op = SimpleFilter.EQ;
+ rhsUnknown = SimpleFilter.unparseSubstring((List<String>) rhsUnknown);
+ }
+
+ Object rhs;
+ if (op == SimpleFilter.SUBSTRING)
+ {
+ rhs = rhsUnknown;
+ }
+ else
+ {
+ try
+ {
+ rhs = coerceType(lhs, (String) rhsUnknown);
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ }
+
+ switch (op)
+ {
+ case SimpleFilter.EQ :
+ return (((Comparable) lhs).compareTo(rhs) == 0);
+ case SimpleFilter.GTE :
+ return (((Comparable) lhs).compareTo(rhs) >= 0);
+ case SimpleFilter.LTE :
+ return (((Comparable) lhs).compareTo(rhs) <= 0);
+// case SimpleFilter.APPROX :
+// return compareToApprox(((Comparable) lhs), rhs);
+ case SimpleFilter.SUBSTRING :
+ return SimpleFilter.compareSubstring((String) lhs, (List<String>) rhs);
+ default:
+ throw new RuntimeException(
+ "Unknown comparison operator: " + op);
+ }
+ }
+ // Booleans do not implement comparable, so special case them.
+ else if (lhs instanceof Boolean)
+ {
+ Object rhs;
+ try
+ {
+ rhs = coerceType(lhs, (String) rhsUnknown);
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+
+ switch (op)
+ {
+ case SimpleFilter.EQ :
+ case SimpleFilter.GTE :
+ case SimpleFilter.LTE :
+// case SimpleFilter.APPROX:
+ return (lhs.equals(rhs));
+ default:
+ throw new RuntimeException(
+ "Unknown comparison operator: " + op);
+ }
+ }
+
+ // If the LHS is not a comparable or boolean, check if it is an
+ // array. If so, convert it to a list so we can treat it as a
+ // collection.
+ if (lhs.getClass().isArray())
+ {
+ lhs = convertArrayToList(lhs);
+ }
+
+ // If LHS is a collection, then call compare() on each element
+ // of the collection until a match is found.
+ if (lhs instanceof Collection)
+ {
+ for (Iterator iter = ((Collection) lhs).iterator(); iter.hasNext(); )
+ {
+ if (compare(iter.next(), rhsUnknown, op))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ // Since we cannot identify the LHS type, then we can only perform
+ // equality comparison.
+ try
+ {
+ return lhs.equals(coerceType(lhs, (String) rhsUnknown));
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ }
+
+ private static Object coerceType(Object lhs, String rhsString) throws Exception
+ {
+ // If the LHS expects a string, then we can just return
+ // the RHS since it is a string.
+ if (lhs.getClass() == rhsString.getClass())
+ {
+ return rhsString;
+ }
+
+ // Try to convert the RHS type to the LHS type by using
+ // the string constructor of the LHS class, if it has one.
+ Object rhs = null;
+ try
+ {
+ // The Character class is a special case, since its constructor
+ // does not take a string, so handle it separately.
+ if (lhs instanceof Character)
+ {
+ rhs = new Character(rhsString.charAt(0));
+ }
+ else
+ {
+ rhs = lhs.getClass()
+ .getConstructor(STRING_CLASS)
+ .newInstance(new Object[] { rhsString });
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new Exception(
+ "Could not instantiate class "
+ + lhs.getClass().getName()
+ + " from string constructor with argument '"
+ + rhsString + "' because " + ex);
+ }
+
+ return rhs;
+ }
+
+ /**
+ * This is an ugly utility method to convert an array of primitives
+ * to an array of primitive wrapper objects. This method simplifies
+ * processing LDAP filters since the special case of primitive arrays
+ * can be ignored.
+ * @param array An array of primitive types.
+ * @return An corresponding array using pritive wrapper objects.
+ **/
+ private static List convertArrayToList(Object array)
+ {
+ int len = Array.getLength(array);
+ List list = new ArrayList(len);
+ for (int i = 0; i < len; i++)
+ {
+ list.add(Array.get(array, i));
+ }
+ return list;
+ }
+}
\ No newline at end of file
Added: felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java?rev=918500&view=auto
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java (added)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java Wed Mar 3 15:04:41 2010
@@ -0,0 +1,103 @@
+/*
+ * 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.Comparator;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+public class CandidateComparator implements Comparator
+{
+ public int compare(Object arg1, Object arg2)
+ {
+ Capability cap1 = (Capability) arg1;
+ Capability cap2 = (Capability) arg2;
+
+ // 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.getModule().isResolved() && !cap2.getModule().isResolved())
+ {
+ c = -1;
+ }
+ else if (!cap1.getModule().isResolved() && cap2.getModule().isResolved())
+ {
+ c = 1;
+ }
+
+ // Next compare version numbers.
+ if ((c == 0) && cap1.getNamespace().equals(Capability.MODULE_NAMESPACE))
+ {
+ c = ((Comparable) cap1.getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)
+ .getValue()).compareTo(cap2.getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)
+ .getValue());
+ if (c == 0)
+ {
+ Version v1 = (cap1.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE) == null)
+ ? Version.emptyVersion
+ : (Version) cap1.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE).getValue();
+ Version v2 = (cap2.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE) == null)
+ ? Version.emptyVersion
+ : (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);
+ }
+ }
+// TODO: PROTO3 RESOLVER - Need to change this to handle arbitrary capabilities
+// that may not have a natural ordering.
+ // Assume everything else is a package capability.
+ else if (c == 0)
+ {
+ c = ((Comparable) cap1.getAttribute(Capability.PACKAGE_ATTR).getValue())
+ .compareTo(cap2.getAttribute(Capability.PACKAGE_ATTR).getValue());
+ if (c == 0)
+ {
+ Version v1 = (cap1.getAttribute(Capability.VERSION_ATTR) == null)
+ ? Version.emptyVersion
+ : (Version) cap1.getAttribute(Capability.VERSION_ATTR).getValue();
+ Version v2 = (cap2.getAttribute(Capability.VERSION_ATTR) == null)
+ ? Version.emptyVersion
+ : (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 module identity.
+ if (c == 0)
+ {
+ if (cap1.getModule().getBundle().getBundleId() <
+ cap2.getModule().getBundle().getBundleId())
+ {
+ c = -1;
+ }
+ else if (cap1.getModule().getBundle().getBundleId() >
+ cap2.getModule().getBundle().getBundleId())
+ {
+ c = 1;
+ }
+ }
+
+ return c;
+ }
+}
\ No newline at end of file
Copied: felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/Content.java (from r915677, felix/trunk/framework/src/main/java/org/apache/felix/moduleloader/IContent.java)
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/Content.java?p2=felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/Content.java&p1=felix/trunk/framework/src/main/java/org/apache/felix/moduleloader/IContent.java&r1=915677&r2=918500&rev=918500&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/moduleloader/IContent.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/Content.java Wed Mar 3 15:04:41 2010
@@ -16,13 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.felix.moduleloader;
+package org.apache.felix.framework.resolver;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
-public interface IContent
+public interface Content
{
/**
* <p>
@@ -93,7 +93,7 @@
* @return An <tt>IContent</tt> instance if a corresponding entry was found,
* <tt>null</tt> otherwise.
**/
- IContent getEntryAsContent(String name);
+ Content getEntryAsContent(String name);
/**
* <p>
Copied: felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/Module.java (from r915677, felix/trunk/framework/src/main/java/org/apache/felix/moduleloader/IModule.java)
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/Module.java?p2=felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/Module.java&p1=felix/trunk/framework/src/main/java/org/apache/felix/moduleloader/IModule.java&r1=915677&r2=918500&rev=918500&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/moduleloader/IModule.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/Module.java Wed Mar 3 15:04:41 2010
@@ -1,59 +1,62 @@
/*
- * 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.
+ * 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.moduleloader;
+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 IModule
+public interface Module
{
final static int EAGER_ACTIVATION = 0;
final static int LAZY_ACTIVATION = 1;
- void setSecurityContext(Object securityContext);
- Object getSecurityContext();
-
// Metadata access methods.
Map getHeaders();
boolean isExtension();
String getSymbolicName();
Version getVersion();
- ICapability[] getCapabilities();
- IRequirement[] getRequirements();
- IRequirement[] getDynamicRequirements();
- R4Library[] getNativeLibraries();
+ List<Capability> getCapabilities();
+ List<Requirement> getRequirements();
+ List<Requirement> getDynamicRequirements();
+ List<R4Library> getNativeLibraries();
int getDeclaredActivationPolicy();
// Run-time data access methods.
Bundle getBundle();
String getId();
- IWire[] getWires();
+ List<Wire> getWires();
boolean isResolved();
+ // TODO: FELIX3 - Shouldn't have mutable method on Module.
+ void setSecurityContext(Object securityContext);
+ Object getSecurityContext();
// Content access methods.
- IContent getContent();
+ Content getContent();
Class getClassByDelegation(String name) throws ClassNotFoundException;
URL getResourceByDelegation(String name);
Enumeration getResourcesByDelegation(String name);
Copied: felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java (from r915677, felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ResolveException.java)
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java?p2=felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java&p1=felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ResolveException.java&r1=915677&r2=918500&rev=918500&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ResolveException.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java Wed Mar 3 15:04:41 2010
@@ -1,61 +1,47 @@
-/*
- * 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.
+/*
+ * 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.searchpolicy;
+package org.apache.felix.framework.resolver;
-import org.apache.felix.moduleloader.IModule;
-import org.apache.felix.moduleloader.IRequirement;
+import org.apache.felix.framework.capabilityset.Requirement;
-/**
- * <p>
- * This exception is thrown if a module cannot be resolved. The module
- * that failed to be resolved is recorded, along with the failed import target
- * identifier and version number. If the error was a result of a propagation
- * conflict, then the propagation error flag is set.
- * </p>
- * @see org.apache.felix.moduleloader.search.ImportSearchPolicy#validate(org.apache.felix.moduleloader.Module)
-**/
-public class ResolveException extends Exception
+public class ResolveException extends RuntimeException
{
- private IModule m_module = null;
- private IRequirement m_req = null;
+ private final Module m_module;
+ private final Requirement m_req;
/**
- * Constructs an exception with the specified message, module,
- * import identifier, import version number, and propagation flag.
- **/
- public ResolveException(String msg, IModule module, IRequirement req)
+ * Constructs an instance of <code>ResolveException</code> with the specified detail message.
+ * @param msg the detail message.
+ */
+ public ResolveException(String msg, Module module, Requirement req)
{
super(msg);
m_module = module;
m_req = req;
}
- /**
- * Returns the module that was being resolved.
- * @return the module that was being resolved.
- **/
- public IModule getModule()
+ public Module getModule()
{
return m_module;
}
- public IRequirement getRequirement()
+ public Requirement getRequirement()
{
return m_req;
}
Added: felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java?rev=918500&view=auto
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java (added)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java Wed Mar 3 15:04:41 2010
@@ -0,0 +1,36 @@
+/*
+ * 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.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Requirement;
+
+public interface Resolver
+{
+ Map<Module, List<Wire>> resolve(ResolverState state, Module module);
+ Map<Module, List<Wire>> resolve(ResolverState state, Module module, String pkgName);
+
+ public static interface ResolverState
+ {
+ Set<Capability> getCandidates(Module module, Requirement req, boolean obeyMandatory);
+ }
+}
\ No newline at end of file