Author: reto
Date: Fri Sep 10 20:36:58 2010
New Revision: 995973
URL: http://svn.apache.org/viewvc?rev=995973&view=rev
Log:
CLEREZZA-286: extracted WeightedTcProvider aggregation from TcManager
Added:
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcProviderMultiplexer.java
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/WeightedProviderComparator.java
Modified:
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcManager.java
Modified:
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcManager.java
URL:
http://svn.apache.org/viewvc/incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcManager.java?rev=995973&r1=995972&r2=995973&view=diff
==============================================================================
---
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcManager.java
(original)
+++
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcManager.java
Fri Sep 10 20:36:58 2010
@@ -21,10 +21,9 @@ package org.apache.clerezza.rdf.core.acc
import org.apache.clerezza.rdf.core.impl.WriteBlockedMGraph;
import org.apache.clerezza.rdf.core.impl.WriteBlockedTripleCollection;
-import java.lang.ref.WeakReference;
import java.security.AccessControlException;
+import java.util.Collection;
import java.util.Collections;
-import java.util.Comparator;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
@@ -33,8 +32,6 @@ import java.util.Map;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
@@ -85,22 +82,14 @@ import org.apache.felix.scr.annotations.
@Reference(name="weightedTcProvider", policy=ReferencePolicy.DYNAMIC,
referenceInterface=WeightedTcProvider.class,
cardinality=ReferenceCardinality.MANDATORY_MULTIPLE)
-public class TcManager implements TcProvider {
+public class TcManager extends TcProviderMultiplexer {
- private SortedSet<WeightedTcProvider> providerList = new
TreeSet<WeightedTcProvider>(
- new WeightedProviderComparator());
private static volatile TcManager instance;
private TcAccessController tcAccessController = new
TcAccessController(this);
- /**
- * Mapping to LockableMGraph's and ServiceRegistration using their
URI's as key.
- * Makes sure that per URI only one instance of the LockableMGraph is
used,
- * otherwise the locks in the <code>LockableMGraph</code>s would have
no effect
- * between different instances and concurrency issues could occur.
- */
- private Map<UriRef, GraphHolder> synchronizedLockableMGraphCache =
Collections
- .synchronizedMap(new HashMap<UriRef, GraphHolder>());
+ private Map<UriRef, ServiceRegistration> serviceRegistrations =
Collections
+ .synchronizedMap(new HashMap<UriRef,
ServiceRegistration>());
@Reference(policy=ReferencePolicy.DYNAMIC,
@@ -108,13 +97,9 @@ public class TcManager implements TcProv
protected QueryEngine queryEngine;
private ComponentContext componentContext;
+ private Collection<UriRef> mGraphsToRegisterOnActivation = new
HashSet<UriRef>();
+ private Collection<UriRef> graphsToRegisterOnActivation = new
HashSet<UriRef>();
- /*
- * A store that keeps <code>WeightedTcProvider</code>S in case the
- * componentContext is null. Used in activate().
- */
- private final Set<WeightedTcProvider> providerStore =
- Collections.synchronizedSet(new
HashSet<WeightedTcProvider>());
/**
* the constructor sets the singleton instance to allow instantiation by
@@ -162,189 +147,26 @@ public class TcManager implements TcProv
protected void activate(final ComponentContext componentContext) {
this.componentContext = componentContext;
- synchronized(providerStore) {
- Iterator<WeightedTcProvider> it =
providerStore.iterator();
- while (it.hasNext()) {
- WeightedTcProvider provider = it.next();
- updateLockableMGraphCache(provider, true);
- }
- }
- providerStore.clear();
- }
-
- protected void deactivate(final ComponentContext componentContext) {
- this.componentContext = null;
- }
-
- /**
- * Registers a provider
- *
- * @param provider
- * the provider to be registered
- */
- protected void bindWeightedTcProvider(WeightedTcProvider provider) {
- providerList.add(provider);
- if (componentContext != null) {
- updateLockableMGraphCache(provider, true);
- } else {
- providerStore.add(provider);
- }
- }
-
- /**
- * Unregister a provider
- *
- * @param provider
- * the provider to be deregistered
- */
- protected void unbindWeightedTcProvider(
- WeightedTcProvider provider) {
- providerList.remove(provider);
- providerStore.remove(provider);
- updateLockableMGraphCache(provider, false);
- }
-
- /**
- * Updates the lockableMGraphCache AFTER a new <code>provider</code> was
- * bound or unbound.
- * This method also takes care of registering and unregistering
- * provided triple collections as services based on the weight of
- * all affected providers.
- *
- * @param provider
- * the provider that was added or removed
- * @param providerAdded
- * <code>boolean</code> that should be set as
<code>true</code>
- * if <code>provider</code> was added to
- *
<code>org.apache.clerezza.rdf.core.TcManager.providerList</code>
- * otherwise <code>false</code>
- */
- private void updateLockableMGraphCache(WeightedTcProvider provider,
- boolean providerAdded) {
- Set<UriRef> uriSet = provider.listTripleCollections();
- if (!(uriSet == null || uriSet.isEmpty())) {
- if (providerAdded) {
- weightedProviderAdded(provider, uriSet);
- } else {
- weightedProviderRemoved(provider, uriSet);
- }
- }
- }
-
- private void weightedProviderAdded(WeightedTcProvider newProvider,
- Set<UriRef> newProvidedUris) {
- Set<WeightedTcProvider> lowerWeightedProviderList =
getLowerWeightedProvider(newProvider);
- for (UriRef name : newProvidedUris) {
- final GraphHolder holder =
synchronizedLockableMGraphCache
- .get(name);
- if ((holder != null) && (holder.getWeightedTcProvider()
!= null)) {
- if (lowerWeightedProviderList.contains(holder
-
.getWeightedTcProvider())) {
- unregisterService(name);
-
synchronizedLockableMGraphCache.remove(name);
- } else {
- continue;
- }
- }
- ServiceRegistration serviceReg = registerAsService(name,
- newProvider.getTriples(name));
- if (serviceReg != null) {
- synchronizedLockableMGraphCache.put(name,
- new GraphHolder(newProvider,
null, serviceReg));
- }
- }
- }
-
- private void unregisterService(UriRef name) {
- GraphHolder entry = synchronizedLockableMGraphCache.get(name);
- if (entry != null) {
- ServiceRegistration reg =
entry.getServiceRegistration();
- if (reg != null) {
- reg.unregister();
- }
- }
- }
-
- private ServiceRegistration registerAsService(UriRef name,
- TripleCollection triples) {
- if (componentContext == null) {
- return null;
+ for (UriRef name : mGraphsToRegisterOnActivation) {
+ registerMGraphAsService(name);
}
- Dictionary props = new Properties();
- props.put("name", name.getUnicodeString());
- String[] interfaceNames;
- Object service;
- if (triples instanceof MGraph) {
- interfaceNames = new String[]{
- MGraph.class.getName(),
- LockableMGraph.class.getName()
- };
- service = new MGraphServiceFactory(this, name,
tcAccessController);
- } else if (triples instanceof Graph) {
- interfaceNames = new String[]{Graph.class.getName()};
- service = new GraphServiceFactory(this, name,
tcAccessController);
- } else {
- return null;
+ for (UriRef name : graphsToRegisterOnActivation) {
+ registerGraphAsService(name);
}
- return componentContext.getBundleContext().registerService(
- interfaceNames, service, props);
}
-
- private Set<WeightedTcProvider> getLowerWeightedProvider(
- WeightedTcProvider newProvider) {
- boolean referenceProviderPassed = false;
- Set<WeightedTcProvider> lowerWeightedProviderList = new
HashSet<WeightedTcProvider>();
- for (WeightedTcProvider weightedProvider : providerList) {
- if (referenceProviderPassed) {
- lowerWeightedProviderList.add(weightedProvider);
- } else if (newProvider.equals(weightedProvider)) {
- referenceProviderPassed = true;
- }
- }
- return lowerWeightedProviderList;
- }
-
- private void weightedProviderRemoved(WeightedTcProvider oldProvider,
- Set<UriRef> oldProvidedUris) {
- for (UriRef name : oldProvidedUris) {
- final GraphHolder holder =
synchronizedLockableMGraphCache
- .get(name);
- if ((holder != null) && (holder.getWeightedTcProvider()
!= null)
- &&
holder.getWeightedTcProvider().equals(oldProvider)) {
- unregisterService(name);
- synchronizedLockableMGraphCache.remove(name);
-
- // check if another WeightedTcProvider has the
TripleCollection.
- // And if so register as service.
- for (WeightedTcProvider provider :
providerList) {
- try {
- TripleCollection triples =
provider.getTriples(name);
-
synchronizedLockableMGraphCache.put(name, new GraphHolder(
- provider, null,
registerAsService(name, triples)));
- break;
- } catch (NoSuchEntityException e) {
- // continue;
- }
- }
-
- }
+ protected void deactivate(final ComponentContext componentContext) {
+ for (ServiceRegistration registration :
serviceRegistrations.values()) {
+ registration.unregister();
}
+ serviceRegistrations.clear();
+ this.componentContext = null;
}
@Override
public Graph getGraph(UriRef name) throws NoSuchEntityException {
tcAccessController.checkReadPermission(name);
- for (TcProvider provider : providerList) {
- try {
- return provider.getGraph(name);
- } catch (NoSuchEntityException e) {
- //we do nothing and try our luck with the next
provider
- } catch (IllegalArgumentException e) {
- //we do nothing and try our luck with the next
provider
- }
- }
- throw new NoSuchEntityException(name);
+ return super.getGraph(name);
}
@Override
@@ -353,60 +175,9 @@ public class TcManager implements TcProv
tcAccessController.checkReadWritePermission(name);
} catch (AccessControlException e) {
tcAccessController.checkReadPermission(name);
- return new WriteBlockedMGraph(getUnsecuredMGraph(name));
- }
- return getUnsecuredMGraph(name);
- }
-
- private LockableMGraph getUnsecuredMGraph(UriRef name)
- throws NoSuchEntityException {
- LockableMGraph result = getMGraphFromCache(name);
- if (result == null) {
- synchronized (this) {
- result = getMGraphFromCache(name);
- if (result == null) {
- result =
getUnsecuredMGraphAndAddToCache(name);
- }
- }
- }
- return result;
- }
-
- private LockableMGraph getMGraphFromCache(UriRef name) {
- GraphHolder holder = synchronizedLockableMGraphCache.get(name);
- if (holder == null) {
- return null;
+ return new WriteBlockedMGraph(super.getMGraph(name));
}
- return holder.getMGraph();
- }
-
- private LockableMGraph getUnsecuredMGraphAndAddToCache(UriRef name)
- throws NoSuchEntityException {
- for (WeightedTcProvider provider : providerList) {
- try {
- MGraph providedMGraph =
provider.getMGraph(name);
- LockableMGraph result;
- if (providedMGraph instanceof LockableMGraph) {
- result = (LockableMGraph)
providedMGraph;
- } else {
- result = new
LockableMGraphWrapper(providedMGraph);
- }
-
- GraphHolder holder =
synchronizedLockableMGraphCache.get(name);
- ServiceRegistration serviceReg = null;
- if (holder != null) {
- serviceReg =
holder.getServiceRegistration();
- }
- synchronizedLockableMGraphCache.put(name, new
GraphHolder(
- provider, result, serviceReg));
- return result;
- } catch (NoSuchEntityException e) {
- //we do nothing and try our luck with the next
provider
- } catch (IllegalArgumentException e) {
- //we do nothing and try our luck with the next
provider
- }
- }
- throw new NoSuchEntityException(name);
+ return super.getMGraph(name);
}
@Override
@@ -416,152 +187,52 @@ public class TcManager implements TcProv
} catch (AccessControlException e) {
tcAccessController.checkReadPermission(name);
return new WriteBlockedTripleCollection(
- getUnsecuredTriples(name));
+ super.getTriples(name));
}
- return getUnsecuredTriples(name);
+ return super.getTriples(name);
}
- private TripleCollection getUnsecuredTriples(UriRef name)
- throws NoSuchEntityException {
- TripleCollection result;
- for (WeightedTcProvider provider : providerList) {
- try {
- result = provider.getTriples(name);
- if (!(result instanceof MGraph)) {
- return result;
- } else {
- // This is to ensure the MGraph gets
added to the cache
- return getUnsecuredMGraph(name);
- }
- } catch (NoSuchEntityException e) {
- //we do nothing and try our luck with the next
provider
- } catch (IllegalArgumentException e) {
- //we do nothing and try our luck with the next
provider
- }
- }
- throw new NoSuchEntityException(name);
- }
+
@Override
public LockableMGraph createMGraph(UriRef name)
throws UnsupportedOperationException {
tcAccessController.checkReadWritePermission(name);
- for (WeightedTcProvider provider : providerList) {
- try {
- MGraph providedMGraph =
provider.createMGraph(name);
- LockableMGraph result;
- if (providedMGraph instanceof LockableMGraph) {
- result = (LockableMGraph)
providedMGraph;
- } else {
- result = new
LockableMGraphWrapper(providedMGraph);
- }
-
- // unregisters a possible Graph or MGraph
service under this name
- // provided by a WeightedTcProvider with a
lower weight.
- unregisterService(name);
-
- ServiceRegistration newReg =
registerAsService(name, result);
- synchronizedLockableMGraphCache.put(name, new
GraphHolder(
- provider, result, newReg));
- return result;
- } catch (UnsupportedOperationException e) {
- //we do nothing and try our luck with the next
provider
- } catch (IllegalArgumentException e) {
- //we do nothing and try our luck with the next
provider
- }
- }
- throw new UnsupportedOperationException(
- "No provider could create MGraph.");
+ return super.createMGraph(name);
}
@Override
public Graph createGraph(UriRef name, TripleCollection triples) {
tcAccessController.checkReadWritePermission(name);
- for (WeightedTcProvider provider : providerList) {
- try {
- Graph result = provider.createGraph(name,
triples);
-
- // unregisters a possible Graph or MGraph
service under this name
- // provided by a WeightedTcProvider with a
lower weight.
- unregisterService(name);
-
- ServiceRegistration newReg =
registerAsService(name, result);
- synchronizedLockableMGraphCache.put(name, new
GraphHolder(
- provider, null, newReg));
- return result;
- } catch (UnsupportedOperationException e) {
- //we do nothing and try our luck with the next
provider
- } catch (IllegalArgumentException e) {
- //we do nothing and try our luck with the next
provider
- }
- }
- throw new UnsupportedOperationException(
- "No provider could create Graph.");
+ return super.createGraph(name, triples);
}
@Override
public void deleteTripleCollection(UriRef name) {
tcAccessController.checkReadWritePermission(name);
- for (TcProvider provider : providerList) {
- try {
- provider.deleteTripleCollection(name);
- final GraphHolder holder =
synchronizedLockableMGraphCache
- .get(name);
- if ((holder != null)
- &&
(holder.getWeightedTcProvider() != null)
- &&
holder.getWeightedTcProvider().equals(provider)) {
- unregisterService(name);
-
synchronizedLockableMGraphCache.remove(name);
- }
- return;
- } catch (UnsupportedOperationException e) {
- // we do nothing and try our luck with the next
provider
- } catch (NoSuchEntityException e) {
- //we do nothing and try our luck with the next
provider
- } catch (IllegalArgumentException e) {
- //we do nothing and try our luck with the next
provider
- }
- }
- // this throws a NoSuchEntityException if the graph doesn't
exist
- getTriples(name);
- // the entity exists but cannot be deleted
- throw new UnsupportedOperationException(
- "No provider could delete the entity.");
+ super.deleteTripleCollection(name);
}
@Override
public Set<UriRef> getNames(Graph graph) {
- Set<UriRef> result = new HashSet<UriRef>();
- for (TcProvider provider : providerList) {
- result.addAll(provider.getNames(graph));
- }
- return result;
+ return super.getNames(graph);
}
@Override
public Set<UriRef> listGraphs() {
- Set<UriRef> result = new HashSet<UriRef>();
- for (TcProvider provider : providerList) {
- result.addAll(provider.listGraphs());
- }
+ Set<UriRef> result = super.listGraphs();
return excludeNonReadable(result);
}
@Override
public Set<UriRef> listMGraphs() {
- Set<UriRef> result = new HashSet<UriRef>();
- for (TcProvider provider : providerList) {
- result.addAll(provider.listMGraphs());
- }
+ Set<UriRef> result = super.listMGraphs();
return excludeNonReadable(result);
}
@Override
public Set<UriRef> listTripleCollections() {
- Set<UriRef> result = new HashSet<UriRef>();
- for (TcProvider provider : providerList) {
- result.addAll(provider.listTripleCollections());
- }
+ Set<UriRef> result = super.listTripleCollections();
return excludeNonReadable(result);
}
@@ -583,24 +254,6 @@ public class TcManager implements TcProv
}
/**
- * Compares the WeightedTcManagementProviders, descending for weight and
- * ascending by name
- */
- static class WeightedProviderComparator implements
- Comparator<WeightedTcProvider> {
-
- @Override
- public int compare(WeightedTcProvider o1, WeightedTcProvider
o2) {
- int o1Weight = o1.getWeight();
- int o2Weight = o2.getWeight();
- if (o1Weight != o2Weight) {
- return o2Weight - o1Weight;
- }
- return
o1.getClass().toString().compareTo(o2.getClass().toString());
- }
- }
-
- /**
* Executes any sparql query. The type of the result object will vary
* depending on the type of the query.
*
@@ -709,33 +362,79 @@ public class TcManager implements TcProv
}
/**
- * Contains an unsecured LockableMGraph, a ServiceRegistration and
- * the WeightedTcProvider that generated the graph
+ * Registers a provider
+ *
+ * @param provider
+ * the provider to be registered
*/
- private static class GraphHolder {
- private WeightedTcProvider tcProvider;
- private WeakReference<LockableMGraph> mGraphReference;
- private ServiceRegistration serviceReg;
+ protected void bindWeightedTcProvider(WeightedTcProvider provider) {
+ addWeightedTcProvider(provider);
+ }
- private GraphHolder(WeightedTcProvider tcProvider,
LockableMGraph mGraph,
- ServiceRegistration serviceReg) {
- this.tcProvider = tcProvider;
- this.mGraphReference = new
WeakReference<LockableMGraph>(mGraph);
- this.serviceReg = serviceReg;
- }
+ /**
+ * Unregister a provider
+ *
+ * @param provider
+ * the provider to be deregistered
+ */
+ protected void unbindWeightedTcProvider(
+ WeightedTcProvider provider) {
+ removeWeightedTcProvider(provider);
+ }
- private LockableMGraph getMGraph() {
- return this.mGraphReference.get();
+ @Override
+ protected void mGraphAppears(UriRef name) {
+ if (componentContext == null) {
+ mGraphsToRegisterOnActivation.add(name);
+ } else {
+ registerMGraphAsService(name);
}
+ }
- private WeightedTcProvider getWeightedTcProvider() {
- return this.tcProvider;
+ @Override
+ protected void graphAppears(UriRef name) {
+ if (componentContext == null) {
+ graphsToRegisterOnActivation.add(name);
+ } else {
+ registerGraphAsService(name);
}
+ }
- private ServiceRegistration getServiceRegistration() {
- return serviceReg;
- }
+ private void registerMGraphAsService(UriRef name) {
+
+ Dictionary props = new Properties();
+ props.put("name", name.getUnicodeString());
+ String[] interfaceNames;
+ final TripleCollection triples = getTriples(name);
+ interfaceNames = new String[]{
+ MGraph.class.getName(),
+ LockableMGraph.class.getName()
+ };
+ Object service = new MGraphServiceFactory(this, name,
tcAccessController);
+ ServiceRegistration serviceReg =
componentContext.getBundleContext().registerService(
+ interfaceNames, service, props);
+ serviceRegistrations.put(name, serviceReg);
+ }
+
+ private void registerGraphAsService(UriRef name) {
+ Dictionary props = new Properties();
+ props.put("name", name.getUnicodeString());
+ String[] interfaceNames;
+ interfaceNames = new String[]{Graph.class.getName()};
+ Object service = new GraphServiceFactory(this, name,
tcAccessController);
+ ServiceRegistration serviceReg =
componentContext.getBundleContext().registerService(
+ interfaceNames, service, props);
+ serviceRegistrations.put(name, serviceReg);
}
+ @Override
+ protected void tcDisappears(UriRef name) {
+ mGraphsToRegisterOnActivation.remove(name);
+ graphsToRegisterOnActivation.remove(name);
+ ServiceRegistration reg = serviceRegistrations.get(name);
+ if (reg != null) {
+ reg.unregister();
+ }
+ }
}
Added:
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcProviderMultiplexer.java
URL:
http://svn.apache.org/viewvc/incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcProviderMultiplexer.java?rev=995973&view=auto
==============================================================================
---
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcProviderMultiplexer.java
(added)
+++
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcProviderMultiplexer.java
Fri Sep 10 20:36:58 2010
@@ -0,0 +1,444 @@
+/*
+ * 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.clerezza.rdf.core.access;
+
+import java.lang.ref.WeakReference;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+
+import org.apache.clerezza.rdf.core.Graph;
+import org.apache.clerezza.rdf.core.MGraph;
+import org.apache.clerezza.rdf.core.TripleCollection;
+import org.apache.clerezza.rdf.core.UriRef;
+import org.apache.clerezza.rdf.core.sparql.QueryEngine;
+
+/**
+ * This makes a set of WeightedTcProvider appear as one TcProvider. It
delegates
+ * requests to the WeightedTcProvider with the highest Weight
+ *
+ * @author reto
+ */
+public class TcProviderMultiplexer implements TcProvider {
+
+ private SortedSet<WeightedTcProvider> providerList = new
TreeSet<WeightedTcProvider>(
+ new WeightedProviderComparator());
+ /**
+ * Mapping to LockableMGraph's and ServiceRegistration using their
URI's as key.
+ * Makes sure that per URI only one instance of the LockableMGraph is
used,
+ * otherwise the locks in the <code>LockableMGraph</code>s would have
no effect
+ * between different instances and concurrency issues could occur.
+ */
+ private Map<UriRef, MGraphHolder> mGraphCache =
Collections.synchronizedMap(new HashMap<UriRef, MGraphHolder>());
+
+ /**
+ * Registers a provider
+ *
+ * @param provider
+ * the provider to be registered
+ */
+ public void addWeightedTcProvider(WeightedTcProvider provider) {
+ providerList.add(provider);
+ updateLockableMGraphCache(provider, true);
+ }
+
+ /**
+ * Unregister a provider
+ *
+ * @param provider
+ * the provider to be deregistered
+ */
+ public void removeWeightedTcProvider(
+ WeightedTcProvider provider) {
+ providerList.remove(provider);
+ updateLockableMGraphCache(provider, false);
+ }
+
+ /**
+ * subclasses overwrite this method to be notified when a new
+ * Graph is available (either because it has been created or being
+ * provided by a newly added WeightedTcProvider). The default
implementation
+ * does nothing.
+ *
+ * @param name
+ */
+ protected void graphAppears(UriRef name) {
+ }
+
+ /**
+ * subclasses overwrite this method to be notified when a new
+ * MGraph is available (either because it has been created or being
+ * provided by a newly added WeightedTcProvider). The default
implementation
+ * does nothing.
+ *
+ * @param name
+ */
+ protected void mGraphAppears(UriRef name) {
+ }
+
+ /**
+ * subclasses overwrite this method to be notified whenTripleCollection
is
+ * no longer available (either because it has been deleted or bacause
its
+ * WeightedTcProvider was removed). The default implementation does
nothing.
+ *
+ * for implementational reasons even for name of TripleCollection not
+ * previously registered.
+ *
+ * @param name
+ */
+ protected void tcDisappears(UriRef name) {
+ }
+
+ /**
+ * Updates the lockableMGraphCache AFTER a new <code>provider</code> was
+ * bound or unbound.
+ * This method also takes care of registering and unregistering
+ * provided triple collections as services based on the weight of
+ * all affected providers.
+ *
+ * @param provider
+ * the provider that was added or removed
+ * @param providerAdded
+ * <code>boolean</code> that should be set as
<code>true</code>
+ * if <code>provider</code> was added to
+ *
<code>org.apache.clerezza.rdf.core.TcManager.providerList</code>
+ * otherwise <code>false</code>
+ */
+ private void updateLockableMGraphCache(WeightedTcProvider provider,
+ boolean providerAdded) {
+ Set<UriRef> uriSet = provider.listTripleCollections();
+ if (!(uriSet == null || uriSet.isEmpty())) {
+ if (providerAdded) {
+ weightedProviderAdded(provider, uriSet);
+ } else {
+ weightedProviderRemoved(provider, uriSet);
+ }
+ }
+ }
+
+ private void weightedProviderAdded(WeightedTcProvider newProvider,
+ Set<UriRef> newProvidedUris) {
+ Set<WeightedTcProvider> lowerWeightedProviderList =
getLowerWeightedProvider(newProvider);
+ for (UriRef name : newProvidedUris) {
+ final MGraphHolder holder = mGraphCache.get(name);
+ if ((holder != null) && (holder.getWeightedTcProvider()
!= null)) {
+ if
(lowerWeightedProviderList.contains(holder.getWeightedTcProvider())) {
+ tcDisappears(name);
+ mGraphCache.remove(name);
+ } else {
+ continue;
+ }
+ }
+ TripleCollection triples = newProvider.getTriples(name);
+ if (triples instanceof MGraph) {
+ mGraphCache.put(name, new
MGraphHolder(newProvider, ensureLockable((MGraph)triples)));
+ mGraphAppears(name);
+ } else {
+ graphAppears(name);
+ }
+
+ }
+ }
+
+
+
+ private Set<WeightedTcProvider> getLowerWeightedProvider(
+ WeightedTcProvider newProvider) {
+ boolean referenceProviderPassed = false;
+ Set<WeightedTcProvider> lowerWeightedProviderList = new
HashSet<WeightedTcProvider>();
+ for (WeightedTcProvider weightedProvider : providerList) {
+ if (referenceProviderPassed) {
+ lowerWeightedProviderList.add(weightedProvider);
+ } else if (newProvider.equals(weightedProvider)) {
+ referenceProviderPassed = true;
+ }
+ }
+ return lowerWeightedProviderList;
+ }
+
+ private void weightedProviderRemoved(WeightedTcProvider oldProvider,
+ Set<UriRef> oldProvidedUris) {
+ for (UriRef name : oldProvidedUris) {
+ final MGraphHolder holder = mGraphCache.get(name);
+ if ((holder != null) && (holder.getWeightedTcProvider()
!= null)
+ &&
holder.getWeightedTcProvider().equals(oldProvider)) {
+ tcDisappears(name);
+ mGraphCache.remove(name);
+
+ // check if another WeightedTcProvider has the
TripleCollection.
+ // And if so register as service.
+ for (WeightedTcProvider provider :
providerList) {
+ try {
+ TripleCollection triples =
provider.getTriples(name);
+ if (triples instanceof MGraph) {
+ mGraphCache.put(name,
new MGraphHolder(provider, ensureLockable((MGraph)triples)));
+ mGraphAppears(name);
+ } else {
+ graphAppears(name);
+ }
+ break;
+ } catch (NoSuchEntityException e) {
+ // continue;
+ }
+ }
+
+ }
+ }
+ }
+
+ @Override
+ public Graph getGraph(UriRef name) throws NoSuchEntityException {
+ for (TcProvider provider : providerList) {
+ try {
+ return provider.getGraph(name);
+ } catch (NoSuchEntityException e) {
+ //we do nothing and try our luck with the next
provider
+ } catch (IllegalArgumentException e) {
+ //we do nothing and try our luck with the next
provider
+ }
+ }
+ throw new NoSuchEntityException(name);
+ }
+
+ @Override
+ public LockableMGraph getMGraph(UriRef name)
+ throws NoSuchEntityException {
+ LockableMGraph result = getMGraphFromCache(name);
+ if (result == null) {
+ synchronized (this) {
+ result = getMGraphFromCache(name);
+ if (result == null) {
+ result =
getUnsecuredMGraphAndAddToCache(name);
+ }
+ }
+ }
+ return result;
+ }
+
+ private LockableMGraph getMGraphFromCache(UriRef name) {
+ MGraphHolder holder = mGraphCache.get(name);
+ if (holder == null) {
+ return null;
+ }
+ return holder.getMGraph();
+ }
+
+ private LockableMGraph getUnsecuredMGraphAndAddToCache(UriRef name)
+ throws NoSuchEntityException {
+ for (WeightedTcProvider provider : providerList) {
+ try {
+ MGraph providedMGraph =
provider.getMGraph(name);
+ LockableMGraph result =
ensureLockable(providedMGraph);
+
+ MGraphHolder holder = mGraphCache.get(name);
+ mGraphCache.put(name, new MGraphHolder(
+ provider, result));
+ return result;
+ } catch (NoSuchEntityException e) {
+ //we do nothing and try our luck with the next
provider
+ } catch (IllegalArgumentException e) {
+ //we do nothing and try our luck with the next
provider
+ }
+ }
+ throw new NoSuchEntityException(name);
+ }
+
+ @Override
+ public TripleCollection getTriples(UriRef name)
+ throws NoSuchEntityException {
+ TripleCollection result;
+ for (WeightedTcProvider provider : providerList) {
+ try {
+ result = provider.getTriples(name);
+ if (!(result instanceof MGraph)) {
+ return result;
+ } else {
+ // This is to ensure the MGraph gets
added to the cache
+ return getMGraph(name);
+ }
+ } catch (NoSuchEntityException e) {
+ //we do nothing and try our luck with the next
provider
+ } catch (IllegalArgumentException e) {
+ //we do nothing and try our luck with the next
provider
+ }
+ }
+ throw new NoSuchEntityException(name);
+ }
+
+ @Override
+ public LockableMGraph createMGraph(UriRef name)
+ throws UnsupportedOperationException {
+
+ for (WeightedTcProvider provider : providerList) {
+ try {
+ MGraph providedMGraph =
provider.createMGraph(name);
+ LockableMGraph result;
+ if (providedMGraph instanceof LockableMGraph) {
+ result = (LockableMGraph)
providedMGraph;
+ } else {
+ result = new
LockableMGraphWrapper(providedMGraph);
+ }
+
+ // unregisters a possible Graph or MGraph
service under this name
+ // provided by a WeightedTcProvider with a
lower weight.
+ tcDisappears(name);
+ mGraphCache.put(name, new
MGraphHolder(provider, null));
+ mGraphAppears(name);
+ return result;
+ } catch (UnsupportedOperationException e) {
+ //we do nothing and try our luck with the next
provider
+ } catch (IllegalArgumentException e) {
+ //we do nothing and try our luck with the next
provider
+ }
+ }
+ throw new UnsupportedOperationException(
+ "No provider could create MGraph.");
+ }
+
+ @Override
+ public Graph createGraph(UriRef name, TripleCollection triples) {
+ for (WeightedTcProvider provider : providerList) {
+ try {
+ Graph result = provider.createGraph(name,
triples);
+
+ // unregisters a possible Graph or MGraph
service under this name
+ // provided by a WeightedTcProvider with a
lower weight.
+ tcDisappears(name);
+ mGraphCache.put(name, new
MGraphHolder(provider, null));
+ graphAppears(name);
+ return result;
+ } catch (UnsupportedOperationException e) {
+ //we do nothing and try our luck with the next
provider
+ } catch (IllegalArgumentException e) {
+ //we do nothing and try our luck with the next
provider
+ }
+ }
+ throw new UnsupportedOperationException(
+ "No provider could create Graph.");
+ }
+
+ @Override
+ public void deleteTripleCollection(UriRef name) {
+ for (TcProvider provider : providerList) {
+ try {
+ provider.deleteTripleCollection(name);
+ final MGraphHolder holder =
mGraphCache.get(name);
+ if ((holder != null)
+ &&
(holder.getWeightedTcProvider() != null)
+ &&
holder.getWeightedTcProvider().equals(provider)) {
+ tcDisappears(name);
+ mGraphCache.remove(name);
+ }
+ return;
+ } catch (UnsupportedOperationException e) {
+ // we do nothing and try our luck with the next
provider
+ } catch (NoSuchEntityException e) {
+ //we do nothing and try our luck with the next
provider
+ } catch (IllegalArgumentException e) {
+ //we do nothing and try our luck with the next
provider
+ }
+ }
+ // this throws a NoSuchEntityException if the graph doesn't
exist
+ getTriples(name);
+ // the entity exists but cannot be deleted
+ throw new UnsupportedOperationException(
+ "No provider could delete the entity.");
+ }
+
+ @Override
+ public Set<UriRef> getNames(Graph graph) {
+ Set<UriRef> result = new HashSet<UriRef>();
+ for (TcProvider provider : providerList) {
+ result.addAll(provider.getNames(graph));
+ }
+ return result;
+ }
+
+ @Override
+ public Set<UriRef> listGraphs() {
+ Set<UriRef> result = new HashSet<UriRef>();
+ for (TcProvider provider : providerList) {
+ result.addAll(provider.listGraphs());
+ }
+ return result;
+ }
+
+ @Override
+ public Set<UriRef> listMGraphs() {
+ Set<UriRef> result = new HashSet<UriRef>();
+ for (TcProvider provider : providerList) {
+ result.addAll(provider.listMGraphs());
+ }
+ return result;
+ }
+
+ @Override
+ public Set<UriRef> listTripleCollections() {
+ Set<UriRef> result = new HashSet<UriRef>();
+ for (TcProvider provider : providerList) {
+ result.addAll(provider.listTripleCollections());
+ }
+ return result;
+ }
+
+ private LockableMGraph ensureLockable(MGraph providedMGraph) {
+ LockableMGraph result;
+ if (providedMGraph instanceof LockableMGraph) {
+ result = (LockableMGraph) providedMGraph;
+ } else {
+ result = new LockableMGraphWrapper(providedMGraph);
+ }
+ return result;
+ }
+
+ /**
+ * Contains an unsecured LockableMGraph, a ServiceRegistration and
+ * the WeightedTcProvider that generated the graph
+ */
+ private static class MGraphHolder {
+
+ private WeightedTcProvider tcProvider;
+ private WeakReference<LockableMGraph> mGraphReference;
+
+ MGraphHolder(WeightedTcProvider tcProvider, LockableMGraph
mGraph) {
+ this.tcProvider = tcProvider;
+ this.mGraphReference = new
WeakReference<LockableMGraph>(mGraph);
+ }
+
+ LockableMGraph getMGraph() {
+ return this.mGraphReference.get();
+ }
+
+ WeightedTcProvider getWeightedTcProvider() {
+ return this.tcProvider;
+ }
+ }
+
+ //methods for debuging / monitoring
+ public SortedSet<WeightedTcProvider> getProviderList() {
+ return providerList;
+ }
+}
Added:
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/WeightedProviderComparator.java
URL:
http://svn.apache.org/viewvc/incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/WeightedProviderComparator.java?rev=995973&view=auto
==============================================================================
---
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/WeightedProviderComparator.java
(added)
+++
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/WeightedProviderComparator.java
Fri Sep 10 20:36:58 2010
@@ -0,0 +1,20 @@
+package org.apache.clerezza.rdf.core.access;
+
+import java.util.Comparator;
+
+/**
+ * Compares the WeightedTcManagementProviders, descending for weight and
+ * ascending by name
+ */
+public class WeightedProviderComparator implements
Comparator<WeightedTcProvider> {
+
+ @Override
+ public int compare(WeightedTcProvider o1, WeightedTcProvider o2) {
+ int o1Weight = o1.getWeight();
+ int o2Weight = o2.getWeight();
+ if (o1Weight != o2Weight) {
+ return o2Weight - o1Weight;
+ }
+ return
o1.getClass().toString().compareTo(o2.getClass().toString());
+ }
+}