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