You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stanbol.apache.org by fc...@apache.org on 2011/03/24 14:56:54 UTC

svn commit: r1084961 - in /incubator/stanbol/branches/http-endpoint-refactoring/commons/web: ./ src/main/java/org/apache/stanbol/commons/ src/main/java/org/apache/stanbol/commons/web/ src/main/java/org/apache/stanbol/commons/web/processor/ src/main/jav...

Author: fchrist
Date: Thu Mar 24 13:56:53 2011
New Revision: 1084961

URL: http://svn.apache.org/viewvc?rev=1084961&view=rev
Log:
STANBOL-120 Cleaned commons web and removed enhancer stuff

Added:
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JerseyEndpoint.java
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JerseyEndpointApplication.java
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JettyServer.java
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/processor/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/processor/FreemarkerViewProcessor.java
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/resource/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/resource/NavigationMixin.java
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/resource/StanbolRootResource.java
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/GraphWriter.java
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/JsonLdSerializerProvider.java
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/ResultSetToXml.java
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/ResultSetWriter.java
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/resources/META-INF/templates/org/apache/stanbol/commons/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/resources/META-INF/templates/org/apache/stanbol/commons/web/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/resources/META-INF/templates/org/apache/stanbol/commons/web/resource/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/resources/META-INF/templates/org/apache/stanbol/commons/web/resource/StanbolRootResource/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/resources/META-INF/templates/org/apache/stanbol/commons/web/resource/StanbolRootResource/index.ftl
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/test/java/org/apache/stanbol/commons/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/test/java/org/apache/stanbol/commons/web/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/test/java/org/apache/stanbol/commons/web/writers/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/test/java/org/apache/stanbol/commons/web/writers/JsonLdSerializerProviderTest.java
Removed:
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/enhancer/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/resources/META-INF/templates/imports/contentitem.ftl
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/resources/META-INF/templates/imports/entities.ftl
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/resources/META-INF/templates/imports/sparql.ftl
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/resources/META-INF/templates/org/apache/stanbol/enhancer/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/test/java/eu/
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/test/java/org/apache/stanbol/enhancer/
Modified:
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/README.txt
    incubator/stanbol/branches/http-endpoint-refactoring/commons/web/pom.xml

Modified: incubator/stanbol/branches/http-endpoint-refactoring/commons/web/README.txt
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/http-endpoint-refactoring/commons/web/README.txt?rev=1084961&r1=1084960&r2=1084961&view=diff
==============================================================================
--- incubator/stanbol/branches/http-endpoint-refactoring/commons/web/README.txt (original)
+++ incubator/stanbol/branches/http-endpoint-refactoring/commons/web/README.txt Thu Mar 24 13:56:53 2011
@@ -1,87 +1,5 @@
-Jersey front-end to the FISE engine
-===================================
+Stanbol HTTP Jersey Endpoint
+============================
 
-Goals for this sub-project:
 
-- RESTful web services API to Stanbol Enhancer for machines.
-
-- Human-friendly HTML interface to quickly test the service and document the API.
-
-
-Building from source
---------------------
-
-Checkount and build Stanbol Enhancer and Stanbol Entityhub:
-
-  $ svn checkout http://svn.apache.org/repos/asf/incubator/stanbol/trunk/entityhub stanbol-entityhub
-  $ cd stanbol-entityhub
-  $ mvn clean install
-  $ cd ..
-
-  $ svn checkout http://svn.apache.org/repos/asf/incubator/stanbol/trunk/enhancer stanbol-enhancer
-  $ cd stanbol-enhancer
-  $ mvn clean install
-
-
-
-Deployment
-----------
-
-Go to 
-  - 'launchers/lite/target' to run the default configuration that comes with
-      a set of engines that is considered as stable
-  - 'launchers/full/target' to run the configuration that contains all availanle
-      engines.Stanbol
-
-  rm -rf sling && java -jar org.apache.stanbol.enhancer.launchers.sling-*-SNAPSHOT.jar
-
-Once deployed (check the logs) you can either use the HTML interface:
-
-  http://localhost:8080
-
-To submit data to engines using a simple form:
-
-  http://localhost:8080/engines
-
-If that page gives errors such as class not found, no web provider, stop and restart the jersey-server bundle.
-There's a bug in Jersey 1.2 that causes those if the core bundle starts before the server bundle.
-
-You can setup an apache virtualhost to blend a Stanbol ehnacer instance on you 
-domain name using a ``NameVirtualHost *:80`` instruction in you global apache 
-configuration and the following virtualhost parameters::
-
-  <VirtualHost *:80>
-
-  ServerName stanbol-enhancer.example.com
-
-  CustomLog logs/stanbol-enhancer.example.com.access.log combined
-  ErrorLog logs/stanbol-enhancer.example.com.error.log
-
-  ProxyPass/  http://localhost:8080/
-  ProxyPassReverse/ http://localhost:8080/
-  ProxyPreserveHostOn
-
-  </VirtualHost>
-
-
-Stateless operation
--------------------
-
-You can use the HTTP (somewhat RESTful) API directly with cURL for instance:
-
-  $ curl -X POST -H "Content-type: text/plain" --data "Paris is a beautiful city." http://localhost:8080/engines/
-
-You can force a specific RDF serialization scheme by setting the "Accept" HTTP header:
-
-  $ curl -X POST -H "Content-type: text/plain" -H "Accept: application/rdf+xml" --data "Paris is a beautiful city." http://localhost:8080/engines/
-
-Or to upload the content of a file:
-
-  $ curl -X POST -H "Content-type: text/plain" -H "Accept: text/rdf+nt" --data @/path/to/my_local_file.txt http://localhost:8080/engines/
-
-
-Asynchronous and stateful operation
------------------------------------
-
-TODO: implement and document me!
 

Modified: incubator/stanbol/branches/http-endpoint-refactoring/commons/web/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/http-endpoint-refactoring/commons/web/pom.xml?rev=1084961&r1=1084960&r2=1084961&view=diff
==============================================================================
--- incubator/stanbol/branches/http-endpoint-refactoring/commons/web/pom.xml (original)
+++ incubator/stanbol/branches/http-endpoint-refactoring/commons/web/pom.xml Thu Mar 24 13:56:53 2011
@@ -41,7 +41,7 @@
 				<configuration>
 					<instructions>
 						<Export-Package>
-							org.apache.stanbol.enhancer.jersey.*
+							org.apache.stanbol.commons.web.*
             			</Export-Package>
 						<Embed-Dependency>*;scope=compile|runtime;inline=false;artifactId=jersey-json|jettison|jackson-core-asl</Embed-Dependency>
 						<Embed-Dependency>freemarker</Embed-Dependency>
@@ -67,16 +67,6 @@
 	</build>
 
 	<dependencies>
-
-		<!-- dependencies on other IKS modules -->
-		<dependency>
-			<groupId>org.apache.stanbol</groupId>
-			<artifactId>org.apache.stanbol.enhancer.servicesapi</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.apache.stanbol</groupId>
-			<artifactId>org.apache.stanbol.enhancer.standalone</artifactId>
-		</dependency>
 		<dependency>
 			<groupId>org.apache.stanbol</groupId>
 			<artifactId>org.apache.stanbol.jsonld</artifactId>
@@ -85,25 +75,9 @@
 		<!-- Clerezza dependencies -->
 		<dependency>
 			<groupId>org.apache.clerezza</groupId>
-			<artifactId>org.apache.clerezza.rdf.core</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.apache.clerezza</groupId>
-			<artifactId>org.apache.clerezza.jaxrs.rdf.providers</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.apache.clerezza</groupId>
 			<artifactId>org.apache.clerezza.rdf.jena.serializer</artifactId>
 		</dependency>
