Permanent fix for ticket #1693. CMS service works with the original urls again.
git-svn-id: https://svn.libreccm.org/ccm/trunk@2143 8810af33-2d31-482b-a856-94f89814c4dfmaster
parent
50bb1a275b
commit
04b1f4f28d
|
|
@ -1,22 +1,34 @@
|
||||||
<dispatcher-configuration>
|
<dispatcher-configuration>
|
||||||
<url-mapping>
|
<url-mapping>
|
||||||
<url>logout/</url>
|
<url>/logout/</url>
|
||||||
<page-class>com.arsdigita.cms.ui.Logout</page-class>
|
<page-class>com.arsdigita.cms.ui.Logout</page-class>
|
||||||
</url-mapping>
|
</url-mapping>
|
||||||
<url-mapping>
|
<url-mapping>
|
||||||
|
<!--
|
||||||
<url>/templates/servlet/cms-service/stream/image/</url>
|
<url>/templates/servlet/cms-service/stream/image/</url>
|
||||||
|
-->
|
||||||
|
<url>/stream/image/</url>
|
||||||
<page-class>com.arsdigita.cms.dispatcher.StreamImage</page-class>
|
<page-class>com.arsdigita.cms.dispatcher.StreamImage</page-class>
|
||||||
</url-mapping>
|
</url-mapping>
|
||||||
<url-mapping>
|
<url-mapping>
|
||||||
|
<!--
|
||||||
<url>/templates/servlet/cms-service/download/image/</url>
|
<url>/templates/servlet/cms-service/download/image/</url>
|
||||||
|
-->
|
||||||
|
<url>/download/image/</url>
|
||||||
<page-class>com.arsdigita.cms.dispatcher.DownloadImage</page-class>
|
<page-class>com.arsdigita.cms.dispatcher.DownloadImage</page-class>
|
||||||
</url-mapping>
|
</url-mapping>
|
||||||
<url-mapping>
|
<url-mapping>
|
||||||
|
<!--
|
||||||
<url>/templates/servlet/cms-service/stream/asset/</url>
|
<url>/templates/servlet/cms-service/stream/asset/</url>
|
||||||
|
-->
|
||||||
|
<url>/stream/asset/</url>
|
||||||
<page-class>com.arsdigita.cms.dispatcher.StreamAsset</page-class>
|
<page-class>com.arsdigita.cms.dispatcher.StreamAsset</page-class>
|
||||||
</url-mapping>
|
</url-mapping>
|
||||||
<url-mapping>
|
<url-mapping>
|
||||||
|
<!--
|
||||||
<url>/templates/servlet/cms-service/download/asset/</url>
|
<url>/templates/servlet/cms-service/download/asset/</url>
|
||||||
|
-->
|
||||||
|
<url>/download/asset/</url>
|
||||||
<page-class>com.arsdigita.cms.dispatcher.DownloadAsset</page-class>
|
<page-class>com.arsdigita.cms.dispatcher.DownloadAsset</page-class>
|
||||||
</url-mapping>
|
</url-mapping>
|
||||||
</dispatcher-configuration>
|
</dispatcher-configuration>
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,7 @@ public class ContentCenterServlet extends BaseApplicationServlet {
|
||||||
sreq = DispatcherHelper.restoreOriginalRequest(sreq);
|
sreq = DispatcherHelper.restoreOriginalRequest(sreq);
|
||||||
rd.forward(sreq, sresp);
|
rd.forward(sreq, sresp);
|
||||||
} else {
|
} else {
|
||||||
// String requestUri = sreq.getRequestURI();
|
|
||||||
sresp.sendError(404, sreq.getRequestURI() + " not found on this server.");
|
sresp.sendError(404, sreq.getRequestURI() + " not found on this server.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ import com.arsdigita.web.Web;
|
||||||
import com.arsdigita.xml.XML;
|
import com.arsdigita.xml.XML;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.RequestDispatcher;
|
import javax.servlet.RequestDispatcher;
|
||||||
|
|
@ -44,10 +43,23 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.xml.sax.helpers.DefaultHandler;
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
|
// Developer's Note:
|
||||||
|
// Class is currently in a transistory state. ServiceServlet itself does process
|
||||||
|
// the request following the new legacy free web application model (i.e. as a
|
||||||
|
// servlet based on BaseApplicationSerevlet / HTTPServlet).
|
||||||
|
// The methods used to invoke the service classes follow the legacy dispatcher
|
||||||
|
// model as set up by BaseApplicationServlet (see #makeLegacyContext). They
|
||||||
|
// should be refactored to work without LegacyContext, probably as a servlet
|
||||||
|
// as well or a legacy free dispatcher / ResourceHandler.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CMS Service application servlet serves all request made for the CMS
|
* CMS Service application servlet serves all request made for the CMS
|
||||||
* service application.
|
* service application.
|
||||||
*
|
*
|
||||||
|
* In many cases a service will open a (Web) page, e.g. the download page for
|
||||||
|
* files of a page to provide details or feedback/results of the service. But
|
||||||
|
* a service may also work without any visual output.
|
||||||
|
*
|
||||||
* URLs of the available services are stored in a XML file which is processed
|
* URLs of the available services are stored in a XML file which is processed
|
||||||
* into a cache of services on a request by request basis (lazy loading).
|
* into a cache of services on a request by request basis (lazy loading).
|
||||||
*
|
*
|
||||||
|
|
@ -55,7 +67,7 @@ import org.xml.sax.helpers.DefaultHandler;
|
||||||
* ServiceServlet is associated with a request URL.
|
* ServiceServlet is associated with a request URL.
|
||||||
*
|
*
|
||||||
* The CMS Service determines whether a <tt>Page</tt> has been registered to
|
* The CMS Service determines whether a <tt>Page</tt> has been registered to
|
||||||
* the URL and if so passes the request to that page.
|
* the URL and if so passes the request to that serviceResource.
|
||||||
*
|
*
|
||||||
* If no <tt>Page</tt> is registered to the URL, then the CMS Service hands
|
* If no <tt>Page</tt> is registered to the URL, then the CMS Service hands
|
||||||
* the request to the TemplateResolver to find an appropriate JSP file.
|
* the request to the TemplateResolver to find an appropriate JSP file.
|
||||||
|
|
@ -74,18 +86,15 @@ public class ServiceServlet extends BaseApplicationServlet {
|
||||||
* class names). */
|
* class names). */
|
||||||
private final static String MAP_FILE = "WEB-INF/resources/cms-service-map.xml";
|
private final static String MAP_FILE = "WEB-INF/resources/cms-service-map.xml";
|
||||||
|
|
||||||
/** Mapping between a relative URL and the class name of a ResourceHandler.*/
|
/** Mapping between a relative URL and the class name of a service. */
|
||||||
private static HashMap s_pageClasses = new HashMap();
|
private static HashMap s_serviceClasses = new HashMap();
|
||||||
|
|
||||||
/** Instantiated ResourceHandler cache. This allows for lazy loading. */
|
/** Instantiated services cache. This allows for lazy loading of the class
|
||||||
private static SimpleCache s_pages = new SimpleCache();
|
* (i.e. irs ResourceHandler) for each service. */
|
||||||
|
private static SimpleCache s_services = new SimpleCache();
|
||||||
|
|
||||||
/** List of URLs which require a trailing slash. These are required for
|
/** Path to directory containg ccm-cms template files, used in case of fall
|
||||||
* creating virtual directories, so that relative URLs and redirects
|
* back, when no service class is found in s_serviceClasses rsp. MAP_FILE */
|
||||||
* work. */
|
|
||||||
private ArrayList m_trailingSlashList = new ArrayList();
|
|
||||||
|
|
||||||
/** Path to directory containg ccm-cms template files */
|
|
||||||
private String m_templatePath;
|
private String m_templatePath;
|
||||||
|
|
||||||
/** Resolvers to find templages (JSP) and other stuff stored in file system.*/
|
/** Resolvers to find templages (JSP) and other stuff stored in file system.*/
|
||||||
|
|
@ -102,11 +111,7 @@ public class ServiceServlet extends BaseApplicationServlet {
|
||||||
s_log.info("starting doInit method");
|
s_log.info("starting doInit method");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize List with an empty URL. Later URL's are added which are
|
/* Process mapping file and fill up s_serviceClasses. */
|
||||||
* provided w/o trailing slash rsp. file extension. */
|
|
||||||
requireTrailingSlash("");
|
|
||||||
|
|
||||||
/* Process mapping file. */
|
|
||||||
readFromFile(MAP_FILE);
|
readFromFile(MAP_FILE);
|
||||||
|
|
||||||
/** Set Template base path for JSP's */
|
/** Set Template base path for JSP's */
|
||||||
|
|
@ -141,42 +146,38 @@ public class ServiceServlet extends BaseApplicationServlet {
|
||||||
}
|
}
|
||||||
DeveloperSupport.startStage("ServiceServlet.doService");
|
DeveloperSupport.startStage("ServiceServlet.doService");
|
||||||
|
|
||||||
Service service = (Service) app;
|
/* Developer's Note:
|
||||||
|
* Legacy context, established by BaseApplicationServlet, currently
|
||||||
|
* KernelContext. Not used in ServiceServlet, but required to invoke
|
||||||
|
* the Resource to provide the service by interface definition.
|
||||||
|
* Cuurently (version 6.6.8) not used in any service class.
|
||||||
|
*/
|
||||||
RequestContext ctx = DispatcherHelper.getRequestContext();
|
RequestContext ctx = DispatcherHelper.getRequestContext();
|
||||||
String url = ctx.getRemainingURLPart(); // here SiteNodeRequestContext
|
|
||||||
String originalUrl = ctx.getOriginalURL();
|
|
||||||
String requestUri = sreq.getRequestURI();
|
|
||||||
|
|
||||||
// An empty remaining URL or a URL which doesn't end in trailing slash:
|
/* Get the service being requested, i.e. the remaining URL following
|
||||||
// probably want to redirect.
|
* the servlet address ( ccm/cms-service by default) */
|
||||||
if ( m_trailingSlashList.contains(url) && !originalUrl.endsWith("/") ) {
|
String url = sreq.getPathInfo();
|
||||||
DispatcherHelper.sendRedirect(sreq, sresp, originalUrl + "/");
|
if (url.length() > 1 && url.endsWith("/")) {
|
||||||
return;
|
/* NOTE: ServletAPI specifies, pathInfo may be empty or will
|
||||||
|
* start with a '/' character. It currently carries a
|
||||||
|
* trailing '/' if a "virtual" serviceResource, i.e. not a real jsp, but
|
||||||
|
* result of a servlet mapping. But Application requires url
|
||||||
|
* NOT to end with a trailing '/' for legacy free applications.
|
||||||
|
* The service classes are currently not real applications, so no
|
||||||
|
* adaptation required here. */
|
||||||
|
// url = url.substring(0, url.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check user access.
|
// User access can not be checked here, but has to be checked by each
|
||||||
// Deprecated and here implemented as a No-OP method!
|
// service!
|
||||||
/* checkUserAccess(request, response, actx); */
|
|
||||||
|
|
||||||
ResourceHandler page = getResource(url);
|
/* Determine the service requested by url */
|
||||||
|
ResourceHandler serviceResource = getResource(url);
|
||||||
|
|
||||||
if (page == null) {
|
if ( serviceResource != null ) {
|
||||||
//Retry without last part
|
// Serve the serviceResource.
|
||||||
final String[] tokens = url.split("/");
|
serviceResource.init();
|
||||||
|
serviceResource.dispatch(sreq, sresp, ctx);
|
||||||
final StringBuilder altUrlBuilder = new StringBuilder('/');
|
|
||||||
for(int i = 0; i < tokens.length - 1; i++) {
|
|
||||||
altUrlBuilder.append(tokens[i]);
|
|
||||||
altUrlBuilder.append('/');
|
|
||||||
}
|
|
||||||
page = getResource(altUrlBuilder.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( page != null ) {
|
|
||||||
// Serve the page.
|
|
||||||
page.init();
|
|
||||||
page.dispatch(sreq, sresp, ctx);
|
|
||||||
} else {
|
} else {
|
||||||
// Fall back on the JSP application dispatcher.
|
// Fall back on the JSP application dispatcher.
|
||||||
if (s_log.isInfoEnabled()) {
|
if (s_log.isInfoEnabled()) {
|
||||||
|
|
@ -192,7 +193,7 @@ public class ServiceServlet extends BaseApplicationServlet {
|
||||||
sreq = DispatcherHelper.restoreOriginalRequest(sreq);
|
sreq = DispatcherHelper.restoreOriginalRequest(sreq);
|
||||||
rd.forward(sreq,sresp);
|
rd.forward(sreq,sresp);
|
||||||
} else {
|
} else {
|
||||||
sresp.sendError(404, requestUri + " not found on this server.");
|
sresp.sendError(404, sreq.getRequestURI() + " not found on this server.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -206,20 +207,24 @@ public class ServiceServlet extends BaseApplicationServlet {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch a page based on the URL stub.
|
* Determines the Resource (ie class) to serve a requested service based
|
||||||
|
* on its url.
|
||||||
|
*
|
||||||
|
* Returns a RecourceHandler for the requested service if it could be found,
|
||||||
|
* i.e. a dispatcher class whose dispatch method invokes the service.
|
||||||
*
|
*
|
||||||
* @param url The URL stub following the site-node URL
|
* @param url The URL stub following the site-node URL
|
||||||
* @return A ResourceHandler or null if none exists.
|
* @return A ResourceHandler or null if none exists.
|
||||||
* @pre (url != null)
|
* @pre (url != null)
|
||||||
*/
|
*/
|
||||||
protected ResourceHandler getResource(String url) throws ServletException {
|
private ResourceHandler getResource(String url) throws ServletException {
|
||||||
|
|
||||||
// First check the pages cache for existing pages.
|
// First check the pages cache for existing pages.
|
||||||
ResourceHandler page = (ResourceHandler) s_pages.get(url);
|
ResourceHandler page = (ResourceHandler) s_services.get(url);
|
||||||
if ( page == null ) {
|
if ( page == null ) {
|
||||||
|
|
||||||
// Next check if the URL maps to a page class.
|
// Next check if the URL maps to a serviceResource class.
|
||||||
String pageClassName = (String) s_pageClasses.get(url);
|
String pageClassName = (String) s_serviceClasses.get(url);
|
||||||
if ( pageClassName != null ) {
|
if ( pageClassName != null ) {
|
||||||
|
|
||||||
Class pageClass;
|
Class pageClass;
|
||||||
|
|
@ -230,7 +235,7 @@ public class ServiceServlet extends BaseApplicationServlet {
|
||||||
throw new ServletException(e);
|
throw new ServletException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try and instantiate the page.
|
// Try and instantiate the serviceResource.
|
||||||
try {
|
try {
|
||||||
page = (ResourceHandler) pageClass.newInstance();
|
page = (ResourceHandler) pageClass.newInstance();
|
||||||
} catch (InstantiationException e) {
|
} catch (InstantiationException e) {
|
||||||
|
|
@ -242,7 +247,7 @@ public class ServiceServlet extends BaseApplicationServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
page.init();
|
page.init();
|
||||||
s_pages.put(url, page);
|
s_services.put(url, page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return page;
|
return page;
|
||||||
|
|
@ -251,48 +256,24 @@ public class ServiceServlet extends BaseApplicationServlet {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Initializes URL-to-Page/Dispatcher/Servlet mappings from a file.
|
* Initializes URL-to-Page (class) mappings from a file.
|
||||||
*
|
*
|
||||||
* Format of the file is XML:
|
* Format of the file is XML:
|
||||||
* <pre>
|
* <pre>
|
||||||
* <dispatcher-configuration>
|
* <dispatcher-configuration>
|
||||||
* <url-mapping
|
* <url-mapping
|
||||||
* <url>my-page</url>
|
* <url>my-serviceResource</url>
|
||||||
* OR <page-class>com.arsdigita.Page.class</page-class>
|
* OR <serviceResource-class>com.arsdigita.Page</page-class>
|
||||||
* <url-mapping
|
* <url-mapping
|
||||||
* </dispatcher-configuration>
|
* </dispatcher-configuration>
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
private void readFromFile(final String file) {
|
private void readFromFile(final String file) {
|
||||||
|
|
||||||
// XML.parseResource(file, newParseConfigHandler(s_pageClasses));
|
XML.parseResource(file, new PageClassConfigHandler(s_serviceClasses));
|
||||||
XML.parseResource(file, new PageClassConfigHandler(s_pageClasses));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a URL to the list of URLs that are required to have trailing
|
|
||||||
* slashes. A request for url will be redirected to url + "/"
|
|
||||||
* if the original URL request (what you see in your browser)
|
|
||||||
* doesn't include a trailing slash. This is required for
|
|
||||||
* creating virtual directories, so that relative URLs and redirects
|
|
||||||
* work.
|
|
||||||
*/
|
|
||||||
public void requireTrailingSlash(String url) {
|
|
||||||
m_trailingSlashList.add(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a SAX event handler object for setting up a MapDispatcher
|
|
||||||
* using an XML config file.
|
|
||||||
* @param map A map to configure
|
|
||||||
* @return a SAX DefaultHandler object for handling SAX events
|
|
||||||
* @pre md.m_map != null
|
|
||||||
*/
|
|
||||||
// protected DefaultHandler newParseConfigHandler(Map map) {
|
|
||||||
// return new PageClassConfigHandler(map);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -52,15 +52,6 @@ class BaseAsset extends ResourceHandlerImpl {
|
||||||
private static final BigDecimalParameter s_assetId = new BigDecimalParameter(ASSET_ID);
|
private static final BigDecimalParameter s_assetId = new BigDecimalParameter(ASSET_ID);
|
||||||
private static final OIDParameter s_oid = new OIDParameter(OID_PARAM);
|
private static final OIDParameter s_oid = new OIDParameter(OID_PARAM);
|
||||||
|
|
||||||
/*
|
|
||||||
* jensp 2011-02-11: No need for static initalizer block here. Moved
|
|
||||||
* to variable declaration (see above).
|
|
||||||
*/
|
|
||||||
/*static {
|
|
||||||
s_assetId = new BigDecimalParameter(ASSET_ID);
|
|
||||||
s_oid = new OIDParameter(OID_PARAM);
|
|
||||||
//s_assetId.addParameterListener(new NotNullValidationListener());
|
|
||||||
}*/
|
|
||||||
private final boolean m_download;
|
private final boolean m_download;
|
||||||
private String m_disposition;
|
private String m_disposition;
|
||||||
|
|
||||||
|
|
@ -121,7 +112,8 @@ class BaseAsset extends ResourceHandlerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void send(HttpServletResponse response,
|
private void send(HttpServletResponse response,
|
||||||
BinaryAsset asset) throws IOException {
|
BinaryAsset asset)
|
||||||
|
throws IOException {
|
||||||
// Stream the blob.
|
// Stream the blob.
|
||||||
OutputStream out = response.getOutputStream();
|
OutputStream out = response.getOutputStream();
|
||||||
try {
|
try {
|
||||||
|
|
@ -131,6 +123,17 @@ class BaseAsset extends ResourceHandlerImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param request HTTP request
|
||||||
|
* @param response HTTP response
|
||||||
|
* @param actx (legacy) context, not used in this method but required by
|
||||||
|
* parent implementation's interface
|
||||||
|
* maybe required in future when access privilege is checked.
|
||||||
|
* @throws IOException
|
||||||
|
* @throws ServletException
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void dispatch(HttpServletRequest request,
|
public final void dispatch(HttpServletRequest request,
|
||||||
HttpServletResponse response,
|
HttpServletResponse response,
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ public class BaseImage extends ResourceHandlerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets RFC2183 governed Contnet-Disposition header to supply filename to
|
* Sets RFC2183 governed Content-Disposition header to supply filename to
|
||||||
* client. See section 19.5.1 of RFC2616 for interpretation of
|
* client. See section 19.5.1 of RFC2616 for interpretation of
|
||||||
* Content-Disposition in HTTP.
|
* Content-Disposition in HTTP.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ public class SimpleCache extends Hashtable{
|
||||||
* @param key The object key
|
* @param key The object key
|
||||||
* @return The cached object, null if there is none
|
* @return The cached object, null if there is none
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Object get(Object key) {
|
public Object get(Object key) {
|
||||||
return super.get(key);
|
return super.get(key);
|
||||||
}
|
}
|
||||||
|
|
@ -64,6 +65,7 @@ public class SimpleCache extends Hashtable{
|
||||||
* @param value The object to be cached
|
* @param value The object to be cached
|
||||||
* @return The cached object
|
* @return The cached object
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Object put(Object key, Object value) {
|
public Object put(Object key, Object value) {
|
||||||
return super.put(key, value);
|
return super.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
@ -74,6 +76,7 @@ public class SimpleCache extends Hashtable{
|
||||||
* @param key The object key
|
* @param key The object key
|
||||||
* @return The formerly-cached object
|
* @return The formerly-cached object
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Object remove(Object key) {
|
public Object remove(Object key) {
|
||||||
return super.remove(key);
|
return super.remove(key);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue