Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoberto E. Escobar2014-08-13 02:03:33 +0000
committerRoberto E. Escobar2014-09-29 22:55:18 +0000
commit436b129e96abc4028393ae3e817cdda4f70e68a1 (patch)
tree9cacf6d23deb056dbab23ff57f8d44a223ac8a17 /plugins/org.eclipse.osee.jaxrs.server
parentae55c5a19aa0c72da73ac22756a9df75228528d9 (diff)
downloadorg.eclipse.osee-436b129e96abc4028393ae3e817cdda4f70e68a1.tar.gz
org.eclipse.osee-436b129e96abc4028393ae3e817cdda4f70e68a1.tar.xz
org.eclipse.osee-436b129e96abc4028393ae3e817cdda4f70e68a1.zip
feature[ats_ATS99009]: Add static content contributions to JAX-RS
Diffstat (limited to 'plugins/org.eclipse.osee.jaxrs.server')
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.admin.application.xml1
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.resource.manager.xml8
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.static.resource.filter.xml9
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsAdminApplication.java7
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsResourceManager.java278
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/JaxRsContributionsResource.java89
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/JaxRsStaticResourceRequestFilter.java136
8 files changed, 496 insertions, 33 deletions
diff --git a/plugins/org.eclipse.osee.jaxrs.server/META-INF/MANIFEST.MF b/plugins/org.eclipse.osee.jaxrs.server/META-INF/MANIFEST.MF
index 631e6b8f57a..f7b2df1c5a1 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.osee.jaxrs.server/META-INF/MANIFEST.MF
@@ -67,6 +67,7 @@ Import-Package: com.google.common.cache,
org.eclipse.osee.jaxrs.client,
org.eclipse.osee.jaxrs.mvc,
org.eclipse.osee.logger,
+ org.eclipse.osgi.util,
org.osgi.framework,
org.osgi.service.http
Bundle-Vendor: Eclipse Open System Engineering Environment
diff --git a/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.admin.application.xml b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.admin.application.xml
index 96661993edc..55292a55db5 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.admin.application.xml
+++ b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.admin.application.xml
@@ -5,4 +5,5 @@
<provide interface="javax.ws.rs.core.Application"/>
</service>
<reference bind="setJaxRsApplicationRegistry" cardinality="1..1" interface="org.eclipse.osee.jaxrs.server.internal.applications.JaxRsApplicationRegistry" name="JaxRsApplicationRegistry" policy="static"/>
+ <reference bind="setJaxRsResourceManager" cardinality="1..1" interface="org.eclipse.osee.jaxrs.server.internal.JaxRsResourceManager" name="JaxRsResourceManager" policy="static"/>
</scr:component>
diff --git a/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.resource.manager.xml b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.resource.manager.xml
new file mode 100644
index 00000000000..de0df916b94
--- /dev/null
+++ b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.resource.manager.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop">
+ <implementation class="org.eclipse.osee.jaxrs.server.internal.JaxRsResourceManager" />
+ <reference bind="setLogger" cardinality="1..1" interface="org.eclipse.osee.logger.Log" name="Log" policy="static"/>
+ <service>
+ <provide interface="org.eclipse.osee.jaxrs.server.internal.JaxRsResourceManager"/>
+ </service>
+</scr:component>
diff --git a/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.static.resource.filter.xml b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.static.resource.filter.xml
new file mode 100644
index 00000000000..e87d4d2906a
--- /dev/null
+++ b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.static.resource.filter.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+ <implementation class="org.eclipse.osee.jaxrs.server.internal.resources.JaxRsStaticResourceRequestFilter" />
+ <service>
+ <provide interface="javax.ws.rs.container.ContainerRequestFilter"/>
+ <provide interface="java.lang.Object"/>
+ </service>
+ <reference bind="setJaxRsResourceManager" cardinality="1..1" interface="org.eclipse.osee.jaxrs.server.internal.JaxRsResourceManager" name="JaxRsResourceManager" policy="static"/>
+</scr:component>
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsAdminApplication.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsAdminApplication.java
index fc86f58318e..83ccc43ea21 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsAdminApplication.java
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsAdminApplication.java
@@ -26,13 +26,18 @@ public class JaxRsAdminApplication extends Application {
private final Set<Object> singletons = new LinkedHashSet<Object>();
private JaxRsApplicationRegistry registry;
+ private JaxRsResourceManager manager;
public void setJaxRsApplicationRegistry(JaxRsApplicationRegistry registry) {
this.registry = registry;
}
+ public void setJaxRsResourceManager(JaxRsResourceManager manager) {
+ this.manager = manager;
+ }
+
public void start() {
- singletons.add(new JaxRsContributionsResource(registry));
+ singletons.add(new JaxRsContributionsResource(registry, manager));
}
public void stop() {
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsResourceManager.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsResourceManager.java
new file mode 100644
index 00000000000..fb3bb59add2
--- /dev/null
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsResourceManager.java
@@ -0,0 +1,278 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.jaxrs.server.internal;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.logger.Log;
+import org.eclipse.osgi.util.ManifestElement;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+
+/**
+ * Class responsible for managing static web resources contributed by bundles.
+ *
+ * <pre>
+ * Contributions are specified in the bundle's MANIFEST.MF file using the following header and syntax:
+ *
+ * <b>Osee-JaxRs-Resource:</b> <i>path_to_resource<i><b>;path=</b><i>web_address</i><b>,</b> ...
+ *
+ * Example:
+ * <b>Osee-JaxRs-Resource:</b> <i>/web/js/*<i><b>;path=</b><i>/lib</i>
+ *
+ * Make all files in <b>/web/js/</b> available through <b>/lib/</b>.
+ * Therefore, if we have a file - /web/js/script.js it will be available at /lib/script.js
+ * </pre>
+ *
+ * @author Roberto E. Escobar
+ */
+public final class JaxRsResourceManager implements BundleListener {
+
+ public interface JaxRsResourceVisitor {
+ void onResource(Bundle bundle, Collection<String> resources);
+ }
+
+ public interface Resource {
+
+ URL getUrl();
+
+ }
+
+ private static final String OSEE_WEB_RESOURCE_HDR = "Osee-JaxRs-Resource";
+ private static final String OSEE_WEB_RESOURCE_HDR__PATH_ATTRIBUTE = "path";
+
+ private Map<String, Resource> pathToResource;
+ private Map<Bundle, Set<String>> bundleToKey;
+
+ private Log logger;
+
+ public void setLogger(Log logger) {
+ this.logger = logger;
+ }
+
+ public void start(BundleContext context) {
+ pathToResource = new HashMap<String, Resource>();
+ bundleToKey = new HashMap<Bundle, Set<String>>();
+
+ context.addBundleListener(this);
+
+ // Add bundles that have already started
+ Bundle[] bundles = context.getBundles();
+ if (bundles != null) {
+ for (Bundle bundle : bundles) {
+ int state = bundle.getState();
+ processBundle(bundle, state);
+ }
+ }
+ }
+
+ public void stop(BundleContext context) {
+ context.removeBundleListener(this);
+
+ if (pathToResource != null) {
+ pathToResource.clear();
+ pathToResource = null;
+ }
+
+ if (bundleToKey != null) {
+ bundleToKey.clear();
+ bundleToKey = null;
+ }
+ }
+
+ public Resource getResource(String path) {
+ String toMatch = JaxRsUtils.normalize(path);
+ return pathToResource.get(toMatch);
+ }
+
+ public void accept(JaxRsResourceVisitor visitor) {
+ for (Entry<Bundle, Set<String>> entry : bundleToKey.entrySet()) {
+ visitor.onResource(entry.getKey(), Collections.unmodifiableCollection(entry.getValue()));
+ }
+ }
+
+ @Override
+ public void bundleChanged(BundleEvent event) {
+ Bundle bundle = event.getBundle();
+ processBundle(bundle, event.getType());
+ }
+
+ private String getWebResourceHeader(Bundle bundle) {
+ return bundle.getHeaders().get(OSEE_WEB_RESOURCE_HDR);
+ }
+
+ private boolean hasWebResourceHeader(Bundle bundle) {
+ String headerValue = getWebResourceHeader(bundle);
+ return Strings.isValid(headerValue);
+ }
+
+ private void processBundle(Bundle bundle, int state) {
+ boolean isActive = false;
+ boolean isStopping = false;
+ if (state == Bundle.ACTIVE //
+ || state == Bundle.STARTING //
+ || state == Bundle.INSTALLED //
+ || state == Bundle.RESOLVED) {
+ isActive = true;
+ } else if (state == Bundle.STOPPING) {
+ isStopping = true;
+ }
+
+ if (isActive && hasWebResourceHeader(bundle)) {
+ addBundle(bundle);
+ } else if (isStopping && hasWebResourceHeader(bundle)) {
+ removeBundle(bundle);
+ }
+ }
+
+ private void removeBundle(Bundle bundle) {
+ Set<String> paths = bundleToKey.get(bundle);
+ if (paths != null && !paths.isEmpty()) {
+ for (String path : paths) {
+ pathToResource.remove(path);
+ }
+ }
+ }
+
+ private boolean isValidEntry(Bundle bundle, String headerValue, String resource, String pathAttribute) {
+ boolean result = false;
+ if (!Strings.isValid(pathAttribute)) {
+ logger.warn("Invalid path attribute [%s] for resource [%s] in bundle [%s] with header[%s]", pathAttribute,
+ resource, bundle.getSymbolicName(), headerValue);
+ } else if (!Strings.isValid(resource)) {
+ logger.warn("Invalid resource [%s] for bundle[%s] with header[%s].", resource, bundle.getSymbolicName(),
+ headerValue);
+ } else {
+ result = true;
+ }
+ return result;
+ }
+
+ private void addBundle(Bundle bundle) {
+ String bundleName = bundle.getSymbolicName();
+ String headerValue = getWebResourceHeader(bundle);
+
+ ManifestElement[] elements = null;
+ try {
+ elements = ManifestElement.parseHeader(OSEE_WEB_RESOURCE_HDR, headerValue);
+ } catch (BundleException ex) {
+ logger.error(ex, "Error parsing manifest header [%s] for bundle [%s]", OSEE_WEB_RESOURCE_HDR, bundleName);
+ }
+
+ if (elements != null && elements.length > 0) {
+ for (ManifestElement element : elements) {
+ String resource = element.getValue();
+ String aliasAttribute = element.getAttribute(OSEE_WEB_RESOURCE_HDR__PATH_ATTRIBUTE);
+ if (isValidEntry(bundle, headerValue, resource, aliasAttribute)) {
+ List<URL> resourceUrls = findUrls(bundle, headerValue, true, resource);
+ if (resourceUrls != null && !resourceUrls.isEmpty()) {
+ Set<String> paths = bundleToKey.get(bundle);
+ if (paths == null) {
+ paths = new HashSet<String>();
+ bundleToKey.put(bundle, paths);
+ }
+ for (URL url : resourceUrls) {
+ addResource(paths, bundle, resource, aliasAttribute, url);
+ }
+ } else {
+ logger.warn("No resource urls found for resource path [%s] in bundle[%s] with header[%s].", resource,
+ bundleName, headerValue);
+ }
+ }
+ }
+ }
+ }
+
+ private List<URL> findUrls(Bundle bundle, String headerValue, boolean recurse, String... resources) {
+ List<URL> resourceUrls = new ArrayList<URL>();
+ for (String resource : resources) {
+ int index = resource.lastIndexOf('/');
+ String path = index != -1 ? resource.substring(0, index) : "/";
+ String resourceName = index != -1 ? resource.substring(index + 1) : resource;
+ Enumeration<URL> urls = bundle.findEntries(path, resourceName, recurse);
+ if (urls != null && urls.hasMoreElements()) {
+ while (urls.hasMoreElements()) {
+ URL url = urls.nextElement();
+ if (!url.toString().endsWith("/")) {
+ resourceUrls.add(url);
+ }
+ }
+ } else {
+ logger.error("Unable to find resource[%s] for bundle [%s]. The component header value is [%s]", resource,
+ bundle.getSymbolicName(), headerValue);
+ }
+ }
+ return resourceUrls;
+ }
+
+ private void addResource(Set<String> paths, Bundle bundle, String resourceBase, String alias, URL url) {
+ int index = resourceBase.lastIndexOf('/');
+ String path = index != -1 ? resourceBase.substring(0, index) : "/";
+ String resourceName = index != -1 ? resourceBase.substring(index + 1) : resourceBase;
+
+ String toStrip = path;
+ if (!resourceName.contains("*")) {
+ toStrip += "/" + resourceName;
+ }
+
+ String urlPath = url.getPath();
+ index = urlPath.indexOf(toStrip);
+ if (index >= 0) {
+ urlPath = urlPath.substring(index + toStrip.length());
+ }
+ urlPath = JaxRsUtils.normalize(urlPath);
+
+ String pathToMatch = String.format("%s%s", alias, urlPath);
+ paths.add(pathToMatch);
+
+ Resource resource = new ResourceImpl(bundle.getSymbolicName(), url);
+ Resource oldResource = pathToResource.put(pathToMatch, resource);
+ if (oldResource != null && !oldResource.getUrl().equals(url)) {
+ logger.error("Resource collision detected for path[%s] between 1:[%s] and 2:[%s]. resource-2 will be used.",
+ pathToMatch, oldResource, resource);
+ }
+ }
+
+ private static final class ResourceImpl implements Resource {
+ private final String bundleName;
+ private final URL url;
+
+ public ResourceImpl(String bundleName, URL url) {
+ super();
+ this.bundleName = bundleName;
+ this.url = url;
+ }
+
+ @Override
+ public URL getUrl() {
+ return url;
+ }
+
+ @Override
+ public String toString() {
+ return "resource [bundleName=" + bundleName + ", url=" + url + "]";
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/JaxRsContributionsResource.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/JaxRsContributionsResource.java
index f7ffaac112b..73ae6ffd617 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/JaxRsContributionsResource.java
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/JaxRsContributionsResource.java
@@ -11,11 +11,11 @@
package org.eclipse.osee.jaxrs.server.internal.resources;
import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
+import java.util.Collection;
import java.util.Dictionary;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
import javax.annotation.security.PermitAll;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@@ -27,6 +27,8 @@ import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import org.eclipse.osee.jaxrs.ApplicationInfo;
import org.eclipse.osee.jaxrs.JaxRsContributionInfo;
+import org.eclipse.osee.jaxrs.server.internal.JaxRsResourceManager;
+import org.eclipse.osee.jaxrs.server.internal.JaxRsResourceManager.JaxRsResourceVisitor;
import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitable;
import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitor;
import org.osgi.framework.Bundle;
@@ -39,18 +41,41 @@ import org.osgi.framework.Constants;
public class JaxRsContributionsResource {
private final JaxRsVisitable visitable;
+ private final JaxRsResourceManager resourceManager;
- public JaxRsContributionsResource(JaxRsVisitable visitable) {
+ public JaxRsContributionsResource(JaxRsVisitable visitable, JaxRsResourceManager resourceManager) {
super();
this.visitable = visitable;
+ this.resourceManager = resourceManager;
+ }
+
+ private String key(String bundleName, String bundleVersion) {
+ return String.format("%s:%s", bundleName, bundleVersion);
+ }
+
+ private JaxRsContributionInfo getOrCreateInfo(Map<String, JaxRsContributionInfo> map, String bundleName, String bundleVersion) {
+ String key = key(bundleName, bundleVersion);
+ JaxRsContributionInfo info = map.get(key);
+ if (info == null) {
+ info = new JaxRsContributionInfo();
+ info.setBundleName(bundleName);
+ info.setVersion(bundleVersion);
+ map.put(key, info);
+ }
+ return info;
+ }
+
+ private String getServletPath(UriInfo uriInfo) {
+ String absolutePath = uriInfo.getAbsolutePath().toASCIIString();
+ absolutePath = absolutePath.replaceAll("/jaxrs-admin/contributions", "");
+ return absolutePath;
}
@PermitAll
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
- public List<JaxRsContributionInfo> getContributionDetails(final @Context UriInfo uriInfo) {
- final List<JaxRsContributionInfo> toReturn = new ArrayList<JaxRsContributionInfo>();
-
+ public Collection<JaxRsContributionInfo> getContributionDetails(final @Context UriInfo uriInfo) {
+ final Map<String, JaxRsContributionInfo> contribs = new HashMap<String, JaxRsContributionInfo>();
visitable.accept(new JaxRsVisitor() {
@Override
public void onApplication(String applicationContext, String componentName, Bundle bundle, Application application) {
@@ -59,17 +84,17 @@ public class JaxRsContributionsResource {
String bundleName = headers.get(Constants.BUNDLE_SYMBOLICNAME);
String bundleVersion = headers.get(Constants.BUNDLE_VERSION);
+ JaxRsContributionInfo contrib = getOrCreateInfo(contribs, bundleName, bundleVersion);
+
ApplicationInfo info = new ApplicationInfo();
- info.setBundleName(bundleName);
- info.setVersion(bundleVersion);
info.setName(componentName);
- String absolutePath = getServletPath();
-
+ String absolutePath = getServletPath(uriInfo);
URI build = UriBuilder.fromPath(absolutePath).path(applicationContext).queryParam("_wadl").build();
String path = build.toASCIIString();
info.setUri(path);
- toReturn.add(info);
+
+ contrib.getApplications().add(info);
}
@Override
@@ -79,32 +104,32 @@ public class JaxRsContributionsResource {
String bundleName = headers.get(Constants.BUNDLE_SYMBOLICNAME);
String bundleVersion = headers.get(Constants.BUNDLE_VERSION);
- JaxRsContributionInfo info = new JaxRsContributionInfo();
- info.setBundleName(bundleName);
- info.setVersion(bundleVersion);
- info.setName(componentName);
- toReturn.add(info);
- }
-
- private String getServletPath() {
- String absolutePath = uriInfo.getAbsolutePath().toASCIIString();
- absolutePath = absolutePath.replaceAll("/jaxrs-admin/contributions", "");
- return absolutePath;
+ JaxRsContributionInfo contrib = getOrCreateInfo(contribs, bundleName, bundleVersion);
+ contrib.getProviders().add(componentName);
}
});
- Collections.sort(toReturn, new Comparator<JaxRsContributionInfo>() {
+
+ resourceManager.accept(new JaxRsResourceVisitor() {
@Override
- public int compare(JaxRsContributionInfo o1, JaxRsContributionInfo o2) {
- int toReturn = o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
- if (toReturn == 0) {
- toReturn = o1.getName().compareTo(o2.getName());
+ public void onResource(Bundle bundle, Collection<String> resources) {
+ Dictionary<String, String> headers = bundle.getHeaders();
+ String bundleName = headers.get(Constants.BUNDLE_SYMBOLICNAME);
+ String bundleVersion = headers.get(Constants.BUNDLE_VERSION);
+
+ JaxRsContributionInfo contrib = getOrCreateInfo(contribs, bundleName, bundleVersion);
+
+ String absolutePath = getServletPath(uriInfo);
+
+ Set<String> staticResources = contrib.getStaticResources();
+ for (String resource : resources) {
+ String uri = UriBuilder.fromPath(absolutePath).path(resource).build().toASCIIString();
+ staticResources.add(uri);
}
- return toReturn;
}
-
});
- return toReturn;
+ return contribs.values();
}
+
}
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/JaxRsStaticResourceRequestFilter.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/JaxRsStaticResourceRequestFilter.java
new file mode 100644
index 00000000000..dfaa2acfb78
--- /dev/null
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/JaxRsStaticResourceRequestFilter.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.jaxrs.server.internal.resources;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URLConnection;
+import java.util.Date;
+import java.util.List;
+import javax.annotation.Priority;
+import javax.servlet.ServletContext;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.PreMatching;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import javax.ws.rs.core.StreamingOutput;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.Provider;
+import org.eclipse.osee.framework.jdk.core.util.Lib;
+import org.eclipse.osee.jaxrs.server.internal.JaxRsResourceManager;
+import org.eclipse.osee.jaxrs.server.internal.JaxRsResourceManager.Resource;
+
+/**
+ * @author Roberto E. Escobar
+ */
+@PreMatching
+@Priority(Priorities.USER)
+@Provider
+public class JaxRsStaticResourceRequestFilter implements ContainerRequestFilter {
+
+ private static final String GET_METHOD = "GET";
+ private static final String HEAD_METHOD = "HEAD";
+
+ private JaxRsResourceManager manager;
+
+ @Context
+ private ServletContext servletContext;
+
+ public void setJaxRsResourceManager(JaxRsResourceManager manager) {
+ this.manager = manager;
+ }
+
+ @Override
+ public void filter(ContainerRequestContext requestContext) throws IOException {
+ Request request = requestContext.getRequest();
+ String method = request.getMethod();
+ if (GET_METHOD.equals(method) || HEAD_METHOD.equals(method)) {
+ UriInfo uriInfo = requestContext.getUriInfo();
+ String path = uriInfo.getAbsolutePath().getPath();
+ Resource resource = manager.getResource(path);
+ if (resource != null) {
+ MultivaluedMap<String, String> headers = requestContext.getHeaders();
+ List<MediaType> acceptableMediaTypes = requestContext.getAcceptableMediaTypes();
+ Response response = newResponse(servletContext, headers, acceptableMediaTypes, path, resource);
+ requestContext.abortWith(response);
+ }
+ }
+ }
+
+ private Response newResponse(ServletContext servletContext, MultivaluedMap<String, String> headers, List<MediaType> acceptableMediaTypes, String toMatch, Resource resource) throws IOException {
+ final URLConnection connection = resource.getUrl().openConnection();
+
+ long lastModified = connection.getLastModified();
+ int contentLength = connection.getContentLength();
+
+ String etag = null;
+ if (lastModified != -1 && contentLength != -1) {
+ etag = String.format("W/\"%s-%s\"", contentLength, lastModified);
+ }
+
+ String ifNoneMatch = headers.getFirst(HttpHeaders.IF_NONE_MATCH);
+ if (ifNoneMatch != null && etag != null && ifNoneMatch.indexOf(etag) != -1) {
+ return Response.notModified().build();
+ }
+
+ ResponseBuilder builder = Response.ok();
+ if (contentLength != -1) {
+ builder.header(HttpHeaders.CONTENT_LENGTH, contentLength);
+ }
+
+ String contentType = null;
+ if (servletContext != null) {
+ contentType = servletContext.getMimeType(toMatch);
+ }
+
+ if (contentType != null) {
+ builder.type(contentType);
+ } else {
+ if (!acceptableMediaTypes.isEmpty()) {
+ builder.type(acceptableMediaTypes.get(0));
+ }
+ }
+
+ if (lastModified > 0) {
+ builder.lastModified(new Date(lastModified));
+ }
+
+ if (etag != null) {
+ builder.tag(etag);
+ }
+
+ StreamingOutput output = new StreamingOutput() {
+
+ @Override
+ public void write(OutputStream outputStream) throws IOException, WebApplicationException {
+ InputStream inputStream = null;
+ try {
+ inputStream = connection.getInputStream();
+ Lib.inputStreamToOutputStream(inputStream, outputStream);
+ } finally {
+ Lib.close(inputStream);
+ }
+ }
+ };
+ builder.entity(output);
+ return builder.build();
+ }
+
+} \ No newline at end of file

Back to the top