diff --git a/ccm-cms/src/com/arsdigita/cms/Loader.java b/ccm-cms/src/com/arsdigita/cms/Loader.java index f10277fc2..83ef3e0e1 100755 --- a/ccm-cms/src/com/arsdigita/cms/Loader.java +++ b/ccm-cms/src/com/arsdigita/cms/Loader.java @@ -56,7 +56,7 @@ import org.apache.log4j.Logger; // Refactor using legacy compatible web/Application and ApplicationSetup *DONE* // Refactor content-section als legacy free application *DONE* // Refactor workspace (content-center) as a legacy free application -// Refactor cms-service as a legacy free application +// Refactor cms-service as a legacy free application *DONE* /** *
Executes nonrecurring at install time and loads (installs and initializes) @@ -130,6 +130,9 @@ public class Loader extends PackageLoader { s_log.debug("CMS.loader (Constructor) completed"); } + /** + * + */ public void run(final ScriptContext ctx) { s_log.debug("CMS.loader.run() invoked"); @@ -186,8 +189,20 @@ public class Loader extends PackageLoader { .createApplicationType(Workspace.PACKAGE_KEY, Workspace.INSTANCE_NAME, Workspace.BASE_DATA_OBJECT_TYPE); - type.setDescription("The content center workspace for content creators."); type.setDispatcherClass(Workspace.DISPATCHER_CLASS); + + /* Create new type legacy free application type + * NOTE: The wording in the title parameter of ApplicationType + * determines the name of the subdirectory for the XSL stylesheets. + * It gets "urlized", i.e. trimming leading and trailing blanks and + * replacing blanks between words and illegal characters with an + * hyphen and converted to lower case. + * "Content Center" will become "content-center". */ + // ApplicationType type = new + // ApplicationType(Workspace.INSTANCE_NAME, + // Workspace.BASE_DATA_OBJECT_TYPE ); + + type.setDescription("The content center workspace for content creators."); type.save(); s_log.debug("CMS Workspace type created."); diff --git a/ccm-cms/src/com/arsdigita/cms/ServiceServlet.java b/ccm-cms/src/com/arsdigita/cms/ServiceServlet.java index 2037c5c30..ea314e43e 100644 --- a/ccm-cms/src/com/arsdigita/cms/ServiceServlet.java +++ b/ccm-cms/src/com/arsdigita/cms/ServiceServlet.java @@ -152,7 +152,7 @@ public class ServiceServlet extends BaseApplicationServlet { // Check user access. // Deprecated and here implemented as a No-OP method! - /* heckUserAccess(request, response, actx); */ + /* checkUserAccess(request, response, actx); */ ResourceHandler page = getResource(url); if ( page != null ) { diff --git a/ccm-cms/src/com/arsdigita/cms/Workspace.java b/ccm-cms/src/com/arsdigita/cms/Workspace.java index fa9093760..17d0e36bb 100644 --- a/ccm-cms/src/com/arsdigita/cms/Workspace.java +++ b/ccm-cms/src/com/arsdigita/cms/Workspace.java @@ -52,8 +52,6 @@ public class Workspace extends Application { public static final String INSTANCE_NAME = "Content Center"; public static final String DISPATCHER_CLASS = "com.arsdigita.cms.dispatcher.ContentCenterDispatcher"; - public final static String STYLESHEET = - "/packages/content-section/xsl/content-center.xsl"; /** * Constructor retrieving a workspace from the database usings its OID. diff --git a/ccm-cms/src/com/arsdigita/cms/WorkspaceServlet.java b/ccm-cms/src/com/arsdigita/cms/WorkspaceServlet.java index 5b49f503a..bded28f89 100644 --- a/ccm-cms/src/com/arsdigita/cms/WorkspaceServlet.java +++ b/ccm-cms/src/com/arsdigita/cms/WorkspaceServlet.java @@ -19,12 +19,17 @@ package com.arsdigita.cms; +import com.arsdigita.cms.dispatcher.ResourceHandler; import com.arsdigita.cms.dispatcher.SimpleCache; import com.arsdigita.developersupport.DeveloperSupport; +import com.arsdigita.dispatcher.DispatcherHelper; +import com.arsdigita.dispatcher.RequestContext; import com.arsdigita.kernel.security.UserContext; import com.arsdigita.kernel.security.Util; import com.arsdigita.ui.login.LoginHelper; +import com.arsdigita.util.Assert; import com.arsdigita.web.Application; +import com.arsdigita.web.ApplicationFileResolver; import com.arsdigita.web.BaseApplicationServlet; import com.arsdigita.web.LoginSignal; @@ -33,6 +38,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; +import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -55,7 +61,7 @@ public class WorkspaceServlet extends BaseApplicationServlet { /** The path of the file that maps resources. */ public final static String DEFAULT_MAP_FILE = - "/WEB-INF/resources/content-center-map.xml"; + "/WEB-INF/resources/content-center-old-map.xml"; /** Mapping between a relative URL and the class name of a ResourceHandler.*/ private static HashMap s_pageClasses = WorkspaceSetup.getURLToClassMap(); @@ -69,11 +75,40 @@ public class WorkspaceServlet extends BaseApplicationServlet { // private Dispatcher m_notFoundHandler; private ArrayList m_trailingSlashList = new ArrayList(); + /** Path to directory containg ccm-cms template files */ + private String m_templatePath; + + /** Resolvers to find templages (JSP) and other stuff stored in file system.*/ + private ApplicationFileResolver m_resolver; + + + /** + * Use parent's class initialization extension point to perform additional + * initialisation tasks. + */ + @Override + protected void doInit() { + if (s_log.isDebugEnabled()) { + s_log.info("starting doInit method"); + } + m_trailingSlashList = new ArrayList(); + requireTrailingSlash(""); + + /** Set Template base path for JSP's */ + m_templatePath = ContentSection.getConfig().getTemplateRoot(); + Assert.exists(m_templatePath, String.class); + Assert.isTrue(m_templatePath.startsWith("/"), + "template-path must start with '/'"); + Assert.isTrue(!m_templatePath.endsWith("/"), + "template-path must not end with '/'"); + /** Set TemplateResolver class */ + m_resolver = Web.getConfig().getApplicationFileResolver(); + } /** * Implements the (abstract) doService method of BaseApplicationServlet to - * create the Worspace page. + * create the Workspace page. * * @see com.arsdigita.web.BaseApplicationServlet#doService * (HttpServletRequest, HttpServletResponse, Application) @@ -88,9 +123,48 @@ public class WorkspaceServlet extends BaseApplicationServlet { } DeveloperSupport.startStage("ContentCenterServlet.doService"); + Workspace workspace = (Workspace) app; + + 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: + // probably want to redirect. + if ( m_trailingSlashList.contains(url) && !originalUrl.endsWith("/") ) { + DispatcherHelper.sendRedirect(sresp, originalUrl + "/"); + return; + } + // Check user access. checkUserAccess(sreq, sresp); + ResourceHandler page = getResource(url); + if ( page != null ) { + // Serve the page. + page.init(); + page.dispatch(sreq, sresp, ctx); + } else { + // Fall back on the JSP application dispatcher. + if (s_log.isInfoEnabled()) { + s_log.info("NO page registered to serve the requst url."); + } + + RequestDispatcher rd = m_resolver.resolve(m_templatePath, + sreq, sresp, app); + if (rd != null) { + if (s_log.isDebugEnabled()) { + s_log.debug("Got dispatcher " + rd); + } + sreq = DispatcherHelper.restoreOriginalRequest(sreq); + rd.forward(sreq,sresp); + } else { + sresp.sendError(404, requestUri + " not found on this server."); + } + + } + DeveloperSupport.endStage("ContentCenterServlet.doService"); if (s_log.isDebugEnabled()) { @@ -98,9 +172,49 @@ public class WorkspaceServlet extends BaseApplicationServlet { } } - - - + /** + * Fetch a page based on the URL stub. + * + * @param url The URL stub following the site-node URL + * @return A ResourceHandler or null if none exists. + * @pre (url != null) + */ + protected ResourceHandler getResource(String url) throws ServletException { + + // First check the pages cache for existing pages. + ResourceHandler page = (ResourceHandler) s_pages.get(url); + if ( page == null ) { + + // Next check if the URL maps to a page class. + String pageClassName = (String) s_pageClasses.get(url); + if ( pageClassName != null ) { + + Class pageClass; + try { + pageClass = Class.forName(pageClassName); + } catch (ClassNotFoundException e) { + s_log.error("error fetching class for ResourceHandler", e); + throw new ServletException(e); + } + + // Try and instantiate the page. + try { + page = (ResourceHandler) pageClass.newInstance(); + } catch (InstantiationException e) { + s_log.error("error instantiating a ResourceHandler", e); + throw new ServletException(e); + } catch (IllegalAccessException e) { + s_log.error("error instantiating a ResourceHandler", e); + throw new ServletException(e); + } + + page.init(); + s_pages.put(url, page); + } + } + return page; + } + /** * Verify that the user is logged in and is able to view the @@ -145,4 +259,17 @@ public class WorkspaceServlet extends BaseApplicationServlet { } } + /** + * 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) { + private void requireTrailingSlash(String url) { + m_trailingSlashList.add(url); + } + }