-		<dependency>
-			<groupId>org.apache.clerezza</groupId>
-			<artifactId>org.apache.clerezza.rdf.jena.parser</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.apache.clerezza</groupId>
-			<artifactId>org.apache.clerezza.rdf.rdfjson</artifactId>
-		</dependency>
-
+ 
 		<!-- Jersey -->
 		<dependency>
 			<groupId>com.sun.jersey</groupId>
@@ -178,54 +152,12 @@
 			<artifactId>slf4j-simple</artifactId>
 			<scope>test</scope>
 		</dependency>
-				
-		<dependency>
-			<groupId>org.apache.stanbol</groupId>
-			<artifactId>org.apache.stanbol.enhancer.jobmanager</artifactId>
-			<scope>test</scope>
-		</dependency>
 		<dependency>
 			<groupId>org.apache.stanbol</groupId>
-			<artifactId>org.apache.stanbol.enhancer.engines.autotagging</artifactId>
+			<artifactId>org.apache.stanbol.enhancer.servicesapi</artifactId>
 			<scope>test</scope>
 		</dependency>
 		
-		<dependency>
-			<groupId>org.apache.lucene</groupId>
-			<artifactId>lucene-queries</artifactId>
-			<scope>test</scope>
-		</dependency>		
-		<dependency>
-			<groupId>org.apache.lucene</groupId>
-			<artifactId>lucene-analyzers</artifactId>
-			<scope>test</scope>
-		</dependency>		
-		
-		<dependency>
-			<groupId>org.mockito</groupId>
-			<artifactId>mockito-all</artifactId>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>com.sun.jersey</groupId>
-			<artifactId>jersey-client</artifactId>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.ops4j.pax.exam</groupId>
-			<artifactId>pax-exam</artifactId>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.ops4j.pax.exam</groupId>
-			<artifactId>pax-exam-junit</artifactId>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.ops4j.pax.exam</groupId>
-			<artifactId>pax-exam-container-default</artifactId>
-			<scope>test</scope>
-		</dependency>
 	</dependencies>
 
 </project>

Added: incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JerseyEndpoint.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JerseyEndpoint.java?rev=1084961&view=auto
==============================================================================
--- incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JerseyEndpoint.java (added)
+++ incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JerseyEndpoint.java Thu Mar 24 13:56:53 2011
@@ -0,0 +1,119 @@
+package org.apache.stanbol.commons.web;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+import org.apache.clerezza.rdf.core.serializedform.Serializer;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.stanbol.commons.web.processor.FreemarkerViewProcessor;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.http.NamespaceException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.jersey.spi.container.servlet.ServletContainer;
+
+/**
+ * Jersey-based RESTful endpoint for the Stanbol Enhancer engines and store.
+ * <p>
+ * This OSGi component serves as a bridge between the OSGi context and the Servlet context available to JAX-RS
+ * resources.
+ */
+@Component(immediate = true, metatype = true)
+public class JerseyEndpoint {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Property(value = "/")
+    public static final String ALIAS_PROPERTY = "org.apache.stanbol.commons.web.alias";
+
+    @Property(value = "/static")
+    public static final String STATIC_RESOURCES_URL_ROOT_PROPERTY = "org.apache.stanbol.commons.web.static.url";
+
+    @Property(value = "/META-INF/static")
+    public static final String STATIC_RESOURCES_CLASSPATH_PROPERTY = "org.apache.stanbol.commons.web.static.classpath";
+
+    @Property(value = "/META-INF/templates")
+    public static final String FREEMARKER_TEMPLATE_CLASSPATH_PROPERTY = "org.apache.stanbol.commons.web.templates.classpath";
+
+    @Reference
+    HttpService httpService;
+
+    @Reference
+    Serializer serializer;
+
+    protected ServletContext servletContext;
+
+    public Dictionary<String,String> getInitParams() {
+        // pass configuration for Jersey resource
+        // TODO: make the list of enabled JAX-RS resources and providers
+        // configurable using an OSGi service
+        Dictionary<String,String> initParams = new Hashtable<String,String>();
+        initParams.put("javax.ws.rs.Application", JerseyEndpointApplication.class.getName());
+
+        // make jersey automatically turn resources into Viewable models and
+        // hence lookup matching freemarker templates
+        initParams.put("com.sun.jersey.config.feature.ImplicitViewables", "true");
+        return initParams;
+    }
+
+    @Activate
+    protected void activate(ComponentContext ctx) throws IOException, ServletException, NamespaceException {
+
+        // register the JAX-RS resources as a servlet under configurable alias
+        ServletContainer container = new ServletContainer();
+        String alias = (String) ctx.getProperties().get(ALIAS_PROPERTY);
+        String staticUrlRoot = (String) ctx.getProperties().get(STATIC_RESOURCES_URL_ROOT_PROPERTY);
+        String staticClasspath = (String) ctx.getProperties().get(STATIC_RESOURCES_CLASSPATH_PROPERTY);
+        String freemakerTemplates = (String) ctx.getProperties().get(FREEMARKER_TEMPLATE_CLASSPATH_PROPERTY);
+
+        log.info("Registering servlets with HTTP service " + httpService.toString());
+        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+        try {
+            httpService.registerServlet(alias, container, getInitParams(), null);
+            httpService.registerResources(staticUrlRoot, staticClasspath, null);
+        } finally {
+            Thread.currentThread().setContextClassLoader(classLoader);
+        }
+
+        // forward the main Stanbol Enhancer OSGi components to the servlet context so that
+        // they can be looked up by the JAX-RS resources
+        servletContext = container.getServletContext();
+        servletContext.setAttribute(BundleContext.class.getName(), ctx.getBundleContext());
+        servletContext.setAttribute(Serializer.class.getName(), serializer);
+
+        servletContext.setAttribute(STATIC_RESOURCES_URL_ROOT_PROPERTY, staticUrlRoot);
+        servletContext.setAttribute(FreemarkerViewProcessor.FREEMARKER_TEMPLATE_PATH_INIT_PARAM,
+            freemakerTemplates);
+
+        log.info("Jersey servlet registered at {}", alias);
+    }
+
+    @Deactivate
+    protected void deactivate(ComponentContext ctx) {
+        log.info("Deactivating jersey bundle");
+        String alias = (String) ctx.getProperties().get(ALIAS_PROPERTY);
+        httpService.unregister(alias);
+        servletContext = null;
+    }
+
+    protected void bindHttpService(HttpService httpService) {
+        this.httpService = httpService;
+    }
+
+    protected void unbindHttpService(HttpService httpService) {
+        this.httpService = null;
+    }
+
+}

