Author: reto
Date: Thu Feb 17 23:25:17 2011
New Revision: 1071836

URL: http://svn.apache.org/viewvc?rev=1071836&view=rev
Log:
CLEREZZA-390: allows bundle with a higher start-level to override web-resources 
provided by bundles with a lower-startlevel

Added:
    
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/DirectoryOverlay.scala
Modified:
    
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/resources/OSGI-INF/serviceComponents.xml
    
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/BundleFsLoader.scala
    
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/PathNode2MGraph.scala
    
incubator/clerezza/trunk/parent/utils/src/main/java/org/apache/clerezza/utils/IteratorMerger.java

Modified: 
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/resources/OSGI-INF/serviceComponents.xml
URL: 
http://svn.apache.org/viewvc/incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/resources/OSGI-INF/serviceComponents.xml?rev=1071836&r1=1071835&r2=1071836&view=diff
==============================================================================
--- 
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/resources/OSGI-INF/serviceComponents.xml
 (original)
+++ 
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/resources/OSGI-INF/serviceComponents.xml
 Thu Feb 17 23:25:17 2011
@@ -2,9 +2,15 @@
 <components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0";>
        <scr:component enabled="true" immediate="true" 
name="org.apache.clerezza.platform.content.fsadaptor.BundleFsLoader">
                <implementation 
class="org.apache.clerezza.platform.content.fsadaptor.BundleFsLoader"/>
+               <service servicefactory="false">
+            <provide 
interface="org.apache.clerezza.rdf.core.access.WeightedTcProvider"/>
+        </service>
                <reference name="tcManager" 
interface="org.apache.clerezza.rdf.core.access.TcManager"
                cardinality="1..1" policy="static" bind="bindTcManager" 
unbind="unbindTcManager"/>
-               <reference name="parser" 
interface="org.apache.clerezza.platform.graphprovider.content.ContentGraphProvider"
+               <reference name="cgProvider" 
interface="org.apache.clerezza.platform.graphprovider.content.ContentGraphProvider"
                cardinality="1..1" policy="static" 
bind="bindContentGraphProvider" unbind="unbindContentGraphProvider"/>
+               <reference name="startLevel" 
interface="org.osgi.service.startlevel.StartLevel"
+               cardinality="1..1" policy="static" bind="bindStartLevel" 
unbind="unbindStartLevel"/>
+
        </scr:component>
 </components>

Modified: 
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/BundleFsLoader.scala
URL: 
http://svn.apache.org/viewvc/incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/BundleFsLoader.scala?rev=1071836&r1=1071835&r2=1071836&view=diff
==============================================================================
--- 
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/BundleFsLoader.scala
 (original)
+++ 
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/BundleFsLoader.scala
 Thu Feb 17 23:25:17 2011
@@ -22,79 +22,201 @@ package org.apache.clerezza.platform.con
 import java.util.Collections
 import org.apache.clerezza.platform.Constants
 import org.apache.clerezza.platform.graphprovider.content.ContentGraphProvider
+import org.apache.clerezza.rdf.core.Graph
 import org.apache.clerezza.rdf.core.MGraph
+import org.apache.clerezza.rdf.core.NonLiteral
+import org.apache.clerezza.rdf.core.Resource
+import org.apache.clerezza.rdf.core.TripleCollection
+import org.apache.clerezza.rdf.core.Triple
 import org.apache.clerezza.rdf.core.UriRef
 import org.apache.clerezza.rdf.core.access.NoSuchEntityException
 import org.apache.clerezza.rdf.core.access.TcManager
+import org.apache.clerezza.rdf.core.access.WeightedTcProvider
 import org.apache.clerezza.rdf.core.access.security.TcPermission
+import org.apache.clerezza.rdf.core.impl.AbstractMGraph
+import org.apache.clerezza.rdf.core.impl.SimpleMGraph
 import org.apache.clerezza.utils.osgi.BundlePathNode
 import org.osgi.framework.Bundle
 import org.osgi.framework.BundleEvent
 import org.osgi.framework.BundleListener
 import org.osgi.service.component.ComponentContext
+import org.osgi.service.startlevel.StartLevel
 import org.slf4j.LoggerFactory
+import scala.util._
 
 object BundleFsLoader {
        private val log = LoggerFactory.getLogger(classOf[BundleFsLoader])
 }
