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());
+       }
+}


Reply via email to