You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@clerezza.apache.org by re...@apache.org on 2011/02/18 00:25:17 UTC

svn commit: r1071836 - in /incubator/clerezza/trunk/parent: platform.content.fsadaptor/src/main/resources/OSGI-INF/ platform.content.fsadaptor/src/main/scala/org/apache/clerezza/platform/content/fsadaptor/ utils/src/main/java/org/apache/clerezza/utils/

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.
 	 *