diff options
author | Thomas Watson | 2016-11-02 20:37:51 +0000 |
---|---|---|
committer | Thomas Watson | 2016-11-02 20:37:51 +0000 |
commit | 8b3d3b6eeaf1c9e70000f8d114432df4abf8ba52 (patch) | |
tree | 4e97504605464dd081644365cf87db3e7f27526d | |
parent | f265b1e3ba40dd733ed8d0bb55d879078c25c629 (diff) | |
download | rt.equinox.framework-8b3d3b6eeaf1c9e70000f8d114432df4abf8ba52.tar.gz rt.equinox.framework-8b3d3b6eeaf1c9e70000f8d114432df4abf8ba52.tar.xz rt.equinox.framework-8b3d3b6eeaf1c9e70000f8d114432df4abf8ba52.zip |
Bug 506939 - Update felix resolver code.
Change-Id: I71b049e22f2aebe2022c7ecdb3c198e9dda0582a
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
13 files changed, 156 insertions, 443 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java index fe24f2384..ef48e85a8 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java @@ -2363,19 +2363,18 @@ public class TestModuleContainer extends AbstractTest { providerManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2"); providerManifest.put(Constants.BUNDLE_SYMBOLICNAME, "provider"); providerManifest.put(Constants.EXPORT_PACKAGE, "provider; version=1.1; attr1=attr1; attr2=attr2; dir1:=dir1; dir2:=dir2"); - providerManifest.put(Constants.PROVIDE_CAPABILITY, - "provider.cap;"// - + " string=sValue;"// - + " string.list1:List=\"v1,v2,v3\";"// - + " string.list2:List<String>=\"v4,v5,v6\";"// - + " version:Version=1.1;"// - + " version.list:List<Version>=\"1.0,2.0,3.0\";"// - + " long:Long=12345;"// - + " long.list:List<Long>=\"1,2,3\";"// - + " double:Double=1.2345;"// - + " double.list:List<Double>=\"1.1,1.2,1.3\";"// - + " uri:uri=some.uri;" // - + " set:set=\"s1,s2,s3\""); + providerManifest.put(Constants.PROVIDE_CAPABILITY, "provider.cap;"// + + " string=sValue;"// + + " string.list1:List=\"v1,v2,v3\";"// + + " string.list2:List<String>=\"v4,v5,v6\";"// + + " version:Version=1.1;"// + + " version.list:List<Version>=\"1.0,2.0,3.0\";"// + + " long:Long=12345;"// + + " long.list:List<Long>=\"1,2,3\";"// + + " double:Double=1.2345;"// + + " double.list:List<Double>=\"1.1,1.2,1.3\";"// + + " uri:uri=some.uri;" // + + " set:set=\"s1,s2,s3\""); Module providerModule = installDummyModule(providerManifest, "provider", container); Map<String, Object> providerAttrs = providerModule.getCurrentRevision().getCapabilities("provider.cap").get(0).getAttributes(); assertEquals("Wrong provider attrs", attrs, providerAttrs); @@ -2384,33 +2383,32 @@ public class TestModuleContainer extends AbstractTest { requirerManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2"); requirerManifest.put(Constants.BUNDLE_SYMBOLICNAME, "requirer"); requirerManifest.put(Constants.IMPORT_PACKAGE, "provider; version=1.1; attr1=attr1; attr2=attr2; dir1:=dir1; dir2:=dir2"); - requirerManifest.put(Constants.REQUIRE_CAPABILITY, - "optional;"// - + " resolution:=optional; " // - + " string=sValue;"// - + " string.list1:List=\"v1,v2,v3\";"// - + " string.list2:List<String>=\"v4,v5,v6\";"// - + " version:Version=1.1;"// - + " version.list:List<Version>=\"1.0,2.0,3.0\";"// - + " long:Long=12345;"// - + " long.list:List<Long>=\"1,2,3\";"// - + " double:Double=1.2345;"// - + " double.list:List<Double>=\"1.1,1.2,1.3\";"// - + " uri:uri=some.uri;" // - + " set:set=\"s1,s2,s3\"," // - + "provider.cap; filter:=\"(string=sValue)\"," // - + "provider.cap; filter:=\"(string.list1=v2)\"," // - + "provider.cap; filter:=\"(string.list2=v5)\"," // - + "provider.cap; filter:=\"(string.list2=v5)\"," // - + "provider.cap; filter:=\"(&(version>=1.1)(version<=1.1.1))\"," // - + "provider.cap; filter:=\"(&(version.list=1)(version.list=2))\"," // - + "provider.cap; filter:=\"(long>=12344)\"," // - + "provider.cap; filter:=\"(long.list=2)\"," // - + "provider.cap; filter:=\"(double>=1.2)\"," // - + "provider.cap; filter:=\"(double.list=1.2)\"," // - + "provider.cap; filter:=\"(uri=some.uri)\"," // - + "provider.cap; filter:=\"(set=s2)\"" // - + ""); + requirerManifest.put(Constants.REQUIRE_CAPABILITY, "optional;"// + + " resolution:=optional; " // + + " string=sValue;"// + + " string.list1:List=\"v1,v2,v3\";"// + + " string.list2:List<String>=\"v4,v5,v6\";"// + + " version:Version=1.1;"// + + " version.list:List<Version>=\"1.0,2.0,3.0\";"// + + " long:Long=12345;"// + + " long.list:List<Long>=\"1,2,3\";"// + + " double:Double=1.2345;"// + + " double.list:List<Double>=\"1.1,1.2,1.3\";"// + + " uri:uri=some.uri;" // + + " set:set=\"s1,s2,s3\"," // + + "provider.cap; filter:=\"(string=sValue)\"," // + + "provider.cap; filter:=\"(string.list1=v2)\"," // + + "provider.cap; filter:=\"(string.list2=v5)\"," // + + "provider.cap; filter:=\"(string.list2=v5)\"," // + + "provider.cap; filter:=\"(&(version>=1.1)(version<=1.1.1))\"," // + + "provider.cap; filter:=\"(&(version.list=1)(version.list=2))\"," // + + "provider.cap; filter:=\"(long>=12344)\"," // + + "provider.cap; filter:=\"(long.list=2)\"," // + + "provider.cap; filter:=\"(double>=1.2)\"," // + + "provider.cap; filter:=\"(double.list=1.2)\"," // + + "provider.cap; filter:=\"(uri=some.uri)\"," // + + "provider.cap; filter:=\"(set=s2)\"" // + + ""); Module requirerModule = installDummyModule(requirerManifest, "requirer", container); Map<String, Object> requirerAttrs = requirerModule.getCurrentRevision().getRequirements("optional").get(0).getAttributes(); assertEquals("Wrong requirer attrs", attrs, requirerAttrs); @@ -2627,6 +2625,47 @@ public class TestModuleContainer extends AbstractTest { } @Test + public void testUnresolvedHostWithFragmentCycle() throws BundleException, IOException { + DummyContainerAdaptor adaptor = createDummyAdaptor(); + ModuleContainer container = adaptor.getContainer(); + + // install a host + Map<String, String> hostManifest = new HashMap<String, String>(); + hostManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2"); + hostManifest.put(Constants.BUNDLE_SYMBOLICNAME, "host"); + hostManifest.put(Constants.BUNDLE_VERSION, "1.0"); + hostManifest.put(Constants.EXPORT_PACKAGE, "host"); + hostManifest.put(Constants.IMPORT_PACKAGE, "host.impl"); + installDummyModule(hostManifest, "host10", container); + hostManifest.put(Constants.BUNDLE_VERSION, "1.1"); + installDummyModule(hostManifest, "host11", container); + hostManifest.put(Constants.BUNDLE_VERSION, "1.2"); + installDummyModule(hostManifest, "host12", container); + //hostManifest.put(Constants.BUNDLE_VERSION, "1.3"); + //installDummyModule(hostManifest, "host13", container); + + // install a host.impl fragment + Map<String, String> hostImplManifest = new HashMap<String, String>(); + hostImplManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2"); + hostImplManifest.put(Constants.BUNDLE_SYMBOLICNAME, "host.impl"); + hostImplManifest.put(Constants.EXPORT_PACKAGE, "host.impl"); + hostImplManifest.put(Constants.IMPORT_PACKAGE, "host"); + hostImplManifest.put(Constants.FRAGMENT_HOST, "host"); + installDummyModule(hostImplManifest, "hostImpl", container); + + // install an importer of host package + Map<String, String> hostImporterManifest = new HashMap<String, String>(); + hostImporterManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2"); + hostImporterManifest.put(Constants.BUNDLE_SYMBOLICNAME, "host.importer"); + hostImporterManifest.put(Constants.IMPORT_PACKAGE, "host"); + Module hostImporter = installDummyModule(hostImporterManifest, "hostImporter", container); + + ResolutionReport report = container.resolve(Arrays.asList(hostImporter), true); + Assert.assertNull("Failed to resolve test.", report.getResolutionException()); + + } + + @Test public void testStartOnResolve() throws BundleException, IOException { doTestStartOnResolve(true); } diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Candidates.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Candidates.java index 8e2b9bb1f..1afed36c3 100755 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Candidates.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Candidates.java @@ -155,7 +155,6 @@ class Candidates return m_delta; } - @SuppressWarnings("ThrowableResultOfMethodCallIgnored") public void populate(Collection<Resource> resources) { ResolveContext rc = m_session.getContext(); @@ -253,19 +252,6 @@ class Candidates return !PackageNamespace.RESOLUTION_DYNAMIC.equals(res); } - private boolean isMandatory(ResolveContext rc, Requirement requirement) { - // The requirement is optional - if (Util.isOptional(requirement)) { - return false; - } - // This is a fragment that is already resolved and there is no unresolved hosts to attach it to - Resource resource = requirement.getResource(); - if (Util.isFragment(resource) && rc.getWirings().containsKey(resource)) { - return false; - } - return true; - } - private void populateSubstitutables() { for (Map.Entry<Resource, PopulateResult> populated : m_populateResultCache.fast()) @@ -280,6 +266,7 @@ class Candidates private void populateSubstitutables(Resource resource) { // Collect the package names exported + @SuppressWarnings("serial") OpenHashMap<String, List<Capability>> exportNames = new OpenHashMap<String, List<Capability>>() { @Override protected List<Capability> compute(String s) { @@ -740,7 +727,7 @@ class Candidates public CandidateSelector clearMultipleCardinalityCandidates(Requirement req, Collection<Capability> caps) { // this is a special case where we need to completely replace the CandidateSelector - // this method should never be called from normal Candidates permutations + // this method should never be called from normal Candidates permutations CandidateSelector candidates = m_candidateMap.get(req); List<Capability> remaining = new ArrayList<Capability>(candidates.getRemainingCandidates()); remaining.removeAll(caps); @@ -939,7 +926,12 @@ class Candidates CandidateSelector cands = m_candidateMap.get(origReq); if (cands != null) { - m_candidateMap.put(r, cands.copy()); + if (cands instanceof ShadowList) + { + m_candidateMap.put(r, ShadowList.deepCopy((ShadowList) cands)); + } else { + m_candidateMap.put(r, cands.copy()); + } for (Capability cand : cands.getRemainingCandidates()) { Set<Requirement> dependents = m_dependentMap.get(cand); diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Logger.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Logger.java index d8c1b3a80..7789ffba1 100755 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Logger.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Logger.java @@ -20,8 +20,6 @@ package org.apache.felix.resolver; import org.osgi.resource.Resource; -import org.osgi.service.resolver.ResolutionException; - /** * <p> * This class mimics the standard OSGi <tt>LogService</tt> interface. An diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java index 1d6f9acd0..13c7ca4f7 100755 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java @@ -375,7 +375,7 @@ public class ResolverImpl implements Resolver return doResolve(session); } - private Map doResolve(ResolveSession session) throws ResolutionException { + private Map<Resource, List<Wire>> doResolve(ResolveSession session) throws ResolutionException { Map<Resource, List<Wire>> wireMap = new HashMap<Resource, List<Wire>>(); boolean retry; @@ -1689,6 +1689,7 @@ public class ResolverImpl implements Resolver List<Capability> caps = (wiring != null) ? wiring.getResourceCapabilities(null) : resource.getCapabilities(null); + @SuppressWarnings("serial") OpenHashMap<String, Set<Capability>> pkgs = new OpenHashMap<String, Set<Capability>>(caps.size()) { public Set<Capability> compute(String pkgName) { return new HashSet<Capability>(); @@ -1967,6 +1968,7 @@ public class ResolverImpl implements Resolver return wireMap; } + @SuppressWarnings("unused") private static void dumpResourcePkgMap( ResolveContext rc, Map<Resource, Packages> resourcePkgMap) { @@ -2025,6 +2027,7 @@ public class ResolverImpl implements Resolver public final OpenHashMap<String, ArrayMap<Capability, UsedBlames>> m_usedPkgs; public final OpenHashMap<Capability, Set<Capability>> m_sources; + @SuppressWarnings("serial") public Packages(Resource resource) { int nbCaps = resource.getCapabilities(null).size(); diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/WrappedCapability.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/WrappedCapability.java index 9bbec36e2..f17969e30 100755 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/WrappedCapability.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/WrappedCapability.java @@ -15,6 +15,8 @@ */ package org.apache.felix.resolver; +import java.util.Collections; +import java.util.HashMap; import java.util.Map; import org.osgi.framework.namespace.PackageNamespace; import org.osgi.resource.Capability; @@ -25,11 +27,25 @@ public class WrappedCapability implements HostedCapability { private final Resource m_host; private final Capability m_cap; + private final Map<String, Object> m_augmentedAttrs; public WrappedCapability(Resource host, Capability cap) { m_host = host; m_cap = cap; + if ("osgi.content".equals(m_cap.getNamespace())) { + // Augment the attributes only for osgi.content namespace. + // This is done to work around issues with wrapper resources equality tests. + // Note this is depends on the implementation details of the ResolveContext to actually + // check the osgi.content capability. + Map<String, Object> augmentedDirs = new HashMap<String, Object>(m_cap.getAttributes()); + Object wrapperUrl = augmentedDirs.get("url"); + wrapperUrl = "wrapper:" + wrapperUrl; + augmentedDirs.put("url", wrapperUrl); + m_augmentedAttrs = Collections.unmodifiableMap(augmentedDirs); + } else { + m_augmentedAttrs = m_cap.getAttributes(); + } } @Override @@ -86,7 +102,7 @@ public class WrappedCapability implements HostedCapability public Map<String, Object> getAttributes() { - return m_cap.getAttributes(); + return m_augmentedAttrs; } // TODO: RFC-112 - Need impl-specific type. diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/WrappedResource.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/WrappedResource.java index f338cac61..c51f74ee2 100755 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/WrappedResource.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/WrappedResource.java @@ -21,7 +21,6 @@ package org.apache.felix.resolver; import java.util.*; import org.osgi.framework.namespace.ExecutionEnvironmentNamespace; import org.osgi.framework.namespace.HostNamespace; -import org.osgi.framework.namespace.IdentityNamespace; import org.osgi.resource.Capability; import org.osgi.resource.Requirement; import org.osgi.resource.Resource; diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/ArrayMap.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/ArrayMap.java index 6ea4cf1fd..c61a194c9 100755 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/ArrayMap.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/ArrayMap.java @@ -20,7 +20,6 @@ package org.apache.felix.resolver.util; import java.util.*; -@SuppressWarnings("NullableProblems") public class ArrayMap<K, V> extends AbstractMap<K, V> { private Object[] table; @@ -133,25 +132,26 @@ public class ArrayMap<K, V> extends AbstractMap<K, V> { @Override public Iterator<Entry<K, V>> iterator() { return new Iterator<Entry<K, V>>() { - FastEntry entry = new FastEntry(); + FastEntry<K, V> entry = new FastEntry<K, V>(); int index = 0; public boolean hasNext() { return index < size; } - public FastEntry next() { + @SuppressWarnings("unchecked") + public FastEntry<K, V> next() { if (index >= size) { throw new NoSuchElementException(); } int i = index << 1; - entry.key = table[i]; - entry.value = table[i + 1]; + entry.key = (K) table[i]; + entry.value = (V) table[i + 1]; index++; return entry; } - - public void remove() { + + public void remove() { throw new UnsupportedOperationException(); } }; diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/CandidateSelector.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/CandidateSelector.java index 0014bf037..de8a5f502 100755 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/CandidateSelector.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/CandidateSelector.java @@ -26,7 +26,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import org.osgi.resource.Capability; public class CandidateSelector { - private final AtomicBoolean isUnmodifiable; + protected final AtomicBoolean isUnmodifiable; protected final List<Capability> unmodifiable; private int currentIndex = 0; diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/CopyOnWriteSet.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/CopyOnWriteSet.java index 92419f3fc..8ae69973e 100755 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/CopyOnWriteSet.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/CopyOnWriteSet.java @@ -19,13 +19,11 @@ package org.apache.felix.resolver.util; import java.lang.reflect.Array; -import java.util.AbstractSet; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.Set; -@SuppressWarnings("NullableProblems") public class CopyOnWriteSet<E> implements Set<E>, Cloneable { Object[] data; @@ -116,6 +114,7 @@ public class CopyOnWriteSet<E> implements Set<E>, Cloneable { return false; } Object[] o1 = data; + @SuppressWarnings("rawtypes") Object[] o2 = ((CopyOnWriteSet) o).data; if (o1 == o2) { return true; diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/OpenHashMap.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/OpenHashMap.java index edd6823d4..b27198c4d 100755 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/OpenHashMap.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/OpenHashMap.java @@ -37,7 +37,6 @@ import java.util.SortedSet; /** * Based on fastutil Object2ObjectLinkedOpenHashMap */ -@SuppressWarnings("NullableProblems") public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, V> { private static final long serialVersionUID = 0L; @@ -126,14 +125,14 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, } else if (!(o instanceof Map)) { return false; } else { - Map m = (Map) o; + Map<?, ?> m = (Map<?, ?>) o; int n = m.size(); if (this.size() != n) { return false; } Iterator<? extends Entry<?, ?>> i = this.fast().iterator(); while (n-- > 0) { - Entry e = i.next(); + Entry<?, ?> e = i.next(); Object k = e.getKey(); Object v = e.getValue(); Object v2 = m.get(k); @@ -239,7 +238,7 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, int n = m.size(); if (m instanceof OpenHashMap) { - Iterator<? extends Map.Entry<? extends K, ? extends V>> i = ((OpenHashMap) m).fast().iterator(); + Iterator<? extends Map.Entry<? extends K, ? extends V>> i = ((OpenHashMap<? extends K, ? extends V>) m).fast().iterator(); while (n-- != 0) { Map.Entry<? extends K, ? extends V> e = i.next(); this.put(e.getKey(), e.getValue()); @@ -413,13 +412,6 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, } @SuppressWarnings("unchecked") - private V setValue(int pos, V v) { - Object oldValue = this.value[pos]; - this.value[pos] = v; - return (V) oldValue; - } - - @SuppressWarnings("unchecked") public V removeFirst() { if (this.size == 0) { throw new NoSuchElementException(); @@ -475,200 +467,6 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, } } - private void moveIndexToFirst(int i) { - if (this.size != 1 && this.first != i) { - if (this.last == i) { - this.last = (int) (this.link[i] >>> 32); - this.link[this.last] |= 0xFFFFFFFFL; - } else { - long linki = this.link[i]; - int prev = (int) (linki >>> 32); - int next = (int) linki; - this.link[prev] ^= (this.link[prev] ^ linki & 0xFFFFFFFFL) & 0xFFFFFFFFL; - this.link[next] ^= (this.link[next] ^ linki & 0xFFFFFFFF00000000L) & 0xFFFFFFFF00000000L; - } - - this.link[this.first] ^= (this.link[this.first] ^ ((long) i & 0xFFFFFFFFL) << 32) & 0xFFFFFFFF00000000L; - this.link[i] = 0xFFFFFFFF00000000L | (long) this.first & 0xFFFFFFFFL; - this.first = i; - } - } - - private void moveIndexToLast(int i) { - if (this.size != 1 && this.last != i) { - if (this.first == i) { - this.first = (int) this.link[i]; - this.link[this.first] |= 0xFFFFFFFF00000000L; - } else { - long linki = this.link[i]; - int prev = (int) (linki >>> 32); - int next = (int) linki; - this.link[prev] ^= (this.link[prev] ^ linki & 0xFFFFFFFFL) & 0xFFFFFFFFL; - this.link[next] ^= (this.link[next] ^ linki & 0xFFFFFFFF00000000L) & 0xFFFFFFFF00000000L; - } - - this.link[this.last] ^= (this.link[this.last] ^ (long) i & 0xFFFFFFFFL) & 0xFFFFFFFFL; - this.link[i] = ((long) this.last & 0xFFFFFFFFL) << 32 | 0xFFFFFFFFL; - this.last = i; - } - } - - @SuppressWarnings("unchecked") - public V getAndMoveToFirst(K k) { - if (k == null) { - if (this.containsNullKey) { - this.moveIndexToFirst(this.n); - return (V) this.value[this.n]; - } else { - return this.defRetValue; - } - } else { - Object[] key = this.key; - Object curr; - int pos; - if ((curr = key[pos = mix(k.hashCode()) & this.mask]) == null) { - return this.defRetValue; - } else if (k.equals(curr)) { - this.moveIndexToFirst(pos); - return (V) this.value[pos]; - } else { - while ((curr = key[pos = pos + 1 & this.mask]) != null) { - if (k.equals(curr)) { - this.moveIndexToFirst(pos); - return (V) this.value[pos]; - } - } - - return this.defRetValue; - } - } - } - - @SuppressWarnings("unchecked") - public V getAndMoveToLast(K k) { - if (k == null) { - if (this.containsNullKey) { - this.moveIndexToLast(this.n); - return (V) this.value[this.n]; - } else { - return this.defRetValue; - } - } else { - Object[] key = this.key; - Object curr; - int pos; - if ((curr = key[pos = mix(k.hashCode()) & this.mask]) == null) { - return this.defRetValue; - } else if (k.equals(curr)) { - this.moveIndexToLast(pos); - return (V) this.value[pos]; - } else { - while ((curr = key[pos = pos + 1 & this.mask]) != null) { - if (k.equals(curr)) { - this.moveIndexToLast(pos); - return (V) this.value[pos]; - } - } - - return this.defRetValue; - } - } - } - - public V putAndMoveToFirst(K k, V v) { - int pos; - if (k == null) { - if (this.containsNullKey) { - this.moveIndexToFirst(this.n); - return this.setValue(this.n, v); - } - - this.containsNullKey = true; - pos = this.n; - } else { - Object[] key = this.key; - Object curr; - if ((curr = key[pos = mix(k.hashCode()) & this.mask]) != null) { - if (curr.equals(k)) { - this.moveIndexToFirst(pos); - return this.setValue(pos, v); - } - - while ((curr = key[pos = pos + 1 & this.mask]) != null) { - if (curr.equals(k)) { - this.moveIndexToFirst(pos); - return this.setValue(pos, v); - } - } - } - - key[pos] = k; - } - - this.value[pos] = v; - if (this.size == 0) { - this.first = this.last = pos; - this.link[pos] = -1L; - } else { - this.link[this.first] ^= (this.link[this.first] ^ ((long) pos & 0xFFFFFFFFL) << 32) & 0xFFFFFFFF00000000L; - this.link[pos] = 0xFFFFFFFF00000000L | (long) this.first & 0xFFFFFFFFL; - this.first = pos; - } - - if (this.size++ >= this.maxFill) { - this.rehash(arraySize(this.size, this.f)); - } - - return this.defRetValue; - } - - public V putAndMoveToLast(K k, V v) { - int pos; - if (k == null) { - if (this.containsNullKey) { - this.moveIndexToLast(this.n); - return this.setValue(this.n, v); - } - - this.containsNullKey = true; - pos = this.n; - } else { - Object[] key = this.key; - Object curr; - if ((curr = key[pos = mix(k.hashCode()) & this.mask]) != null) { - if (curr.equals(k)) { - this.moveIndexToLast(pos); - return this.setValue(pos, v); - } - - while ((curr = key[pos = pos + 1 & this.mask]) != null) { - if (curr.equals(k)) { - this.moveIndexToLast(pos); - return this.setValue(pos, v); - } - } - } - - key[pos] = k; - } - - this.value[pos] = v; - if (this.size == 0) { - this.first = this.last = pos; - this.link[pos] = -1L; - } else { - this.link[this.last] ^= (this.link[this.last] ^ (long) pos & 0xFFFFFFFFL) & 0xFFFFFFFFL; - this.link[pos] = ((long) this.last & 0xFFFFFFFFL) << 32 | 0xFFFFFFFFL; - this.last = pos; - } - - if (this.size++ >= this.maxFill) { - this.rehash(arraySize(this.size, this.f)); - } - - return this.defRetValue; - } - @SuppressWarnings("unchecked") public V get(Object k) { if (k == null) { @@ -845,7 +643,7 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, public SortedSet<Map.Entry<K, V>> entrySet() { if (entries == null) { - entries = new OpenHashMap.MapEntrySet(); + entries = new MapEntrySet(); } return this.entries; @@ -853,7 +651,7 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, public SortedSet<K> keySet() { if (keys == null) { - keys = new OpenHashMap.KeySet(); + keys = new KeySet(); } return keys; @@ -1052,7 +850,7 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, private void writeObject(ObjectOutputStream s) throws IOException { Object[] key = this.key; Object[] value = this.value; - OpenHashMap.MapIterator i = new OpenHashMap.MapIterator(null); + OpenHashMap<K, V>.MapIterator i = new MapIterator(); s.defaultWriteObject(); int j = this.size; @@ -1109,23 +907,7 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, } - private void checkTable() { - } - private final class ValueIterator extends MapIterator implements Iterator<V> { - @SuppressWarnings("unchecked") - public V previous() { - return (V) value[this.previousEntry()]; - } - - public void set(V v) { - throw new UnsupportedOperationException(); - } - - public void add(V v) { - throw new UnsupportedOperationException(); - } - public ValueIterator() { super(); } @@ -1140,10 +922,6 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, private KeySet() { } - public Iterator<K> iterator(K from) { - return new KeyIterator(from); - } - public Iterator<K> iterator() { return new KeyIterator(); } @@ -1202,23 +980,6 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, } private final class KeyIterator extends MapIterator implements Iterator<K> { - public KeyIterator(Object k) { - super(k); - } - - @SuppressWarnings("unchecked") - public K previous() { - return (K) key[this.previousEntry()]; - } - - public void set(K k) { - throw new UnsupportedOperationException(); - } - - public void add(K k) { - throw new UnsupportedOperationException(); - } - public KeyIterator() { super(); } @@ -1273,7 +1034,7 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, if (!(o instanceof java.util.Map.Entry)) { return false; } else { - java.util.Map.Entry e = (java.util.Map.Entry) o; + Map.Entry<?, ?> e = (Map.Entry<?, ?>) o; Object k = e.getKey(); if (k == null) { if (containsNullKey) { @@ -1314,7 +1075,7 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, if (!(o instanceof java.util.Map.Entry)) { return false; } else { - java.util.Map.Entry e = (java.util.Map.Entry) o; + Map.Entry<?, ?> e = (Map.Entry<?, ?>) o; Object k = e.getKey(); Object v = e.getValue(); if (k == null) { @@ -1380,18 +1141,6 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, public void clear() { OpenHashMap.this.clear(); } - - public EntryIterator iterator(Entry<K, V> from) { - return new EntryIterator(from.getKey()); - } - - public FastEntryIterator fastIterator() { - return new FastEntryIterator(); - } - - public FastEntryIterator fastIterator(Entry<K, V> from) { - return new FastEntryIterator(from.getKey()); - } } private class FastEntryIterator extends MapIterator implements Iterator<Entry<K, V>> { @@ -1402,61 +1151,27 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, this.entry = new MapEntry(); } - public FastEntryIterator(Object from) { - super(from); - this.entry = new MapEntry(); - } - - public OpenHashMap.MapEntry next() { + public MapEntry next() { this.entry.index = this.nextEntry(); return this.entry; } - - public OpenHashMap.MapEntry previous() { - this.entry.index = this.previousEntry(); - return this.entry; - } - - public void set(Entry<K, V> ok) { - throw new UnsupportedOperationException(); - } - - public void add(Entry<K, V> ok) { - throw new UnsupportedOperationException(); - } } private class EntryIterator extends MapIterator implements Iterator<Entry<K, V>> { - private OpenHashMap.MapEntry entry; + private MapEntry entry; public EntryIterator() { super(); } - public EntryIterator(Object from) { - super(from); - } - - public OpenHashMap.MapEntry next() { + public MapEntry next() { return this.entry = new MapEntry(this.nextEntry()); } - public OpenHashMap.MapEntry previous() { - return this.entry = new MapEntry(this.previousEntry()); - } - public void remove() { super.remove(); this.entry.index = -1; } - - public void set(Entry<K, V> ok) { - throw new UnsupportedOperationException(); - } - - public void add(Entry<K, V> ok) { - throw new UnsupportedOperationException(); - } } public static abstract class AbstractObjectSet<K> extends AbstractObjectCollection<K> implements Cloneable { @@ -1466,7 +1181,7 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, } else if (!(o instanceof Set)) { return false; } else { - Set s = (Set) o; + Set<?> s = (Set<?>) o; return s.size() == this.size() && this.containsAll(s); } } @@ -1476,7 +1191,7 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, int n = this.size(); Object k; - for (Iterator i = this.iterator(); n-- != 0; h += k == null ? 0 : k.hashCode()) { + for (Iterator<K> i = this.iterator(); n-- != 0; h += k == null ? 0 : k.hashCode()) { k = i.next(); } @@ -1507,39 +1222,10 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, this.index = 0; } - private MapIterator(Object from) { - if (from == null) { - if (containsNullKey) { - this.next = (int) link[n]; - this.prev = n; - } else { - throw new NoSuchElementException("The key " + from + " does not belong to this map."); - } - } else { - if (key[last] == null ? from == null : (key[last].equals(from))) { - this.prev = last; - this.index = size; - } else { - for (int pos = mix(from.hashCode()) & mask; key[pos] != null; pos = pos + 1 & mask) { - if (key[pos].equals(from)) { - this.next = (int) link[pos]; - this.prev = pos; - return; - } - } - throw new NoSuchElementException("The key " + from + " does not belong to this map."); - } - } - } - public boolean hasNext() { return this.next != -1; } - public boolean hasPrevious() { - return this.prev != -1; - } - private void ensureIndexKnown() { if (index < 0) { if (prev == -1) { @@ -1555,16 +1241,6 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, } } - public int nextIndex() { - ensureIndexKnown(); - return index; - } - - public int previousIndex() { - ensureIndexKnown(); - return index - 1; - } - public int nextEntry() { if (!hasNext()) { throw new NoSuchElementException(); @@ -1579,27 +1255,13 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, } } - public int previousEntry() { - if (!hasPrevious()) { - throw new NoSuchElementException(); - } else { - curr = prev; - prev = (int) (link[curr] >>> 32); - next = curr; - if (index >= 0) { - --index; - } - return curr; - } - } - public void remove() { this.ensureIndexKnown(); if (curr == -1) throw new IllegalStateException(); if (curr == prev) { /* If the last operation was a next(), we are removing an entry that preceeds - the current index, and thus we must decrement it. */ + * the current index, and thus we must decrement it. */ index--; prev = (int) (link[curr] >>> 32); } else { @@ -1607,8 +1269,8 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, } size--; - /* Now we manually fix the pointers. Because of our knowledge of next - and prev, this is going to be faster than calling fixPointers(). */ + /* Now we manually fix the pointers. Because of our knowledge of next + * and prev, this is going to be faster than calling fixPointers(). */ if (prev == -1) { first = next; } else { @@ -1650,18 +1312,6 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, } } } - - public int skip(final int n) { - int i = n; - while (i-- != 0 && hasNext()) nextEntry(); - return n - i - 1; - } - - public int back(final int n) { - int i = n; - while (i-- != 0 && hasPrevious()) previousEntry(); - return n - i - 1; - } } final class MapEntry implements Entry<K, V> { @@ -1695,7 +1345,7 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, if (!(o instanceof Entry)) { return false; } else { - Entry e = (Entry) o; + Entry<?, ?> e = (Entry<?, ?>) o; if (key[this.index] == null) { if (e.getKey() != null) { return false; @@ -1767,7 +1417,7 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, public boolean containsAll(Collection<?> c) { int n = c.size(); - Iterator i = c.iterator(); + Iterator<?> i = c.iterator(); do { if (n-- == 0) { @@ -1781,7 +1431,7 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, public boolean retainAll(Collection<?> c) { boolean retVal = false; int n = this.size(); - Iterator i = this.iterator(); + Iterator<K> i = this.iterator(); while (n-- != 0) { if (!c.contains(i.next())) { @@ -1796,7 +1446,7 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, public boolean removeAll(Collection<?> c) { boolean retVal = false; int n = c.size(); - Iterator i = c.iterator(); + Iterator<?> i = c.iterator(); while (n-- != 0) { if (this.remove(i.next())) { @@ -1813,7 +1463,7 @@ public class OpenHashMap<K, V> implements Serializable, Cloneable, SortedMap<K, public String toString() { StringBuilder s = new StringBuilder(); - Iterator i = this.iterator(); + Iterator<K> i = this.iterator(); int n = this.size(); boolean first = true; s.append("{"); diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/OpenHashMapList.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/OpenHashMapList.java index ececcba03..34b92f26f 100755 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/OpenHashMapList.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/OpenHashMapList.java @@ -21,6 +21,7 @@ package org.apache.felix.resolver.util; import org.osgi.resource.Requirement; public class OpenHashMapList extends OpenHashMap<Requirement, CandidateSelector> { + private static final long serialVersionUID = 0L; public OpenHashMapList() { super(); diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/OpenHashMapSet.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/OpenHashMapSet.java index ff008a48f..2cdf70635 100755 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/OpenHashMapSet.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/OpenHashMapSet.java @@ -19,6 +19,7 @@ package org.apache.felix.resolver.util; public class OpenHashMapSet<K, V> extends OpenHashMap<K, CopyOnWriteSet<V>> { + private static final long serialVersionUID = 1L; public OpenHashMapSet() { super(); @@ -28,6 +29,7 @@ public class OpenHashMapSet<K, V> extends OpenHashMap<K, CopyOnWriteSet<V>> { super(initialCapacity); } + @SuppressWarnings("unchecked") public OpenHashMapSet<K, V> deepClone() { OpenHashMapSet<K, V> copy = (OpenHashMapSet<K, V>) super.clone(); Object[] values = copy.value; diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/ShadowList.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/ShadowList.java index bb052a893..f69025fdc 100755 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/ShadowList.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/util/ShadowList.java @@ -20,7 +20,7 @@ package org.apache.felix.resolver.util; import java.util.ArrayList; import java.util.List; - +import java.util.concurrent.atomic.AtomicBoolean; import org.osgi.resource.Capability; import org.osgi.service.resolver.HostedCapability; import org.osgi.service.resolver.ResolveContext; @@ -28,9 +28,18 @@ import org.osgi.service.resolver.ResolveContext; public class ShadowList extends CandidateSelector { public static ShadowList createShadowList(CandidateSelector original) { + if (original instanceof ShadowList) + { + throw new IllegalArgumentException("Cannot create a ShadowList using another ShadowList."); + } return new ShadowList(original); } + public static ShadowList deepCopy(ShadowList original) { + List<Capability> originalCopy = new ArrayList<Capability>(original.m_original); + return new ShadowList(original.unmodifiable, originalCopy, original.isUnmodifiable); + } + private final List<Capability> m_original; private ShadowList(CandidateSelector original) @@ -45,6 +54,11 @@ public class ShadowList extends CandidateSelector m_original = original; } + public ShadowList(List<Capability> unmodifiable, List<Capability> originalCopy, AtomicBoolean isUnmodifiable) { + super(unmodifiable, isUnmodifiable); + m_original = originalCopy; + } + public ShadowList copy() { return new ShadowList(this, m_original); } |