Added: incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JerseyEndpointApplication.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JerseyEndpointApplication.java?rev=1084961&view=auto
==============================================================================
--- incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JerseyEndpointApplication.java (added)
+++ incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JerseyEndpointApplication.java Thu Mar 24 13:56:53 2011
@@ -0,0 +1,44 @@
+package org.apache.stanbol.commons.web;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.ws.rs.core.Application;
+
+import org.apache.stanbol.commons.web.processor.FreemarkerViewProcessor;
+import org.apache.stanbol.commons.web.resource.StanbolRootResource;
+import org.apache.stanbol.commons.web.writers.GraphWriter;
+import org.apache.stanbol.commons.web.writers.ResultSetWriter;
+
+/**
+ * Statically define the list of available resources and providers to be used by the Stanbol JAX-RS Endpoint.
+ * <p>
+ * The jersey auto-scan mechanism does not seem to work when deployed through OSGi's HttpService
+ * initialization.
+ * <p>
+ * In the future this class might get refactored as an OSGi service to allow for dynamic configuration and
+ * deployment of additional JAX-RS resources and providers.
+ */
+public class JerseyEndpointApplication extends Application {
+
+    @Override
+    public Set<Class<?>> getClasses() {
+        Set<Class<?>> classes = new HashSet<Class<?>>();
+        // resources
+        classes.add(StanbolRootResource.class);
+
+        // message body writers
+        classes.add(GraphWriter.class);
+        classes.add(ResultSetWriter.class);
+        return classes;
+    }
+
+    @Override
+    public Set<Object> getSingletons() {
+        Set<Object> singletons = new HashSet<Object>();
+        // view processors
+        singletons.add(new FreemarkerViewProcessor());
+        return singletons;
+    }
+
+}

Added: incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JettyServer.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JettyServer.java?rev=1084961&view=auto
==============================================================================
--- incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JettyServer.java (added)
+++ incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/JettyServer.java Thu Mar 24 13:56:53 2011
@@ -0,0 +1,94 @@
+package org.apache.stanbol.commons.web;
+
+import java.net.URI;
+import java.util.Dictionary;
+import java.util.Enumeration;
+
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.servlet.Context;
+import org.mortbay.jetty.servlet.ServletHolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.jersey.spi.container.servlet.ServletContainer;
+
+/**
+ * Standalone (OSGi independent) Jetty-based server with the Stanbol Jersey
+ * endpoint. The OSGi component need be injected manually to the ServletContext
+ * to make them available to the resources.
+ * <p>
+ * This class is mainly useful for testing the JAX-RS resources without faking a
+ * complete OSGI runtime.
+ * <p>
+ * For seamless OSGi deployments the JerseyEndpoint component should be
+ * automatically registered in the container and registers the JAXRS resources
+ * automatically.
+ */
+public class JettyServer {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    public static final String DEFAULT_BASE_URI = "http://localhost:9998/";
+
+    private Server server = new Server();
+
+    private Context context;
+
+    public void start(String baseUri) throws Exception {
+        log.info("starting the Jetty / Jersey endpoint");
+        ServletHolder servletHolder = new ServletHolder(ServletContainer.class);
+        Dictionary<String, String> initParams = new JerseyEndpoint().getInitParams();
+        Enumeration<String> keys = initParams.keys();
+        while (keys.hasMoreElements()) {
+            String key = keys.nextElement();
+            servletHolder.setInitParameter(key, initParams.get(key));
+        }
+
+        URI uri = new URI(baseUri);
+        // restart any previous server instance while keeping the previous
+        // attribute settings
+        if (server.isRunning()) {
+            server.stop();
+        }
+        server = new Server(uri.getPort());
+        context = new Context(server, "/", Context.SESSIONS);
+        context.addServlet(servletHolder, "/*");
+        server.start();
+    }
+
+    public void stop() throws Exception {
+        log.info("stopping the Jetty / Jersey endpoint");
+        server.stop();
+    }
+
+    public void setAttribute(String name, Object value) {
+        if (context != null) {
+            context.getServletContext().setAttribute(name, value);
+        }
+    }
+
+    public Object getAttribute(String name) {
+        if (context != null) {
+            return context.getServletContext().getAttribute(name);
+        }
+        return null;
+    }
+
+    public void removeAttribute(String name) {
+        if (context != null) {
+            context.getServletContext().removeAttribute(name);
+        }
+    }
+
+    /**
+     * For starting manually.
+     */
+    public static void main(String[] args) throws Exception {
+        JettyServer server = new JettyServer();
+        server.start(DEFAULT_BASE_URI);
+        System.out.println("Hit enter to stop it...");
+        System.in.read();
+        server.stop();
+    }
+
+}

