On Thu, Nov 10, 2011 at 4:30 PM, Justin Deoliveira <[email protected]>wrote:
> What do you think? Seems rather straightforward to me, and increases the
>> server modularity
>> quite a bit, giving also modules the ability to publish whatever on the
>> webapp right out
>> of the classpath (say, for example, that you need a specific javascript
>> library, more schemas
>> or something like that)
>>
>
> Sounds good to me. Looked over the patch... i think it might not include
> all changes? For instance AbstractURLPublisher... i can't find that class
> anywhere but it seems the patch contains modifications to it... or am I
> crazy? :)
>
Doh sorry, rediffed. I still omitted all the schema movements around, just
the code and app context changes
Cheers
Andrea
--
-------------------------------------------------------
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 962313
http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf
-------------------------------------------------------
diff --git a/src/main/src/main/java/applicationContext.xml b/src/main/src/main/java/applicationContext.xml
index e294a9a..d5e5926 100644
--- a/src/main/src/main/java/applicationContext.xml
+++ b/src/main/src/main/java/applicationContext.xml
@@ -87,6 +87,9 @@
<constructor-arg ref="resourceLoader" />
</bean>
+ <!-- classpath publisher, allows resources in the classpath to be published as static files -->
+ <bean id="classpathPublisher" class="org.geoserver.ows.ClasspathPublisher"/>
+
<!-- jai initializer -->
<bean id="jaiInitializer" class="org.geoserver.jai.JAIInitializer"/>
@@ -132,6 +135,16 @@
</property>
</bean>
+ <bean id="classpathPublisherMapping"
+ class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
+ <property name="alwaysUseFullPath" value="true"/>
+ <property name="mappings">
+ <props>
+ <prop key="/schemas/**">classpathPublisher</prop>
+ </props>
+ </property>
+ </bean>
+
<!-- geotools repository adapter for catalog -->
<bean id="catalogRepository" class="org.geoserver.catalog.CatalogRepository">
<constructor-arg ref="catalog"/>
diff --git a/src/ows/src/main/java/org/geoserver/ows/AbstractURLPublisher.java b/src/ows/src/main/java/org/geoserver/ows/AbstractURLPublisher.java
new file mode 100644
index 0000000..ae03ef4
--- /dev/null
+++ b/src/ows/src/main/java/org/geoserver/ows/AbstractURLPublisher.java
@@ -0,0 +1,143 @@
+/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
+ * This code is licensed under the GPL 2.0 license, availible at the root
+ * application directory.
+ */
+package org.geoserver.ows;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.geoserver.ows.util.EncodingInfo;
+import org.geoserver.ows.util.XmlCharsetDetector;
+import org.geotools.data.DataUtilities;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.AbstractController;
+
+/**
+ * Controller which publishes files through a web interface from the classpath
+ * <p>
+ * To use this controller, it should be mapped to a particular url in the url mapping of the spring
+ * dispatcher servlet. Example:
+ *
+ * <pre>
+ * <code>
+ * <bean id="filePublisher" class="org.geoserver.ows.FilePublisher"/>
+ * <bean id="dispatcherMappings"
+ * <property name="alwaysUseFullPath" value="true"/>
+ * class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
+ * <property name="mappings">
+ * <prop key="/schemas/** /*.xsd">filePublisher</prop>
+ * <prop key="/schemas/** /*.dtd">filePublisher</prop>
+ * <prop key="/styles/*">filePublisher</prop>
+ * </property>
+ * </bean>
+ * </code>
+ * </pre>
+ *
+ * </p>
+ *
+ * @author Justin Deoliveira, The Open Planning Project
+ * @author Andrea Aime - GeoSolutions
+ */
+public abstract class AbstractURLPublisher extends AbstractController {
+
+ protected ModelAndView handleRequestInternal(HttpServletRequest request,
+ HttpServletResponse response) throws Exception {
+ URL url = getUrl(request);
+
+ // if not found return a 404
+ if (url == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return null;
+ }
+
+ File file = DataUtilities.urlToFile(url);
+ if(file != null && file.exists() && file.isDirectory()) {
+ String uri = request.getRequestURI().toString();
+ uri += uri.endsWith("/") ? "index.html" : "/index.html";
+
+ response.addHeader("Location", uri);
+ response.sendError(HttpServletResponse.SC_MOVED_TEMPORARILY);
+
+ return null;
+ }
+
+
+
+ // set the mime if known by the servlet container, set nothing otherwise
+ // (Tomcat behaves like this when it does not recognize the file format)
+ String mime = getServletContext().getMimeType(new File(url.getFile()).getName());
+ if (mime != null) {
+ response.setContentType(mime);
+ }
+
+ // set the content length and content type
+ URLConnection connection = null;
+ InputStream input = null;
+ try {
+ connection = url.openConnection();
+ long length = connection.getContentLength();
+ if (length > 0 && length <= Integer.MAX_VALUE) {
+ response.setContentLength((int) length);
+ }
+
+ long lastModified = connection.getLastModified();
+ if (lastModified > 0) {
+ SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss",
+ Locale.ENGLISH);
+ format.setTimeZone(TimeZone.getTimeZone("GMT"));
+ String formatted = format.format(new Date(lastModified)) + " GMT";
+ response.setHeader("Last-Modified", formatted);
+ }
+
+ // Guessing the charset (and closing the stream)
+ EncodingInfo encInfo = null;
+ OutputStream output = null;
+ final byte[] b4 = new byte[4];
+ int count = 0;
+ // open the output
+ input = connection.getInputStream();
+
+ // Read the first four bytes, and determine charset encoding
+ count = input.read(b4);
+ encInfo = XmlCharsetDetector.getEncodingName(b4, count);
+ response.setCharacterEncoding(encInfo.getEncoding() != null ? encInfo.getEncoding()
+ : "UTF-8");
+
+ // send out the first four bytes read
+ output = response.getOutputStream();
+ output.write(b4, 0, count);
+
+ // copy the content to the output
+ byte[] buffer = new byte[8192];
+ int n = -1;
+ while ((n = input.read(buffer)) != -1) {
+ output.write(buffer, 0, n);
+ }
+ } finally {
+ if (input != null)
+ input.close();
+ }
+
+ return null;
+ }
+
+ /**
+ * Retrieves the resource URL from the specified request
+ * @param request
+ * @return
+ * @throws IOException
+ */
+ protected abstract URL getUrl(HttpServletRequest request) throws IOException;
+}
diff --git a/src/ows/src/main/java/org/geoserver/ows/ClasspathPublisher.java b/src/ows/src/main/java/org/geoserver/ows/ClasspathPublisher.java
new file mode 100644
index 0000000..df7a4ea
--- /dev/null
+++ b/src/ows/src/main/java/org/geoserver/ows/ClasspathPublisher.java
@@ -0,0 +1,85 @@
+/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
+ * This code is licensed under the GPL 2.0 license, availible at the root
+ * application directory.
+ */
+package org.geoserver.ows;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.geoserver.ows.util.EncodingInfo;
+import org.geoserver.ows.util.XmlCharsetDetector;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.AbstractController;
+
+/**
+ * Controller which publishes files through a web interface from the classpath
+ * <p>
+ * To use this controller, it should be mapped to a particular url in the url mapping of the spring
+ * dispatcher servlet. Example:
+ *
+ * <pre>
+ * <code>
+ * <bean id="filePublisher" class="org.geoserver.ows.FilePublisher"/>
+ * <bean id="dispatcherMappings"
+ * <property name="alwaysUseFullPath" value="true"/>
+ * class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
+ * <property name="mappings">
+ * <prop key="/schemas/** /*.xsd">filePublisher</prop>
+ * <prop key="/schemas/** /*.dtd">filePublisher</prop>
+ * <prop key="/styles/*">filePublisher</prop>
+ * </property>
+ * </bean>
+ * </code>
+ * </pre>
+ *
+ * </p>
+ *
+ * @author Justin Deoliveira, The Open Planning Project
+ * @author Andrea Aime - GeoSolutions
+ */
+public class ClasspathPublisher extends AbstractURLPublisher {
+ Class clazz;
+
+ /**
+ * Creates the new classpath publisher.
+ *
+ * @param clazz the class used to perform classpath lookups with
+ * {@link Class#getResource(String)}
+ */
+ public ClasspathPublisher(Class clazz) {
+ this.clazz = clazz;
+ }
+
+ public ClasspathPublisher() {
+ this.clazz = ClasspathPublisher.class;
+ }
+
+ @Override
+ protected URL getUrl(HttpServletRequest request) {
+ String ctxPath = request.getContextPath();
+ String reqPath = request.getRequestURI();
+ reqPath = reqPath.substring(ctxPath.length());
+
+ // try a few lookups
+ URL url = clazz.getResource(reqPath);
+ if (url == null && !reqPath.startsWith("/")) {
+ url = clazz.getResource("/");
+ }
+ if (url == null && (reqPath.length() > 1) && reqPath.startsWith("/")) {
+ url = clazz.getResource(reqPath.substring(1));
+ }
+ return url;
+ }
+
+}
diff --git a/src/ows/src/main/java/org/geoserver/ows/FilePublisher.java b/src/ows/src/main/java/org/geoserver/ows/FilePublisher.java
index 848ac6a..d0ef206 100644
--- a/src/ows/src/main/java/org/geoserver/ows/FilePublisher.java
+++ b/src/ows/src/main/java/org/geoserver/ows/FilePublisher.java
@@ -6,7 +6,9 @@ package org.geoserver.ows;
import java.io.File;
import java.io.FileInputStream;
+import java.io.IOException;
import java.io.OutputStream;
+import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
@@ -19,17 +21,18 @@ import javax.servlet.http.HttpServletResponse;
import org.geoserver.ows.util.EncodingInfo;
import org.geoserver.ows.util.XmlCharsetDetector;
import org.geoserver.platform.GeoServerResourceLoader;
+import org.geotools.data.DataUtilities;
import org.springframework.web.context.support.ServletContextResource;
import org.springframework.web.context.support.ServletContextResourceLoader;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
-
/**
* Controller which publishes files through a web interface.
* <p>
- * To use this controller, it should be mapped to a particular url in the url
- * mapping of the spring dispatcher servlet. Example:
+ * To use this controller, it should be mapped to a particular url in the url mapping of the spring
+ * dispatcher servlet. Example:
+ *
* <pre>
* <code>
* <bean id="filePublisher" class="org.geoserver.ows.FilePublisher"/>
@@ -44,25 +47,26 @@ import org.springframework.web.servlet.mvc.AbstractController;
* </bean>
* </code>
* </pre>
+ *
* </p>
- *
+ *
* @author Justin Deoliveira, The Open Planning Project
- *
+ *
*/
-public class FilePublisher extends AbstractController {
+public class FilePublisher extends AbstractURLPublisher {
/**
* Resource loader
*/
protected GeoServerResourceLoader loader;
-
+
/**
* Servlet resource loader
*/
protected ServletContextResourceLoader scloader;
-
+
/**
* Creates the new file publisher.
- *
+ *
* @param loader The loader used to locate files.
*/
public FilePublisher(GeoServerResourceLoader loader) {
@@ -73,9 +77,9 @@ public class FilePublisher extends AbstractController {
protected void initServletContext(ServletContext servletContext) {
this.scloader = new ServletContextResourceLoader(servletContext);
}
-
- protected ModelAndView handleRequestInternal(HttpServletRequest request,
- HttpServletResponse response) throws Exception {
+
+ @Override
+ protected URL getUrl(HttpServletRequest request) throws IOException {
String ctxPath = request.getContextPath();
String reqPath = request.getRequestURI();
reqPath = reqPath.substring(ctxPath.length());
@@ -83,91 +87,30 @@ public class FilePublisher extends AbstractController {
if ((reqPath.length() > 1) && reqPath.startsWith("/")) {
reqPath = reqPath.substring(1);
}
-
+
// sigh, in order to serve the file we have to open it 2 times
// 1) to determine its mime type
// 2) to determine its encoding and really serve it
- // we can't coalish 1) because we don't have a way to give jmimemagic the bytes at the
+ // we can't coalish 1) because we don't have a way to give jmimemagic the bytes at the
// beginning of the file without disabling extension quick matching
// load the file
File file = loader.find(reqPath);
if (file == null && scloader != null) {
- //try loading as a servlet resource
- ServletContextResource resource = (ServletContextResource) scloader.getResource(reqPath);
+ // try loading as a servlet resource
+ ServletContextResource resource = (ServletContextResource) scloader
+ .getResource(reqPath);
if (resource != null && resource.exists()) {
file = resource.getFile();
}
}
- if (file == null) {
- //return a 404
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
-
- return null;
- }
-
- if (file.isDirectory()) {
- String uri = request.getRequestURI().toString();
- uri += uri.endsWith("/") ? "index.html" : "/index.html";
-
- response.addHeader("Location", uri);
- response.sendError(HttpServletResponse.SC_MOVED_TEMPORARILY);
-
+ if(file != null) {
+ return DataUtilities.fileToURL(file);
+ } else {
return null;
}
-
- // set the mime if known by the servlet container, set nothing otherwise
- // (Tomcat behaves like this when it does not recognize the file format)
- String mime = getServletContext().getMimeType(file.getName());
- if (mime != null)
- response.setContentType(mime);
-
- // set the content length
- long length = file.length();
- if(length > 0 && length <= Integer.MAX_VALUE)
- response.setContentLength((int) length);
-
- // set the last modified header
- long lastModified = file.lastModified();
- if(lastModified > 0) {
- SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss", Locale.ENGLISH);
- format.setTimeZone(TimeZone.getTimeZone("GMT"));
- String formatted = format.format(new Date(lastModified)) + " GMT";
- response.setHeader("Last-Modified", formatted);
- }
-
- // Guessing the charset (and closing the stream)
- EncodingInfo encInfo = null;
- FileInputStream input = null;
- OutputStream output = null;
- final byte[] b4 = new byte[4];
- int count = 0;
- try {
- // open the output
- input = new FileInputStream(file);
-
- // Read the first four bytes, and determine charset encoding
- count = input.read(b4);
- encInfo = XmlCharsetDetector.getEncodingName(b4, count);
- response.setCharacterEncoding(encInfo.getEncoding() != null ? encInfo.getEncoding() : "UTF-8");
-
- // send out the first four bytes read
- output = response.getOutputStream();
- output.write(b4, 0, count);
-
- // copy the content to the output
- byte[] buffer = new byte[8192];
- int n = -1;
- while ((n = input.read(buffer)) != -1) {
- output.write(buffer, 0, n);
- }
- } finally {
- if(output != null) output.flush();
- if(input != null) input.close();
- }
-
- return null;
}
+
}
diff --git a/src/wms/src/main/java/applicationContext.xml b/src/wms/src/main/java/applicationContext.xml
index ce5ac94..1f74249 100644
--- a/src/wms/src/main/java/applicationContext.xml
+++ b/src/wms/src/main/java/applicationContext.xml
@@ -700,4 +700,15 @@
<bean id="envVariableCleaner" class="org.geoserver.wms.EnvVariableCleaner"/>
<bean id="rasterCleaner" class="org.geoserver.wms.RasterCleaner"/>
+
+ <bean id="wmsClasspathPublisherMapping"
+ class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
+ <property name="alwaysUseFullPath" value="true"/>
+ <property name="mappings">
+ <props>
+ <prop key="/openlayers/**">classpathPublisher</prop>
+ <prop key="/options.png">classpathPublisher</prop>
+ </props>
+ </property>
+ </bean>
</beans>
------------------------------------------------------------------------------
RSA(R) Conference 2012
Save $700 by Nov 18
Register now
http://p.sf.net/sfu/rsa-sfdev2dev1
_______________________________________________
Geoserver-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geoserver-devel