Repository: tomee Updated Branches: refs/heads/develop 34d2a97a9 -> 3373c194f
TOMEE-1498 web resources support for openejb-http Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/3373c194 Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/3373c194 Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/3373c194 Branch: refs/heads/develop Commit: 3373c194fe44faffac364db522f71ff24b908eb7 Parents: 34d2a97 Author: Romain Manni-Bucau <[email protected]> Authored: Thu Jan 22 08:35:49 2015 +0100 Committer: Romain Manni-Bucau <[email protected]> Committed: Thu Jan 22 08:35:49 2015 +0100 ---------------------------------------------------------------------- .../openejb/testing/ApplicationComposers.java | 4 + .../org/apache/openejb/testing/WebResource.java | 29 +++++++ .../server/httpd/HttpListenerRegistry.java | 82 +++++++++++++++++--- .../openejb/server/httpd/ResourcesTest.java | 68 ++++++++++++++++ .../test/resources/META-INF/resources/foo.txt | 16 ++++ .../resources/META-INF/resources/other/foo.txt | 16 ++++ server/openejb-http/src/test/web/bar.txt | 16 ++++ server/openejb-http/src/test/web/sub/bar.txt | 16 ++++ 8 files changed, 238 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/3373c194/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java b/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java index fd7a21e..3c41676 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java @@ -393,6 +393,10 @@ public final class ApplicationComposers { configuration.setProperty("httpejbd.indent.xml", "true"); configuration.setProperty("logging.level.OpenEJB.server.http", "FINE"); } + final WebResource webResource = testClass.getAnnotation(WebResource.class); + if (webResource != null && webResource.value().length > 0) { + configuration.setProperty("openejb.embedded.http.resources", Join.join(",", webResource.value())); + } Openejb openejb = null; final Map<Object, List<Method>> configs = new HashMap<>(); http://git-wip-us.apache.org/repos/asf/tomee/blob/3373c194/container/openejb-core/src/main/java/org/apache/openejb/testing/WebResource.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/testing/WebResource.java b/container/openejb-core/src/main/java/org/apache/openejb/testing/WebResource.java new file mode 100644 index 0000000..9db2df2 --- /dev/null +++ b/container/openejb-core/src/main/java/org/apache/openejb/testing/WebResource.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.openejb.testing; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface WebResource { + String[] value(); +} http://git-wip-us.apache.org/repos/asf/tomee/blob/3373c194/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java ---------------------------------------------------------------------- diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java index e37232a..15012b1 100644 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java +++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java @@ -20,6 +20,7 @@ import org.apache.openejb.AppContext; import org.apache.openejb.assembler.classic.WebAppBuilder; import org.apache.openejb.cdi.CdiAppContextsService; import org.apache.openejb.cdi.Proxys; +import org.apache.openejb.core.ParentClassLoaderFinder; import org.apache.openejb.core.WebContext; import org.apache.openejb.loader.IO; import org.apache.openejb.loader.SystemInstance; @@ -32,6 +33,8 @@ import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; +import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URL; @@ -39,6 +42,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.Map; import java.util.StringTokenizer; @@ -50,6 +54,9 @@ public class HttpListenerRegistry implements HttpListener { private final Map<String, Collection<HttpListener>> filterRegistry = new LinkedHashMap<>(); private final ThreadLocal<FilterListener> currentFilterListener = new ThreadLocal<>(); private final ThreadLocal<HttpRequest> request = new ThreadLocal<>(); + private final ClassLoader defaultClassLoader; + private final File[] resourceBases; + private final Map<String, String> defaultContextTypes = new HashMap<>(); public HttpListenerRegistry() { HttpServletRequest mock = null; @@ -100,6 +107,32 @@ public class HttpListenerRegistry implements HttpListener { if (systemInstance.getComponent(ServletContext.class) == null) { // a poor impl but at least we set something systemInstance.setComponent(ServletContext.class, new EmbeddedServletContext()); } + + defaultClassLoader = ParentClassLoaderFinder.Helper.get(); + + String resourceFolderPaths = SystemInstance.get().getProperty("openejb.embedded.http.resources"); + Collection<File> resources = new LinkedList<>(); + if (resourceFolderPaths != null) { + for (final String path : resourceFolderPaths.split(" , ")) { + if (!path.isEmpty()) { + resources.add(new File(path)); + } + } + } + resourceBases = resources.toArray(new File[resources.size()]); + + defaultContextTypes.put("html", "text/html"); + defaultContextTypes.put("html", "text/html"); + defaultContextTypes.put("css", "text/css"); + defaultContextTypes.put("txt", "text/plain"); + defaultContextTypes.put("xml", "application/xml"); + defaultContextTypes.put("xsl", "application/xml"); + defaultContextTypes.put("js", "text/javascript"); + defaultContextTypes.put("gif", "image/gif"); + defaultContextTypes.put("jpeg", "image/jpeg"); + defaultContextTypes.put("jpg", "image/jpeg"); + defaultContextTypes.put("png", "image/png"); + defaultContextTypes.put("tiff", "image/tiff"); } @Override @@ -163,19 +196,41 @@ public class HttpListenerRegistry implements HttpListener { if (!found) { final String servletPath = request.getServletPath(); if (servletPath != null) { - final URL url = SystemInstance.get().getComponent(ServletContext.class).getResource(servletPath); + URL url = SystemInstance.get().getComponent(ServletContext.class).getResource(servletPath); if (url != null) { - final InputStream from = url.openStream(); - try { - IO.copy(from, response.getOutputStream()); - } finally { - IO.close(from); + serveResource(response, url); + } else { + final String pathWithoutSlash = servletPath.startsWith("/") ? servletPath.substring(1) : servletPath; + url = defaultClassLoader.getResource("META-INF/resources/" + pathWithoutSlash); + if (url != null) { + serveResource(response, url); + } else if (resourceBases.length > 0) { + for (final File f : resourceBases) { + final File file = new File(f, pathWithoutSlash); + if (file.isFile()) { + url = file.toURI().toURL(); + serveResource(response, url); + break; + } + } } } - if (servletPath.endsWith(".html")) { - response.setContentType("text/html"); + if (url != null) { + final int dot = servletPath.lastIndexOf('.'); + if (dot > 0 && dot < servletPath.length() - 1) { + final String ext = servletPath.substring(dot + 1); + final String ct = defaultContextTypes.get(ext); + if (ct != null) { + response.setContentType(ct); + } else { + final String uct = SystemInstance.get().getProperty("openejb.embedded.http.content-type." + ext); + if (uct != null) { + response.setContentType(uct); + } + } + } } - } + } // TODO else 404 } } finally { if (currentFL == null) { @@ -187,6 +242,15 @@ public class HttpListenerRegistry implements HttpListener { } } + private void serveResource(HttpResponse response, URL url) throws IOException { + final InputStream from = url.openStream(); + try { + IO.copy(from, response.getOutputStream()); + } finally { + IO.close(from); + } + } + private String getRequestHandledPath(final HttpRequest request) { final String servletPath = request.getServletPath(); return request.getContextPath() + (!servletPath.startsWith("/") ? "/" : "") + servletPath; http://git-wip-us.apache.org/repos/asf/tomee/blob/3373c194/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ResourcesTest.java ---------------------------------------------------------------------- diff --git a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ResourcesTest.java b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ResourcesTest.java new file mode 100644 index 0000000..af70c79 --- /dev/null +++ b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ResourcesTest.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.openejb.server.httpd; + +import org.apache.openejb.junit.ApplicationComposerRule; +import org.apache.openejb.loader.IO; +import org.apache.openejb.testing.Classes; +import org.apache.openejb.testing.ContainerProperties; +import org.apache.openejb.testing.EnableServices; +import org.apache.openejb.testing.RandomPort; +import org.apache.openejb.testing.WebResource; +import org.junit.Rule; +import org.junit.Test; + +import javax.inject.Inject; +import javax.servlet.AsyncContext; +import javax.servlet.AsyncEvent; +import javax.servlet.AsyncListener; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URL; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +@EnableServices("http") +@WebResource("src/test/web") +@Classes +@ContainerProperties(@ContainerProperties.Property(name = "httpejbd.useJetty", value = "fase")) +public class ResourcesTest { + @Rule + public final ApplicationComposerRule container = new ApplicationComposerRule(this); + + @RandomPort("http") + private URL context; + + @Test + public void classloader() throws IOException { + assertTrue(IO.slurp(new URL(context.toExternalForm() + "openejb/foo.txt")).contains("from classloader")); + assertTrue(IO.slurp(new URL(context.toExternalForm() + "openejb/other/foo.txt")).contains("from classloader2")); + } + + @Test + public void folder() throws IOException { + assertTrue(IO.slurp(new URL(context.toExternalForm() + "openejb/bar.txt")).contains("from web")); + assertTrue(IO.slurp(new URL(context.toExternalForm() + "openejb/sub/bar.txt")).contains("from web2")); + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/3373c194/server/openejb-http/src/test/resources/META-INF/resources/foo.txt ---------------------------------------------------------------------- diff --git a/server/openejb-http/src/test/resources/META-INF/resources/foo.txt b/server/openejb-http/src/test/resources/META-INF/resources/foo.txt new file mode 100644 index 0000000..6c9c7dd --- /dev/null +++ b/server/openejb-http/src/test/resources/META-INF/resources/foo.txt @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from classloader \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tomee/blob/3373c194/server/openejb-http/src/test/resources/META-INF/resources/other/foo.txt ---------------------------------------------------------------------- diff --git a/server/openejb-http/src/test/resources/META-INF/resources/other/foo.txt b/server/openejb-http/src/test/resources/META-INF/resources/other/foo.txt new file mode 100644 index 0000000..0461556 --- /dev/null +++ b/server/openejb-http/src/test/resources/META-INF/resources/other/foo.txt @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from classloader2 \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tomee/blob/3373c194/server/openejb-http/src/test/web/bar.txt ---------------------------------------------------------------------- diff --git a/server/openejb-http/src/test/web/bar.txt b/server/openejb-http/src/test/web/bar.txt new file mode 100644 index 0000000..36c7fcd --- /dev/null +++ b/server/openejb-http/src/test/web/bar.txt @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from web \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tomee/blob/3373c194/server/openejb-http/src/test/web/sub/bar.txt ---------------------------------------------------------------------- diff --git a/server/openejb-http/src/test/web/sub/bar.txt b/server/openejb-http/src/test/web/sub/bar.txt new file mode 100644 index 0000000..1cf577a --- /dev/null +++ b/server/openejb-http/src/test/web/sub/bar.txt @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from web2 \ No newline at end of file