-class BundleFsLoader extends BundleListener with Logger {
+class BundleFsLoader extends BundleListener with Logger with 
WeightedTcProvider {
 
-       private val MGRAPH_NAME = new 
UriRef("http://zz.localhost/web-resources.graph";)
+       private val RESOURCE_MGRAPH_URI = new 
UriRef("http://zz.localhost/web-resources.graph";)
+       private var currentCacheUri: UriRef = null
 
        private var tcManager: TcManager = null
        private var cgProvider: ContentGraphProvider = null
+       private var startLevel: StartLevel = null
+       private var bundleList = List[Bundle]()
+       private var currentCacheMGraph: MGraph = null
+
+       private val virtualMGraph = new AbstractMGraph() {
+               override def performFilter(s: NonLiteral, p: UriRef,
+                               o: Resource): java.util.Iterator[Triple] = {
+                       currentCacheMGraph.filter(s,p,o)
+               }
 
-       protected def activate(context: ComponentContext) {
-               try {
-                       tcManager.getMGraph(MGRAPH_NAME);
-               } catch {
-                       case e: NoSuchEntityException => {
-                               tcManager.createMGraph(MGRAPH_NAME);
-                               
tcManager.getTcAccessController.setRequiredReadPermissions(
-                                       MGRAPH_NAME, Collections.singleton(new 
TcPermission(Constants.CONTENT_GRAPH_URI_STRING, TcPermission.READ)))
+               override def size = currentCacheMGraph.size
+       }
+
+       class UpdateThread extends Thread {
+
+               private var updateRequested = false;
+
+               start()
+
+               override def run() {
+                       try {
+                               while (!isInterrupted) {
+                                       synchronized {
+                                               while (!updateRequested) wait();
+                                       }
+                                       updateRequested = false
+                                       updateCache()
+                               }
+                       } catch {
+                               case e: InterruptedException => 
BundleFsLoader.log.debug("Update thread interrupted");
                        }
-                       case e => throw e
                }
-               for (bundle <- context.getBundleContext().getBundles()) {
-                       addToGraph(bundle);
+
+               def update() = {
+                       synchronized {
+                               updateRequested = true
+                               notify();
+                       }
+               }
+       }
+       
+       private var updateThread: UpdateThread = null
+
+
+       protected def activate(context: ComponentContext) {
+               synchronized {
+                       for (bundle <- context.getBundleContext().getBundles();
+                                       if bundle.getState == Bundle.ACTIVE) {
+                               bundleList ::= bundle
+                       }
+                       context.getBundleContext().addBundleListener(this);
+                       updateCache
+                       
tcManager.getTcAccessController.setRequiredReadPermissions(
+                                       RESOURCE_MGRAPH_URI, 
Collections.singleton(new TcPermission(Constants.CONTENT_GRAPH_URI_STRING, 
TcPermission.READ)))
+                       
cgProvider.addTemporaryAdditionGraph(RESOURCE_MGRAPH_URI)
+                       updateThread = new UpdateThread()
                }
-               context.getBundleContext().addBundleListener(this);
-               cgProvider.addTemporaryAdditionGraph(MGRAPH_NAME)
        }
        protected def deactivate(context: ComponentContext) {
-               context.getBundleContext().removeBundleListener(this);
-               cgProvider.removeTemporaryAdditionGraph(MGRAPH_NAME)
-               tcManager.deleteTripleCollection(MGRAPH_NAME);
+               synchronized {
+                       context.getBundleContext().removeBundleListener(this);
+                       updateThread.interrupt()
+                       
cgProvider.removeTemporaryAdditionGraph(RESOURCE_MGRAPH_URI)
+                       tcManager.deleteTripleCollection(currentCacheUri);
+               }
        }
 
-       def bundleChanged(event: BundleEvent) {
-               val bundle = event.getBundle();
-               event.getType() match  {
-                       case BundleEvent.STARTED =>
-                               addToGraph(bundle);
-                       case BundleEvent.STOPPED =>
-                               removeFromGraph(bundle);
-                       case _ => BundleFsLoader.log.debug("only reacting on 
bundle start and stop")
+       private def updateCache() = {
+               def getVirtualTripleCollection(bundles: Seq[Bundle]): 
TripleCollection = {
+                       if (bundles.isEmpty) {
+                               new SimpleMGraph()
+                       } else {
+                               val pathNode = new BundlePathNode(bundles.head, 
"CLEREZZA-INF/web-resources");
+                               if (pathNode.isDirectory) {
+                                       BundleFsLoader.log.debug("Creating 
directory overlay for "+bundles.head)
+                                       new DirectoryOverlay(pathNode, 
getVirtualTripleCollection(bundles.tail))
+                               } else {
+                                       getVirtualTripleCollection(bundles.tail)
+                               }
+                       }
+               }
+               synchronized {
+                       val sortedList = Sorting.stableSort(bundleList, 
(b:Bundle) => -startLevel.getBundleStartLevel(b))
+                       val newCacheUri = new 
UriRef("http://zz.localhost/web-resources-cache.graph"+System.currentTimeMillis)
+                       val newChacheMGraph = 
tcManager.createMGraph(newCacheUri);
+                       
tcManager.getTcAccessController.setRequiredReadPermissions(
+                                       newCacheUri, Collections.singleton(new 
TcPermission(Constants.CONTENT_GRAPH_URI_STRING, TcPermission.READ)))
+                       
newChacheMGraph.addAll(getVirtualTripleCollection(sortedList))
+                       currentCacheMGraph = newChacheMGraph
+                       val oldCacheUri = currentCacheUri
+                       currentCacheUri = newCacheUri
+                       if (oldCacheUri != null) 
tcManager.deleteTripleCollection(oldCacheUri);
+                       BundleFsLoader.log.debug("updated web-resource cache")
                }
        }
+
        
-       def addToGraph(bundle: Bundle) {
-               val pathNode = new BundlePathNode(bundle, 
"CLEREZZA-INF/web-resources");
-               val mGraph: MGraph = tcManager.getMGraph(MGRAPH_NAME);
-               PathNode2MGraph.describeInGraph(pathNode, mGraph);
-               BundleFsLoader.log.info("size of mgraph after adding resources 
of {}: {}", bundle, mGraph.size)
-               //log.info("size of mgraph after adding resources of {}: {}", 
bundle, mGraph.size)
+
+       override def getWeight() = 30
+
+       override def getMGraph(name: UriRef) = {
+               if (name.equals(RESOURCE_MGRAPH_URI)) {
+                       virtualMGraph
+               } else {
+                       throw new NoSuchEntityException(name);
+               }
        }
 
-       def removeFromGraph(bundle: Bundle) {
-               val pathNode = new BundlePathNode(bundle, 
"CLEREZZA-INF/web-resources");
-               val mGraph: MGraph = tcManager.getMGraph(MGRAPH_NAME);
-               BundleFsLoader.log.info("Size of mgraph before removing 
resources of {}: {}", bundle, mGraph.size)
-               PathNode2MGraph.removeNodesFromGraph(pathNode, mGraph);
-               BundleFsLoader.log.info("Size of mgraph after removing 
resources of {}: {}", bundle, mGraph.size)
+       override def getTriples(name: UriRef) = {
+               getMGraph(name);
+       }
 
+       override def getGraph(name: UriRef) = {
+               throw new NoSuchEntityException(name);
        }
 
+
+       override def listMGraphs(): java.util.Set[UriRef] = {
+               java.util.Collections.singleton(RESOURCE_MGRAPH_URI);
+       }
+
+       override def listGraphs() = {
+               new java.util.HashSet[UriRef]();
+       }
+
+       override def listTripleCollections() = {
+               Collections.singleton(RESOURCE_MGRAPH_URI);
+       }
+
+       override def createMGraph(name: UriRef) =  {
+               throw new UnsupportedOperationException("Not supported.");
+       }
+
+       override def createGraph(name: UriRef, triples: TripleCollection): 
Graph = {
+               throw new UnsupportedOperationException("Not supported.");
+       }
+
+       override def deleteTripleCollection(name: UriRef) {
+               throw new UnsupportedOperationException("Not supported.");
+       }
+
+       override def getNames(graph: Graph) = {
+               val result = new java.util.HashSet[UriRef]();
+               result;
+       }
+
+
+       def bundleChanged(event: BundleEvent) {
+               val bundle = event.getBundle();
+               event.getType() match  {
+                       case BundleEvent.STARTED => {
+                               bundleList ::= bundle
+                               updateThread.update()
+                       }
+                       case BundleEvent.STOPPED => {
+                               bundleList = bundleList.filterNot(b => b == 
bundle)
+                               updateThread.update()
+                       }
+                       case _ => BundleFsLoader.log.debug("only reacting on 
bundle start and stop")
+               }
+       }
+
+
        def bindTcManager(tcManager: TcManager) {
                this.tcManager = tcManager;
        }
@@ -110,4 +232,13 @@ class BundleFsLoader extends BundleListe
        def unbindContentGraphProvider(p: ContentGraphProvider) {
                cgProvider = null
        }
+
+       def bindStartLevel(startLevel: StartLevel) {
+               this.startLevel = startLevel;
+       }
+
+       def unbindStartLevel(startLevel: StartLevel) {
+               this.startLevel = null;
+       }
+       
 }

Added: 
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/DirectoryOverlay.scala
URL: 
http://svn.apache.org/viewvc/incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/DirectoryOverlay.scala?rev=1071836&view=auto
==============================================================================
--- 
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/DirectoryOverlay.scala
 (added)
+++ 
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/DirectoryOverlay.scala
 Thu Feb 17 23:25:17 2011
@@ -0,0 +1,76 @@
+/*
+ * 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.platform.content.fsadaptor
+
+import org.apache.clerezza.rdf.core.NonLiteral
+import org.apache.clerezza.rdf.core.Resource
+import org.apache.clerezza.rdf.core.Triple
+import org.apache.clerezza.rdf.core.TripleCollection
+import org.apache.clerezza.rdf.core.UriRef
+import org.apache.clerezza.rdf.core.impl.AbstractTripleCollection
+import org.apache.clerezza.rdf.core.impl.SimpleMGraph
+import org.apache.clerezza.utils.IteratorMerger
+import org.wymiwyg.commons.util.dirbrowser.PathNode
+import java.util.Iterator
+
+class DirectoryOverlay(pathNode: PathNode, base: TripleCollection)
+       extends AbstractTripleCollection {
+
+       private val addedTriples = new SimpleMGraph()
+
+       PathNode2MGraph.describeInGraph(pathNode, addedTriples)
+
+       import collection.JavaConversions._
+
+       val subjects = (for (triple <- addedTriples; subject = 
triple.getSubject) yield {
+               subject
+       }).toSet
+
+       class FilteringIterator(baseIter: Iterator[Triple]) extends 
Iterator[Triple] {
+               var nextElem: Triple = null
+               def prepareNext {
+                       nextElem = if (baseIter.hasNext) baseIter.next else null
+                       if ((nextElem != null) && 
+                               (subjects.contains(nextElem.getSubject))) {
+                                       //println("skipping "+nextElem)
+                                       prepareNext
+                       }
+               }
+               prepareNext
+
+               override def next = {
+                       val result = nextElem
+                       prepareNext
+                       result
+               }
+               override def hasNext = nextElem != null
+               override def remove = throw new UnsupportedOperationException
+       }
+
+       override def performFilter(s: NonLiteral, p: UriRef,
+                       o: Resource): Iterator[Triple] = {
+               new IteratorMerger(new FilteringIterator(base.filter(s, p, o)), 
addedTriples.filter(s,p, o))
+       }
+
+       /**
+        * returns an upper bound of the size (removals in abse are not 
deducted)
+        */
+       override def size = base.size+addedTriples.size
+}

Modified: 
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/PathNode2MGraph.scala
URL: 
http://svn.apache.org/viewvc/incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/PathNode2MGraph.scala?rev=1071836&r1=1071835&r2=1071836&view=diff
==============================================================================
--- 
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/PathNode2MGraph.scala
 (original)
+++ 
incubator/clerezza/trunk/parent/platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/PathNode2MGraph.scala
 Thu Feb 17 23:25:17 2011
@@ -47,7 +47,12 @@ object PathNode2MGraph {
 
        private def getMediaType(file: PathNode) = {
                val guessedMediaType: MediaType = 
MediaTypeGuesser.getInstance().guessTypeForName(file.getPath());
-               guessedMediaType.toString
+               if (guessedMediaType != null) {
+                       guessedMediaType.toString
+               } else {
+                       "application/octet-stream"
+               }
+
        }
 
        private def getData(file: PathNode) = {

Modified: 
incubator/clerezza/trunk/parent/utils/src/main/java/org/apache/clerezza/utils/IteratorMerger.java
URL: 
http://svn.apache.org/viewvc/incubator/clerezza/trunk/parent/utils/src/main/java/org/apache/clerezza/utils/IteratorMerger.java?rev=1071836&r1=1071835&r2=1071836&view=diff
==============================================================================
--- 
incubator/clerezza/trunk/parent/utils/src/main/java/org/apache/clerezza/utils/IteratorMerger.java
 (original)
+++ 
incubator/clerezza/trunk/parent/utils/src/main/java/org/apache/clerezza/utils/IteratorMerger.java
 Thu Feb 17 23:25:17 2011
@@ -20,6 +20,7 @@
 package org.apache.clerezza.utils;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 
@@ -51,6 +52,15 @@ public class IteratorMerger<T> implement
        }
 
        /**
+        * constructs an iterator that will return the elements of the 
baseIterators
+        *
+        * @param baseIterators
+        */
+       public IteratorMerger(Iterator<T>... baseIterators) {
+               init(Arrays.asList(baseIterators).iterator());
+       }
+
+       /**
         * Constructs an iterator that iterates over all elements of the 
collections
         * contained in the collection.
         * 


Reply via email to