Added: incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/processor/FreemarkerViewProcessor.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/processor/FreemarkerViewProcessor.java?rev=1084961&view=auto
==============================================================================
--- incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/processor/FreemarkerViewProcessor.java (added)
+++ incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/processor/FreemarkerViewProcessor.java Thu Mar 24 13:56:53 2011
@@ -0,0 +1,220 @@
+package org.apache.stanbol.commons.web.processor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.ext.Provider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.jersey.api.view.Viewable;
+import com.sun.jersey.spi.resource.Singleton;
+import com.sun.jersey.spi.template.ViewProcessor;
+
+import freemarker.cache.ClassTemplateLoader;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+
+/**
+ * Match a Viewable-named view with a Freemarker template.
+ *
+ * This class is based on the following original implementation:
+ * http://github.com/cwinters/jersey-freemarker/
+ *
+ * <p>
+ * You can configure the location of your templates with the context param
+ * 'freemarker.template.path'. If not assigned we'll use a default of
+ * <tt>WEB-INF/templates</tt>. Note that this uses Freemarker's
+ * {@link freemarker.cache.WebappTemplateLoader} to load/cache the templates, so
+ * check its docs (or crank up the logging under the 'freemarker.cache' package)
+ * if your templates aren't getting loaded.
+ * </p>
+ *
+ * <p>
+ * This will put your Viewable's model object in the template variable "it",
+ * unless the model is a Map. If so, the values will be assigned to the template
+ * assuming the map is of type <tt>Map&lt;String,Object></tt>.
+ * </p>
+ *
+ * <p>
+ * There are a number of methods you can override to change the behavior, such
+ * as handling processing exceptions, changing the default template extension,
+ * or adding variables to be assigned to every template context.
+ * </p>
+ *
+ * @author Chris Winters <ch...@cwinters.com> // original code
+ * @author Olivier Grisel <og...@nuxeo.com> // ViewProcessor refactoring
+ */
+@Singleton
+@Provider
+public class FreemarkerViewProcessor implements ViewProcessor<Template> {
+
+    public static final String FREEMARKER_TEMPLATE_PATH_INIT_PARAM = "freemarker.template.path";
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    protected Configuration freemarkerConfig;
+
+    protected String rootPath;
+
+    @Context
+    protected ServletContext context;
+
+    public FreemarkerViewProcessor() {
+    }
+
+    /**
+     * @return extension for templates, ".ftl" by default; if we don't see this
+     *         at the end of your view we'll append it so we can find the
+     *         template resource
+     */
+    protected String getDefaultExtension() {
+        return ".ftl";
+    }
+
+    /**
+     * Define additional variables to make available to the template.
+     *
+     * @param viewableVariables variables provided by whomever generated the
+     *            viewable object; these are provided for reference only, there
+     *            will be no effect if you modify this map
+     * @return new variables for the template context, which will override any
+     *         defaults provided
+     */
+    protected Map<String, Object> getVariablesForTemplate(
+            final Map<String, Object> viewableVariables) {
+        return Collections.emptyMap();
+    }
+
+    /**
+     * Catch any exception generated during template processing.
+     *
+     * @param t throwable caught
+     * @param templatePath path of template we're executing
+     * @param templateContext context use when evaluating this template
+     * @param out output stream from servlet container
+     * @throws IOException on any write errors, or if you want to rethrow
+     */
+    protected void onProcessException(final Throwable t,
+            final Template template, final Map<String, Object> templateContext,
+            final OutputStream out) throws IOException {
+        log.error("Error processing freemarker template @ "
+                + template.getName() + ": " + t.getMessage(), t);
+        out.write("<pre>".getBytes());
+        t.printStackTrace(new PrintStream(out));
+        out.write("</pre>".getBytes());
+    }
+
+    /**
+     * Modify freemarker configuration after we've created it and applied any
+     * settings from 'freemarker.properties' on the classpath.
+     *
+     * @param config configuration we've created so far
+     * @param context servlet context used to create the configuration
+     */
+    protected void assignFreemarkerConfig(final Configuration config,
+            final ServletContext context) {
+        // TODO read those parameters from context instead of hardcoding them
+
+        // don't always put a ',' in numbers (e.g., id=2000 vs id=2,000)
+        config.setNumberFormat("0");
+
+        // don't look for list.en.ftl when list.ftl requested
+        config.setLocalizedLookup(false);
+
+        // don't cache for more that 2s
+        config.setTemplateUpdateDelay(2);
+        log.info("Assigned default freemarker configuration");
+    }
+
+    protected Configuration getConfig() {
+        if (freemarkerConfig == null) {
+            // deferred initialization of the freemarker config to ensure that
+            // the injected ServletContext is fully functional and for some
+            // reason the #getInitParam access does not work hence using the
+            // #getAttribute access after servlet init.
+            Configuration config = new Configuration();
+            if (context != null) {
+                rootPath = (String) context.getAttribute(FREEMARKER_TEMPLATE_PATH_INIT_PARAM);
+            }
+            if (rootPath == null || rootPath.trim().length() == 0) {
+                log.info("No 'freemarker.template.path' context-param, "
+                        + "defaulting to '/WEB-INF/templates'");
+                rootPath = "/WEB-INF/templates";
+            }
+            rootPath = rootPath.replaceAll("/$", "");
+            config.setTemplateLoader(new ClassTemplateLoader(getClass(), rootPath));
+
+            // TODO: make the usage of a freemaker properties file an explicit
+            // parameter declared in the servlet context instead of magic
+            // classloading auto-detect. That way the application could
+            // explicitly override the defaults
+            final InputStream fmProps = context.getResourceAsStream("freemarker.properties");
+            boolean loadDefaults = true;
+            if (fmProps != null) {
+                try {
+                    config.setSettings(fmProps);
+                    log.info("Assigned freemarker configuration from 'freemarker.properties'");
+                    loadDefaults = false;
+                } catch (Throwable t) {
+                    log.warn(
+                            "Failed to load/assign freemarker.properties, will"
+                                    + " use default settings instead: "
+                                    + t.getMessage(), t);
+                }
+            }
+            if (loadDefaults) {
+                assignFreemarkerConfig(config, context);
+            }
+            freemarkerConfig = config;
+        }
+        return freemarkerConfig;
+    }
+
+    public Template resolve(final String path) {
+        // accept both '/path/to/template' and '/path/to/template.ftl'
+        final String defaultExtension = getDefaultExtension();
+        final String filePath = path.endsWith(defaultExtension) ? path : path
+                + defaultExtension;
+        try {
+            return getConfig().getTemplate(filePath);
+        } catch (IOException e) {
+            log.error("Failed to load freemaker template: " + rootPath
+                    + filePath);
+            return null;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void writeTo(Template template, Viewable viewable, OutputStream out)
+            throws IOException {
+        out.flush(); // send status + headers
+
+        Object model = viewable.getModel();
+        final Map<String, Object> vars = new HashMap<String, Object>();
+        if (model instanceof Map<?, ?>) {
+            vars.putAll((Map<String, Object>) model);
+        } else {
+            vars.put("it", model);
+        }
+        // override custom variables if any
+        vars.putAll(getVariablesForTemplate(vars));
+
+        final OutputStreamWriter writer = new OutputStreamWriter(out);
+        try {
+            template.process(vars, writer);
+        } catch (Throwable t) {
+            onProcessException(t, template, vars, out);
+        }
+    }
+
+}

Added: incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/resource/NavigationMixin.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/resource/NavigationMixin.java?rev=1084961&view=auto
==============================================================================
--- incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/resource/NavigationMixin.java (added)
+++ incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/resource/NavigationMixin.java Thu Mar 24 13:56:53 2011
@@ -0,0 +1,54 @@
+package org.apache.stanbol.commons.web.resource;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
+
+public class NavigationMixin {
+
+    @Context
+    protected UriInfo uriInfo;
+
+    public URI getPublicBaseUri() {
+        return uriInfo.getBaseUri();
+    }
+
+    public List<MenuItem> getMainMenuItems() {
+        return Arrays.asList(
+                new MenuItem("/engines", "/engines", uriInfo),
+                new MenuItem("/store", "/store", uriInfo),
+                new MenuItem("/sparql", "/sparql", uriInfo));
+    }
+
+    public static class MenuItem {
+
+        public MenuItem(String label, String link, UriInfo uriInfo) {
+            this.label = label;
+            this.link = link;
+            cssClass = uriInfo.getPath().startsWith(link.substring(1)) ? "selected" : "unselected";
+        }
+
+        protected final String label;
+
+        protected final  String link;
+
+        protected final  String cssClass;
+
+        public String getLabel() {
+            return label;
+        }
+
+        public String getLink() {
+            return link;
+        }
+
+        public String getCssClass() {
+            return cssClass;
+        }
+
+    }
+
+}

Added: incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/resource/StanbolRootResource.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/resource/StanbolRootResource.java?rev=1084961&view=auto
==============================================================================
--- incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/resource/StanbolRootResource.java (added)
+++ incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/resource/StanbolRootResource.java Thu Mar 24 13:56:53 2011
@@ -0,0 +1,17 @@
+package org.apache.stanbol.commons.web.resource;
+
+import javax.ws.rs.Path;
+
+
+import com.sun.jersey.api.view.ImplicitProduces;
+
+/**
+ * Root JAX-RS resource. The HTML view is implicitly rendered by a freemarker
+ * template to be found in the META-INF/templates folder.
+ */
+@Path("/")
+@ImplicitProduces("text/html")
+public class StanbolRootResource extends NavigationMixin {
+
+
+}

Added: incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/GraphWriter.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/GraphWriter.java?rev=1084961&view=auto
==============================================================================
--- incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/GraphWriter.java (added)
+++ incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/GraphWriter.java Thu Mar 24 13:56:53 2011
@@ -0,0 +1,64 @@
+package org.apache.stanbol.commons.web.writers;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
+import static org.apache.clerezza.rdf.core.serializedform.SupportedFormat.N3;
+import static org.apache.clerezza.rdf.core.serializedform.SupportedFormat.N_TRIPLE;
+import static org.apache.clerezza.rdf.core.serializedform.SupportedFormat.RDF_JSON;
+import static org.apache.clerezza.rdf.core.serializedform.SupportedFormat.RDF_XML;
+import static org.apache.clerezza.rdf.core.serializedform.SupportedFormat.TURTLE;
+import static org.apache.clerezza.rdf.core.serializedform.SupportedFormat.X_TURTLE;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.servlet.ServletContext;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.clerezza.rdf.core.TripleCollection;
+import org.apache.clerezza.rdf.core.serializedform.Serializer;
+
+
+@Provider
+@Produces( { TEXT_PLAIN, N3, N_TRIPLE, RDF_XML, TURTLE, X_TURTLE,
+        RDF_JSON, APPLICATION_JSON })
+public class GraphWriter implements MessageBodyWriter<TripleCollection> {
+
+    @Context
+    protected ServletContext servletContext;
+
+    protected Serializer getSerializer() {
+        return (Serializer) servletContext.getAttribute(Serializer.class.getName());
+    }
+
+    public boolean isWriteable(Class<?> type, Type genericType,
+            Annotation[] annotations, MediaType mediaType) {
+        return TripleCollection.class.isAssignableFrom(type);
+    }
+
+    public long getSize(TripleCollection t, Class<?> type, Type genericType,
+            Annotation[] annotations, MediaType mediaType) {
+        return -1;
+    }
+
+    public void writeTo(TripleCollection t, Class<?> type, Type genericType,
+            Annotation[] annotations, MediaType mediaType,
+            MultivaluedMap<String, Object> httpHeaders,
+            OutputStream entityStream) throws IOException,
+            WebApplicationException {
+
+        if (mediaType == null || mediaType.isWildcardType() || TEXT_PLAIN.equals(mediaType.toString())) {
+           getSerializer().serialize(entityStream, t, APPLICATION_JSON);
+        } else {
+            getSerializer().serialize(entityStream, t, mediaType.toString());
+        }
+    }
+}

Added: incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/JsonLdSerializerProvider.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/JsonLdSerializerProvider.java?rev=1084961&view=auto
==============================================================================
--- incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/JsonLdSerializerProvider.java (added)
+++ incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/JsonLdSerializerProvider.java Thu Mar 24 13:56:53 2011
@@ -0,0 +1,154 @@
+package org.apache.stanbol.commons.web.writers;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.clerezza.rdf.core.BNode;
+import org.apache.clerezza.rdf.core.NonLiteral;
+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.serializedform.SerializingProvider;
+import org.apache.clerezza.rdf.core.serializedform.SupportedFormat;
+import org.apache.stanbol.jsonld.JsonLd;
+import org.apache.stanbol.jsonld.JsonLdResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Implements a <a href="http://json-ld.org/">JSON-LD</a> serialization of a Clerezza
+ * {@link TripleCollection}.<br>
+ * <br>
+ * Note: This implementation is based on <a href="http://json-ld.org/spec/">JSON-LD
+ * specification</a> draft from 25 October 2010.
+ *
+ * @author Fabian Christ
+ *
+ * @scr.component immediate="true"
+ * @scr.service
+ *                 interface="org.apache.clerezza.rdf.core.serializedform.SerializingProvider"
+ */
+@SupportedFormat(JsonLdSerializerProvider.SUPPORTED_FORMAT)
+public class JsonLdSerializerProvider implements SerializingProvider {
+
+    public static final String SUPPORTED_FORMAT = APPLICATION_JSON;
+
+    private static final String RDF_NS_TYPE="http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
+
+    private static final Logger logger = LoggerFactory.getLogger(JsonLdSerializerProvider.class);
+
+    // Map from Namespace -> to Prefix
+    private Map<String, String> namespacePrefixMap = new HashMap<String, String>();
+
+    private int indentation = 2;
+
+    @Override
+    public void serialize(OutputStream serializedGraph, TripleCollection tc, String formatIdentifier) {
+        if (!formatIdentifier.equals(SUPPORTED_FORMAT)) {
+            logger.info("serialize() the format '" + formatIdentifier + "' is not supported by this implementation");
+            return;
+        }
+
+        JsonLd jsonLd = new JsonLd();
+        jsonLd.setNamespacePrefixMap(this.namespacePrefixMap);
+
+        Map<NonLiteral, String> subjects = createSubjectsMap(tc);
+        for (NonLiteral subject : subjects.keySet()) {
+            JsonLdResource resource = new JsonLdResource();
+            resource.setSubject(subject.toString());
+
+            Iterator<Triple> triplesFromSubject = tc.filter(subject, null, null);
+            while (triplesFromSubject.hasNext()) {
+                Triple currentTriple = triplesFromSubject.next();
+                if (currentTriple.getPredicate().getUnicodeString().equals(RDF_NS_TYPE)) {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("serialize() adding rdf:type: \"a\":" + currentTriple.getObject());
+                    }
+                    resource.addType(currentTriple.getObject().toString());
+                } else {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("serializer() adding predicate " + currentTriple.getPredicate().toString() + " with object " + currentTriple.getObject().toString());
+                    }
+
+                    String property = currentTriple.getPredicate().getUnicodeString();
+                    String value = currentTriple.getObject().toString();
+                    resource.putProperty(property, value);
+                }
+            }
+
+            jsonLd.put(resource.getSubject(), resource);
+        }
+
+        try {
+            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(serializedGraph));
+            writer.write(jsonLd.toString(this.indentation));
+            writer.flush();
+        } catch (IOException ioe) {
+            logger.error(ioe.getMessage());
+            throw new RuntimeException(ioe.getMessage());
+        }
+    }
+
+    private Map<NonLiteral, String> createSubjectsMap(TripleCollection tc) {
+        Map<NonLiteral, String> subjects = new HashMap<NonLiteral, String>();
+        int bNodeCounter = 0;
+        for (Triple triple : tc) {
+            NonLiteral subject = triple.getSubject();
+            if (!subjects.containsKey(subject)) {
+                if (subject instanceof UriRef) {
+                    subjects.put(subject, subject.toString());
+                } else if (subject instanceof BNode) {
+                    bNodeCounter++;
+                    subjects.put(subject, "_:bnode" + bNodeCounter);
+                }
+            }
+        }
+        return subjects;
+    }
+
+    /**
+     * Get the known namespace to prefix mapping.
+     *
+     * @return A {@link Map} from namespace String to prefix String.
+     */
+    public Map<String, String> getNamespacePrefixMap() {
+        return namespacePrefixMap;
+    }
+
+    /**
+     * Sets the known namespaces for the serializer.
+     *
+     * @param knownNamespaces A {@link Map} from namespace String to prefix String.
+     */
+    public void setNamespacePrefixMap(Map<String, String> knownNamespaces) {
+        this.namespacePrefixMap = knownNamespaces;
+    }
+
+    /**
+     * Returns the current number of space characters which are used
+     * to indent the serialized output.
+     *
+     * @return Number of space characters used for indentation.
+     */
+    public int getIndentation() {
+        return indentation;
+    }
+
+    /**
+     * Sets the number of characters used per indentation level for the serialized output.<br />
+     * Set this value to zero (0) if you don't want indentation. Default value is 2.
+     *
+     * @param indentation Number of space characters used for indentation.
+     */
+    public void setIndentation(int indentation) {
+        this.indentation = indentation;
+    }
+}

Added: incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/ResultSetToXml.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/ResultSetToXml.java?rev=1084961&view=auto
==============================================================================
--- incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/ResultSetToXml.java (added)
+++ incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/ResultSetToXml.java Thu Mar 24 13:56:53 2011
@@ -0,0 +1,97 @@
+package org.apache.stanbol.commons.web.writers;
+
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.clerezza.rdf.core.BNode;
+import org.apache.clerezza.rdf.core.Language;
+import org.apache.clerezza.rdf.core.PlainLiteral;
+import org.apache.clerezza.rdf.core.Resource;
+import org.apache.clerezza.rdf.core.TypedLiteral;
+import org.apache.clerezza.rdf.core.UriRef;
+import org.apache.clerezza.rdf.core.sparql.ResultSet;
+import org.apache.clerezza.rdf.core.sparql.SolutionMapping;
+import org.apache.clerezza.rdf.core.sparql.query.Variable;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+class ResultSetToXml {
+
+    private final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+
+    Document toDocument(ResultSet rs) throws ParserConfigurationException {
+        final Document doc = dbf.newDocumentBuilder().newDocument();
+
+        // root element
+        Element root = doc.createElement("sparql");
+        root.setAttribute("xmlns", "http://www.w3.org/2005/sparql-results#");
+        doc.appendChild(root);
+        Element head = doc.createElement("head");
+        root.appendChild(head);
+
+        // result set
+        Element results = doc.createElement("results");
+        SolutionMapping solutionMapping = null;
+        while (rs.hasNext()) {
+            solutionMapping = rs.next();
+            createResultElement(solutionMapping, results, doc);
+        }
+        createVariable(solutionMapping, head, doc);
+        root.appendChild(results);
+
+        return doc;
+    }
+
+    private void createResultElement(SolutionMapping solutionMap, Element results, Document doc) {
+        Set<Variable> keys = solutionMap.keySet();
+        Element result = doc.createElement("result");
+        results.appendChild(result);
+        for (Variable key : keys) {
+            Element bindingElement = doc.createElement("binding");
+            bindingElement.setAttribute("name", key.getName());
+            bindingElement.appendChild(createValueElement(
+                    (Resource) solutionMap.get(key), doc));
+            result.appendChild(bindingElement);
+        }
+    }
+
+    private void createVariable(SolutionMapping solutionMap, Element head, Document doc) {
+        if(solutionMap != null) {
+            Set<Variable> keys = solutionMap.keySet();
+            for (Variable key : keys) {
+                Element varElement = doc.createElement("variable");
+                varElement.setAttribute("name", key.getName());
+                head.appendChild(varElement);
+            }
+        }
+    }
+
+    private Element createValueElement(Resource resource, Document doc) {
+        Element value;
+        if (resource instanceof UriRef) {
+            value = doc.createElement("uri");
+            value.appendChild(doc.createTextNode(((UriRef) resource)
+                    .getUnicodeString()));
+        } else if (resource instanceof TypedLiteral) {
+            value = doc.createElement("literal");
+            value.appendChild(doc.createTextNode(((TypedLiteral) resource)
+                    .getLexicalForm()));
+            value.setAttribute("datatype", (((TypedLiteral) resource)
+                    .getDataType().getUnicodeString()));
+        } else if (resource instanceof PlainLiteral) {
+            value = doc.createElement("literal");
+            value.appendChild(doc.createTextNode(((PlainLiteral) resource)
+                    .getLexicalForm()));
+            Language lang = ((PlainLiteral) resource).getLanguage();
+            if (lang != null) {
+                value.setAttribute("xml:lang", (lang.toString()));
+            }
+        } else {
+            value = doc.createElement("bnode");
+            value.appendChild(doc.createTextNode(((BNode) resource).toString()));
+        }
+        return value;
+    }
+}

Added: incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/ResultSetWriter.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/ResultSetWriter.java?rev=1084961&view=auto
==============================================================================
--- incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/ResultSetWriter.java (added)
+++ incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/java/org/apache/stanbol/commons/web/writers/ResultSetWriter.java Thu Mar 24 13:56:53 2011
@@ -0,0 +1,70 @@
+package org.apache.stanbol.commons.web.writers;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.clerezza.rdf.core.sparql.ResultSet;
+import org.w3c.dom.Document;
+
+/**
+ * MessageBodyWriter for a ResultSet.
+ * Clerezza does provide such a writer, but it seems to require
+ * quite a lot of Clerezza dependencies that we don't really need.
+ */
+@Provider
+@Produces({"application/sparql-results+xml", "application/xml", "text/xml"})
+public class ResultSetWriter implements MessageBodyWriter<ResultSet> {
+
+    public static final String ENCODING = "UTF-8";
+
+    @Override
+    public long getSize(ResultSet resultSet, Class<?> type, Type genericType,
+            Annotation[] annotations, MediaType mediaType) {
+        return -1;
+    }
+
+    @Override
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return ResultSet.class.isAssignableFrom(type);
+    }
+
+    @Override
+    public void writeTo(ResultSet resultSet, Class<?> type, Type genericType,
+            Annotation[] annotations, MediaType mediaType,
+            MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
+            throws IOException, WebApplicationException {
+
+        try {
+            Document doc = new ResultSetToXml().toDocument(resultSet);
+            DOMSource domSource = new DOMSource(doc);
+            StreamResult streamResult = new StreamResult(entityStream);
+            TransformerFactory tf = TransformerFactory.newInstance();
+            Transformer serializer = tf.newTransformer();
+            serializer.setOutputProperty(OutputKeys.ENCODING,ENCODING);
+            serializer.setOutputProperty(OutputKeys.INDENT,"yes");
+            serializer.transform(domSource, streamResult);
+        } catch(TransformerException te) {
+            throw new IOException("TransformerException in writeTo()", te);
+        } catch(ParserConfigurationException pce) {
+            throw new IOException("Exception in ResultSetToXml.toDocument()", pce);
+        }
+
+        entityStream.flush();
+    }
+}

Added: incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/resources/META-INF/templates/org/apache/stanbol/commons/web/resource/StanbolRootResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/resources/META-INF/templates/org/apache/stanbol/commons/web/resource/StanbolRootResource/index.ftl?rev=1084961&view=auto
==============================================================================
--- incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/resources/META-INF/templates/org/apache/stanbol/commons/web/resource/StanbolRootResource/index.ftl (added)
+++ incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/main/resources/META-INF/templates/org/apache/stanbol/commons/web/resource/StanbolRootResource/index.ftl Thu Mar 24 13:56:53 2011
@@ -0,0 +1,50 @@
+<#import "/imports/common.ftl" as common>
+<#import "/imports/sparql.ftl" as sparql>
+<#escape x as x?html>
+<@common.page title="Welcome to Apache Stanbol!" hasrestapi=false> 
+
+<p>Apache Stanbol is an Open Source HTTP service meant to help Content
+Management System developers to semi-automatically enhance unstructured
+content (text, image, ...) with semantic annotations to be able to link
+documents with related entities and topics.</p>
+
+<p>Please go to <a href="http://incubator.apache.org/stanbol">the
+official website</a> to learn more on the project, read the
+documentation and join the mailing list.</p>
+
+<p>Here are the main HTTP entry points. Each resource comes with a web
+view that documents the matching RESTful API for applications:</p>
+<dl>
+
+  <dt><a href="engines">/engines</a><dt>
+  <dd>This is a <strong>stateless interface</strong> to allow clients to submit content to <strong>analyze</strong>
+   by the <code>EnhancementEngine</code>s and get the resulting <strong>RDF enhancements</strong> at once
+   without storing anything on the server-side.</dd>
+
+  <dt><a href="store">/store</a><dt>
+  <dd>This is a <strong>stateful interface</strong> to submit content to <strong>analyze and store
+   the results</strong> on the server. It is then possible to browse the resulting enhanced
+   content items.</dd>
+
+  <dt><a href="sparql">/sparql</a><dt>
+  <dd>This is the <strong>SPARQL endpoint</strong> for the Stanbol store.
+     <a href="http://en.wikipedia.org/wiki/Sparql">SPARQL</a> is the
+     standard query language the most commonly used to provide interactive
+     access to semantic knowledge bases.</dd>
+
+  <dt><a href="system/console">/system/console</a><dt>
+  <dd>
+    <p>This is the OSGi administration console (for administrators and developers). The initial
+       username / password is set to <em>admin / admin</em>.</p>
+    <p>Use the console to add new bundles and activate, de-activate and configure components.</p>
+    <p>The console can also be used to perform hot-(re)deployment of any OSGi bundles.
+       For instance to re-deploy a new version of this web interface, go to the <tt>$STANBOL_HOME/enhancer/jersey</tt>
+       source folder and run the following command:</p>
+<pre>
+mvn install -o -DskipTests -PinstallBundle -Dsling.url=${it.publicBaseUri}system/console
+</pre>
+  </dd>
+
+</dl>
+</...@common.page>
+</#escape>

