You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by wi...@apache.org on 2013/02/25 16:59:14 UTC
[2/3] git commit: more renaming
more renaming
Project: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/commit/c77a4b0b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/tree/c77a4b0b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/diff/c77a4b0b
Branch: refs/heads/master
Commit: c77a4b0b628fc97f440e7dddc4b51d969c165add
Parents: bdf52ac
Author: Sergio Fernández <wi...@apache.org>
Authored: Mon Feb 25 16:57:28 2013 +0100
Committer: Sergio Fernández <wi...@apache.org>
Committed: Mon Feb 25 16:57:28 2013 +0100
----------------------------------------------------------------------
.../core/servlet/MarmottaH2ConsoleFilter.java | 89 ++++++
.../core/servlet/MarmottaOptionsFilter.java | 168 +++++++++++
.../core/servlet/MarmottaPostStartupFilter.java | 121 ++++++++
.../core/servlet/MarmottaPreStartupFilter.java | 116 ++++++++
.../core/servlet/MarmottaPreStartupListener.java | 61 ++++
.../core/servlet/MarmottaResourceFilter.java | 218 +++++++++++++++
.../platform/core/test/base/AbstractMarmotta.java | 125 +++++++++
.../platform/core/test/base/EmbeddedMarmotta.java | 43 +++
.../platform/core/test/base/JettyMarmotta.java | 128 +++++++++
9 files changed, 1069 insertions(+), 0 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c77a4b0b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaH2ConsoleFilter.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaH2ConsoleFilter.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaH2ConsoleFilter.java
new file mode 100644
index 0000000..90d17a7
--- /dev/null
+++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaH2ConsoleFilter.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright (C) 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.platform.core.servlet;
+
+import org.apache.marmotta.platform.core.api.config.ConfigurationService;
+import org.slf4j.Logger;
+
+import javax.inject.Inject;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * This filter injects the database configuration into the H2 console using the LMF Configuration settings
+ * <p/>
+ * User: sschaffe
+ */
+public class MarmottaH2ConsoleFilter implements Filter {
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private ConfigurationService configurationService;
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+
+
+ if(servletRequest instanceof HttpServletRequest) {
+ HttpServletRequest req = (HttpServletRequest)servletRequest;
+
+ if(req.getPathInfo() != null && req.getPathInfo().endsWith("login.jsp")) {
+ // we redirect immediately to the action, since the login screen is not needed
+ String origUri = req.getRequestURI();
+ String redirectUri = origUri.substring(0,origUri.lastIndexOf("/")) + "/login.do?jsessionid="+req.getParameter("jsessionid");
+
+ ((HttpServletResponse)servletResponse).sendRedirect(redirectUri);
+ }
+
+ if(req.getPathInfo() != null && req.getPathInfo().endsWith("login.do")) {
+ // set the database configuration from system configuration
+ String db_type = configurationService.getStringConfiguration("database.type","h2");
+ String db_driver = configurationService.getStringConfiguration("database."+db_type+".driver");
+ String db_url = configurationService.getStringConfiguration("database.url");
+ String db_user = configurationService.getStringConfiguration("database.user");
+ String db_password = configurationService.getStringConfiguration("database.password");
+
+ servletRequest.setAttribute("driver",db_driver);
+ servletRequest.setAttribute("url",db_url);
+ servletRequest.setAttribute("user",db_user);
+ servletRequest.setAttribute("password",db_password);
+ }
+ }
+
+ filterChain.doFilter(servletRequest,servletResponse);
+
+
+ }
+
+ @Override
+ public void destroy() {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c77a4b0b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaOptionsFilter.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaOptionsFilter.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaOptionsFilter.java
new file mode 100644
index 0000000..07135db
--- /dev/null
+++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaOptionsFilter.java
@@ -0,0 +1,168 @@
+/**
+ * Copyright (C) 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.platform.core.servlet;
+
+import org.apache.marmotta.platform.core.api.config.ConfigurationService;
+import org.jboss.resteasy.spi.DefaultOptionsMethodException;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.slf4j.Logger;
+
+import javax.inject.Inject;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * This filter checks for OPTIONS requests. If the response returned by the other filters throws an exception
+ * org.jboss.resteasy.spi.DefaultOptionsMethodException, the filter writes to the response the default options
+ * of the Apache Marmotta system, in particular the following headers:
+ *
+ * Access-Control-Allow-Origin: * (or as configured in config.properties)
+ * Access-Control-Allow-Methods: POST, PUT, GET, DELETE, HEAD, OPTIONS
+ *
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class MarmottaOptionsFilter implements Filter {
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private ConfigurationService configurationService;
+
+ /**
+ * Called by the web container to indicate to a filter that it is being placed into
+ * service. The servlet container calls the init method exactly once after instantiating the
+ * filter. The init method must complete successfully before the filter is asked to do any
+ * filtering work. <br><br>
+ * <p/>
+ * The web container cannot place the filter into service if the init method either<br>
+ * 1.Throws a ServletException <br>
+ * 2.Does not return within a time period defined by the web container
+ */
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ ResteasyProviderFactory.getInstance().addExceptionMapper(new OptionsMapper());
+ }
+
+ /**
+ * The <code>doFilter</code> method of the Filter is called by the container
+ * each time a request/response pair is passed through the chain due
+ * to a client request for a resource at the end of the chain. The FilterChain passed in to this
+ * method allows the Filter to pass on the request and response to the next entity in the
+ * chain.<p>
+ * A typical implementation of this method would follow the following pattern:- <br>
+ * 1. Examine the request<br>
+ * 2. Optionally wrap the request object with a custom implementation to
+ * filter content or headers for input filtering <br>
+ * 3. Optionally wrap the response object with a custom implementation to
+ * filter content or headers for output filtering <br>
+ * 4. a) <strong>Either</strong> invoke the next entity in the chain using the FilterChain object (<code>chain.doFilter()</code>), <br>
+ * * 4. b) <strong>or</strong> not pass on the request/response pair to the next entity in the filter chain to block the request processing<br>
+ * * 5. Directly set headers on the response after invocation of the next entity in the filter chain.
+ */
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+
+
+ try {
+
+ chain.doFilter(request,response);
+// DG: The addition of the response header fails because the respons is already committed - so remote the code
+//
+/* if(response instanceof HttpServletResponse) {
+ HttpServletResponse resp = (HttpServletResponse)response;
+ HttpServletRequest req = (HttpServletRequest)request;
+
+ // adjust the header only when the request is not yet com
+ if (! resp.isCommitted() ) {
+ if(!"OPTIONS".equalsIgnoreCase(req.getMethod()) && !resp.containsHeader("Access-Control-Allow-Origin")) {
+ resp.setHeader("Access-Control-Allow-Origin",configurationService.getStringConfiguration("kiwi.allow_origin","*"));
+ }
+ }
+
+ }
+*/
+ } catch (DefaultOptionsMethodException ex) {
+ if(response instanceof HttpServletResponse) {
+ HttpServletResponse resp = (HttpServletResponse)response;
+ HttpServletRequest req = (HttpServletRequest)request;
+
+ if(req.getMethod().equalsIgnoreCase("OPTIONS")) {
+ resp.setStatus(200);
+ resp.resetBuffer();
+
+
+ if(!resp.containsHeader("Access-Control-Allow-Origin")) {
+ resp.setHeader("Access-Control-Allow-Origin",configurationService.getStringConfiguration("kiwi.allow_origin","*"));
+ }
+ if(!resp.containsHeader("Access-Control-Allow-Methods")) {
+ for(String method : configurationService.getListConfiguration("kiwi.allow_methods", Arrays.asList("POST, PUT, GET, DELETE, HEAD".split(",")))) {
+ resp.addHeader("Access-Control-Allow-Methods",method);
+ }
+ }
+ if(req.getHeader("Access-Control-Request-Headers") != null) {
+ String header = req.getHeader("Access-Control-Request-Headers");
+ String[] values = header.split(",");
+ for(String value : values) {
+ resp.addHeader("Access-Control-Allow-Headers",value.trim());
+ }
+ }
+
+ }
+ }
+ }
+
+
+
+ }
+
+ /**
+ * Called by the web container to indicate to a filter that it is being taken out of service. This
+ * method is only called once all threads within the filter's doFilter method have exited or after
+ * a timeout period has passed. After the web container calls this method, it will not call the
+ * doFilter method again on this instance of the filter. <br><br>
+ * <p/>
+ * This method gives the filter an opportunity to clean up any resources that are being held (for
+ * example, memory, file handles, threads) and make sure that any persistent state is synchronized
+ * with the filter's current state in memory.
+ */
+ @Override
+ public void destroy() {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ @Provider
+ protected static class OptionsMapper implements ExceptionMapper<DefaultOptionsMethodException> {
+
+ @Override
+ public Response toResponse(DefaultOptionsMethodException exception) {
+ throw exception;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c77a4b0b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaPostStartupFilter.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaPostStartupFilter.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaPostStartupFilter.java
new file mode 100644
index 0000000..3c0a161
--- /dev/null
+++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaPostStartupFilter.java
@@ -0,0 +1,121 @@
+/**
+ * Copyright (C) 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.platform.core.servlet;
+
+import java.io.IOException;
+
+import javax.enterprise.event.Event;
+import javax.enterprise.inject.Any;
+import javax.inject.Inject;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import org.apache.marmotta.platform.core.api.config.ConfigurationService;
+import org.apache.marmotta.platform.core.api.user.UserService;
+import org.apache.marmotta.platform.core.events.SystemStartupEvent;
+import org.apache.marmotta.platform.core.model.module.ModuleConfiguration;
+
+import org.slf4j.Logger;
+
+/**
+ * This filter is currently only used to indicate that the LMF server has been started successfully.
+ * <p/>
+ * User: sschaffe
+ */
+public class MarmottaPostStartupFilter implements Filter {
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private ConfigurationService configurationService;
+
+ @Inject
+ private UserService userService;
+
+ @Inject
+ private ModuleConfiguration moduleConfiguration;
+
+ @Inject @Any
+ private Event<SystemStartupEvent> startupEvent;
+
+ /**
+ * Called by the web container to indicate to a filter that it is being placed into
+ * service. The servlet container calls the init method exactly once after instantiating the
+ * filter. The init method must complete successfully before the filter is asked to do any
+ * filtering work. <br><br>
+ * <p/>
+ * The web container cannot place the filter into service if the init method either<br>
+ * 1.Throws a ServletException <br>
+ * 2.Does not return within a time period defined by the web container
+ */
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ // if the system is already configured, we can safely trigger a startup event
+ if(configurationService.getBooleanConfiguration("kiwi.setup.host",false)) {
+ // startupEvent.fire(new SystemStartupEvent());
+ }
+
+ if(moduleConfiguration.hasBuildInfo()) {
+ log.warn("Apache Marmotta Core Version {} has started up successfully!", moduleConfiguration.getModuleVersion());
+ } else {
+ log.warn("Apache Marmotta Core (Development Version) has started up successfully!");
+ }
+
+ log.warn("You can access the system now at the URL {}", "http://"+configurationService.getServerName()+":"+configurationService.getServerPort()+configurationService.getServerContext()+"/");
+ }
+
+ /**
+ * The <code>doFilter</code> method of the Filter is called by the container
+ * each time a request/response pair is passed through the chain due
+ * to a client request for a resource at the end of the chain. The FilterChain passed in to this
+ * method allows the Filter to pass on the request and response to the next entity in the
+ * chain.<p>
+ * A typical implementation of this method would follow the following pattern:- <br>
+ * 1. Examine the request<br>
+ * 2. Optionally wrap the request object with a custom implementation to
+ * filter content or headers for input filtering <br>
+ * 3. Optionally wrap the response object with a custom implementation to
+ * filter content or headers for output filtering <br>
+ * 4. a) <strong>Either</strong> invoke the next entity in the chain using the FilterChain object (<code>chain.doFilter()</code>), <br>
+ * * 4. b) <strong>or</strong> not pass on the request/response pair to the next entity in the filter chain to block the request processing<br>
+ * * 5. Directly set headers on the response after invocation of the next entity in the filter chain.
+ */
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ chain.doFilter(request, response);
+ }
+
+ /**
+ * Called by the web container to indicate to a filter that it is being taken out of service. This
+ * method is only called once all threads within the filter's doFilter method have exited or after
+ * a timeout period has passed. After the web container calls this method, it will not call the
+ * doFilter method again on this instance of the filter. <br><br>
+ * <p/>
+ * This method gives the filter an opportunity to clean up any resources that are being held (for
+ * example, memory, file handles, threads) and make sure that any persistent state is synchronized
+ * with the filter's current state in memory.
+ */
+ @Override
+ public void destroy() {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c77a4b0b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaPreStartupFilter.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaPreStartupFilter.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaPreStartupFilter.java
new file mode 100644
index 0000000..ebc1ea1
--- /dev/null
+++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaPreStartupFilter.java
@@ -0,0 +1,116 @@
+/**
+ * Copyright (C) 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.platform.core.servlet;
+
+import org.apache.marmotta.platform.core.api.config.ConfigurationService;
+import org.apache.marmotta.platform.core.startup.MarmottaStartupService;
+import org.slf4j.Logger;
+
+import javax.inject.Inject;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+/**
+ * This filter is evaluated when the Apache Marmotta system is accessed for the very first time using an HTTP client (e.g. a
+ * browser). Its purpose is to set configuration variables that cannot be determined when the server is starting
+ * up because they need information how the server is accessed. In particular, it will set the following
+ * configuration variables in case the system has not yet been configured:
+ * <ul>
+ * <li>kiwi.context - will be set to the base URI of this KiWi installation; used for constructing resource URIs</li>
+ * <li>kiwi.host - will be set to the base URL of the KiWi installation; used for accessing additional web services like SOLR and H2</li>
+ * </ul>
+ * <p/>
+ * User: Sebastian Schaffert
+ */
+public class MarmottaPreStartupFilter implements Filter {
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private MarmottaStartupService startupService;
+
+ @Inject
+ private ConfigurationService configurationService;
+
+ private boolean started = false;
+
+ /**
+ * If the hostname (config properties kiwi.host and kiwi.context) of the system has not been configured yet, we
+ * try to automatically determine the correct values from the first request. The config variable
+ * kiwi.setup.host indicates whether setup has already been carried out.
+ * @param request
+ */
+ private String getBaseUrl(ServletRequest request) {
+ // check whether we need to perform setup
+ if (request instanceof HttpServletRequest) {
+ HttpServletRequest hreq = (HttpServletRequest) request;
+
+ String contextName = hreq.getContextPath();
+ String hostName = hreq.getServerName();
+ int hostPort = hreq.getServerPort();
+ String hostScheme = hreq.getScheme();
+
+ String baseUrl = hostScheme + "://" + hostName;
+ if( hostPort == 80 && "http".equals(hostScheme) ||
+ hostPort == 443 && "https".equals(hostScheme) ) {
+ baseUrl = baseUrl + contextName + "/";
+ } else {
+ baseUrl = baseUrl + ":" + hostPort + contextName + "/";
+ }
+
+ return baseUrl;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+
+ }
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+
+ if(!started) {
+ synchronized (this) {
+ started = true;
+
+ String baseUrl = getBaseUrl(request);
+ if(baseUrl != null) {
+ startupService.startupHost(baseUrl, baseUrl);
+ } else {
+ log.error("could not determine host name; cannot startup Apache Marmotta");
+ }
+ }
+ }
+
+ filterChain.doFilter(request,servletResponse);
+ }
+
+
+ @Override
+ public void destroy() {
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c77a4b0b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaPreStartupListener.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaPreStartupListener.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaPreStartupListener.java
new file mode 100644
index 0000000..d451645
--- /dev/null
+++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaPreStartupListener.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (C) 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.platform.core.servlet;
+
+import org.apache.marmotta.platform.core.startup.MarmottaStartupService;
+import org.apache.marmotta.platform.core.util.CDIContext;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+/**
+ * This filter is executed first in the startup chain. It initialises the Apache Marmotta system variables if necessary and
+ * starts up the configuration service.
+ */
+public class MarmottaPreStartupListener implements ServletContextListener {
+
+ private MarmottaStartupService lmfStartupService;
+
+ /**
+ * * Notification that the web application initialization
+ * * process is starting.
+ * * All ServletContextListeners are notified of context
+ * * initialization before any filter or servlet in the web
+ * * application is initialized.
+ */
+ @Override
+ public void contextInitialized(ServletContextEvent sce) {
+
+ if(lmfStartupService == null) {
+ lmfStartupService = CDIContext.getInstance(MarmottaStartupService.class);
+ }
+
+ lmfStartupService.startupConfiguration(null,null,sce.getServletContext());
+
+ }
+
+ /**
+ * * Notification that the servlet context is about to be shut down.
+ * * All servlets and filters have been destroy()ed before any
+ * * ServletContextListeners are notified of context
+ * * destruction.
+ */
+ @Override
+ public void contextDestroyed(ServletContextEvent sce) {
+ lmfStartupService.shutdown();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c77a4b0b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaResourceFilter.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaResourceFilter.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaResourceFilter.java
new file mode 100644
index 0000000..6e46ba0
--- /dev/null
+++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/servlet/MarmottaResourceFilter.java
@@ -0,0 +1,218 @@
+/**
+ * Copyright (C) 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.platform.core.servlet;
+
+import org.apache.marmotta.platform.core.api.config.ConfigurationService;
+import org.apache.marmotta.platform.core.api.modules.MarmottaHttpFilter;
+import org.apache.marmotta.platform.core.api.modules.ModuleService;
+import org.slf4j.Logger;
+
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * This filter is used by KiWi for initialisation of the KiWi system on startup of the server. It does not perform
+ * any actual filtering. For this purpose, a listener would have been better, but CDI in Jetty does not support
+ * injection into listeners, so we "abuse" a filter for this purpose. Filters always get initialised before servlets,
+ * so by adding the KiWiFilter as the first entry into web.xml, we can ensure that the KiWi initialisation is done
+ * before everything else.
+ * <p/>
+ * User: sschaffe
+ */
+public class MarmottaResourceFilter implements Filter {
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private ConfigurationService configurationService;
+
+ @Inject
+ private ModuleService moduleService;
+
+ @Inject @Any
+ private Instance<MarmottaHttpFilter> filters;
+
+ private List<MarmottaHttpFilter> filterList;
+
+ /**
+ * Called by the web container to indicate to a filter that it is being placed into
+ * service. The servlet container calls the init method exactly once after instantiating the
+ * filter. The init method must complete successfully before the filter is asked to do any
+ * filtering work. <br><br>
+ * <p/>
+ * The web container cannot place the filter into service if the init method either<br>
+ * 1.Throws a ServletException <br>
+ * 2.Does not return within a time period defined by the web container
+ */
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ log.info("Apache Marmotta Resource Filter {} starting up ... ", configurationService.getConfiguration("kiwi.version"));
+
+
+ // initialise filter chain and sort it according to priority
+ this.filterList = new ArrayList<MarmottaHttpFilter>();
+
+ for(MarmottaHttpFilter filter : filters) {
+ try {
+ filter.init(filterConfig);
+ filterList.add(filter);
+
+ log.debug("module {}: registered filter {}", moduleService.getModuleConfiguration(filter.getClass()).getModuleName(), filter.getClass().getCanonicalName());
+ } catch (ServletException ex) {
+ log.error("could not instantiate filter {}, servlet exception during initialisation ({})",filter.getClass(),ex.getMessage());
+ }
+ }
+
+ Collections.sort(filterList,new FilterComparator());
+
+ }
+
+
+
+ /**
+ * The <code>doFilter</code> method of the Filter is called by the container
+ * each time a request/response pair is passed through the chain due
+ * to a client request for a resource at the end of the chain. The FilterChain passed in to this
+ * method allows the Filter to pass on the request and response to the next entity in the
+ * chain.<p>
+ * A typical implementation of this method would follow the following pattern:- <br>
+ * 1. Examine the request<br>
+ * 2. Optionally wrap the request object with a custom implementation to
+ * filter content or headers for input filtering <br>
+ * 3. Optionally wrap the response object with a custom implementation to
+ * filter content or headers for output filtering <br>
+ * 4. a) <strong>Either</strong> invoke the next entity in the chain using the FilterChain object (<code>chain.doFilter()</code>), <br>
+ * * 4. b) <strong>or</strong> not pass on the request/response pair to the next entity in the filter chain to block the request processing<br>
+ * * 5. Directly set headers on the response after invocation of the next entity in the filter chain.
+ */
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ URL url = null;
+ String prefix = null, path = null;
+ if (request instanceof HttpServletRequest) {
+ url = new URL(((HttpServletRequest)request).getRequestURL().toString());
+ prefix = ((HttpServletRequest)request).getContextPath();
+ if(url.getPath().startsWith(prefix)) {
+ path = url.getPath().substring(prefix.length());
+ }
+ }
+
+ new LMFFilterChain(path,chain).doFilter(request,response);
+
+ }
+
+
+
+
+ /**
+ * Called by the web container to indicate to a filter that it is being taken out of service. This
+ * method is only called once all threads within the filter's doFilter method have exited or after
+ * a timeout period has passed. After the web container calls this method, it will not call the
+ * doFilter method again on this instance of the filter. <br><br>
+ * <p/>
+ * This method gives the filter an opportunity to clean up any resources that are being held (for
+ * example, memory, file handles, threads) and make sure that any persistent state is synchronized
+ * with the filter's current state in memory.
+ */
+ @Override
+ public void destroy() {
+ for(MarmottaHttpFilter filter : filterList) {
+ filter.destroy();
+ }
+ }
+
+
+ /**
+ * A special filter chain that implements the LMFHttpFilter calls
+ */
+ private class LMFFilterChain implements FilterChain {
+
+ private Iterator<MarmottaHttpFilter> filters;
+
+ private String path;
+
+ private FilterChain originalChain;
+
+ LMFFilterChain(String path, FilterChain originalChain) {
+ this.path = path;
+ this.filters = filterList.iterator();
+ this.originalChain = originalChain;
+ }
+
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
+ if(filters.hasNext()) {
+ MarmottaHttpFilter filter = filters.next();
+
+ if(path.matches(filter.getPattern())) {
+ filter.doFilter(request,response,this);
+ } else {
+ doFilter(request,response);
+ }
+ } else {
+ originalChain.doFilter(request,response);
+ }
+ }
+ }
+
+
+
+ private static class FilterComparator implements Comparator<MarmottaHttpFilter>, Serializable {
+
+ private static final long serialVersionUID = -7264645592168345092L;
+
+ /**
+ * Compares its two arguments for order. Returns a negative integer,
+ * zero, or a positive integer as the first argument is less than, equal
+ * to, or greater than the second.<p>
+ * <p/>
+ *
+ * @param o1 the first object to be compared.
+ * @param o2 the second object to be compared.
+ * @return a negative integer, zero, or a positive integer as the
+ * first argument is less than, equal to, or greater than the
+ * second.
+ * @throws ClassCastException if the arguments' types prevent them from
+ * being compared by this comparator.
+ */
+ @Override
+ public int compare(MarmottaHttpFilter o1, MarmottaHttpFilter o2) {
+ if(o1.getPriority() < o2.getPriority())
+ return -1;
+ else if(o1.getPriority() > o2.getPriority()) return 1;
+ else
+ return 0;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c77a4b0b/platform/marmotta-core/src/test/java/org/apache/marmotta/platform/core/test/base/AbstractMarmotta.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-core/src/test/java/org/apache/marmotta/platform/core/test/base/AbstractMarmotta.java b/platform/marmotta-core/src/test/java/org/apache/marmotta/platform/core/test/base/AbstractMarmotta.java
new file mode 100644
index 0000000..138c2b8
--- /dev/null
+++ b/platform/marmotta-core/src/test/java/org/apache/marmotta/platform/core/test/base/AbstractMarmotta.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright (C) 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.platform.core.test.base;
+
+import com.google.common.io.Files;
+import org.apache.marmotta.platform.core.jndi.MarmottaInitialContextFactoryBuilder;
+import org.apache.marmotta.platform.core.startup.MarmottaStartupService;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
+import org.apache.commons.io.FileUtils;
+import org.jboss.weld.environment.se.Weld;
+import org.jboss.weld.environment.se.WeldContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.spi.NamingManager;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public abstract class AbstractMarmotta {
+
+ protected static Logger log = LoggerFactory.getLogger(EmbeddedMarmotta.class);
+
+ protected Weld weld;
+ protected WeldContainer container;
+ protected MarmottaStartupService startupService;
+ protected Configuration override;
+
+ protected File home;
+
+ protected AbstractMarmotta() {
+
+ // initialise JNDI environment
+ try {
+ NamingManager.setInitialContextFactoryBuilder(new MarmottaInitialContextFactoryBuilder());
+ } catch (NamingException e) {
+
+ } catch (IllegalStateException e) {
+ }
+
+ // initialise CDI environment
+ weld = new Weld();
+ container = weld.initialize();
+
+ cleanJNDI();
+
+
+ // put bean manager into JNDI
+ try {
+ new InitialContext().bind("java:comp/BeanManager",container.getBeanManager());
+ } catch (NamingException e) {
+ log.error("error adding bean manager to JNDI",e);
+ }
+
+
+ // create temporary LMF home directory
+ home = Files.createTempDir();
+
+ // create a temporary configuration with an in-memory database URL for h2
+ override = new MapConfiguration(new HashMap<String,Object>());
+ override.setProperty("database.h2.url","jdbc:h2:mem;MVCC=true;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=10");
+ override.setProperty("logging.template", "/logback-testing.xml");
+
+ // initialise LMF using a temporary directory
+ startupService = getService(MarmottaStartupService.class);
+ }
+
+
+ public <T> T getService(Class<T> serviceClass) {
+ return container.instance().select(serviceClass).get();
+ }
+
+
+ public void shutdown() {
+ // remove bean manager from JNDI
+ cleanJNDI();
+
+ startupService.shutdown();
+ weld.shutdown();
+
+ try {
+ FileUtils.deleteDirectory(home);
+ } catch (IOException e) {
+ log.error("error while deleting temporary Marmotta home directory");
+ }
+ }
+
+
+ private void cleanJNDI() {
+ try {
+ new InitialContext().unbind("java:comp/env/BeanManager");
+ } catch (NamingException e) {
+ }
+ try {
+ new InitialContext().unbind("java:comp/BeanManager");
+ } catch (NamingException e) {
+ }
+ try {
+ new InitialContext().unbind("java:app/BeanManager");
+ } catch (NamingException e) {
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c77a4b0b/platform/marmotta-core/src/test/java/org/apache/marmotta/platform/core/test/base/EmbeddedMarmotta.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-core/src/test/java/org/apache/marmotta/platform/core/test/base/EmbeddedMarmotta.java b/platform/marmotta-core/src/test/java/org/apache/marmotta/platform/core/test/base/EmbeddedMarmotta.java
new file mode 100644
index 0000000..466fdd2
--- /dev/null
+++ b/platform/marmotta-core/src/test/java/org/apache/marmotta/platform/core/test/base/EmbeddedMarmotta.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright (C) 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.platform.core.test.base;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An embedded version of the LMF. Provides support to startup and shutdown the CDI container and the LMF for test cases.
+ * After the embedded LMF has been used, it should always be shutdown before being reused.
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class EmbeddedMarmotta extends AbstractMarmotta {
+
+ private static Logger log = LoggerFactory.getLogger(EmbeddedMarmotta.class);
+
+ public EmbeddedMarmotta() {
+ super();
+
+ // initiate the first startup phase without a servlet context and with the override definition of the parent
+ startupService.startupConfiguration(home.getAbsolutePath(), override,null);
+
+ // initiate the second startup phase and pretend we are running at localhost
+ startupService.startupHost("http://localhost/","http://localhost/");
+
+ log.info("EmbeddedLMF created");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c77a4b0b/platform/marmotta-core/src/test/java/org/apache/marmotta/platform/core/test/base/JettyMarmotta.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-core/src/test/java/org/apache/marmotta/platform/core/test/base/JettyMarmotta.java b/platform/marmotta-core/src/test/java/org/apache/marmotta/platform/core/test/base/JettyMarmotta.java
new file mode 100644
index 0000000..2ff3447
--- /dev/null
+++ b/platform/marmotta-core/src/test/java/org/apache/marmotta/platform/core/test/base/JettyMarmotta.java
@@ -0,0 +1,128 @@
+/**
+ * Copyright (C) 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.platform.core.test.base;
+
+import org.apache.marmotta.platform.core.servlet.MarmottaResourceFilter;
+import org.apache.marmotta.platform.core.test.base.jetty.TestApplication;
+import org.apache.marmotta.platform.core.test.base.jetty.TestInjectorFactory;
+import org.apache.marmotta.platform.core.util.CDIContext;
+import org.apache.marmotta.platform.core.webservices.CoreApplication;
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Handler;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.jetty.servlet.Context;
+import org.mortbay.jetty.servlet.FilterHolder;
+import org.mortbay.jetty.servlet.ServletHolder;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * An extended version of the EmbeddedLMF which also starts a jetty webcontainer. The context name and port
+ * are passed in the constructor. The JettyLMF can optionally take a set of web service classes as argument.
+ * If this argument is present, only the given web services will be instantiated; otherwise, all configured
+ * web services will be instantiated (as in a normal LMF webapp installation).
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class JettyMarmotta extends AbstractMarmotta {
+
+ private Server jetty;
+
+ public JettyMarmotta(String context, int port) {
+ this(context, port, (Set<Class<?>>) null);
+ }
+
+ public JettyMarmotta(String context, int port, Class<?> webservice) {
+ this(context,port, Collections.<Class<?>>singleton(webservice));
+ }
+
+ public JettyMarmotta(String context, int port, Class<?>... webservices) {
+ this(context,port, new HashSet<Class<?>>(Arrays.asList(webservices)));
+ }
+
+
+ public JettyMarmotta(String context, int port, Set<Class<?>> webservice) {
+ super();
+
+ // create a new jetty
+ jetty = new Server();
+
+ // run it on port 8080
+ Connector connector=new SelectChannelConnector();
+ connector.setPort(port);
+ jetty.setConnectors(new Connector[]{connector});
+
+
+ TestInjectorFactory.setManager(container.getBeanManager());
+
+ Context ctx = new Context(jetty,context != null ? context : "/");
+
+ // now we have a context, start up the first phase of the LMF initialisation
+ startupService.startupConfiguration(home.getAbsolutePath(),override,ctx.getServletContext());
+
+ // register the RestEasy CDI injector factory
+ ctx.setAttribute("resteasy.injector.factory", TestInjectorFactory.class.getCanonicalName());
+
+ // register filters
+ FilterHolder resourceFilter = new FilterHolder(CDIContext.getInstance(MarmottaResourceFilter.class));
+ resourceFilter.setInitParameter("kiwi.resourceCaching", "true");
+ ctx.addFilter(resourceFilter,"/*", Handler.DEFAULT);
+
+ // register RestEasy so we can run web services
+
+ // if a single web service is given, only register that webservice, otherwise startup the default configuration
+ //FilterHolder restEasyFilter = new FilterHolder(org.jboss.resteasy.plugins.server.servlet.FilterDispatcher.class);
+ ServletHolder restEasyFilter = new ServletHolder(org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.class);
+ restEasyFilter.setInitParameter("resteasy.injector.factory", TestInjectorFactory.class.getCanonicalName());
+
+
+ if(webservice != null) {
+ TestApplication.setTestedWebServices(webservice);
+ //restEasyFilter.setInitParameter("resteasy.resources", webservice.getName());
+ restEasyFilter.setInitParameter("javax.ws.rs.Application", TestApplication.class.getCanonicalName());
+ } else {
+ restEasyFilter.setInitParameter("javax.ws.rs.Application", CoreApplication.class.getCanonicalName());
+ }
+
+ //ctx.addFilter(restEasyFilter,"/*", Handler.ALL);
+ ctx.addServlet(restEasyFilter, "/*");
+
+ try {
+ jetty.start();
+
+ String url = "http://localhost:"+port+ (context != null ? context + "/" : "/");
+
+ startupService.startupHost(url,url);
+ } catch (Exception e) {
+ log.error("could not start up embedded jetty server",e);
+ }
+ }
+
+ @Override
+ public void shutdown() {
+ try {
+ jetty.stop();
+ } catch (Exception e) {
+ log.error("could not shutdown embedded jetty server",e);
+ }
+ super.shutdown();
+ }
+
+}