From 8b3d3b6eeaf1c9e70000f8d114432df4abf8ba52 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Wed, 2 Nov 2016 15:37:51 -0500 Subject: Bug 506939 - Update felix resolver code. Change-Id: I71b049e22f2aebe2022c7ecdb3c198e9dda0582a Signed-off-by: Thomas Watson --- .../osgi/tests/container/TestModuleContainer.java | 119 ++++--- .../src/org/apache/felix/resolver/Candidates.java | 24 +- .../src/org/apache/felix/resolver/Logger.java | 2 - .../org/apache/felix/resolver/ResolverImpl.java | 5 +- .../apache/felix/resolver/WrappedCapability.java | 18 +- .../org/apache/felix/resolver/WrappedResource.java | 1 - .../org/apache/felix/resolver/util/ArrayMap.java | 14 +- .../felix/resolver/util/CandidateSelector.java | 2 +- .../apache/felix/resolver/util/CopyOnWriteSet.java | 3 +- .../apache/felix/resolver/util/OpenHashMap.java | 392 ++------------------- .../felix/resolver/util/OpenHashMapList.java | 1 + .../apache/felix/resolver/util/OpenHashMapSet.java | 2 + .../org/apache/felix/resolver/util/ShadowList.java | 16 +- 13 files changed, 156 insertions(+), 443 deletions(-) (limited to 'bundles') 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=\"v4,v5,v6\";"// - + " version:Version=1.1;"// - + " version.list:List=\"1.0,2.0,3.0\";"// - + " long:Long=12345;"// - + " long.list:List=\"1,2,3\";"// - + " double:Double=1.2345;"// - + " double.list:List=\"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=\"v4,v5,v6\";"// + + " version:Version=1.1;"// + + " version.list:List=\"1.0,2.0,3.0\";"// + + " long:Long=12345;"// + + " long.list:List=\"1,2,3\";"// + + " double:Double=1.2345;"// + + " double.list:List=\"1.1,1.2,1.3\";"// + + " uri:uri=some.uri;" // + + " set:set=\"s1,s2,s3\""); Module providerModule = installDummyModule(providerManifest, "provider", container); Map 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=\"v4,v5,v6\";"// - + " version:Version=1.1;"// - + " version.list:List=\"1.0,2.0,3.0\";"// - + " long:Long=12345;"// - + " long.list:List=\"1,2,3\";"// - + " double:Double=1.2345;"// - + " double.list:List=\"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=\"v4,v5,v6\";"// + + " version:Version=1.1;"// + + " version.list:List=\"1.0,2.0,3.0\";"// + + " long:Long=12345;"// + + " long.list:List=\"1,2,3\";"// + + " double:Double=1.2345;"// + + " double.list:List=\"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 requirerAttrs = requirerModule.getCurrentRevision().getRequirements("optional").get(0).getAttributes(); assertEquals("Wrong requirer attrs", attrs, requirerAttrs); @@ -2626,6 +2624,47 @@ public class TestModuleContainer extends AbstractTest { } } + @Test + public void testUnresolvedHostWithFragmentCycle() throws BundleException, IOException { + DummyContainerAdaptor adaptor = createDummyAdaptor(); + ModuleContainer container = adaptor.getContainer(); + + // install a host + Map hostManifest = new HashMap(); + 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 hostImplManifest = new HashMap(); + 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 hostImporterManifest = new HashMap(); + 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 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 populated : m_populateResultCache.fast()) @@ -280,6 +266,7 @@ class Candidates private void populateSubstitutables(Resource resource) { // Collect the package names exported + @SuppressWarnings("serial") OpenHashMap> exportNames = new OpenHashMap>() { @Override protected List compute(String s) { @@ -740,7 +727,7 @@ class Candidates public CandidateSelector clearMultipleCardinalityCandidates(Requirement req, Collection 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 remaining = new ArrayList(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 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; - /** *

* This class mimics the standard OSGi LogService 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> doResolve(ResolveSession session) throws ResolutionException { Map> wireMap = new HashMap>(); boolean retry; @@ -1689,6 +1689,7 @@ public class ResolverImpl implements Resolver List caps = (wiring != null) ? wiring.getResourceCapabilities(null) : resource.getCapabilities(null); + @SuppressWarnings("serial") OpenHashMap> pkgs = new OpenHashMap>(caps.size()) { public Set compute(String pkgName) { return new HashSet(); @@ -1967,6 +1968,7 @@ public class ResolverImpl implements Resolver return wireMap; } + @SuppressWarnings("unused") private static void dumpResourcePkgMap( ResolveContext rc, Map resourcePkgMap) { @@ -2025,6 +2027,7 @@ public class ResolverImpl implements Resolver public final OpenHashMap> m_usedPkgs; public final OpenHashMap> 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 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 augmentedDirs = new HashMap(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 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 extends AbstractMap { private Object[] table; @@ -133,25 +132,26 @@ public class ArrayMap extends AbstractMap { @Override public Iterator> iterator() { return new Iterator>() { - FastEntry entry = new FastEntry(); + FastEntry entry = new FastEntry(); int index = 0; public boolean hasNext() { return index < size; } - public FastEntry next() { + @SuppressWarnings("unchecked") + public FastEntry 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 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 implements Set, Cloneable { Object[] data; @@ -116,6 +114,7 @@ public class CopyOnWriteSet implements Set, 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 implements Serializable, Cloneable, SortedMap { private static final long serialVersionUID = 0L; @@ -126,14 +125,14 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap m = (Map) o; int n = m.size(); if (this.size() != n) { return false; } Iterator> 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 implements Serializable, Cloneable, SortedMap> i = ((OpenHashMap) m).fast().iterator(); + Iterator> i = ((OpenHashMap) m).fast().iterator(); while (n-- != 0) { Map.Entry e = i.next(); this.put(e.getKey(), e.getValue()); @@ -412,13 +411,6 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap implements Serializable, Cloneable, SortedMap>> 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 implements Serializable, Cloneable, SortedMap> entrySet() { if (entries == null) { - entries = new OpenHashMap.MapEntrySet(); + entries = new MapEntrySet(); } return this.entries; @@ -853,7 +651,7 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap keySet() { if (keys == null) { - keys = new OpenHashMap.KeySet(); + keys = new KeySet(); } return keys; @@ -1052,7 +850,7 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap.MapIterator i = new MapIterator(); s.defaultWriteObject(); int j = this.size; @@ -1109,23 +907,7 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap { - @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 implements Serializable, Cloneable, SortedMap iterator(K from) { - return new KeyIterator(from); - } - public Iterator iterator() { return new KeyIterator(); } @@ -1202,23 +980,6 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap { - 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 implements Serializable, Cloneable, SortedMap e = (Map.Entry) o; Object k = e.getKey(); if (k == null) { if (containsNullKey) { @@ -1314,7 +1075,7 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap e = (Map.Entry) o; Object k = e.getKey(); Object v = e.getValue(); if (k == null) { @@ -1380,18 +1141,6 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap from) { - return new EntryIterator(from.getKey()); - } - - public FastEntryIterator fastIterator() { - return new FastEntryIterator(); - } - - public FastEntryIterator fastIterator(Entry from) { - return new FastEntryIterator(from.getKey()); - } } private class FastEntryIterator extends MapIterator implements Iterator> { @@ -1402,61 +1151,27 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap ok) { - throw new UnsupportedOperationException(); - } - - public void add(Entry ok) { - throw new UnsupportedOperationException(); - } } private class EntryIterator extends MapIterator implements Iterator> { - 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 ok) { - throw new UnsupportedOperationException(); - } - - public void add(Entry ok) { - throw new UnsupportedOperationException(); - } } public static abstract class AbstractObjectSet extends AbstractObjectCollection implements Cloneable { @@ -1466,7 +1181,7 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap s = (Set) o; return s.size() == this.size() && this.containsAll(s); } } @@ -1476,7 +1191,7 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap i = this.iterator(); n-- != 0; h += k == null ? 0 : k.hashCode()) { k = i.next(); } @@ -1507,39 +1222,10 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap implements Serializable, Cloneable, SortedMap implements Serializable, Cloneable, SortedMap>> 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 implements Serializable, Cloneable, SortedMap implements Serializable, Cloneable, SortedMap { @@ -1695,7 +1345,7 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap e = (Entry) o; if (key[this.index] == null) { if (e.getKey() != null) { return false; @@ -1767,7 +1417,7 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap c) { int n = c.size(); - Iterator i = c.iterator(); + Iterator i = c.iterator(); do { if (n-- == 0) { @@ -1781,7 +1431,7 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap c) { boolean retVal = false; int n = this.size(); - Iterator i = this.iterator(); + Iterator i = this.iterator(); while (n-- != 0) { if (!c.contains(i.next())) { @@ -1796,7 +1446,7 @@ public class OpenHashMap implements Serializable, Cloneable, SortedMap 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 implements Serializable, Cloneable, SortedMap 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 { + 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 extends OpenHashMap> { + private static final long serialVersionUID = 1L; public OpenHashMapSet() { super(); @@ -28,6 +29,7 @@ public class OpenHashMapSet extends OpenHashMap> { super(initialCapacity); } + @SuppressWarnings("unchecked") public OpenHashMapSet deepClone() { OpenHashMapSet copy = (OpenHashMapSet) 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 originalCopy = new ArrayList(original.m_original); + return new ShadowList(original.unmodifiable, originalCopy, original.isUnmodifiable); + } + private final List m_original; private ShadowList(CandidateSelector original) @@ -45,6 +54,11 @@ public class ShadowList extends CandidateSelector m_original = original; } + public ShadowList(List unmodifiable, List originalCopy, AtomicBoolean isUnmodifiable) { + super(unmodifiable, isUnmodifiable); + m_original = originalCopy; + } + public ShadowList copy() { return new ShadowList(this, m_original); } -- cgit v1.2.3