Added: incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/test/java/org/apache/stanbol/commons/web/writers/JsonLdSerializerProviderTest.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/test/java/org/apache/stanbol/commons/web/writers/JsonLdSerializerProviderTest.java?rev=1084961&view=auto
==============================================================================
--- incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/test/java/org/apache/stanbol/commons/web/writers/JsonLdSerializerProviderTest.java (added)
+++ incubator/stanbol/branches/http-endpoint-refactoring/commons/web/src/test/java/org/apache/stanbol/commons/web/writers/JsonLdSerializerProviderTest.java Thu Mar 24 13:56:53 2011
@@ -0,0 +1,190 @@
+package org.apache.stanbol.commons.web.writers;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.apache.clerezza.rdf.core.MGraph;
+import org.apache.clerezza.rdf.core.UriRef;
+import org.apache.clerezza.rdf.core.impl.SimpleMGraph;
+import org.apache.clerezza.rdf.core.impl.util.W3CDateFormat;
+import org.apache.commons.io.IOUtils;
+import org.apache.stanbol.commons.web.writers.JsonLdSerializerProvider;
+import org.apache.stanbol.enhancer.servicesapi.ContentItem;
+import org.apache.stanbol.enhancer.servicesapi.TextAnnotation;
+import org.apache.stanbol.enhancer.servicesapi.helper.RdfEntityFactory;
+import org.apache.stanbol.enhancer.servicesapi.rdf.OntologicalClasses;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class JsonLdSerializerProviderTest {
+
+    private JsonLdSerializerProvider jsonldProvider;
+    private String formatIdentifier = "application/json";
+
+    private String expectedW3CFormattedDate;
+    
+    @Before
+    public void setup() {
+        jsonldProvider = new JsonLdSerializerProvider();
+    }
+
+    @Test
+    public void testWrongFormat() {
+        String context = "Dr. Patrick Marshall (1869 - November 1950) was a geologist who lived "
+            + "in New Zealand and worked at the University of Otago.";
+        ContentItem ci = getContentItem("urn:iks-project:enhancer:test:content-item:person", context);
+
+        OutputStream serializedGraph = new ByteArrayOutputStream();
+        jsonldProvider.serialize(serializedGraph, ci.getMetadata(), "application/format+notsupported");
+    }
+
+    @Test
+    public void testSingleSubjectSerializeNoNs() {
+        String context = "Dr. Patrick Marshall (1869 - November 1950) was a geologist who lived "
+            + "in New Zealand and worked at the University of Otago.";
+
+        ContentItem ci = getContentItem("urn:iks-project:enhancer:test:content-item:person", context);
+        getTextAnnotation(ci, "Person", "Patrick Marshall", context, OntologicalClasses.DBPEDIA_PERSON);
+
+        OutputStream serializedGraph = new ByteArrayOutputStream();
+        jsonldProvider.setIndentation(0);
+        jsonldProvider.serialize(serializedGraph, ci.getMetadata(), formatIdentifier);
+        
+        String expected = "{\"@\":\"<urn:iks-project:enhancer:test:text-annotation:Person>\",\"a\":[\"<http:\\/\\/fise.iks-project.eu\\/ontology\\/Enhancement>\",\"<http:\\/\\/fise.iks-project.eu\\/ontology\\/TextAnnotation>\"],\"http:\\/\\/fise.iks-project.eu\\/ontology\\/end\":\"\\\"20\\\"^^<http:\\/\\/www.w3.org\\/2001\\/XMLSchema#int>\",\"http:\\/\\/fise.iks-project.eu\\/ontology\\/selected-text\":\"\\\"Patrick Marshall\\\"^^<http:\\/\\/www.w3.org\\/2001\\/XMLSchema#string>\",\"http:\\/\\/fise.iks-project.eu\\/ontology\\/selection-context\":\"\\\"Dr. Patrick Marshall (1869 - November 1950) was a geologist who lived in New Zealand and worked at the University of Otago.\\\"^^<http:\\/\\/www.w3.org\\/2001\\/XMLSchema#string>\",\"http:\\/\\/fise.iks-project.eu\\/ontology\\/start\":\"\\\"4\\\"^^<http:\\/\\/www.w3.org\\/2001\\/XMLSchema#int>\",\"http:\\/\\/purl.org\\/dc\\/terms\\/created\":\"\\\"" + this.expectedW3CFormattedDate + "\\\"^^<http:\\/\\/www.w3.org\\/2001\\/XMLSche
 ma#dateTime>\",\"http:\\/\\/purl.org\\/dc\\/terms\\/creator\":\"<urn:iks-project:enhancer:test:dummyEngine>\",\"http:\\/\\/purl.org\\/dc\\/terms\\/type\":\"<http:\\/\\/dbpedia.org\\/ontology\\/Person>\"}";
+        String result = serializedGraph.toString();
+        Assert.assertEquals(expected, result);
+    }
+
+    @Test
+    public void testSingleSubjectSerializeNoNsWithIndent() {
+        String context = "Dr. Patrick Marshall (1869 - November 1950) was a geologist who lived in New Zealand and worked at the University of Otago.";
+
+        ContentItem ci = getContentItem("urn:iks-project:enhancer:test:content-item:person", context);
+        getTextAnnotation(ci, "Person", "Patrick Marshall", context, OntologicalClasses.DBPEDIA_PERSON);
+
+        OutputStream serializedGraph = new ByteArrayOutputStream();
+        jsonldProvider.serialize(serializedGraph, ci.getMetadata(), formatIdentifier);
+
+        String expected = "{\n  \"@\": \"<urn:iks-project:enhancer:test:text-annotation:Person>\",\n  \"a\": [\n    \"<http:\\/\\/fise.iks-project.eu\\/ontology\\/Enhancement>\",\n    \"<http:\\/\\/fise.iks-project.eu\\/ontology\\/TextAnnotation>\"\n  ],\n  \"http:\\/\\/fise.iks-project.eu\\/ontology\\/end\": \"\\\"20\\\"^^<http:\\/\\/www.w3.org\\/2001\\/XMLSchema#int>\",\n  \"http:\\/\\/fise.iks-project.eu\\/ontology\\/selected-text\": \"\\\"Patrick Marshall\\\"^^<http:\\/\\/www.w3.org\\/2001\\/XMLSchema#string>\",\n  \"http:\\/\\/fise.iks-project.eu\\/ontology\\/selection-context\": \"\\\"Dr. Patrick Marshall (1869 - November 1950) was a geologist who lived in New Zealand and worked at the University of Otago.\\\"^^<http:\\/\\/www.w3.org\\/2001\\/XMLSchema#string>\",\n  \"http:\\/\\/fise.iks-project.eu\\/ontology\\/start\": \"\\\"4\\\"^^<http:\\/\\/www.w3.org\\/2001\\/XMLSchema#int>\",\n  \"http:\\/\\/purl.org\\/dc\\/terms\\/created\": \"\\\"" + this.expectedW3CFormattedDa
 te + "\\\"^^<http:\\/\\/www.w3.org\\/2001\\/XMLSchema#dateTime>\",\n  \"http:\\/\\/purl.org\\/dc\\/terms\\/creator\": \"<urn:iks-project:enhancer:test:dummyEngine>\",\n  \"http:\\/\\/purl.org\\/dc\\/terms\\/type\": \"<http:\\/\\/dbpedia.org\\/ontology\\/Person>\"\n}";
+        String result = serializedGraph.toString();
+        Assert.assertEquals(expected, result);
+    }
+
+    @Test
+    public void testSingleSubjectSerializeWithNs() {
+        String context = "Dr. Patrick Marshall (1869 - November 1950) was a geologist who lived in New Zealand and worked at the University of Otago.";
+
+        ContentItem ci = getContentItem("urn:iks-project:enhancer:test:content-item:person", context);
+        getTextAnnotation(ci, "Person", "Patrick Marshall", context, OntologicalClasses.DBPEDIA_PERSON);
+
+        OutputStream serializedGraph = new ByteArrayOutputStream();
+        Map<String, String> nsMap = new HashMap<String, String>();
+        nsMap.put("http://fise.iks-project.eu/ontology/", "enhancer");
+        nsMap.put("http://www.w3.org/2001/XMLSchema#", "xmlns");
+        nsMap.put("http://dbpedia.org/ontology/", "dbpedia");
+        nsMap.put("http://purl.org/dc/terms", "dcterms");
+        jsonldProvider.setIndentation(0);
+        jsonldProvider.setNamespacePrefixMap(nsMap);
+        jsonldProvider.serialize(serializedGraph, ci.getMetadata(), formatIdentifier);
+
+        String expected = "{\"#\":{\"dbpedia\":\"http:\\/\\/dbpedia.org\\/ontology\\/\",\"dcterms\":\"http:\\/\\/purl.org\\/dc\\/terms\",\"enhancer\":\"http:\\/\\/fise.iks-project.eu\\/ontology\\/\",\"xmlns\":\"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\"},\"@\":\"<urn:iks-project:enhancer:test:text-annotation:Person>\",\"a\":[\"<enhancer:Enhancement>\",\"<enhancer:TextAnnotation>\"],\"dcterms:\\/created\":\"\\\"" + this.expectedW3CFormattedDate + "\\\"^^<xmlns:dateTime>\",\"dcterms:\\/creator\":\"<urn:iks-project:enhancer:test:dummyEngine>\",\"dcterms:\\/type\":\"<dbpedia:Person>\",\"enhancer:end\":\"\\\"20\\\"^^<xmlns:int>\",\"enhancer:selected-text\":\"\\\"Patrick Marshall\\\"^^<xmlns:string>\",\"enhancer:selection-context\":\"\\\"Dr. Patrick Marshall (1869 - November 1950) was a geologist who lived in New Zealand and worked at the University of Otago.\\\"^^<xmlns:string>\",\"enhancer:start\":\"\\\"4\\\"^^<xmlns:int>\"}";
+        String result = serializedGraph.toString();
+        Assert.assertEquals(expected, result);
+    }
+
+    @Test
+    public void testSingleSubjectSerializeWithNsWithIndent() {
+        String context = "Dr. Patrick Marshall (1869 - November 1950) was a geologist who lived in New Zealand and worked at the University of Otago.";
+
+        ContentItem ci = getContentItem("urn:iks-project:enhancer:test:content-item:person", context);
+        getTextAnnotation(ci, "Person", "Patrick Marshall", context, OntologicalClasses.DBPEDIA_PERSON);
+
+        OutputStream serializedGraph = new ByteArrayOutputStream();
+        Map<String, String> nsMap = new HashMap<String, String>();
+        nsMap.put("http://fise.iks-project.eu/ontology/", "enhancer");
+        nsMap.put("http://www.w3.org/2001/XMLSchema#", "xmlns");
+        nsMap.put("http://dbpedia.org/ontology/", "dbpedia");
+        nsMap.put("http://purl.org/dc/terms", "dcterms");
+        jsonldProvider.setIndentation(4);
+        jsonldProvider.setNamespacePrefixMap(nsMap);
+        jsonldProvider.serialize(serializedGraph, ci.getMetadata(), formatIdentifier);
+
+        String expected = "{\n    \"#\": {\n        \"dbpedia\": \"http:\\/\\/dbpedia.org\\/ontology\\/\",\n        \"dcterms\": \"http:\\/\\/purl.org\\/dc\\/terms\",\n        \"enhancer\": \"http:\\/\\/fise.iks-project.eu\\/ontology\\/\",\n        \"xmlns\": \"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\"\n    },\n    \"@\": \"<urn:iks-project:enhancer:test:text-annotation:Person>\",\n    \"a\": [\n        \"<enhancer:Enhancement>\",\n        \"<enhancer:TextAnnotation>\"\n    ],\n    \"dcterms:\\/created\": \"\\\"" + this.expectedW3CFormattedDate + "\\\"^^<xmlns:dateTime>\",\n    \"dcterms:\\/creator\": \"<urn:iks-project:enhancer:test:dummyEngine>\",\n    \"dcterms:\\/type\": \"<dbpedia:Person>\",\n    \"enhancer:end\": \"\\\"20\\\"^^<xmlns:int>\",\n    \"enhancer:selected-text\": \"\\\"Patrick Marshall\\\"^^<xmlns:string>\",\n    \"enhancer:selection-context\": \"\\\"Dr. Patrick Marshall (1869 - November 1950) was a geologist who lived in New Zealand and worked at the Univ
 ersity of Otago.\\\"^^<xmlns:string>\",\n    \"enhancer:start\": \"\\\"4\\\"^^<xmlns:int>\"\n}";
+        String result = serializedGraph.toString();
+        Assert.assertEquals(expected, result);
+    }
+
+    private ContentItem getContentItem(final String id, final String text) {
+        return new ContentItem() {
+
+            SimpleMGraph metadata = new SimpleMGraph();
+
+            public InputStream getStream() {
+                return new ByteArrayInputStream(text.getBytes());
+            }
+
+            public String getMimeType() {
+                return "text/plain";
+            }
+
+            public MGraph getMetadata() {
+                return metadata;
+            }
+
+            public String getId() {
+                return id;
+            }
+        };
+    }
+
+    private void getTextAnnotation(ContentItem ci, String annotationURNExtension, String namedEntity, String context, UriRef type) {
+        String content;
+        try {
+            content = IOUtils.toString(ci.getStream(),"UTF-8");
+        } catch (IOException e) {
+            // should never happen anyway!
+            content = "";
+        }
+        RdfEntityFactory factory = RdfEntityFactory.createInstance(ci.getMetadata());
+        TextAnnotation testAnnotation = factory.getProxy(new UriRef("urn:iks-project:enhancer:test:text-annotation:" + annotationURNExtension), TextAnnotation.class);
+        testAnnotation.setCreator(new UriRef("urn:iks-project:enhancer:test:dummyEngine"));
+
+        Calendar myCal = Calendar.getInstance();
+        myCal.set(2010, 9, 27, 12, 0, 0);
+        myCal.set(Calendar.MILLISECOND, 0);
+        myCal.setTimeZone(TimeZone.getTimeZone("UTC"));
+        testAnnotation.setCreated(myCal.getTime());
+        
+        this.expectedW3CFormattedDate = new W3CDateFormat().format(myCal.getTime());
+        
+        testAnnotation.setSelectedText(namedEntity);
+        testAnnotation.setSelectionContext(context);
+        testAnnotation.getDcType().add(type);
+        Integer start = content.indexOf(namedEntity);
+        if (start < 0) { // if not found in the content set start to 42
+            start = 42;
+        }
+        testAnnotation.setStart(start);
+        testAnnotation.setEnd(start + namedEntity.length());
+    }
+
+    @SuppressWarnings("unused")
+    private void toConsole(String result) {
+        System.out.println(result);
+        String s = result;
+        s = s.replaceAll("\\\\", "\\\\\\\\");
+        s = s.replace("\"", "\\\"");
+        s = s.replace("\n", "\\n");
+        System.out.println(s);
+    }
+
+}