diff --git a/ccm-atoz-siteproxy/src/com/arsdigita/atoz/siteproxy/SiteProxyGenerator.java b/ccm-atoz-siteproxy/src/com/arsdigita/atoz/siteproxy/SiteProxyGenerator.java index ff77b6268..9ca55c2d0 100755 --- a/ccm-atoz-siteproxy/src/com/arsdigita/atoz/siteproxy/SiteProxyGenerator.java +++ b/ccm-atoz-siteproxy/src/com/arsdigita/atoz/siteproxy/SiteProxyGenerator.java @@ -131,7 +131,7 @@ public class SiteProxyGenerator extends AtoZGeneratorAbstractImpl { ParameterMap map = new ParameterMap(); map.setParameter("oid", m_oid.toString()); - URL here = Web.getContext().getRequestURL(); + URL here = Web.getWebContext().getRequestURL(); return (new URL(here.getScheme(), here.getServerName(), here .getServerPort(), "", "", "/redirect/", map)).toString(); diff --git a/ccm-atoz/src/com/arsdigita/atoz/CategoryGenerator.java b/ccm-atoz/src/com/arsdigita/atoz/CategoryGenerator.java index 253a125d7..519139df5 100755 --- a/ccm-atoz/src/com/arsdigita/atoz/CategoryGenerator.java +++ b/ccm-atoz/src/com/arsdigita/atoz/CategoryGenerator.java @@ -93,7 +93,7 @@ public class CategoryGenerator extends AtoZGeneratorAbstractImpl { ParameterMap map = new ParameterMap(); map.setParameter("oid", m_oid.toString()); - URL here = Web.getContext().getRequestURL(); + URL here = Web.getWebContext().getRequestURL(); return (new URL(here.getScheme(), here.getServerName(), here .getServerPort(), "", "", "/redirect/", map)).toString(); diff --git a/ccm-atoz/src/com/arsdigita/atoz/ItemGenerator.java b/ccm-atoz/src/com/arsdigita/atoz/ItemGenerator.java index ffcf4c041..116fd13df 100755 --- a/ccm-atoz/src/com/arsdigita/atoz/ItemGenerator.java +++ b/ccm-atoz/src/com/arsdigita/atoz/ItemGenerator.java @@ -125,7 +125,7 @@ public class ItemGenerator extends AtoZGeneratorAbstractImpl { ParameterMap map = new ParameterMap(); map.setParameter("oid", m_oid.toString()); - URL here = Web.getContext().getRequestURL(); + URL here = Web.getWebContext().getRequestURL(); return (new URL(here.getScheme(), here.getServerName(), here .getServerPort(), "", "", "/redirect/", map)).toString(); diff --git a/ccm-bookmarks/src/com/arsdigita/bookmarks/ui/BookmarkEditPane.java b/ccm-bookmarks/src/com/arsdigita/bookmarks/ui/BookmarkEditPane.java index 1b7457e85..69ec66087 100755 --- a/ccm-bookmarks/src/com/arsdigita/bookmarks/ui/BookmarkEditPane.java +++ b/ccm-bookmarks/src/com/arsdigita/bookmarks/ui/BookmarkEditPane.java @@ -252,7 +252,7 @@ public class BookmarkEditPane extends DynamicListWizard { public Component getComponent(List list, PageState state, Object value, String key, int index, boolean isSelected) { - Bookmarks app = (Bookmarks) Web.getContext() + Bookmarks app = (Bookmarks) Web.getWebContext() .getApplication(); BookmarkCollection bColl = app.getBookmarks(); final long size = bColl.size(); diff --git a/ccm-bookmarks/src/com/arsdigita/bookmarks/ui/BookmarkPortlet.java b/ccm-bookmarks/src/com/arsdigita/bookmarks/ui/BookmarkPortlet.java index 6cf293fe3..6d9ae396f 100755 --- a/ccm-bookmarks/src/com/arsdigita/bookmarks/ui/BookmarkPortlet.java +++ b/ccm-bookmarks/src/com/arsdigita/bookmarks/ui/BookmarkPortlet.java @@ -79,7 +79,7 @@ public class BookmarkPortlet extends AppPortlet { if (!PermissionService.checkPermission( new PermissionDescriptor(PrivilegeDescriptor.READ, app, - Web.getContext().getUser()))) { + Web.getWebContext().getUser()))) { return null; } return (URL.getDispatcherPath() + app.getPrimaryURL()); diff --git a/ccm-bundle/src/com/arsdigita/bundle/ui/SimplePage.java b/ccm-bundle/src/com/arsdigita/bundle/ui/SimplePage.java index b5f56e7fa..fd4e0a98d 100644 --- a/ccm-bundle/src/com/arsdigita/bundle/ui/SimplePage.java +++ b/ccm-bundle/src/com/arsdigita/bundle/ui/SimplePage.java @@ -54,8 +54,8 @@ public class SimplePage extends com.arsdigita.ui.SimplePage { * Two xml attributes are added in addition to the bebop standard * implementation. */ - if (Web.getContext().getRequestURL() != null) { - page.addAttribute("url", Web.getContext().getRequestURL().toString()); + if (Web.getWebContext().getRequestURL() != null) { + page.addAttribute("url", Web.getWebContext().getRequestURL().toString()); page.addAttribute("textOnly", "/text".equals( DispatcherHelper diff --git a/ccm-cms-types-formitem/src/com/arsdigita/cms/formbuilder/FormItem.java b/ccm-cms-types-formitem/src/com/arsdigita/cms/formbuilder/FormItem.java index d96f977b0..f9b368fad 100755 --- a/ccm-cms-types-formitem/src/com/arsdigita/cms/formbuilder/FormItem.java +++ b/ccm-cms-types-formitem/src/com/arsdigita/cms/formbuilder/FormItem.java @@ -253,7 +253,7 @@ public class FormItem extends ContentPage implements XMLGenerator { generateXMLBody(fake, element, c); String action = form.getAction(); if (action == null) { - final URL requestURL = Web.getContext().getRequestURL(); + final URL requestURL = Web.getWebContext().getRequestURL(); if (requestURL == null) { action = state.getRequest().getRequestURI(); diff --git a/ccm-cms-types-formsectionitem/src/com/arsdigita/cms/formbuilder/FormSectionItem.java b/ccm-cms-types-formsectionitem/src/com/arsdigita/cms/formbuilder/FormSectionItem.java index bc0ae86b3..717ef55ae 100755 --- a/ccm-cms-types-formsectionitem/src/com/arsdigita/cms/formbuilder/FormSectionItem.java +++ b/ccm-cms-types-formsectionitem/src/com/arsdigita/cms/formbuilder/FormSectionItem.java @@ -192,7 +192,7 @@ public class FormSectionItem extends ContentPage String action = c.getAction(); if (action == null) { - final URL requestURL = Web.getContext().getRequestURL(); + final URL requestURL = Web.getWebContext().getRequestURL(); if (requestURL == null) { action = state.getRequest().getRequestURI(); diff --git a/ccm-cms-types-survey/src/com/arsdigita/cms/contenttypes/SurveyXMLGenerator.java b/ccm-cms-types-survey/src/com/arsdigita/cms/contenttypes/SurveyXMLGenerator.java index 9760c57d0..002773d71 100644 --- a/ccm-cms-types-survey/src/com/arsdigita/cms/contenttypes/SurveyXMLGenerator.java +++ b/ccm-cms-types-survey/src/com/arsdigita/cms/contenttypes/SurveyXMLGenerator.java @@ -72,7 +72,7 @@ public class SurveyXMLGenerator extends SimpleXMLGenerator { String action = pForm.getAction(); if (action == null) { - final URL requestURL = Web.getContext().getRequestURL(); + final URL requestURL = Web.getWebContext().getRequestURL(); if (requestURL == null) { action = state.getRequest().getRequestURI(); diff --git a/ccm-cms/src/com/arsdigita/cms/CMS.java b/ccm-cms/src/com/arsdigita/cms/CMS.java index f841946f6..49212ba2f 100755 --- a/ccm-cms/src/com/arsdigita/cms/CMS.java +++ b/ccm-cms/src/com/arsdigita/cms/CMS.java @@ -60,12 +60,9 @@ public abstract class CMS { return s_initialContext; } }; - private static final CMSConfig s_config = new CMSConfig(); - static { - s_log.debug("Static initializer starting..."); - s_config.load(); - s_log.debug("Static initializer finished."); - } + + /** Config object containing various parameter */ + private static final CMSConfig s_config = CMSConfig.getInstanceOf(); /** diff --git a/ccm-cms/src/com/arsdigita/cms/CMSConfig.java b/ccm-cms/src/com/arsdigita/cms/CMSConfig.java index 4393511ed..d1a5bd370 100755 --- a/ccm-cms/src/com/arsdigita/cms/CMSConfig.java +++ b/ccm-cms/src/com/arsdigita/cms/CMSConfig.java @@ -76,7 +76,7 @@ public final class CMSConfig extends AbstractConfig { * * @return The CMSConfig record; it cannot be null */ - public static synchronized CMSConfig getInstance() { + public static synchronized CMSConfig getInstanceOf() { if (s_config == null) { s_config = new CMSConfig(); s_config.load(); @@ -668,7 +668,9 @@ public final class CMSConfig extends AbstractConfig { // Moved to publishToFile.PublishToFileConfig as of version 6.0.2 // private final Parameter m_disableItemPfs; // private final Parameter m_publishToFileClass; - /** + + + /** * Constructor, but do NOT instantiate this class directly. * * @see ContentSection#getConfig() diff --git a/ccm-cms/src/com/arsdigita/cms/ContentBundle.java b/ccm-cms/src/com/arsdigita/cms/ContentBundle.java index 00637a4d8..60929724a 100755 --- a/ccm-cms/src/com/arsdigita/cms/ContentBundle.java +++ b/ccm-cms/src/com/arsdigita/cms/ContentBundle.java @@ -174,7 +174,7 @@ public class ContentBundle extends ContentItem { s_log.debug("Item id is: " + instance.getID()); final Workflow workflow = template.instantiateNewWorkflow(); workflow.setObjectID(instance.getID()); - workflow.start(Web.getContext().getUser()); + workflow.start(Web.getWebContext().getUser()); workflow.save(); } diff --git a/ccm-cms/src/com/arsdigita/cms/ContentCenterServlet.java b/ccm-cms/src/com/arsdigita/cms/ContentCenterServlet.java index 09e1342fb..f209d1c64 100644 --- a/ccm-cms/src/com/arsdigita/cms/ContentCenterServlet.java +++ b/ccm-cms/src/com/arsdigita/cms/ContentCenterServlet.java @@ -146,7 +146,7 @@ public class ContentCenterServlet extends BaseApplicationServlet { // ContentCenter workspace = (ContentCenter) app; /* Check user and privilegies */ - if (Web.getContext().getUser() == null) { // user not logged in + if (Web.getWebContext().getUser() == null) { // user not logged in throw new LoginSignal(sreq); // send to login page } // Check whether logged in user has access to at least one content section diff --git a/ccm-cms/src/com/arsdigita/cms/ContentItem.java b/ccm-cms/src/com/arsdigita/cms/ContentItem.java index 3b80b7c0a..18b79c76c 100755 --- a/ccm-cms/src/com/arsdigita/cms/ContentItem.java +++ b/ccm-cms/src/com/arsdigita/cms/ContentItem.java @@ -1330,7 +1330,7 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { Assert.isTrue(isLive(), "Attempt to republish non live item " + getOID()); //ToDo Remove item from cache - if (CMSConfig.getInstance().getEnableXmlCache()) { + if (CMSConfig.getInstanceOf().getEnableXmlCache()) { XMLDeliveryCache.getInstance().removeFromCache(getOID()); } @@ -1974,7 +1974,7 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { } /*final AssociationCopierLoader assocCopierLoader = - AssociationCopierLoader.getInstance(); + AssociationCopierLoader.getInstanceOf(); final AssociationCopier assocCopier = assocCopierLoader. getAssociationCopierFor(property, source); if (assocCopier != null) { diff --git a/ccm-cms/src/com/arsdigita/cms/ContentSection.java b/ccm-cms/src/com/arsdigita/cms/ContentSection.java index 941e3771c..aab1bf649 100755 --- a/ccm-cms/src/com/arsdigita/cms/ContentSection.java +++ b/ccm-cms/src/com/arsdigita/cms/ContentSection.java @@ -125,7 +125,7 @@ public class ContentSection extends Application { private final static String ITEM_QUERY = "com.arsdigita.cms.ItemsInSection"; private final static String SECTION_ID = "sectionId"; - private static final CMSConfig s_config = CMSConfig.getInstance(); + private static final CMSConfig s_config = CMSConfig.getInstanceOf(); /* DO NOT use CMSConfig constructor to instantiate ! private static final CMSConfig s_config = new CMSConfig(); diff --git a/ccm-cms/src/com/arsdigita/cms/ContentSectionServlet.java b/ccm-cms/src/com/arsdigita/cms/ContentSectionServlet.java index 8a51db9c9..b2f16c1d8 100755 --- a/ccm-cms/src/com/arsdigita/cms/ContentSectionServlet.java +++ b/ccm-cms/src/com/arsdigita/cms/ContentSectionServlet.java @@ -305,7 +305,9 @@ public class ContentSectionServlet extends BaseApplicationServlet { sreq = DispatcherHelper.restoreOriginalRequest(sreq); rd.forward(sreq, sresp); } else { - // sresp.sendError(404, packageURL + " not found on this server."); + if (s_log.isDebugEnabled()) { + s_log.debug("No dispatcher found for" + rd); + } String requestUri = sreq.getRequestURI(); // same as ctx.getRemainingURLPart() sresp.sendError(404, requestUri + " not found on this server."); } diff --git a/ccm-cms/src/com/arsdigita/cms/CustomizableContentItemXMLRenderer.java b/ccm-cms/src/com/arsdigita/cms/CustomizableContentItemXMLRenderer.java index cba0396f0..de877481c 100644 --- a/ccm-cms/src/com/arsdigita/cms/CustomizableContentItemXMLRenderer.java +++ b/ccm-cms/src/com/arsdigita/cms/CustomizableContentItemXMLRenderer.java @@ -200,7 +200,7 @@ public class CustomizableContentItemXMLRenderer //Build paginator //Get pageNumber from request URL - URL requestUrl = Web.getContext().getRequestURL(); + URL requestUrl = Web.getWebContext().getRequestURL(); String pageNumberValue = requestUrl.getParameter("pageNumber"); long pageNumber; if (pageNumberValue == null) { diff --git a/ccm-cms/src/com/arsdigita/cms/DomainCopier.java b/ccm-cms/src/com/arsdigita/cms/DomainCopier.java index bd43d541d..65079483a 100755 --- a/ccm-cms/src/com/arsdigita/cms/DomainCopier.java +++ b/ccm-cms/src/com/arsdigita/cms/DomainCopier.java @@ -493,7 +493,7 @@ class DomainCopier extends DomainService { * @param dobj */ private void checkXmlCache(final DomainObject dobj) { - if ((dobj instanceof ContentItem) && CMSConfig.getInstance().getEnableXmlCache()) { + if ((dobj instanceof ContentItem) && CMSConfig.getInstanceOf().getEnableXmlCache()) { final ContentItem item = (ContentItem) dobj; XMLDeliveryCache.getInstance().removeFromCache(item.getOID()); } diff --git a/ccm-cms/src/com/arsdigita/cms/Initializer.java b/ccm-cms/src/com/arsdigita/cms/Initializer.java index 7bb614cd2..6e75561d5 100755 --- a/ccm-cms/src/com/arsdigita/cms/Initializer.java +++ b/ccm-cms/src/com/arsdigita/cms/Initializer.java @@ -97,7 +97,7 @@ public class Initializer extends CompoundInitializer { /** Creates a s_logging category with name = to the full name of class */ private static Logger s_log = Logger.getLogger(Initializer.class); /** Configuration object for the CMS module */ - private static final CMSConfig s_conf = CMSConfig.getInstance(); + private static final CMSConfig s_conf = CMSConfig.getInstanceOf(); /** * Constructor, adds db connection information and various sub-initializers diff --git a/ccm-cms/src/com/arsdigita/cms/XMLDeliveryCache.java b/ccm-cms/src/com/arsdigita/cms/XMLDeliveryCache.java index f80b4ecae..4a3c01f9f 100644 --- a/ccm-cms/src/com/arsdigita/cms/XMLDeliveryCache.java +++ b/ccm-cms/src/com/arsdigita/cms/XMLDeliveryCache.java @@ -24,8 +24,8 @@ public final class XMLDeliveryCache { * The real cache. */ private CacheTable cache = new CacheTable(XMLDeliveryCache.class.getName(), - CMSConfig.getInstance().getXmlCacheSize(), - CMSConfig.getInstance().getXmlCacheSize(), + CMSConfig.getInstanceOf().getXmlCacheSize(), + CMSConfig.getInstanceOf().getXmlCacheSize(), true); /** * Maps from the OID of the master version of an item in the cache to the OID of the item in the cache. diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/CompoundContentItemPanel.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/CompoundContentItemPanel.java index b1efae4d9..329c775e9 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/CompoundContentItemPanel.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/CompoundContentItemPanel.java @@ -218,7 +218,7 @@ public abstract class CompoundContentItemPanel parent.newChildElement("nav:paginator", "http://ccm.redhat.com/navigation"); - URL requestURL = Web.getContext().getRequestURL(); + URL requestURL = Web.getWebContext().getRequestURL(); ParameterMap map = new ParameterMap(); diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericOrgaUnitPaginator.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericOrgaUnitPaginator.java index fd9de2f7a..916e8ecc0 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericOrgaUnitPaginator.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericOrgaUnitPaginator.java @@ -49,7 +49,7 @@ public class GenericOrgaUnitPaginator { "nav:paginator", "http://ccm.redhat.com/navigation"); - final URL requestUrl = Web.getContext().getRequestURL(); + final URL requestUrl = Web.getWebContext().getRequestURL(); final ParameterMap parameters = new ParameterMap(); if (requestUrl.getParameterMap() != null) { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/panels/Paginator.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/panels/Paginator.java index 6714bc30b..78ba0e43e 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/panels/Paginator.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/panels/Paginator.java @@ -60,7 +60,7 @@ public class Paginator { final Element paginatorElem = parent.newChildElement( "nav:paginator", "http://ccm.redhat.com/navigation"); - final URL requestUrl = Web.getContext().getRequestURL(); + final URL requestUrl = Web.getWebContext().getRequestURL(); final ParameterMap parameters = new ParameterMap(); diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/AssetURLFinder.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/AssetURLFinder.java index b13681a76..54e8c09bf 100755 --- a/ccm-cms/src/com/arsdigita/cms/dispatcher/AssetURLFinder.java +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/AssetURLFinder.java @@ -17,7 +17,6 @@ package com.arsdigita.cms.dispatcher; import com.arsdigita.cms.Asset; - import com.arsdigita.kernel.NoValidURLException; import com.arsdigita.kernel.URLFinder; import com.arsdigita.persistence.OID; @@ -25,28 +24,27 @@ import com.arsdigita.web.Web; import com.arsdigita.web.WebConfig; /** - * @author mbooth@redhat.com + * Implementation of URLFinder for Assets. * - * Implementation of URLFinder for Assets + * @author mbooth@redhat.com */ public class AssetURLFinder implements URLFinder { + /** - * - * find URL for an asset - * - * @param oid the OID of the asset - * @param context the context of the lookup (live/draft) - * - */ + * Find URL for an asset. + * + * @param oid the OID of the asset + * @param context the context of the lookup (live/draft) + * @return + */ public String find(OID oid, String context) throws NoValidURLException { if( !"live".equals( context ) ) throw new NoValidURLException("No draft URL for assets"); - WebConfig config = Web.getConfig(); - - StringBuffer url = new StringBuffer(); - url.append( config.getDispatcherServletPath() ); - url.append( config.getDispatcherContextPath() ); + StringBuilder url = new StringBuilder(); + url.append( Web.getConfig().getDispatcherServletPath() ); +// Must be wrong! ContextPath is before ServletPath! +// url.append( Web.getConfig().getDispatcherContextPath() ); url.append( "/cms-service/stream/asset/?asset_id=" ); url.append( oid.get( Asset.ID ).toString() ); @@ -54,11 +52,11 @@ public class AssetURLFinder implements URLFinder { } /** - * - * find URL for an asset in the live context - * - * @param oid the OID of the asset - */ + * Find URL for an asset in the live context + * + * @param oid the OID of the asset + * @return + */ public String find(OID oid) throws NoValidURLException { return find(oid, "live"); } diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/CMSPage.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/CMSPage.java index 5336c60fc..2044f3eb5 100755 --- a/ccm-cms/src/com/arsdigita/cms/dispatcher/CMSPage.java +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/CMSPage.java @@ -34,7 +34,6 @@ import com.arsdigita.dispatcher.RequestContext; import com.arsdigita.domain.DataObjectNotFoundException; import com.arsdigita.domain.DomainObjectFactory; import com.arsdigita.kernel.Kernel; -// import com.arsdigita.kernel.KernelContext; import com.arsdigita.kernel.User; import com.arsdigita.kernel.permissions.PermissionDescriptor; import com.arsdigita.kernel.permissions.PermissionService; @@ -150,6 +149,7 @@ public class CMSPage extends Page implements ResourceHandler { * This method is called by the {@link com.arsdigita.dispatcher.Dispatcher} * that initializes this page. */ + @Override public synchronized void init() { s_log.debug("Initializing the page"); @@ -196,6 +196,7 @@ public class CMSPage extends Page implements ResourceHandler { * On the other hand, if deprecated, implementing ResourceHandler * may not be required */ + @Override public ContentSection getContentSection(HttpServletRequest request) { // Resets all content sections associations. // return ContentSectionDispatcher.getContentSection(request); @@ -261,6 +262,7 @@ public class CMSPage extends Page implements ResourceHandler { * * @pre m_transformer != null */ + @Override public void dispatch(final HttpServletRequest request, final HttpServletResponse response , RequestContext actx @@ -270,6 +272,7 @@ public class CMSPage extends Page implements ResourceHandler { DeveloperSupport.startStage("CMSPage.dispatch: serve page"); CMSExcursion excursion = new CMSExcursion() { + @Override public void excurse() throws IOException, ServletException { Application app = Application.getCurrentApplication(request); ContentSection section = null; @@ -350,7 +353,7 @@ public class CMSPage extends Page implements ResourceHandler { // /** // * @deprecated Use Kernel.getContext().getParty() if possible and -// * Web.getContext().getUser() if necessary. +// * Web.getWebContext().getUser() if necessary. // */ // public static User getCurrentUser(PageState state) { // return (User) Kernel.getContext().getParty(); diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/ContentItemDispatcher.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/ContentItemDispatcher.java index a65f359d3..d06b5d2ab 100755 --- a/ccm-cms/src/com/arsdigita/cms/dispatcher/ContentItemDispatcher.java +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/ContentItemDispatcher.java @@ -97,7 +97,7 @@ public class ContentItemDispatcher implements Dispatcher { final ContentItem item = getContentItem(request); //get the Content Section final ContentSection section = - (ContentSection) Web.getContext().getApplication(); + (ContentSection) Web.getWebContext().getApplication(); Assert.exists(item); diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/MultilingualItemResolver.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/MultilingualItemResolver.java index c53232391..6f301c61b 100755 --- a/ccm-cms/src/com/arsdigita/cms/dispatcher/MultilingualItemResolver.java +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/MultilingualItemResolver.java @@ -220,7 +220,7 @@ public class MultilingualItemResolver extends AbstractItemResolver implements It public String getCurrentContext(final PageState state) { s_log.debug("Getting the current context"); - // XXX need to use Web.getContext().getRequestURL() here. + // XXX need to use Web.getWebContext().getRequestURL() here. String url = state.getRequest().getRequestURI(); final ContentSection section = @@ -410,6 +410,7 @@ public class MultilingualItemResolver extends AbstractItemResolver implements It * @param item The content item * @param request The HTTP request * @return The master page + * @throws javax.servlet.ServletException */ @Override public CMSPage getMasterPage(final ContentItem item, diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/SimpleXMLGenerator.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/SimpleXMLGenerator.java index bfb133ae4..1a8bd2cb7 100755 --- a/ccm-cms/src/com/arsdigita/cms/dispatcher/SimpleXMLGenerator.java +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/SimpleXMLGenerator.java @@ -194,7 +194,7 @@ public class SimpleXMLGenerator implements XMLGenerator { final XMLDeliveryCache xmlCache = XMLDeliveryCache.getInstance(); - if (CMSConfig.getInstance().getEnableXmlCache() && xmlCache.isCached(item.getOID(), useContext, listMode)) { + if (CMSConfig.getInstanceOf().getEnableXmlCache() && xmlCache.isCached(item.getOID(), useContext, listMode)) { xmlCache.retrieveFromCache(content, item.getOID(), useContext, listMode); } else { final ContentItemXMLRenderer renderer = new ContentItemXMLRenderer(content); @@ -239,7 +239,7 @@ public class SimpleXMLGenerator implements XMLGenerator { //Only published items //Only the XML of the item itself, no extra XML - if (CMSConfig.getInstance().getEnableXmlCache() && item.isLiveVersion()) { + if (CMSConfig.getInstanceOf().getEnableXmlCache() && item.isLiveVersion()) { xmlCache.cache(item.getOID(), item, content, useContext, listMode); } } diff --git a/ccm-cms/src/com/arsdigita/cms/publishToFile/PublishToFile.java b/ccm-cms/src/com/arsdigita/cms/publishToFile/PublishToFile.java index a0c6ebb67..7faf9dd5b 100755 --- a/ccm-cms/src/com/arsdigita/cms/publishToFile/PublishToFile.java +++ b/ccm-cms/src/com/arsdigita/cms/publishToFile/PublishToFile.java @@ -38,7 +38,7 @@ import com.arsdigita.util.servlet.HttpHost; import com.arsdigita.util.servlet.HttpResourceLocator; import com.arsdigita.web.Host; import com.arsdigita.web.Web; -import com.arsdigita.web.WebConfig; + import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; @@ -47,6 +47,7 @@ import java.math.BigDecimal; import java.net.URL; import java.util.HashMap; import java.util.Map; + import org.apache.log4j.Logger; /** @@ -185,20 +186,18 @@ public class PublishToFile implements PublishToFileListener { * @return the source URL for fetching the item */ public static URL getSource(final String path) { + if (Assert.isEnabled()) { Assert.exists(path, String.class); Assert.isTrue(path.startsWith("/"), "Path starts with '/'"); } - final WebConfig config = Web.getConfig(); - final HttpHost host = Web.getConfig().getHost(); - // def scheme, no query str - + final HttpResourceLocator hrl = new HttpResourceLocator - (host, - config.getDispatcherContextPath(), - config.getDispatcherServletPath(), + (Web.getConfig().getHost(), + Web.getConfig().getDispatcherContextPath(), + Web.getConfig().getDispatcherServletPath(), path, null); diff --git a/ccm-cms/src/com/arsdigita/cms/search/IntermediaQueryEngine.java b/ccm-cms/src/com/arsdigita/cms/search/IntermediaQueryEngine.java index 642e3beb3..0f6897973 100755 --- a/ccm-cms/src/com/arsdigita/cms/search/IntermediaQueryEngine.java +++ b/ccm-cms/src/com/arsdigita/cms/search/IntermediaQueryEngine.java @@ -189,7 +189,7 @@ public class IntermediaQueryEngine extends BaseQueryEngine { Calendar startCal = GregorianCalendar.getInstance(); startCal.setTime(start); /* - Calendar truncCal = GregorianCalendar.getInstance(); + Calendar truncCal = GregorianCalendar.getInstanceOf(); truncCal.set(Calendar.DAY_OF_YEAR, startCal.get(Calendar.DAY_OF_YEAR)); truncCal.set(Calendar.YEAR, startCal.get(Calendar.YEAR)); truncCal.set(Calendar.MINUTE, 0); diff --git a/ccm-cms/src/com/arsdigita/cms/ui/BrowsePane.java b/ccm-cms/src/com/arsdigita/cms/ui/BrowsePane.java index 0cee1f9c8..5e579a452 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/BrowsePane.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/BrowsePane.java @@ -142,7 +142,7 @@ public class BrowsePane extends LayoutPanel implements Resettable { ().getRootFolder(); BigDecimal folderID = root.getID(); - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); if ( user != null ) { Folder homeFolder = Folder.getUserHomeFolder(user,CMS.getContext().getContentSection()); if ( homeFolder != null ) { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/CMSApplicationPage.java b/ccm-cms/src/com/arsdigita/cms/ui/CMSApplicationPage.java index 1ef2e2306..d5ab61078 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/CMSApplicationPage.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/CMSApplicationPage.java @@ -20,8 +20,6 @@ package com.arsdigita.cms.ui; import com.arsdigita.bebop.*; import com.arsdigita.bebop.page.PageTransformer; -import com.arsdigita.cms.ContentItem; -import com.arsdigita.cms.ContentSection; import com.arsdigita.cms.dispatcher.Utilities; import com.arsdigita.kernel.Kernel; import com.arsdigita.kernel.User; @@ -143,6 +141,9 @@ public class CMSApplicationPage extends Page { * * This method is called by the various servlets serving the various pages * of the CMS package, before serving and displaying the page. + * @param sreq + * @param sresp + * @param app */ public synchronized void init(HttpServletRequest sreq, HttpServletResponse sresp, @@ -344,7 +345,7 @@ public class CMSApplicationPage extends Page { // document it in the classes. Probably remove one ore the other // way from the API if possible. User user = (User) Kernel.getContext().getParty(); - // User user = Web.getContext().getUser(); + // User user = Web.getWebContext().getUser(); if ( user != null ) { pageElement.addAttribute("name",user.getDisplayName()); } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/CMSItemSearchPage.java b/ccm-cms/src/com/arsdigita/cms/ui/CMSItemSearchPage.java index 6eaac5178..f9687a9ff 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/CMSItemSearchPage.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/CMSItemSearchPage.java @@ -64,7 +64,7 @@ public class CMSItemSearchPage extends CMSApplicationPage { private ItemSearchCreateItemPane m_create; private BigDecimalParameter m_sectionId; private int m_lastTab; - private static final CMSConfig s_conf = CMSConfig.getInstance(); + private static final CMSConfig s_conf = CMSConfig.getInstanceOf(); private static final boolean LIMIT_TO_CONTENT_SECTION = false; public static final String CONTENT_SECTION = "section_id"; @@ -309,7 +309,7 @@ public class CMSItemSearchPage extends CMSApplicationPage { public void excurse() throws IOException, ServletException { ContentSection section = null; - Application app = Web.getContext().getApplication(); + Application app = Web.getWebContext().getApplication(); if (app instanceof ContentSection) { section = (ContentSection) app; } else { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionPage.java b/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionPage.java index b0a525dae..7e4ccd643 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionPage.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionPage.java @@ -180,7 +180,7 @@ public class ContentSectionPage extends CMSPage implements ActionListener { } SecurityManager sm = CMS.getContext().getSecurityManager(); - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); //m_tabbedPane.setTabVisible(state, m_userAdminPane, sm.canAccess(user, SecurityConstants.STAFF_ADMIN)); if (ContentSection.getConfig().getHideAdminTabs()) { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/FlatItemList.java b/ccm-cms/src/com/arsdigita/cms/ui/FlatItemList.java index 5dd25fc6d..c46552d52 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/FlatItemList.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/FlatItemList.java @@ -191,7 +191,7 @@ public class FlatItemList extends SegmentedPanel m_homeFolderLabel = new Label(new PrintListener() { public final void prepare(final PrintEvent e) { Label label = (Label) e.getTarget(); - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); Folder folder = Folder.getUserHomeFolder(user, CMS.getContext().getContentSection()); if (folder != null) { @@ -448,12 +448,12 @@ public class FlatItemList extends SegmentedPanel } else if (source == m_togglePrivateAction) { togglePermissions(s); } else if (source == m_setHomeFolderAction) { - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); Folder folder = m_folder.getFolder(s); user = (User) DomainObjectFactory.newInstance(user.getOID()); Folder.setUserHomeFolder(user, folder); } else if( source == m_removeHomeFolderAction) { - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); ContentSection section = CMS.getContext().getContentSection(); UserHomeFolderMap map = UserHomeFolderMap.findUserHomeFolderMap(user, section); if (map != null) { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/FormSecurityListener.java b/ccm-cms/src/com/arsdigita/cms/ui/FormSecurityListener.java index 9291cf23f..edba9586c 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/FormSecurityListener.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/FormSecurityListener.java @@ -58,7 +58,7 @@ public class FormSecurityListener implements FormSubmissionListener { public final void submitted(final FormSectionEvent e) throws FormProcessException { final PageState state = e.getPageState(); - final User user = Web.getContext().getUser(); + final User user = Web.getWebContext().getUser(); final SecurityManager sm = Utilities.getSecurityManager(state); if (m_item == null) { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ImageSelectPage.java b/ccm-cms/src/com/arsdigita/cms/ui/ImageSelectPage.java index be34d8e66..799336c07 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/ImageSelectPage.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ImageSelectPage.java @@ -42,7 +42,7 @@ public class ImageSelectPage extends CMSPage { private final StringParameter m_imageComponentKey; private final MapComponentSelectionModel m_imageComponent; private final ImageComponentSelectListener m_selectListener; - private static final CMSConfig s_conf = CMSConfig.getInstance(); + private static final CMSConfig s_conf = CMSConfig.getInstanceOf(); public static final String CONTENT_SECTION = "section_id"; public static final String RESULT = "result"; diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchFlatBrowsePane.java b/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchFlatBrowsePane.java index fc25841af..11b233276 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchFlatBrowsePane.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchFlatBrowsePane.java @@ -61,7 +61,7 @@ public class ItemSearchFlatBrowsePane extends SimpleContainer { private final QueryFieldsRequestLocal queryFields = new QueryFieldsRequestLocal(); //private final List queryFields = new ArrayList(); //private final Submit submit; - private final static CMSConfig CMS_CONFIG = CMSConfig.getInstance(); + private final static CMSConfig CMS_CONFIG = CMSConfig.getInstanceOf(); public ItemSearchFlatBrowsePane() { //super(name); diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchPage.java b/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchPage.java index 1c65d789d..255ac53cb 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchPage.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchPage.java @@ -64,7 +64,7 @@ public class ItemSearchPage extends CMSPage { private ItemSearchCreateItemPane m_create; private BigDecimalParameter m_sectionId; private int m_lastTab; - private static final CMSConfig s_conf = CMSConfig.getInstance(); + private static final CMSConfig s_conf = CMSConfig.getInstanceOf(); private static final boolean LIMIT_TO_CONTENT_SECTION = false; public static final String CONTENT_SECTION = "section_id"; @@ -305,7 +305,7 @@ public class ItemSearchPage extends CMSPage { public void excurse() throws IOException, ServletException { ContentSection section = null; - Application app = Web.getContext().getApplication(); + Application app = Web.getWebContext().getApplication(); if (app instanceof ContentSection) { section = (ContentSection) app; } else { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/UserAdminPane.java b/ccm-cms/src/com/arsdigita/cms/ui/UserAdminPane.java index b44727de8..9b31f36c6 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/UserAdminPane.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/UserAdminPane.java @@ -104,7 +104,7 @@ public class UserAdminPane extends SimpleContainer { if ( !isVisible(state) ) { return; } SecurityManager sm = CMS.getContext().getSecurityManager(); - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); if ( !sm.canAccess(user,SecurityConstants.STAFF_ADMIN) ) { m_deniedLabel.generateXML(state, parent); diff --git a/ccm-cms/src/com/arsdigita/cms/ui/authoring/ApplyWorkflowFormSection.java b/ccm-cms/src/com/arsdigita/cms/ui/authoring/ApplyWorkflowFormSection.java index 66ba7b016..17881856f 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/authoring/ApplyWorkflowFormSection.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/authoring/ApplyWorkflowFormSection.java @@ -170,7 +170,7 @@ public class ApplyWorkflowFormSection extends FormSection implements FormInitLis boolean result = false; if (super.isVisible(state) && getSecurityManager(state).canAccess - (Web.getContext().getUser(), SecurityConstants.APPLY_ALTERNATE_WORKFLOWS, + (Web.getWebContext().getUser(), SecurityConstants.APPLY_ALTERNATE_WORKFLOWS, m_creationSelector.getFolder(state))) { TaskCollection t = m_listener.getCollection(state); if (t.next()) { @@ -192,7 +192,7 @@ public class ApplyWorkflowFormSection extends FormSection implements FormInitLis */ public void applyWorkflow(PageState state, ContentItem item) { final BigDecimal flowID = (BigDecimal) m_radio.getValue(state); - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); final ContentSection section = m_creationSelector.getContentSection(state); Folder f = m_creationSelector.getFolder(state); final WorkflowTemplate template; @@ -246,7 +246,7 @@ public class ApplyWorkflowFormSection extends FormSection implements FormInitLis TaskCollection templates = super.getCollection(state); Filter f = templates.addInSubqueryFilter ("id", "com.arsdigita.cms.getWorkflowTemplateUserFilter"); - f.set("userId", Web.getContext().getUser().getID()); + f.set("userId", Web.getWebContext().getUser().getID()); return templates; } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryItemPane.java b/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryItemPane.java index a73f45bf9..b5af2766e 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryItemPane.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryItemPane.java @@ -677,7 +677,7 @@ class CategoryItemPane extends BaseItemPane { */ private boolean isItemEditable(ContentItem item, PageState state) { BigDecimal id = item.getID(); - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); ContentItem ci = new ContentItem(new OID(ContentItem.class.getName(), Integer.parseInt(id.toString()))); Iterator permissions = PermissionService.getImpliedPrivileges( diff --git a/ccm-cms/src/com/arsdigita/cms/ui/contentcenter/ContentSectionContainer.java b/ccm-cms/src/com/arsdigita/cms/ui/contentcenter/ContentSectionContainer.java index 5c56729a6..bd801b604 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/contentcenter/ContentSectionContainer.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/contentcenter/ContentSectionContainer.java @@ -141,7 +141,7 @@ public class ContentSectionContainer extends CMSContainer { ContentSection section = form.getContentSection(state); SecurityManager sm = new SecurityManager(section); Folder folder = null; - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); if (user != null) { folder = Folder.getUserHomeFolder(user, section); } @@ -438,7 +438,7 @@ public class ContentSectionContainer extends CMSContainer { int row, int column) { ContentSection section = (ContentSection) value; Folder folder = null; - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); if (user != null) { folder = Folder.getUserHomeFolder(user, section); } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/contentcenter/TasksPanel.java b/ccm-cms/src/com/arsdigita/cms/ui/contentcenter/TasksPanel.java index 6288ce25b..56d37ccb5 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/contentcenter/TasksPanel.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/contentcenter/TasksPanel.java @@ -444,7 +444,7 @@ public class TasksPanel extends CMSContainer { ContentSection sec = (ContentSection) m_sectionSel.getSelectedObject(s); Assert.exists(sec); - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); if (user != null) { Folder folder = Folder.getUserHomeFolder(user, sec); if (folder != null) { @@ -670,7 +670,7 @@ public class TasksPanel extends CMSContainer { String sectionPath = item.getContentSection().getPath(); if (wf != null) { - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); Engine engine = Engine.getInstance(CMSEngine.CMS_ENGINE_TYPE); Iterator i = engine.getEnabledTasks(user, wf.getID()).iterator(); if (i.hasNext()) { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/contentsection/MainPage.java b/ccm-cms/src/com/arsdigita/cms/ui/contentsection/MainPage.java index 6e5966f50..b02b4f1df 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/contentsection/MainPage.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/contentsection/MainPage.java @@ -193,7 +193,7 @@ public class MainPage extends CMSApplicationPage implements ActionListener { } SecurityManager sm = CMS.getContext().getSecurityManager(); - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); m_tabbedPane.setTabVisible(state, m_userAdminPane, sm.canAccess(user, diff --git a/ccm-cms/src/com/arsdigita/cms/ui/cse/ContentSoonExpiredPane.java b/ccm-cms/src/com/arsdigita/cms/ui/cse/ContentSoonExpiredPane.java index 5aeae859f..bf5e5fac5 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/cse/ContentSoonExpiredPane.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/cse/ContentSoonExpiredPane.java @@ -76,7 +76,7 @@ public class ContentSoonExpiredPane extends SimpleContainer { if ( !isVisible(state) ) { return; } SecurityManager sm = CMS.getContext().getSecurityManager(); - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); DataTable dt = getDataTable(); DataQuery dq = dt.getDataQuery(state); @@ -198,7 +198,7 @@ public class ContentSoonExpiredPane extends SimpleContainer { int row, int column) { boolean canEdit = false; BigDecimal id = (BigDecimal) key; - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); ContentItem ci = getItemFromIdString(id.toString()); Iterator permissions = PermissionService.getImpliedPrivileges(ci.getOID(), user.getOID()); while (permissions.hasNext()) { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/folder/FolderManipulator.java b/ccm-cms/src/com/arsdigita/cms/ui/folder/FolderManipulator.java index 81079f546..8ed4044e9 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/folder/FolderManipulator.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/folder/FolderManipulator.java @@ -292,7 +292,7 @@ public class FolderManipulator extends SimpleContainer d.addError(globalize("cms.ui.folder.not_within_same_folder")); } // check create item permission - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); if (!sm.canAccess(user, SecurityManager.NEW_ITEM, target)) { d.addError(globalize("cms.ui.folder.no_permission_for_item")); } @@ -606,7 +606,7 @@ public class FolderManipulator extends SimpleContainer @Override public boolean isVisible(PageState state) { if (super.isVisible(state) - && (modelBuilder.getFolderSize(state) >= CMSConfig.getInstance(). + && (modelBuilder.getFolderSize(state) >= CMSConfig.getInstanceOf(). getFolderAtoZShowLimit())) { return true; } else { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/item/Summary.java b/ccm-cms/src/com/arsdigita/cms/ui/item/Summary.java index 8044b122f..c8a1ab194 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/item/Summary.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/item/Summary.java @@ -104,7 +104,7 @@ public class Summary extends CMSContainer { ContentItem item = getContentItem(state); ContentSection section = getContentSection(state); - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); // NOT USED - CUSTOMIZED SUMMARY // Take advantage of caching in the CMS Dispatcher. @@ -350,7 +350,7 @@ public class Summary extends CMSContainer { String key = state.getControlEventName(); String value = state.getControlEventValue(); if (RESTART_WORKFLOW.equals(key)) { - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); ContentItem item = getContentItem(state); ContentSection section = item.getContentSection(); Workflow w = Workflow.getObjectWorkflow(item); @@ -397,7 +397,7 @@ public class Summary extends CMSContainer { TaskCollection templates = item.getContentSection().getWorkflowTemplates(); Filter f = templates.addInSubqueryFilter ("id", "com.arsdigita.cms.getWorkflowTemplateUserFilter"); - f.set("userId", Web.getContext().getUser().getID()); + f.set("userId", Web.getWebContext().getUser().getID()); templates.addEqualsFilter(ACSObject.ID, workflow.getWorkflowTemplate().getID()); PrivilegeDescriptor pd = PrivilegeDescriptor.get(SecurityConstants.CMS_WORKFLOW_ADMIN); diff --git a/ccm-cms/src/com/arsdigita/cms/ui/lifecycle/ItemLifecycleAdminPane.java b/ccm-cms/src/com/arsdigita/cms/ui/lifecycle/ItemLifecycleAdminPane.java index 7f1a53112..61eb11de8 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/lifecycle/ItemLifecycleAdminPane.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/lifecycle/ItemLifecycleAdminPane.java @@ -136,7 +136,7 @@ public class ItemLifecycleAdminPane extends BaseItemPane { final PageState state = e.getPageState(); - if (CMSConfig.getInstance().getThreadedPublishing() + if (CMSConfig.getInstanceOf().getThreadedPublishing() && PublishLock.getInstance().isLocked(m_item.getContentItem( state))) { if (PublishLock.getInstance().hasError(m_item.getContentItem( diff --git a/ccm-cms/src/com/arsdigita/cms/ui/lifecycle/ItemLifecycleItemPane.java b/ccm-cms/src/com/arsdigita/cms/ui/lifecycle/ItemLifecycleItemPane.java index eb89a5fe0..89d613a2b 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/lifecycle/ItemLifecycleItemPane.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/lifecycle/ItemLifecycleItemPane.java @@ -75,9 +75,10 @@ import java.text.DateFormat; import org.apache.log4j.Logger; /** - * This class contains the component which displays the information for a particular lifecycle, with - * the ability to edit and delete. This information also includes the associated phases for this - * lifecycle, also with the ability to add, edit, and delete. + * This class contains the component which displays the information for a + * particular lifecycle, with the ability to edit and delete. This information + * also includes the associated phases for this lifecycle, also with the ability + * to add, edit, and delete. * * @author Michael Pih * @author Jack Chung @@ -89,7 +90,7 @@ import org.apache.log4j.Logger; class ItemLifecycleItemPane extends BaseItemPane { private static final Logger s_log = Logger.getLogger( - ItemLifecycleItemPane.class); + ItemLifecycleItemPane.class); private final ContentItemRequestLocal m_item; private final LifecycleRequestLocal m_lifecycle; private final SimpleContainer m_detailPane; @@ -284,12 +285,12 @@ class ItemLifecycleItemPane extends BaseItemPane { public final void actionPerformed(final ActionEvent e) { final PageState state = e.getPageState(); final ContentItem item = m_item.getContentItem(state); - final User user = Web.getContext().getUser(); + final User user = Web.getWebContext().getUser(); /* * jensp 2011-12-14: Check is threaded publishing is active. If yes, execute publishing in a thread. */ - if (CMSConfig.getInstance().getThreadedPublishing()) { + if (CMSConfig.getInstanceOf().getThreadedPublishing()) { final Republisher republisher = new Republisher(item, user); final Thread thread = new Thread(republisher); thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @@ -307,10 +308,10 @@ class ItemLifecycleItemPane extends BaseItemPane { item.getOID().toString()), ex); - if ((CMSConfig.getInstance(). + if ((CMSConfig.getInstanceOf(). getPublicationFailureSender() == null) - && (CMSConfig.getInstance(). + && (CMSConfig.getInstanceOf(). getPublicationFailureReceiver() == null)) { return; } @@ -318,7 +319,7 @@ class ItemLifecycleItemPane extends BaseItemPane { final PartyCollection receiverParties = Party.retrieveAllParties(); Party receiver = null; receiverParties.addEqualsFilter("primaryEmail", - CMSConfig.getInstance(). + CMSConfig.getInstanceOf(). getPublicationFailureReceiver()); if (receiverParties.next()) { receiver = receiverParties.getParty(); @@ -328,7 +329,7 @@ class ItemLifecycleItemPane extends BaseItemPane { final PartyCollection senderParties = Party.retrieveAllParties(); Party sender = null; senderParties.addEqualsFilter("primaryEmail", - CMSConfig.getInstance(). + CMSConfig.getInstanceOf(). getPublicationFailureReceiver()); if (senderParties.next()) { sender = senderParties.getParty(); @@ -430,12 +431,12 @@ class ItemLifecycleItemPane extends BaseItemPane { public final void actionPerformed(final ActionEvent e) { final PageState state = e.getPageState(); final ContentItem item = m_item.getContentItem(state); - final User user = Web.getContext().getUser(); + final User user = Web.getWebContext().getUser(); /** * jensp 2011-12-14: Execute is a thread if threaded publishing is active. */ - if (CMSConfig.getInstance().getThreadedPublishing()) { + if (CMSConfig.getInstanceOf().getThreadedPublishing()) { final Republisher republisher = new Republisher(item, user); final Thread thread = new Thread(republisher); thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @@ -453,10 +454,10 @@ class ItemLifecycleItemPane extends BaseItemPane { item.getOID().toString()), ex); - if ((CMSConfig.getInstance(). + if ((CMSConfig.getInstanceOf(). getPublicationFailureSender() == null) - && (CMSConfig.getInstance(). + && (CMSConfig.getInstanceOf(). getPublicationFailureReceiver() == null)) { return; } @@ -464,7 +465,7 @@ class ItemLifecycleItemPane extends BaseItemPane { final PartyCollection receiverParties = Party.retrieveAllParties(); Party receiver = null; receiverParties.addEqualsFilter("primaryEmail", - CMSConfig.getInstance(). + CMSConfig.getInstanceOf(). getPublicationFailureReceiver()); if (receiverParties.next()) { receiver = receiverParties.getParty(); @@ -474,7 +475,7 @@ class ItemLifecycleItemPane extends BaseItemPane { final PartyCollection senderParties = Party.retrieveAllParties(); Party sender = null; senderParties.addEqualsFilter("primaryEmail", - CMSConfig.getInstance(). + CMSConfig.getInstanceOf(). getPublicationFailureReceiver()); if (senderParties.next()) { sender = senderParties.getParty(); @@ -656,7 +657,7 @@ class ItemLifecycleItemPane extends BaseItemPane { FormProcessException { final PageState state = fse.getPageState(); final FormData data = fse.getFormData(); - final User user = Web.getContext().getUser(); + final User user = Web.getWebContext().getUser(); String selected = (String) data.get(LIFECYCLE_ACTION); final ContentItem item = m_item.getContentItem(state); @@ -666,7 +667,7 @@ class ItemLifecycleItemPane extends BaseItemPane { * active. */ if (REPUBLISH.equals(selected)) { - if (CMSConfig.getInstance().getThreadedPublishing()) { + if (CMSConfig.getInstanceOf().getThreadedPublishing()) { final RepublishRunner runner = new RepublishRunner(item, user); final Thread thread = new Thread(runner); thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @@ -684,10 +685,10 @@ class ItemLifecycleItemPane extends BaseItemPane { item.getOID().toString()), ex); - if ((CMSConfig.getInstance(). + if ((CMSConfig.getInstanceOf(). getPublicationFailureSender() == null) - && (CMSConfig.getInstance(). + && (CMSConfig.getInstanceOf(). getPublicationFailureReceiver() == null)) { return; } @@ -695,7 +696,7 @@ class ItemLifecycleItemPane extends BaseItemPane { final PartyCollection receiverParties = Party.retrieveAllParties(); Party receiver = null; receiverParties.addEqualsFilter("primaryEmail", - CMSConfig.getInstance(). + CMSConfig.getInstanceOf(). getPublicationFailureReceiver()); if (receiverParties.next()) { receiver = receiverParties.getParty(); @@ -705,7 +706,7 @@ class ItemLifecycleItemPane extends BaseItemPane { final PartyCollection senderParties = Party.retrieveAllParties(); Party sender = null; senderParties.addEqualsFilter("primaryEmail", - CMSConfig.getInstance(). + CMSConfig.getInstanceOf(). getPublicationFailureReceiver()); if (senderParties.next()) { sender = senderParties.getParty(); @@ -753,7 +754,7 @@ class ItemLifecycleItemPane extends BaseItemPane { } } } else if (REPUBLISH_AND_RESET.equals(selected)) { - if (CMSConfig.getInstance().getThreadedPublishing()) { + if (CMSConfig.getInstanceOf().getThreadedPublishing()) { final RepublishAndResetRunner runner = new RepublishAndResetRunner(item, user); final Thread thread = new Thread(runner); thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @@ -771,10 +772,10 @@ class ItemLifecycleItemPane extends BaseItemPane { item.getOID().toString()), ex); - if ((CMSConfig.getInstance(). + if ((CMSConfig.getInstanceOf(). getPublicationFailureSender() == null) - && (CMSConfig.getInstance(). + && (CMSConfig.getInstanceOf(). getPublicationFailureReceiver() == null)) { return; } @@ -782,7 +783,7 @@ class ItemLifecycleItemPane extends BaseItemPane { final PartyCollection receiverParties = Party.retrieveAllParties(); Party receiver = null; receiverParties.addEqualsFilter("primaryEmail", - CMSConfig.getInstance(). + CMSConfig.getInstanceOf(). getPublicationFailureReceiver()); if (receiverParties.next()) { receiver = receiverParties.getParty(); @@ -792,7 +793,7 @@ class ItemLifecycleItemPane extends BaseItemPane { final PartyCollection senderParties = Party.retrieveAllParties(); Party sender = null; senderParties.addEqualsFilter("primaryEmail", - CMSConfig.getInstance(). + CMSConfig.getInstanceOf(). getPublicationFailureReceiver()); if (senderParties.next()) { sender = senderParties.getParty(); diff --git a/ccm-cms/src/com/arsdigita/cms/ui/lifecycle/ItemLifecycleSelectForm.java b/ccm-cms/src/com/arsdigita/cms/ui/lifecycle/ItemLifecycleSelectForm.java index f67b8e1f2..9dc531355 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/lifecycle/ItemLifecycleSelectForm.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/lifecycle/ItemLifecycleSelectForm.java @@ -86,8 +86,7 @@ import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; /** - *

- * A form to select and apply a lifecycle to a content item.

+ *

A form to select and apply a lifecycle to a content item.

* * @author Michael Pih * @author Xixi D'moon <xdmoon@redhat.com> @@ -97,7 +96,8 @@ import org.apache.log4j.Logger; */ class ItemLifecycleSelectForm extends BaseForm { - private static final Logger s_log = Logger.getLogger(ItemLifecycleSelectForm.class); + private static final Logger s_log = + Logger.getLogger(ItemLifecycleSelectForm.class); private final static String LIFECYCLE = "lifecycle"; private final static String START_DATE = "start_date"; private final static String END_DATE = "end_date"; @@ -347,8 +347,8 @@ class ItemLifecycleSelectForm extends BaseForm { } /** - * jensp 2011-12-14: Some larger changes to the behavior of the process listener. The real - * action has been moved to the + * jensp 2011-12-14: Some larger changes to the behavior of the process + * listener. The real action has been moved to the * @link{Publisher} class. If threaded publishing is active, the publish * process runs in a separate thread (the item is locked before using * {@link PublishLock}. If threaded publishing is not active, nothing has @@ -363,7 +363,7 @@ class ItemLifecycleSelectForm extends BaseForm { final ContentItem item = m_item.getContentItem(state); final Publisher publisher = new Publisher(state); - if (CMSConfig.getInstance().getThreadedPublishing()) { + if (CMSConfig.getInstanceOf().getThreadedPublishing()) { final Runnable threadAction = new Runnable() { @Override @@ -391,9 +391,9 @@ class ItemLifecycleSelectForm extends BaseForm { item.getOID().toString()), ex); - if ((CMSConfig.getInstance().getPublicationFailureSender() + if ((CMSConfig.getInstanceOf().getPublicationFailureSender() == null) - && (CMSConfig.getInstance(). + && (CMSConfig.getInstanceOf(). getPublicationFailureReceiver() == null)) { return; } @@ -402,7 +402,7 @@ class ItemLifecycleSelectForm extends BaseForm { retrieveAllParties(); Party receiver = null; receiverParties.addEqualsFilter("primaryEmail", - CMSConfig.getInstance(). + CMSConfig.getInstanceOf(). getPublicationFailureReceiver()); if (receiverParties.next()) { receiver = receiverParties.getParty(); @@ -413,7 +413,7 @@ class ItemLifecycleSelectForm extends BaseForm { retrieveAllParties(); Party sender = null; senderParties.addEqualsFilter("primaryEmail", CMSConfig. - getInstance().getPublicationFailureReceiver()); + getInstanceOf().getPublicationFailureReceiver()); if (senderParties.next()) { sender = senderParties.getParty(); } @@ -446,7 +446,7 @@ class ItemLifecycleSelectForm extends BaseForm { publisher.publish(); } - if (CMSConfig.getInstance().getThreadedPublishing()) { + if (CMSConfig.getInstanceOf().getThreadedPublishing()) { throw new RedirectSignal( URL.getDispatcherPath() + ContentItemPage.getItemURL(item, @@ -486,7 +486,7 @@ class ItemLifecycleSelectForm extends BaseForm { * java.util.Date startDate = (java.util.Date) * m_startDate.getValue(state); * - * final Calendar start = Calendar.getInstance(); + * final Calendar start = Calendar.getInstanceOf(); * start.setTime(startDate); start.set(Calendar.AM_PM, * startAmpm.intValue()); start.set(Calendar.MINUTE, * startMinute.intValue()); start.set(Calendar.AM_PM, @@ -502,7 +502,7 @@ class ItemLifecycleSelectForm extends BaseForm { * m_endDate.getValue(state); * * if (endDate != null) { final Calendar end = - * Calendar.getInstance(); + * Calendar.getInstanceOf(); * * end.setTime(endDate); end.set(Calendar.AM_PM, * endAmpm.intValue()); end.set(Calendar.MINUTE, @@ -575,7 +575,7 @@ class ItemLifecycleSelectForm extends BaseForm { * item.save(); * * final Workflow workflow = m_workflow.getWorkflow(state); try { - * finish(workflow, item, Web.getContext().getUser()); } catch + * finish(workflow, item, Web.getWebContext().getUser()); } catch * (TaskException te) { throw new FormProcessException(te); } // * redirect to /content-center if streamlined creation mode is * active. if @@ -689,7 +689,7 @@ class ItemLifecycleSelectForm extends BaseForm { workflowOid = null; } - user = Web.getContext().getUser(); + user = Web.getWebContext().getUser(); } /** @@ -698,8 +698,8 @@ class ItemLifecycleSelectForm extends BaseForm { public void publish() { /** - * We have to create a new instance here since it is not possible to access the same - * data object from multiple threads. + * We have to create a new instance here since it is not possible to + * access the same data object from multiple threads. */ final OID oid = OID.valueOf(oidStr); final ContentItem item = (ContentItem) DomainObjectFactory. @@ -1003,12 +1003,14 @@ class ItemLifecycleSelectForm extends BaseForm { } /** - * Find out at which date a notification (about an item that is about to expire) should be sent, - * based on the endDate (== date at which the item is unpublished) and the notification period. + * Find out at which date a notification (about an item that is about to + * expire) should be sent, based on the endDate (== date at which the item + * is unpublished) and the notification period. * - * @param endDate the endDate of the lifecycle, i.e. the date when the item is going to be - * unpublished - * @param notification how many hours the users shouls be notified in advance + * @param endDate the endDate of the lifecycle, i.e. the date when the item + * is going to be unpublished + * @param notification how many hours the users shouls be notified in + * advance */ private java.util.Date computeNotificationDate(java.util.Date endDate, int notificationPeriod) { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/portlet/TaskPortletRenderer.java b/ccm-cms/src/com/arsdigita/cms/ui/portlet/TaskPortletRenderer.java index 870882902..ddd8f33d3 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/portlet/TaskPortletRenderer.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/portlet/TaskPortletRenderer.java @@ -81,7 +81,7 @@ public class TaskPortletRenderer extends AbstractPortletRenderer { Label dueday; Date dday; - User currentUser = Web.getContext().getUser(); + User currentUser = Web.getWebContext().getUser(); Date currentDate = new Date(); final int numTasks = m_portlet.getMaxNumTasks(); diff --git a/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskSection.java b/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskSection.java index 31d6dcfae..ef0c9751c 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskSection.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskSection.java @@ -150,7 +150,7 @@ public final class AssignedTaskSection extends Section { protected final Object initialValue(final PageState state) { final Workflow workflow = m_flow.getWorkflow(state); final Engine engine = Engine.getInstance(CMSEngine.CMS_ENGINE_TYPE); - return engine.getEnabledTasks(Web.getContext().getUser(), workflow.getID()); + return engine.getEnabledTasks(Web.getWebContext().getUser(), workflow.getID()); } final ArrayList getTasks(final PageState state) { @@ -160,7 +160,7 @@ public final class AssignedTaskSection extends Section { final void restartWorkflow(final PageState state) { final Workflow workflow = m_flow.getWorkflow(state); - workflow.start(Web.getContext().getUser()); + workflow.start(Web.getWebContext().getUser()); workflow.save(); // Lock tasks if not locked @@ -176,7 +176,7 @@ public final class AssignedTaskSection extends Section { final CMSTask task = (CMSTask) iter.next(); if (relevant(task) && !task.isLocked()) { - task.lock(Web.getContext().getUser()); + task.lock(Web.getWebContext().getUser()); task.save(); } } @@ -189,7 +189,7 @@ public final class AssignedTaskSection extends Section { final CMSTask task = (CMSTask) iter.next(); if (relevant(task) && task.isLocked()) { - task.unlock(Web.getContext().getUser()); + task.unlock(Web.getWebContext().getUser()); task.save(); } } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskTable.java b/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskTable.java index a11398bf8..baa600bd1 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskTable.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskTable.java @@ -69,7 +69,7 @@ public final class AssignedTaskTable extends Table { if (column == 1) { final CMSTask task = new CMSTask(new BigDecimal(e.getRowKey() .toString())); - User currentUser = Web.getContext().getUser(); + User currentUser = Web.getWebContext().getUser(); User lockingUser = task.getLockedUser(); if (task.isLocked() && lockingUser != null && lockingUser.equals(currentUser)) { @@ -92,7 +92,7 @@ public final class AssignedTaskTable extends Table { User lockingUser = (User) value; if (lockingUser != null) { StringBuilder sb = new StringBuilder("Locked by
"); - if (lockingUser.equals(Web.getContext().getUser())) { + if (lockingUser.equals(Web.getWebContext().getUser())) { sb.append("you"); p.add(new ControlLink(new Label( gz("cms.ui.workflow.task.unlock")))); diff --git a/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskTableModelBuilder.java b/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskTableModelBuilder.java index 4e7777802..be6dc1038 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskTableModelBuilder.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskTableModelBuilder.java @@ -63,7 +63,7 @@ class AssignedTaskTableModelBuilder extends AbstractTableModelBuilder { Assert.exists(engine, Engine.class); - m_iter = engine.getEnabledTasks(Web.getContext().getUser(), workflow.getID()).iterator(); + m_iter = engine.getEnabledTasks(Web.getWebContext().getUser(), workflow.getID()).iterator(); } else { m_iter = Collections.emptyList().iterator(); } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/workflow/BaseWorkflowItemPane.java b/ccm-cms/src/com/arsdigita/cms/ui/workflow/BaseWorkflowItemPane.java index 572bddfd1..3c5151ddb 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/workflow/BaseWorkflowItemPane.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/workflow/BaseWorkflowItemPane.java @@ -138,7 +138,7 @@ abstract class BaseWorkflowItemPane extends BaseItemPane { User lockingUser = task.getLockedUser(); boolean visible = task.isEnabled() && (lockingUser == null || - lockingUser.equals(Web.getContext().getUser())); + lockingUser.equals(Web.getWebContext().getUser())); return visible; } @@ -148,7 +148,7 @@ abstract class BaseWorkflowItemPane extends BaseItemPane { try { m_task.getTask(state).finish - (Web.getContext().getUser()); + (Web.getWebContext().getUser()); } catch (TaskException te) { throw new UncheckedWrapperException(te); } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/workflow/CommentAddForm.java b/ccm-cms/src/com/arsdigita/cms/ui/workflow/CommentAddForm.java index aee21f448..110cc6e0a 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/workflow/CommentAddForm.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/workflow/CommentAddForm.java @@ -66,7 +66,7 @@ class CommentAddForm extends BaseForm { final PageState state = e.getPageState(); final CMSTask task = m_task.getTask(state); - final User user = Web.getContext().getUser(); + final User user = Web.getWebContext().getUser(); final TaskComment comment = new TaskComment (task.getID(), user, (String) m_comment.getValue(state)); diff --git a/ccm-cms/src/com/arsdigita/cms/ui/workflow/ItemWorkflowItemPane.java b/ccm-cms/src/com/arsdigita/cms/ui/workflow/ItemWorkflowItemPane.java index 162438d36..755d5ce40 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/workflow/ItemWorkflowItemPane.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/workflow/ItemWorkflowItemPane.java @@ -95,7 +95,7 @@ final class ItemWorkflowItemPane extends BaseWorkflowItemPane { final Workflow workflow = m_workflow.getWorkflow (state); - workflow.stop(Web.getContext().getUser()); + workflow.stop(Web.getWebContext().getUser()); } } } @@ -125,7 +125,7 @@ final class ItemWorkflowItemPane extends BaseWorkflowItemPane { final Workflow workflow = m_workflow.getWorkflow (state); - workflow.start(Web.getContext().getUser()); + workflow.start(Web.getWebContext().getUser()); } } } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/workflow/ItemWorkflowSelectForm.java b/ccm-cms/src/com/arsdigita/cms/ui/workflow/ItemWorkflowSelectForm.java index 66876ed17..319ab38f9 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/workflow/ItemWorkflowSelectForm.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/workflow/ItemWorkflowSelectForm.java @@ -92,7 +92,7 @@ class ItemWorkflowSelectForm extends CMSForm { final Workflow flow = template.instantiateNewWorkflow(); flow.setObjectID(itemID); - flow.start(Web.getContext().getUser()); + flow.start(Web.getWebContext().getUser()); flow.save(); } } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/workflow/TaskFinishForm.java b/ccm-cms/src/com/arsdigita/cms/ui/workflow/TaskFinishForm.java index 35e9614bd..b5180d7ec 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/workflow/TaskFinishForm.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/workflow/TaskFinishForm.java @@ -154,7 +154,7 @@ public final class TaskFinishForm extends CommentAddForm { s_log.debug("The task is approved; finishing the task"); try { - task.finish(Web.getContext().getUser()); + task.finish(Web.getWebContext().getUser()); finishedTask = true; } catch (TaskException te) { throw new FormValidationException(te.toString()); @@ -183,14 +183,14 @@ public final class TaskFinishForm extends CommentAddForm { + "it"); try { - task.finish(Web.getContext().getUser()); + task.finish(Web.getWebContext().getUser()); finishedTask = true; } catch (TaskException te) { throw new FormValidationException(te.toString()); } } if (finishedTask) { - Iterator tasks = Engine.getInstance(CMSEngine.CMS_ENGINE_TYPE).getEnabledTasks(Web.getContext().getUser(), + Iterator tasks = Engine.getInstance(CMSEngine.CMS_ENGINE_TYPE).getEnabledTasks(Web.getWebContext().getUser(), task.getParentID()).iterator(); if (tasks.hasNext()) { CMSTask thisTask = (CMSTask) tasks.next(); diff --git a/ccm-cms/src/com/arsdigita/cms/ui/workflow/TaskItemPane.java b/ccm-cms/src/com/arsdigita/cms/ui/workflow/TaskItemPane.java index 05e365b20..384a96eff 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/workflow/TaskItemPane.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/workflow/TaskItemPane.java @@ -155,7 +155,7 @@ final class TaskItemPane extends BaseItemPane { private boolean assigned(final PageState state) { final Workflow workflow = m_workflow.getWorkflow(state); - final User user = Web.getContext().getUser(); + final User user = Web.getWebContext().getUser(); final CMSTask task = m_task.getTask(state); final Engine engine = Engine.getInstance(CMSEngine.CMS_ENGINE_TYPE); @@ -230,7 +230,7 @@ final class TaskItemPane extends BaseItemPane { if (hasAdmin(state)) { final CMSTask task = m_task.getTask(state); - task.lock(Web.getContext().getUser()); + task.lock(Web.getWebContext().getUser()); task.save(); } } @@ -256,7 +256,7 @@ final class TaskItemPane extends BaseItemPane { if (hasAdmin(state)) { final CMSTask task = m_task.getTask(state); - task.unlock(Web.getContext().getUser()); + task.unlock(Web.getWebContext().getUser()); task.save(); } } diff --git a/ccm-cms/web/WEB-INF/web.ccm-cms.xml b/ccm-cms/web/WEB-INF/web.ccm-cms.xml new file mode 100644 index 000000000..f738805da --- /dev/null +++ b/ccm-cms/web/WEB-INF/web.ccm-cms.xml @@ -0,0 +1,61 @@ + + + + + + + content-section + com.arsdigita.cms.ContentSectionServlet + + + + content-type-xsl + com.arsdigita.cms.dispatcher.ContentTypeXSLServlet + + + + content-item-xsl + com.arsdigita.cms.dispatcher.ContentItemXSLServlet + + + + template-xsl + com.arsdigita.cms.dispatcher.TemplateXSLServlet + + + + + + content-section + /themes/servlet/content-section/* + + + + content-item-xsl + /themes/servlet/content-item/* + + + + content-type-xsl + /themes/servlet/content-type/* + + + + template-xsl + /themes/servlet/template/* + + + diff --git a/ccm-cms/web/WEB-INF/web.optional-ccm-cms.xml b/ccm-cms/web/WEB-INF/web.optional-ccm-cms.xml new file mode 100644 index 000000000..9602ed88a --- /dev/null +++ b/ccm-cms/web/WEB-INF/web.optional-ccm-cms.xml @@ -0,0 +1,51 @@ + + + + + + + TextOnlyServlet + Text Only Servlet + com.arsdigita.web.InternalPrefixerServlet + + prefix + /text + + + + + PrintFriendlyServlet + Printer Friendly Output Servlet + com.arsdigita.web.InternalPrefixerServlet + + prefix + /print + + + + + + + TextOnlyServlet + /text/* + + + + PrintFriendlyServlet + /print/* + + + diff --git a/ccm-cms/web/templates/ccm-cms/content-section/admin/index.jsp b/ccm-cms/web/templates/ccm-cms/content-section/admin/index.jsp index a6ab17905..7613c5808 100755 --- a/ccm-cms/web/templates/ccm-cms/content-section/admin/index.jsp +++ b/ccm-cms/web/templates/ccm-cms/content-section/admin/index.jsp @@ -21,7 +21,7 @@ ContentSection section = ContentSectionServlet.getContentSection(request); - if (Web.getContext().getUser() == null) { + if (Web.getWebContext().getUser() == null) { throw new LoginSignal(request); } else if (! ContentSectionServlet.checkAdminAccess(request, section)) { throw new com.arsdigita.cms.dispatcher.AccessDeniedException(); diff --git a/ccm-cms/web/templates/ccm-cms/content-section/admin/item.jsp b/ccm-cms/web/templates/ccm-cms/content-section/admin/item.jsp index 58f0e9124..78d16bb67 100755 --- a/ccm-cms/web/templates/ccm-cms/content-section/admin/item.jsp +++ b/ccm-cms/web/templates/ccm-cms/content-section/admin/item.jsp @@ -31,7 +31,7 @@ ContentSectionServlet.getContentSection(request); - if (Web.getContext().getUser() == null) { + if (Web.getWebContext().getUser() == null) { throw new LoginSignal(request); } else if (! ContentSectionServlet.checkAdminAccess(request, section)) { throw new com.arsdigita.cms.dispatcher.AccessDeniedException(); diff --git a/ccm-core/src/com/arsdigita/auditing/WebAuditingSaveInfo.java b/ccm-core/src/com/arsdigita/auditing/WebAuditingSaveInfo.java index 2712c302a..ddda56bbb 100755 --- a/ccm-core/src/com/arsdigita/auditing/WebAuditingSaveInfo.java +++ b/ccm-core/src/com/arsdigita/auditing/WebAuditingSaveInfo.java @@ -44,7 +44,7 @@ public class WebAuditingSaveInfo implements AuditingSaveInfo { private String m_ip; public WebAuditingSaveInfo() { - m_user = Web.getContext().getUser(); + m_user = Web.getWebContext().getUser(); // The user may be null. HttpServletRequest req = Web.getRequest(); diff --git a/ccm-core/src/com/arsdigita/bebop/Form.java b/ccm-core/src/com/arsdigita/bebop/Form.java index 5de358503..f0da30a02 100755 --- a/ccm-core/src/com/arsdigita/bebop/Form.java +++ b/ccm-core/src/com/arsdigita/bebop/Form.java @@ -216,7 +216,7 @@ public class Form extends FormSection implements BebopConstants { String url = null; if (m_action == null) { - final URL requestURL = Web.getContext().getRequestURL(); + final URL requestURL = Web.getWebContext().getRequestURL(); if (requestURL == null) { url = s.getRequest().getRequestURI(); diff --git a/ccm-core/src/com/arsdigita/bebop/PageState.java b/ccm-core/src/com/arsdigita/bebop/PageState.java index 0e6ac3358..4a1db95ae 100755 --- a/ccm-core/src/com/arsdigita/bebop/PageState.java +++ b/ccm-core/src/com/arsdigita/bebop/PageState.java @@ -976,7 +976,7 @@ public class PageState { * @return the URI to which the current request was made */ public String getRequestURI() { - final URL url = Web.getContext().getRequestURL(); + final URL url = Web.getWebContext().getRequestURL(); if (url == null) { return m_request.getRequestURI(); diff --git a/ccm-core/src/com/arsdigita/bebop/demo/MySitePage.java b/ccm-core/src/com/arsdigita/bebop/demo/MySitePage.java index 2246c91d1..b885ad19b 100755 --- a/ccm-core/src/com/arsdigita/bebop/demo/MySitePage.java +++ b/ccm-core/src/com/arsdigita/bebop/demo/MySitePage.java @@ -88,7 +88,7 @@ public class MySitePage extends Page { Element elt = new Element("bebop:message", BEBOP_XML_NS); elt.setText("MySite: dynamic page header. You requested: " + - Web.getContext().getRequestURL()); + Web.getWebContext().getRequestURL()); parent.addContent(elt); } diff --git a/ccm-core/src/com/arsdigita/bebop/page/BebopApplicationServlet.java b/ccm-core/src/com/arsdigita/bebop/page/BebopApplicationServlet.java index 7c37b622b..c7b732220 100755 --- a/ccm-core/src/com/arsdigita/bebop/page/BebopApplicationServlet.java +++ b/ccm-core/src/com/arsdigita/bebop/page/BebopApplicationServlet.java @@ -140,6 +140,7 @@ public class BebopApplicationServlet extends BaseApplicationServlet { * @throws ServletException * @throws IOException */ + @Override protected final void doService(final HttpServletRequest sreq, final HttpServletResponse sresp, final Application app) @@ -174,6 +175,12 @@ public class BebopApplicationServlet extends BaseApplicationServlet { * Provides the opportunity for subclasses to do some preprocessing * of a given url, before it is handed off to main service process. * One typical action is to ensure permissions. + * @param sreq + * @param sresp + * @param app + * @param url + * @throws javax.servlet.ServletException + * @throws java.io.IOException */ protected void preprocessRequest(HttpServletRequest sreq, HttpServletResponse sresp, diff --git a/ccm-core/src/com/arsdigita/bebop/page/PageDispatcher.java b/ccm-core/src/com/arsdigita/bebop/page/PageDispatcher.java index 0bf7d9cbd..a3f0ad4da 100755 --- a/ccm-core/src/com/arsdigita/bebop/page/PageDispatcher.java +++ b/ccm-core/src/com/arsdigita/bebop/page/PageDispatcher.java @@ -47,6 +47,8 @@ public class PageDispatcher implements Dispatcher { /** * Creates a new page dispatcher for a page object and a * PresentationManager. + * @param page + * @param pres */ public PageDispatcher(final Page page, final PresentationManager pres) { @@ -57,6 +59,7 @@ public class PageDispatcher implements Dispatcher { /** * Creates a new page dispatcher for a page object. Uses the * default presentation manager. + * @param page */ public PageDispatcher(final Page page) { m_page = page; @@ -66,7 +69,11 @@ public class PageDispatcher implements Dispatcher { /** * Serves the Bebop page using the specified * PresentationManager. + * @param req + * @param resp + * @param ctx */ + @Override public void dispatch(final HttpServletRequest req, final HttpServletResponse resp, final RequestContext ctx) diff --git a/ccm-core/src/com/arsdigita/bebop/page/PageTransformer.java b/ccm-core/src/com/arsdigita/bebop/page/PageTransformer.java index dd390c0c2..ac78ea10d 100755 --- a/ccm-core/src/com/arsdigita/bebop/page/PageTransformer.java +++ b/ccm-core/src/com/arsdigita/bebop/page/PageTransformer.java @@ -60,10 +60,10 @@ import javax.xml.transform.stream.StreamResult; import org.apache.log4j.Logger; /** - * A class for managing and obtaining a Stylesheet based on the - * current request's location in the site map. First, we try to find - * a stylesheet specific to this site node. If we can't find one, - * then we walk up the site map until we find a parent of this site + * A class for managing and obtaining a Stylesheet based on the current + * request's location in the site map. + * First, we try to find a stylesheet specific to this site node. If we can't + * find one, then we walk up the site map until we find a parent of this site * node that has a stylesheet associated with it. * * If we haven't found one by the time we reach the root, then we'll @@ -106,7 +106,7 @@ public class PageTransformer implements PresentationManager { new XSLParameterGenerator() { @Override public String generateValue(HttpServletRequest request) { - return Web.getContext().getRequestURL().getContextPath(); + return Web.getWebContext().getRequestURL().getContextPath(); } }); @@ -115,7 +115,7 @@ public class PageTransformer implements PresentationManager { new XSLParameterGenerator() { @Override public String generateValue(HttpServletRequest request) { - return Web.getContext().getRequestURL().getContextPath() + return Web.getWebContext().getRequestURL().getContextPath() + com.arsdigita.web.URL.INTERNAL_THEME_DIR; } @@ -318,12 +318,11 @@ public class PageTransformer implements PresentationManager { } /** - * Serves an XML Document, getting and applying the appropriate - * XSLT. Also allows for parameters to be set for the - * transformer. These will become top-level xsl:params in the - * stylesheet. The "contextPath" parameter will always be passed - * to XSLT, which is the value of - * req.getContextPath(). + * Serves an XML Document, getting and applying the appropriate XSLT. + * Also allows for parameters to be set for the transformer. These will + * become top-level xsl:params in the stylesheet. + * The "contextPath" parameter will always be passed to XSLT, which is the + * value of req.getWebContextPath(). * * @param doc the Bebop page to serve * @param req the servlet request @@ -347,8 +346,8 @@ public class PageTransformer implements PresentationManager { Profiler.startOp("XSLT"); try { - final String charset = Globalization.getDefaultCharset(Kernel. - getContext().getLocale()); + final String charset = Globalization.getDefaultCharset( + Kernel.getContext().getLocale()); final String output = req.getParameter("output"); s_log.info("output=" + output); @@ -358,7 +357,7 @@ public class PageTransformer implements PresentationManager { boolean fancyErrors = Bebop.getConfig().wantFancyXSLErrors() || Boolean.TRUE.equals(req.getAttribute( - FANCY_ERRORS)); + FANCY_ERRORS)); // Get the stylesheet transformer object corresponding to the // current request. @@ -383,8 +382,7 @@ public class PageTransformer implements PresentationManager { endTransaction(req); // Transformers are not thread-safe, so we assume we have - // exclusive - // use of xf here. But we could recycle it. + // exclusive use of xf here. But we could recycle it. xf.clearParameters(); if (params != null) { @@ -490,8 +488,8 @@ public class PageTransformer implements PresentationManager { } /** - * Ends the current transaction. Is a performance optimization to end ASAP before - * serving the page. + * Ends the current transaction. Is a performance optimization to end + * ASAP before serving the page. * * @param req HTTP request. */ @@ -509,6 +507,8 @@ public class PageTransformer implements PresentationManager { * XSLStylesheets. If this is called a second time with the same * parameter name then all previous calls are overwritten and * only the last registered generator is used. + * @param parameterName + * @param parameterGenerator */ public static void registerXSLParameterGenerator(String parameterName, XSLParameterGenerator parameterGenerator) { @@ -518,6 +518,7 @@ public class PageTransformer implements PresentationManager { /** * This removes the parameter from the list of parameters that * will be added to stylesheets + * @param parameterName */ public static void removeXSLParameterGenerator(String parameterName) { s_XSLParameters.remove(parameterName); @@ -526,14 +527,18 @@ public class PageTransformer implements PresentationManager { /** * This is a Collection of all names of XSL Parameters that have been * registered + * @return */ public static Collection getXSLParameterNames() { return s_XSLParameters.keySet(); } /** - * This takes a name and request and returns the value that should - * be used in the XSL for the given name + * This takes a name and request and returns the value that should + * be used in the XSL for the given name + * @param name + * @param request + * @return */ public static String getXSLParameterValue(String name, HttpServletRequest request) { @@ -547,8 +552,10 @@ public class PageTransformer implements PresentationManager { } /** - * This takes in a transformer and adds all of the registered - * xsl paraemters. + * This takes in a transformer and adds all of the registered + * xsl paraemters. + * @param transformer + * @param request */ public static void addXSLParameters(Transformer transformer, HttpServletRequest request) { diff --git a/ccm-core/src/com/arsdigita/categorization/ui/ApplicationCategoryPicker.java b/ccm-core/src/com/arsdigita/categorization/ui/ApplicationCategoryPicker.java index 8aae2e32d..3af24707f 100755 --- a/ccm-core/src/com/arsdigita/categorization/ui/ApplicationCategoryPicker.java +++ b/ccm-core/src/com/arsdigita/categorization/ui/ApplicationCategoryPicker.java @@ -33,7 +33,7 @@ public class ApplicationCategoryPicker extends ObjectCategoryPicker { } protected ACSObject getObject(PageState state) { - return Web.getContext().getApplication(); + return Web.getWebContext().getApplication(); } protected String getContext(PageState state) { diff --git a/ccm-core/src/com/arsdigita/kernel/permissions/Permission.java b/ccm-core/src/com/arsdigita/kernel/permissions/Permission.java index cf8f9f103..77bfd4361 100755 --- a/ccm-core/src/com/arsdigita/kernel/permissions/Permission.java +++ b/ccm-core/src/com/arsdigita/kernel/permissions/Permission.java @@ -280,7 +280,7 @@ class Permission extends DomainObject { * */ private void setCreationInfo() { - User user = Web.getContext().getUser(); + User user = Web.getWebContext().getUser(); // The user may be null. HttpServletRequest req = Web.getRequest(); diff --git a/ccm-core/src/com/arsdigita/kernel/security/UserContext.java b/ccm-core/src/com/arsdigita/kernel/security/UserContext.java index 575a4aedc..9b87fd0d6 100755 --- a/ccm-core/src/com/arsdigita/kernel/security/UserContext.java +++ b/ccm-core/src/com/arsdigita/kernel/security/UserContext.java @@ -490,7 +490,7 @@ public class UserContext { */ public static String encodeReturnURL(HttpServletRequest req) { StringBuilder returnURL = new StringBuilder(100); - returnURL.append(Web.getContext().getRequestURL().getRequestURI()); + returnURL.append(Web.getWebContext().getRequestURL().getRequestURI()); returnURL.append('?'); // convert posted parameters to URL parameters diff --git a/ccm-core/src/com/arsdigita/runtime/CompoundInitializer.java b/ccm-core/src/com/arsdigita/runtime/CompoundInitializer.java index 074b0b660..168a3ebf2 100755 --- a/ccm-core/src/com/arsdigita/runtime/CompoundInitializer.java +++ b/ccm-core/src/com/arsdigita/runtime/CompoundInitializer.java @@ -82,6 +82,7 @@ public class CompoundInitializer implements Initializer { * * @param evt The data init event. */ + @Override public void init(DataInitEvent evt) { int i = 1; for (Iterator it = m_inits.iterator(); it.hasNext(); i++) { @@ -102,6 +103,7 @@ public class CompoundInitializer implements Initializer { * * @param evt The domain init event. */ + @Override public void init(DomainInitEvent evt) { int i = 1; for (Iterator it = m_inits.iterator(); it.hasNext(); i++) { @@ -142,6 +144,7 @@ public class CompoundInitializer implements Initializer { * * @param evt The legacy init event. */ + @Override public void init(ContextInitEvent evt) { int i = 1; for (Iterator it = m_inits.iterator(); it.hasNext(); i++) { @@ -164,6 +167,7 @@ public class CompoundInitializer implements Initializer { * * @param evt The context close event. */ + @Override public void close(ContextCloseEvent evt) { s_log.info("CompoundInitializer.close(ContextCloseEvent) invoked"); diff --git a/ccm-core/src/com/arsdigita/search/ui/ResultsPane.java b/ccm-core/src/com/arsdigita/search/ui/ResultsPane.java index b53d3533b..564a04f9b 100755 --- a/ccm-core/src/com/arsdigita/search/ui/ResultsPane.java +++ b/ccm-core/src/com/arsdigita/search/ui/ResultsPane.java @@ -200,7 +200,7 @@ public class ResultsPane extends SimpleComponent { long end, long objectCount) { Element paginator = Search.newElement("paginator"); - URL url = Web.getContext().getRequestURL(); + URL url = Web.getWebContext().getRequestURL(); ParameterMap map = new ParameterMap(); Iterator current = url.getParameterMap().keySet().iterator(); diff --git a/ccm-core/src/com/arsdigita/templating/ApplicationOIDPatternGenerator.java b/ccm-core/src/com/arsdigita/templating/ApplicationOIDPatternGenerator.java index 7b1e026d5..df9d83125 100755 --- a/ccm-core/src/com/arsdigita/templating/ApplicationOIDPatternGenerator.java +++ b/ccm-core/src/com/arsdigita/templating/ApplicationOIDPatternGenerator.java @@ -18,8 +18,8 @@ */ package com.arsdigita.templating; -import com.arsdigita.web.Web; import com.arsdigita.web.Application; +import com.arsdigita.web.Web; import javax.servlet.http.HttpServletRequest; @@ -31,10 +31,22 @@ import java.net.URLEncoder; */ public class ApplicationOIDPatternGenerator implements PatternGenerator { + /** + * Looks up the current application and returns its OID as String. + * The Return type is (unneccessarily) String[] due to the current API, but + * currently never returns more than just one value (one OID). + * + * @param key placeholder from the pattern string, without surrounding + * colons, constantly "oid" here. + * @param req current HttpServletRequest + * @return OID as String in an Array of Strings. This array is never longer + * as one element. + */ + @Override public String[] generateValues(String key, HttpServletRequest req) { - final Application application = Web.getContext().getApplication(); + final Application application = Web.getWebContext().getApplication(); if (application != null) { String[] oid = new String[1]; diff --git a/ccm-core/src/com/arsdigita/templating/ApplicationPatternGenerator.java b/ccm-core/src/com/arsdigita/templating/ApplicationPatternGenerator.java index a6b60464a..8cbc4b4ef 100755 --- a/ccm-core/src/com/arsdigita/templating/ApplicationPatternGenerator.java +++ b/ccm-core/src/com/arsdigita/templating/ApplicationPatternGenerator.java @@ -48,52 +48,24 @@ public class ApplicationPatternGenerator implements PatternGenerator { * @param req * @return */ + @Override public String[] generateValues(String key, HttpServletRequest req) { s_log.debug("Processing Application with key: " + key ); - final Application app = Web.getContext().getApplication(); + final Application app = Web.getWebContext().getApplication(); if (app != null) { String[] returnValue = { app.getApplicationType().getName() }; s_log.debug("Found application >>"+returnValue+"<< in Application."); return returnValue; } - // SiteNodeRequestContext is deprecated and replaced by web.WebContext - // used in the code above (Web.getContext(). - // This code should never be executed. - // Findings: SideNode is requirred for modules which dont use - // legacy-compatible applications but package-type apps. content-center - // and cms-service are 2 examples. Code can be eliminated when all apps - // will use web.Application for loading and instantiation. - // UPDATE - // CMS had been migrated. It is only necessary for the root package, - // which is "Main Site" = acs-subsite which is used by some login - // redirects. s_log.debug("ApplicationType for >>" +key + "<< not found. Trying SiteNodes instead."); throw new IllegalArgumentException( "No ApplicationType found for type name " + key); -/* - SiteNodeRequestContext ctx = (SiteNodeRequestContext) - DispatcherHelper.getRequestContext(req); - - SiteNode node = ctx.getSiteNode(); - - if (node != null) { - String[] returnValue = { - node.getPackageInstance().getType().getKey() - }; - s_log.debug("Found node >>" + returnValue + "<< in SiteNodes."); - return returnValue; - } - - s_log.debug("ApplicationType for " +key + - " could not be found in SiteNodes either. Returning empty String[]"); -*/ -// return new String[] {}; } } diff --git a/ccm-core/src/com/arsdigita/templating/HostPatternGenerator.java b/ccm-core/src/com/arsdigita/templating/HostPatternGenerator.java index 40a7600df..aed3c1114 100755 --- a/ccm-core/src/com/arsdigita/templating/HostPatternGenerator.java +++ b/ccm-core/src/com/arsdigita/templating/HostPatternGenerator.java @@ -28,17 +28,40 @@ import org.apache.log4j.Logger; /** * Generates a set of patterns corresponding to the current - * web application prefix + * host name. (actually just retrieves the current hostname from configuration + * file, StringArray returned is for sake of methods consistency) */ public class HostPatternGenerator implements PatternGenerator { + /** Internal logger instance to faciliate debugging. Enable logging output + * by editing /WEB-INF/conf/log4j.properties int the runtime environment + * and set com.arsdigita.templating.HostPatternGenerator=DEBUG + * by uncommenting or adding the line. */ private static final Logger s_log = - Logger.getLogger(URLPatternGenerator.class); + Logger.getLogger(HostPatternGenerator.class); + /** + * Looks up the hostname from configuration and returns it as String. + * The Return type is (unneccessarily) String[] due to the current API, but + * currently never returns more than just one value (one hostname:port). + * + * @param key placeholder from the pattern string, without surrounding + * colons, constantly "host" here. + * @param req current HttpServletRequest + * @return Hostname (including port if any), retrieved from CCM + * configuration + */ + @Override public String[] generateValues(String key, HttpServletRequest req) { HttpHost host = Web.getConfig().getHost(); - + String hostName = host.toString(); + + if (s_log.isDebugEnabled()) { + s_log.debug("Generating Values for key: " + key + " [" + + "Hostname retrieved: >>" + hostName + "<<]"); + } + return new String[] { host.toString() }; } } diff --git a/ccm-core/src/com/arsdigita/templating/PatternStylesheetResolver.java b/ccm-core/src/com/arsdigita/templating/PatternStylesheetResolver.java index 62d3dc0b9..6c69f93d3 100755 --- a/ccm-core/src/com/arsdigita/templating/PatternStylesheetResolver.java +++ b/ccm-core/src/com/arsdigita/templating/PatternStylesheetResolver.java @@ -94,7 +94,7 @@ import org.apache.log4j.Logger; * * * ::application:: - * Current application name + * Current CCM Application name * navigation * * @@ -145,7 +145,6 @@ import org.apache.log4j.Logger; * and add it in a custom integration package Initializer (e.g. ccm-ldn-aplaws) * by following code: * // Register additional PatternStyleSheetResolver for Web app. - * // With all modules installing in one context no longer required. * PatternStylesheetResolver.registerPatternGenerator( * "[myKey]", * new [My]PatternGenerator() @@ -156,7 +155,10 @@ import org.apache.log4j.Logger; */ public class PatternStylesheetResolver implements StylesheetResolver { - /** Logger instance for debugging. */ + /** Internal logger instance to faciliate debugging. Enable logging output + * by editing /WEB-INF/conf/log4j.properties int the runtime environment + * and set com.arsdigita.templating.PatternStylesheetResolver=DEBUG + * by uncommenting or adding the line. */ private static final Logger s_log = Logger.getLogger (PatternStylesheetResolver.class); @@ -176,6 +178,8 @@ public class PatternStylesheetResolver implements StylesheetResolver { s_generators.put(key, gen); } + /* Statiic initializer block to initialize the standard pattern generators + * at load time. */ static { s_log.debug("Static initalizer starting..."); registerPatternGenerator @@ -195,60 +199,20 @@ public class PatternStylesheetResolver implements StylesheetResolver { s_log.debug("Static initalizer finished."); } + /** Complete path to the file specifing stylesheet patterns. Configurable + * by configuration option in TemplatingConfig */ private String m_path = null; - // This is a List of Lists. + /** A List of Lists each of its lists containing one pattern to resolve + * a probably appropriate stylesheet to apply. (i.e. one row of the + * file m_path above) */ private List m_paths = null; - /** - * - * @param path - */ - private void loadPaths(String path) { - if (s_log.isInfoEnabled()) { - s_log.info("Loading paths from " + path); - } - m_path = path; - try { - // Read the source file. - ClassLoader cload = Thread.currentThread().getContextClassLoader(); - InputStream stream = cload.getResourceAsStream(path.substring(1)); - s_log.debug("got stream using path " + path.substring(1)); - s_log.debug("stream.available is " + stream.available()); - m_paths = new ArrayList(); - - LineNumberReader file = new LineNumberReader - (new InputStreamReader(stream)); - String line; - int lineNum; - while ((line = file.readLine()) != null) { - lineNum = file.getLineNumber(); - // Ignore blank lines and comments. - line = line.trim(); - s_log.debug("line is " + line); - if ("".equals(line) || line.startsWith("#") - || line.startsWith("!") || line.startsWith("//")) { - continue; - } - - // Split up the line. - List list = StringUtils.splitUp(line, "/::\\w+::/"); - // Save the split line. - m_paths.add(list); - } - } catch (IOException ex) { - throw new UncheckedWrapperException( - "cannot read XSLT paths from " + path, ex); - - } catch (Exception e) { - s_log.debug("loadPaths threw exception " + e); - } - } - /** * * @param request * @return */ + @Override public URL resolve(HttpServletRequest request) { synchronized(this) { if (m_paths == null) { @@ -273,10 +237,19 @@ public class PatternStylesheetResolver implements StylesheetResolver { String[] bits = (String[])files.next(); String resource = StringUtils.join(bits, ""); + // UGLY HACK + // If a placeholder returns an empty string (as in the example of + // the root webapp) the provided string contains a "//" as there is + // a slash before as well as after the placeholder in the pattern + // string. It's ugly so we'll replace it. + resource = resource.replace("//","/"); + // The hack destroys the http protocol as well so we need another hack + resource = resource.replace("http:/","http://"); + if (s_log.isInfoEnabled()) { s_log.info("Looking to see if resource " + resource + " exists"); } - //java.net.URL url = Web.findResource(resource); + URL origURL = null; try { origURL = new URL(resource); @@ -289,8 +262,8 @@ public class PatternStylesheetResolver implements StylesheetResolver { s_log.info("origURL is " + origURL); } - final URL xfrmedURL = (origURL == null) ? - null : Templating.transformURL(origURL); + final URL xfrmedURL = (origURL==null) ? null : Templating + .transformURL(origURL); if (s_log.isInfoEnabled()) { s_log.info("Transformed resource is " + xfrmedURL); @@ -303,6 +276,10 @@ public class PatternStylesheetResolver implements StylesheetResolver { } if (is != null) { is.close(); + // xfrmedURL may test for existence either as http request + // or as a file lookup. Anyway we return the original URL + // which used to be a http request. + // Note: we are returning the URL, not the resource! return origURL; } } catch (FileNotFoundException ex) { @@ -311,13 +288,13 @@ public class PatternStylesheetResolver implements StylesheetResolver { } // fall through & try next pattern } catch (IOException ex) { - throw new UncheckedWrapperException( - "cannot open stream " + resource, ex); + throw new UncheckedWrapperException("cannot open stream " + + resource, ex); } } - throw new RuntimeException - ("no path to XSL stylesheet found; " + "try modifying " + m_path); + throw new RuntimeException("no path to XSL stylesheet found; " + + "try modifying " + m_path); } /** @@ -339,20 +316,24 @@ public class PatternStylesheetResolver implements StylesheetResolver { while (!queue.isEmpty()) { String[] bits = (String[])queue.removeFirst(); if (s_log.isDebugEnabled()) { - s_log.debug("Process queue entry " + StringUtils.join(bits, "")); + s_log.debug("Process queue entry " + StringUtils.join(bits, "")); } boolean clean = true; for (int i = 0 ; i < bits.length && clean ; i++) { - if (bits[i].startsWith("::") && - bits[i].endsWith("::")) { + if (bits[i].startsWith("::") && bits[i].endsWith("::")) { clean = false; - String[] vals = getValues( - bits[i].substring(2, bits[i].length() - 2), - values, - request); + String[] vals = getValues(bits[i] + .substring(2, bits[i].length()-2), + values, + request); if (vals != null) { for (int k = 0 ; k < vals.length ; k++) { String[] newBits = new String[bits.length]; + // In case the pattern for an element is an empty + // string (e.g. for the ROOT webapp) the slash before + // as well as after the placeholder are added + // resulting in a "//" which does no harm but is + // ugly. for (int j = 0 ; j < bits.length ; j++) { if (j == i) { newBits[j] = vals[k]; @@ -405,4 +386,50 @@ public class PatternStylesheetResolver implements StylesheetResolver { return vals; } + /** + * + * @param path + */ + private void loadPaths(String path) { + if (s_log.isInfoEnabled()) { + s_log.info("Loading paths from " + path); + } + + m_path = path; + try { + // Read the source file. + ClassLoader cload = Thread.currentThread().getContextClassLoader(); + InputStream stream = cload.getResourceAsStream(path.substring(1)); + s_log.debug("got stream using path " + path.substring(1)); + s_log.debug("stream.available is " + stream.available()); + m_paths = new ArrayList(); + + LineNumberReader file = new LineNumberReader + (new InputStreamReader(stream)); + String line; + int lineNum; + while ((line = file.readLine()) != null) { + lineNum = file.getLineNumber(); + // Ignore blank lines and comments. + line = line.trim(); + s_log.debug("line is " + line); + if ("".equals(line) || line.startsWith("#") + || line.startsWith("!") || line.startsWith("//")) { + continue; + } + + // Split up the line. + List list = StringUtils.splitUp(line, "/::\\w+::/"); + // Save the split line. + m_paths.add(list); + } + } catch (IOException ex) { + throw new UncheckedWrapperException( + "cannot read XSLT paths from " + path, ex); + + } catch (Exception e) { + s_log.debug("loadPaths threw exception " + e); + } + } + } diff --git a/ccm-core/src/com/arsdigita/templating/PrefixPatternGenerator.java b/ccm-core/src/com/arsdigita/templating/PrefixPatternGenerator.java index eac01aaeb..d4ef430d8 100755 --- a/ccm-core/src/com/arsdigita/templating/PrefixPatternGenerator.java +++ b/ccm-core/src/com/arsdigita/templating/PrefixPatternGenerator.java @@ -34,6 +34,7 @@ public class PrefixPatternGenerator implements PatternGenerator { * @param req * @return */ + @Override public String[] generateValues(String key, HttpServletRequest req) { String value = DispatcherHelper.getDispatcherPrefix(req); diff --git a/ccm-core/src/com/arsdigita/templating/SimpleURIResolver.java b/ccm-core/src/com/arsdigita/templating/SimpleURIResolver.java index 482ea49ff..ebf92875f 100755 --- a/ccm-core/src/com/arsdigita/templating/SimpleURIResolver.java +++ b/ccm-core/src/com/arsdigita/templating/SimpleURIResolver.java @@ -35,21 +35,24 @@ import javax.xml.transform.stream.StreamSource; import org.apache.log4j.Logger; /** - * An implementation of the URIResolver interface that keeps track of - * all the URLs that have been loaded. If you set this as the URI - * resolver for a Transformer then this will track all the - * xsl:import and xsl:include statements. + * An implementation of the URIResolver interface that keeps track of all the + * URLs that have been loaded. + * If you set this as the URI resolver for a Transformer then this will track + * all the xsl:import and xsl:include statements. * * @version $Id: SimpleURIResolver.java 287 2005-02-22 00:29:02Z sskracic $ */ final class SimpleURIResolver implements URIResolver { private static final Logger s_log = Logger.getLogger - (SimpleURIResolver.class); + (SimpleURIResolver.class); private final Set m_uniqueStylesheetURIs; private final List m_stylesheetURIs; + /** + * Constructor, just initializes internal properties. + */ public SimpleURIResolver() { m_uniqueStylesheetURIs = new HashSet(); m_stylesheetURIs = new ArrayList(); @@ -70,10 +73,11 @@ final class SimpleURIResolver implements URIResolver { * @param href the url to resolve * @param base the base url to resolve relative to */ + @Override public Source resolve(final String href, final String base) - throws TransformerException { + throws TransformerException { if (s_log.isDebugEnabled()) { - s_log.debug("Resolve " + href + " (" + base + ")"); + s_log.debug("Resolve " + href + " (found in " + base + ")"); } URL baseURL = null; @@ -127,7 +131,10 @@ final class SimpleURIResolver implements URIResolver { // are relative to 'thisURL' return new StreamSource(is, thisURL.toString()); } catch (IOException ex) { - throw new TransformerException(String.format("cannot read stream for %s", thisURL.toString()), ex); + throw new TransformerException( + String.format("cannot read stream for %s", + thisURL.toString()), + ex); } } } diff --git a/ccm-core/src/com/arsdigita/templating/StylesheetResolver.java b/ccm-core/src/com/arsdigita/templating/StylesheetResolver.java index 7821264a8..710eb4ddd 100755 --- a/ccm-core/src/com/arsdigita/templating/StylesheetResolver.java +++ b/ccm-core/src/com/arsdigita/templating/StylesheetResolver.java @@ -34,6 +34,7 @@ public interface StylesheetResolver { * * @param sreq the HttpServletRequest for which to * resolve a template + * @return URL where to try to find a stylesheet */ public URL resolve(HttpServletRequest sreq); } diff --git a/ccm-core/src/com/arsdigita/templating/Templating.java b/ccm-core/src/com/arsdigita/templating/Templating.java index b9b67e2c7..635a095e2 100755 --- a/ccm-core/src/com/arsdigita/templating/Templating.java +++ b/ccm-core/src/com/arsdigita/templating/Templating.java @@ -57,28 +57,34 @@ import org.apache.log4j.Logger; */ public class Templating { + /** Internal logger instance to faciliate debugging. Enable logging output + * by editing /WEB-INF/conf/log4j.properties int hte runtime environment + * and set com.arsdigita.templating.Templating=DEBUG by uncommenting it + * or adding the line. */ private static final Logger s_log = Logger.getLogger(Templating.class); - // just a tag to assure an implementation exists -// public static final Class DEFAULT_PRESENTATION_MANAGER -// = SimplePresentationManager.class; - /** - * This is the name of the attribute that is set in the request whose + + /** This is the name of the attribute that is set in the request whose * value, if present, is a collection of TransformerExceptions that - * can be used to produce a "pretty" error. - */ + * can be used to produce a "pretty" error. */ public static final String FANCY_ERROR_COLLECTION = "fancyErrorCollection"; - // this was instantiated with hardcoded values, not anymore + + /** + * The cache data storage for caching XSL templates. + */ private static CacheTable s_templates = null; - private static final TemplatingConfig s_config = new TemplatingConfig(); + + /** Config object containing various parameter */ + private static final TemplatingConfig s_config = TemplatingConfig + .getInstanceOf(); static { s_log.debug("Static initalizer starting..."); - s_config.load("ccm-core/templating.properties"); Exceptions.registerUnwrapper( TransformerException.class, new ExceptionUnwrapper() { + @Override public Throwable unwrap(Throwable t) { TransformerException ex = (TransformerException) t; return ex.getCause(); @@ -112,11 +118,12 @@ public class Templating { /** * Returns a new instance of the current presentation manager class. This is - * an object which has the {@link com.arsdigita.templating.PresentationManager - * PresentationManager} interface which can be used to transform an XML - * document into an output stream. + * an object which has the + * {@link com.arsdigita.templating.PresentationManager PresentationManager} + * interface which can be used to transform an XML document into an output + * stream. * - * As of v ersion 6.6.0 the bebop framework is the only instance to provide + * As of version 6.6.0 the bebop framework is the only instance to provide * an implementation. To avoid class hierachie kludge we directly return the * bebop config here. * @@ -156,12 +163,12 @@ public class Templating { * * @param source the URL to the top-level template resource * @param fancyErrors Should this place any xsl errors in the request - * for use by another class. If this is true, the - * the errors are stored for later use. + * for use by another class. If this is true, the + * the errors are stored for later use. * @param useCache Should the templates be pulled from cache, if available? - * True means they are pulled from cache. False means - * they are pulled from the disk. If this is false - * the pages are also not placed in the cache. + * True means they are pulled from cache. False means + * they are pulled from the disk. If this is false + * the pages are also not placed in the cache. * @return an XSLTemplate instance representing * source */ @@ -235,7 +242,7 @@ public class Templating { } /** - * Resolves and retrieves the template for the given request. + * Resolves the template for the given request to an URL. * * @param sreq The current request object * @param fancyErrors Should this place any xsl errors in the request @@ -250,10 +257,10 @@ public class Templating { public static XSLTemplate getTemplate(final HttpServletRequest sreq, boolean fancyErrors, boolean useCache) { + Assert.exists(sreq, HttpServletRequest.class); final URL sheet = getConfig().getStylesheetResolver().resolve(sreq); - Assert.exists(sheet, URL.class); return Templating.getTemplate(sheet, fancyErrors, useCache); @@ -296,7 +303,7 @@ public class Templating { * @return a virtual XSL file */ public static InputStream multiplexXSLFiles(Iterator paths) { - StringBuffer buf = new StringBuffer(); + // StringBuilder buf = new StringBuilder(); Element root = new Element("xsl:stylesheet", "http://www.w3.org/1999/XSL/Transform"); root.addAttribute("version", "1.0"); @@ -328,33 +335,75 @@ public class Templating { return new ByteArrayInputStream(doc.toString(true).getBytes()); } - // Transforms a URL, short-circuiting access to the resource - // servlet. This xfrms most http:// urls into file:// allowing - // XSLT invalidation to work for these resources. It has the - // added benefit of speeding up loading of XSL... + /** + * Transforms an URL, that refers to a local resource inside the running + * CCM web application. NON-local URLs remain unmodified. + * + * In case of a virtual path "/resource" it is short-circuiting access to + * the resource servlet. All other http:// URLs are transformed into file:// + * for XSLT validation to work for these resources. It has the added benefit + * of speeding up loading of XSL... + */ static URL transformURL(URL url) { HttpHost self = Web.getConfig().getHost(); - String path = url.getPath(); - if (self.getName().equals(url.getHost()) && ((self.getPort() == url. - getPort()) || (url.getPort() - == -1 - && self. - getPort() - == 80))) { + /** Indicates whether url refers to a local resource inside the + * running CCM web application (inside it's webapp context) */ + Boolean isLocal = false; + /** Contains the transformed "localized" path to url, i.e. without + * host part. */ + String localPath = ""; + + // Check if the url refers to our own host + if (self.getName().equals(url.getHost()) + && ( (self.getPort() == url.getPort()) + || (url.getPort()== -1 && self.getPort()== 80) + ) + ) { + // host part denotes to a local resource, cut off host part. + localPath = url.getPath(); + isLocal = true; + } + // java.net.URL is unaware of JavaEE webapplication. If CCM is not + // installed into the ROOT context, the path includes the webapp part + // which must be removed as well. + // It's a kind of HACK, unfortunately. If CCM is installed into the + // root context we don't detect whether the first part of the path + // refers to another web application inside the host and assume local + // and unrestricted access. The complete code should get refactored to + // use ServletContext#getResource(path) + String installContext = Web.getWebappContextPath(); + if (s_log.isDebugEnabled()) { + s_log.debug("Installation context is >" + installContext + "<."); + } + if (!installContext.equals("")) { + // CCM is installed into a non-ROOT context + if (localPath.startsWith(installContext)) { + // remove webapp context part + localPath = localPath.substring(installContext.length()); + if (s_log.isDebugEnabled()) { + s_log.debug("WebApp context removed: >>" + + localPath + "<<"); + } + } + } + + if (isLocal) { + // url specifies the running CCM host and port (or port isn't + // specified in url and default for running CCM host - if (path.startsWith("/resource")) { - // A virtual path to the servlet - path = path.substring("/resource".length()); - URL newURL = Web.findResource(path); + if (localPath.startsWith("/resource")) { + // A virtual path to the ResourceServlet + localPath = localPath.substring("/resource".length()); //remove virtual part + URL newURL = Web.findResource(localPath); //without host part here! if (s_log.isDebugEnabled()) { s_log.debug("Transforming resource " + url + " to " + newURL); } return newURL; } else { // A real path to disk - final String filename = - Web.getServletContext().getRealPath(path); + final String filename = Web.getServletContext() + .getRealPath(localPath); File file = new File(filename); if (file.exists()) { try { @@ -375,12 +424,14 @@ public class Templating { } } } else { + // url is not the (local) running CCM host, no transformation + // is done if (s_log.isDebugEnabled()) { s_log.debug("URL " + url + " is not local"); } } - return url; + return url; // returns the original, unmodified url here } } @@ -388,7 +439,7 @@ class LoggingErrorListener implements ErrorListener { private static final Logger s_log = Logger.getLogger(LoggingErrorListener.class); - private ArrayList m_errors; + private final ArrayList m_errors; LoggingErrorListener() { m_errors = new ArrayList(); @@ -398,14 +449,17 @@ class LoggingErrorListener implements ErrorListener { return m_errors; } + @Override public void warning(TransformerException e) throws TransformerException { log(Level.WARN, e); } + @Override public void error(TransformerException e) throws TransformerException { log(Level.ERROR, e); } + @Override public void fatalError(TransformerException e) throws TransformerException { log(Level.FATAL, e); } diff --git a/ccm-core/src/com/arsdigita/templating/TemplatingConfig.java b/ccm-core/src/com/arsdigita/templating/TemplatingConfig.java index 926931d7d..20fe4bb60 100755 --- a/ccm-core/src/com/arsdigita/templating/TemplatingConfig.java +++ b/ccm-core/src/com/arsdigita/templating/TemplatingConfig.java @@ -31,9 +31,31 @@ import org.apache.log4j.Logger; */ public final class TemplatingConfig extends AbstractConfig { + /** Internal logger instance to faciliate debugging. Enable logging output + * by editing /WEB-INF/conf/log4j.properties int hte runtime environment + * and set com.arsdigita.templating.TemplatingConfig=DEBUG by uncommenting + * it */ private static final Logger s_log = Logger.getLogger (TemplatingConfig.class); + /** Singelton config object. */ + private static TemplatingConfig s_conf; + /** + * Gain a WorkspaceConfig object. + * + * Singelton pattern, don't instantiate a config object using the + * constructor directly! + * @return + */ + public static synchronized TemplatingConfig getInstanceOf() { + if (s_conf == null) { + s_conf = new TemplatingConfig(); + s_conf.load(); + } + + return s_conf; + } + /** Fully qualified path string to file contain the pattern file for {@link com.arsdigita.templating.PatternStylesheetResolver PatternStylesheetResolver} */ @@ -80,17 +102,20 @@ public final class TemplatingConfig extends AbstractConfig { * Gets the stylesheet resolver. This value is set via the * com.arsdigita.templating.stylesheet_resolver * system property. + * @return */ public final StylesheetResolver getStylesheetResolver() { return (StylesheetResolver) get(m_resolver); } - /** Can be null. */ + /** Can be null. + * @return */ public final Integer getCacheSize() { return (Integer) get(m_cacheSize); } - /** Can be null. */ + /** Can be null. + * @return */ public final Integer getCacheAge() { return (Integer) get(m_cacheAge); } diff --git a/ccm-core/src/com/arsdigita/templating/URLPatternGenerator.java b/ccm-core/src/com/arsdigita/templating/URLPatternGenerator.java index 3275d3eac..5f3841c58 100755 --- a/ccm-core/src/com/arsdigita/templating/URLPatternGenerator.java +++ b/ccm-core/src/com/arsdigita/templating/URLPatternGenerator.java @@ -131,7 +131,7 @@ public class URLPatternGenerator implements PatternGenerator { private String getPath() { String base = getBasePath(); - String url = Web.getContext().getRequestURL().getPathInfo(); + String url = Web.getWebContext().getRequestURL().getPathInfo(); if (s_log.isDebugEnabled()) { s_log.debug("Base is " + base + " url is " + url); @@ -145,16 +145,16 @@ public class URLPatternGenerator implements PatternGenerator { /** * Provides the base URL of the application in the current Web request * (i.e. application's PrimaryURL). If no application can be found or - * no PrimaryURL can be determined ROOT ("/") is returned. - * - * XXX fix me, why can't we get this from Web.getContext().getRequestURL + no PrimaryURL can be determined ROOT ("/") is returned. + + XXX fix me, why can't we get this from Web.getWebContext().getRequestURL * * @return primary url of an application or ROOT */ private String getBasePath() { // retrieve the application of the request - Application app = Web.getContext().getApplication(); + Application app = Web.getWebContext().getApplication(); if (app == null) { return "/"; } else { diff --git a/ccm-core/src/com/arsdigita/templating/WebAppPatternGenerator.java b/ccm-core/src/com/arsdigita/templating/WebAppPatternGenerator.java index 06f6cab50..7c8121e1e 100755 --- a/ccm-core/src/com/arsdigita/templating/WebAppPatternGenerator.java +++ b/ccm-core/src/com/arsdigita/templating/WebAppPatternGenerator.java @@ -33,44 +33,60 @@ import org.apache.log4j.Logger; */ public class WebAppPatternGenerator implements PatternGenerator { - /** Private Logger instance for debugging purpose. */ + /** Internal logger instance to faciliate debugging. Enable logging output + * by editing /WEB-INF/conf/log4j.properties int hte runtime environment + * and set com.arsdigita.templating.WebAppPatternGenerator=DEBUG by + * uncommenting or adding the line. */ private static final Logger s_log = Logger.getLogger(WebAppPatternGenerator.class); + /** + * + * @param key placeholder from the pattern string, without surrounding + * colons, constantly "webapp" here. + * @param req current HttpServletRequest + * @return List of webapps contextPath names in an Array of Strings. + */ + @Override public String[] generateValues(String key, HttpServletRequest req) { - Application app = Web.getContext().getApplication(); - String ctx = app == null ? null : app.getContextPath(); + Application app = Web.getWebContext().getApplication(); + String ctx = (app == null) ? null : app.getContextPath(); + + if (app == null || ctx == null || "".equals(ctx)) { + ctx = Web.getWebappContextPath() ; + } + + // JavaEE requires a leading "/" for web context part, but the pattern + // string already contains a "/", so we have to remove it here to + // too avoid a "//" + if (ctx.startsWith("/")) { + ctx = ctx.substring(1); + } if (s_log.isDebugEnabled()) { s_log.debug("Generating Values key: " + key + " [" + - "Web.getContext(): " + Web.getContext() + "," + - "Application: " + Web.getContext().getApplication() + "," + - "ContextPath: " + ctx + "," + "]"); - } - - if (app == null || ctx == null || "".equals(ctx)) { - return new String[] { Web.ROOT_WEBAPP }; // Currently "ROOT" - } - - if (ctx.startsWith("/")) { - ctx = ctx.substring(1); + "Web.getWebContext(): " + Web.getWebContext() + " ," + + "Application: " + Web.getWebContext().getApplication() + "," + + "ContextPath: >" + ctx + "<]"); } /* "Older version: prior 6.6. Some modules used to be installed into * its own web application context, but needed access to the main - * applications package files (e.g. bebop) which were installed into - * to ROOT web context. Therefore ROOT had to be added. - */ - // return new String[] { ctx + "," + Web.ROOT_WEBAPP }; - - /* As of version 6.6 all packages are installed in one web application - * context, therefore the ROOT entry is no longer valid. + * applications package files (e.g. bebop). Therefore the webapp context + * (ServletContext in API speech) of the main CCM application had to be + * added (which was ROOT by default) + * + * As of version 6.6 all packages are installed in one web application + * context, therefore no additional entry is required. * This variation had first be introduced with the APLAWS integration * package, which used to register an additional WebAppPatternGenerator, * which simply cuts ","+ Web.ROOT_WEBAPP, under a different key * "Webapp" (singular) */ + // return new String[] { ctx + "," + Web.getRootWebappContextPath() }; + + return new String[] { ctx }; } } diff --git a/ccm-core/src/com/arsdigita/templating/XSLParameterGenerator.java b/ccm-core/src/com/arsdigita/templating/XSLParameterGenerator.java index 672cc7069..6d6a45600 100755 --- a/ccm-core/src/com/arsdigita/templating/XSLParameterGenerator.java +++ b/ccm-core/src/com/arsdigita/templating/XSLParameterGenerator.java @@ -34,6 +34,8 @@ public interface XSLParameterGenerator { * This returns the correct value for the parameter. This is the * value that is added to the transformer and is available to all * stylesheets + * @param request + * @return */ public String generateValue(HttpServletRequest request); } diff --git a/ccm-core/src/com/arsdigita/templating/XSLTemplate.java b/ccm-core/src/com/arsdigita/templating/XSLTemplate.java index 1fca9a022..cf97aeaea 100755 --- a/ccm-core/src/com/arsdigita/templating/XSLTemplate.java +++ b/ccm-core/src/com/arsdigita/templating/XSLTemplate.java @@ -58,7 +58,14 @@ import org.w3c.dom.Document; */ public final class XSLTemplate { + /** Internal logger instance to faciliate debugging. Enable logging output + * by editing /WEB-INF/conf/log4j.properties int hte runtime environment + * and set com.arsdigita.templating.XSLTemplate=DEBUG by uncommenting + * or adding the line. */ private static final Logger s_log = Logger.getLogger(XSLTemplate.class); + + /** Property containing the URL to the XSL source file or create this + * instance */ private final URL m_source; private final Templates m_templates; private final List m_dependents; @@ -102,6 +109,11 @@ public final class XSLTemplate { throw new WrappedTransformerException(ex); } + // List contains each include/import URL found in the style sheet + // recursively(!) (i.e. scanning each style sheet whose URL has been + // found in a style sheet, etc. + // In case of Mandalay (single entry stylesheet) about 250 URL's, all + // resolved when found Mandalay's start.xml in one go. m_dependents = resolver.getStylesheetURIs(); m_created = new Date(); } diff --git a/ccm-core/src/com/arsdigita/ui/DebugPanel.java b/ccm-core/src/com/arsdigita/ui/DebugPanel.java index 6e221dab1..48f927d24 100755 --- a/ccm-core/src/com/arsdigita/ui/DebugPanel.java +++ b/ccm-core/src/com/arsdigita/ui/DebugPanel.java @@ -65,7 +65,7 @@ public class DebugPanel extends SimpleComponent { UIConstants.UI_XML_NS); exportAttributes(content); - URL here = Web.getContext().getRequestURL(); + URL here = Web.getWebContext().getRequestURL(); URL xmlURL = selfURL(state, here, "output", "xml"); URL xslURL = selfURL(state, here, "output", "xsl"); diff --git a/ccm-core/src/com/arsdigita/ui/login/UserAuthenticationListener.java b/ccm-core/src/com/arsdigita/ui/login/UserAuthenticationListener.java index e2fada498..9d2469c62 100755 --- a/ccm-core/src/com/arsdigita/ui/login/UserAuthenticationListener.java +++ b/ccm-core/src/com/arsdigita/ui/login/UserAuthenticationListener.java @@ -104,7 +104,7 @@ public class UserAuthenticationListener implements RequestListener { // first make sure we're not already looking at the login // page -- if we are, don't redirect! - if (urlBase.equals(Web.getContext().getRequestURL().getRequestURI())) { + if (urlBase.equals(Web.getWebContext().getRequestURL().getRequestURI())) { s_log.debug("preventing cyclic redirect to: " + urlBase); // return without redirect return; diff --git a/ccm-core/src/com/arsdigita/util/Record.java b/ccm-core/src/com/arsdigita/util/Record.java index cfaf11cf1..9caf74c2a 100755 --- a/ccm-core/src/com/arsdigita/util/Record.java +++ b/ccm-core/src/com/arsdigita/util/Record.java @@ -28,6 +28,10 @@ import org.apache.log4j.Logger; */ public abstract class Record { + /** Internal logger instance to faciliate debugging. Enable logging output + * by editing /WEB-INF/conf/log4j.properties int the runtime environment + * and set com.arsdigita.util.Record=DEBUG + * by uncommenting or adding the line. */ private static final Logger s_log = Logger.getLogger(Record.class); private Class m_class; diff --git a/ccm-core/src/com/arsdigita/util/ResourceManager.java b/ccm-core/src/com/arsdigita/util/ResourceManager.java index 224f065d2..0bc0fc9c6 100755 --- a/ccm-core/src/com/arsdigita/util/ResourceManager.java +++ b/ccm-core/src/com/arsdigita/util/ResourceManager.java @@ -71,8 +71,8 @@ public class ResourceManager { /** * Returns a new InputStream object reading the URL argument. - * Behaves similarly to ServletContext.getResourceAsStream(), - * reading pathnames relative to the webapp root. + * Behaves similarly to ServletContext.getResourceAsStream(), reading + * pathnames relative to the webapp root. * * @param url a URL interpreted as a pathname relative to the webapp root * @return a new input stream reading the named file, or null @@ -81,12 +81,14 @@ public class ResourceManager { * not configured prior to use. */ public InputStream getResourceAsStream(String url) { + if (m_webappRoot == null && m_servletContext == null) { throw new IllegalStateException(CONFIGURE_MESSAGE); } if (StringUtils.emptyString(url)) { throw new IllegalArgumentException("URL is empty: " + url); } + if (m_servletContext != null) { // If we have a Servlet Context, use it. InputStream is = m_servletContext.getResourceAsStream(url); @@ -212,6 +214,7 @@ public class ResourceManager { /** * Returns the last-modified time for the file on disk. * + * @param path * @return the last-modified time for the file on disk. Returns * 0L if this isn't available (within a WAR file, for example), * the file isn't found, or there's an I/O error. This is consistent diff --git a/ccm-core/src/com/arsdigita/web/Application.java b/ccm-core/src/com/arsdigita/web/Application.java index e4e48d245..6447587aa 100755 --- a/ccm-core/src/com/arsdigita/web/Application.java +++ b/ccm-core/src/com/arsdigita/web/Application.java @@ -615,6 +615,10 @@ public class Application extends Resource { return canonicalURL; } + /** + * + * @return + */ public String getContextPath() { return ""; } @@ -663,7 +667,7 @@ public class Application extends Resource { @Override protected void beforeSave() { if (isPropertyModified(PRIMARY_URL) || isNew()) { - BaseDispatcher.scheduleRefresh(); + CCMDispatcherServlet.scheduleRefresh(); } super.beforeSave(); @@ -687,7 +691,7 @@ public class Application extends Resource { */ @Override public void afterDelete() { - BaseDispatcher.scheduleRefresh(); + CCMDispatcherServlet.scheduleRefresh(); } /** diff --git a/ccm-core/src/com/arsdigita/web/ApplicationFileServlet.java b/ccm-core/src/com/arsdigita/web/ApplicationFileServlet.java index 3f6bda791..4326a6aea 100755 --- a/ccm-core/src/com/arsdigita/web/ApplicationFileServlet.java +++ b/ccm-core/src/com/arsdigita/web/ApplicationFileServlet.java @@ -68,14 +68,14 @@ import org.apache.log4j.Logger; * In the Application class it should define: *

*
- *  public String getContextPath() {
- *     return "ccm-mywebapp";
- *  }
- * 
- *  public String getServletPath() {
- *    return "/files";
- *  }
- * 
+ public String getWebContextPath() { + return "ccm-mywebapp"; + } + + public String getServletPath() { + return "/files"; + } + *

* It can then put JSP files in a 'templates/ccm-mywebapp' directory at * the root of its private webapp. Files in this directory can be scoped by diff --git a/ccm-core/src/com/arsdigita/web/BaseApplicationServlet.java b/ccm-core/src/com/arsdigita/web/BaseApplicationServlet.java index d4ac4430e..be3381919 100755 --- a/ccm-core/src/com/arsdigita/web/BaseApplicationServlet.java +++ b/ccm-core/src/com/arsdigita/web/BaseApplicationServlet.java @@ -106,7 +106,7 @@ public abstract class BaseApplicationServlet extends BaseServlet { throw new IllegalStateException("Application not found"); } - Web.getContext().setApplication(app); + Web.getWebContext().setApplication(app); final RequestContext rc = makeLegacyContext (sreq, app, Web.getUserContext()); diff --git a/ccm-core/src/com/arsdigita/web/BaseDispatcher.java b/ccm-core/src/com/arsdigita/web/BaseDispatcher.java.nolongerInUse similarity index 100% rename from ccm-core/src/com/arsdigita/web/BaseDispatcher.java rename to ccm-core/src/com/arsdigita/web/BaseDispatcher.java.nolongerInUse diff --git a/ccm-core/src/com/arsdigita/web/BaseFilter.java b/ccm-core/src/com/arsdigita/web/BaseFilter.java index f621767c0..bf7624112 100755 --- a/ccm-core/src/com/arsdigita/web/BaseFilter.java +++ b/ccm-core/src/com/arsdigita/web/BaseFilter.java @@ -35,39 +35,43 @@ import org.apache.log4j.Logger; /** - * A base class for filters that require a persistence - * session to be present. This implements the doFilter - * method to open up a default persistence session, and - * then hand off to the doService method. Subclasses - * should override this doService method to provide the - * processing they require. + * A base class for filters that require a persistence session to be present. + * This implements the doFilter method to open up a default persistence session, + * and then hand off to the doService method. Subclasses should override this + * doService method to provide the processing they require. * - * Assumes a initialized database connection and domain - * coupling machinery (provided by CCMApplicationListener - * during container startup). + * Assumes an initialized database connection and domain coupling machinery + * (provided by CCMApplicationListener during container startup). * * Actually, the class does nothing at all! */ public class BaseFilter implements Filter { - private static Logger s_log = Logger.getLogger(BaseFilter.class); + /** Internal logger instance to faciliate debugging. Enable logging output + * by editing /WEB-INF/conf/log4j.properties int the runtime environment + * and set com.arsdigita.web.BaseFilter=DEBUG + * by uncommenting or adding the line. */ + private static final Logger s_log = Logger.getLogger(BaseFilter.class); /** - * + * Initialization code, introduces an extension point for subclasses. * @param sconfig * @throws javax.servlet.ServletException */ + @Override public final void init(final FilterConfig sconfig) throws ServletException { if (s_log.isInfoEnabled()) { s_log.info("Initializing filter " + sconfig.getFilterName() + " (class: " + getClass().getName() + ")"); } + // extension point for subclasses doInit(); } /** - * + * Initialization extension stub. Subclasses should overwrite this method + * to add functionality as required. * @throws javax.servlet.ServletException */ protected void doInit() throws ServletException { @@ -75,8 +79,9 @@ public class BaseFilter implements Filter { } /** - * + * Shutdown code, introduces an extension point for subclasses. */ + @Override public final void destroy() { if (s_log.isInfoEnabled()) { s_log.info @@ -87,7 +92,8 @@ public class BaseFilter implements Filter { } /** - * + * Shutdown extension stub. Subclasses should overwrite this method + * to add functionality as required and properly stopp services. */ protected void doDestroy() { // Empty @@ -101,6 +107,7 @@ public class BaseFilter implements Filter { * @throws java.io.IOException * @throws javax.servlet.ServletException */ + @Override public void doFilter(ServletRequest sreq, ServletResponse sresp, FilterChain chain) @@ -118,6 +125,11 @@ public class BaseFilter implements Filter { /** * This is the extension point for users of this class. + * @param sreq + * @param sresp + * @param chain + * @throws javax.servlet.ServletException + * @throws java.io.IOException */ protected void doService(final HttpServletRequest sreq, final HttpServletResponse sresp, diff --git a/ccm-core/src/com/arsdigita/web/BaseJSP.java b/ccm-core/src/com/arsdigita/web/BaseJSP.java index 64f1296e5..d4b9edfcc 100755 --- a/ccm-core/src/com/arsdigita/web/BaseJSP.java +++ b/ccm-core/src/com/arsdigita/web/BaseJSP.java @@ -34,7 +34,7 @@ import org.apache.log4j.Logger; * *

  * <%@page extends="com.arsdigita.web.BaseJSP" %>
- * <%= Web.getContext().getUser().toString() %>
+ * <%= Web.getWebContext().getUser().toString() %>
  * 
* * @see com.arsdigita.web.BaseServlet @@ -43,13 +43,18 @@ import org.apache.log4j.Logger; */ public abstract class BaseJSP extends BaseServlet implements HttpJspPage { - /** A logger instance, primarily to assist debugging . */ - private static Logger s_log = Logger.getLogger(BaseJSP.class); + /** Internal logger instance to faciliate debugging. Enable logging output + * by editing /WEB-INF/conf/log4j.properties int the runtime environment + * and set com.arsdigita.web.BaseJSP=DEBUG + * by uncommenting or adding the line. */ + private static final Logger s_log = Logger.getLogger(BaseJSP.class); /** *

Invokes the _jspService(sreq, sresp) method in * the environment prepared by BaseServlet.

* + * @throws javax.servlet.ServletException + * @throws java.io.IOException * @see #_jspService(HttpServletRequest,HttpServletResponse) * @see com.arsdigita.web.BaseServlet * @see com.arsdigita.web.BaseServlet#doService(HttpServletRequest,HttpServletResponse) @@ -86,16 +91,23 @@ public abstract class BaseJSP extends BaseServlet implements HttpJspPage { *

The method that JSP compilers will override to produce the * body of the page.

* + * @param sreq + * @param sresp + * @throws javax.servlet.ServletException + * @throws java.io.IOException * @see javax.servlet.jsp.HttpJspPage#_jspService(HttpServletRequest,HttpServletResponse) */ + @Override public abstract void _jspService(HttpServletRequest sreq, HttpServletResponse sresp) throws ServletException, IOException; + @Override public void jspInit() { } + @Override public void jspDestroy() { } diff --git a/ccm-core/src/com/arsdigita/web/BaseServlet.java b/ccm-core/src/com/arsdigita/web/BaseServlet.java index 4a11f5f38..46f1ac9a5 100755 --- a/ccm-core/src/com/arsdigita/web/BaseServlet.java +++ b/ccm-core/src/com/arsdigita/web/BaseServlet.java @@ -48,9 +48,9 @@ import org.apache.log4j.Logger; * Note: Database initialization (Startup() ) has been moved to * CCMApplicationContextListener). * - *

Users of this class may implement {@link - * #doService(HttpServletRequest,HttpServletResponse)} to service a - * request in this environment.

+ *

Users of this class may implement + * {@link #doService(HttpServletRequest,HttpServletResponse)} + * to service a request in this environment.

* * @see com.arsdigita.web.BaseApplicationServlet * @see com.arsdigita.web.BaseJSP @@ -60,10 +60,10 @@ import org.apache.log4j.Logger; */ public abstract class BaseServlet extends HttpServlet { - private static Logger s_log = Logger.getLogger(BaseServlet.class); + private static final Logger s_log = Logger.getLogger(BaseServlet.class); /** The name of the request attribute used to store the originally - * requested URL. */ + * requested URL. */ public static final String REQUEST_URL_ATTRIBUTE = BaseServlet.class.getName() + ".request_url"; @@ -71,7 +71,10 @@ public abstract class BaseServlet extends HttpServlet { * Initializer uses parent class's initializer to setup the servlet request / * response and application context. Usually a user of this class will not * overwrite this method but the user extension point doInit to perform - * local initialization tasks. + * local initialization tasks! + * + * @param sconfig + * @throws javax.servlet.ServletException */ @Override public void init(final ServletConfig sconfig) throws ServletException { @@ -140,7 +143,7 @@ public abstract class BaseServlet extends HttpServlet { final UserContext uc = getUserContext(sreq, sresp); Web.init(sreq, getServletContext(), uc); - Web.getContext().setRequestURL(getRequestURL(sreq)); + Web.getWebContext().setRequestURL(getRequestURL(sreq)); final ServletException[] servletException = { null }; final IOException[] ioException = { null }; @@ -161,7 +164,7 @@ public abstract class BaseServlet extends HttpServlet { s_log.debug("Finished preparing the context for " + "this request"); s_log.debug("Current state of WebContext:\n" + - Web.getContext().getCurrentState()); + Web.getWebContext().getCurrentState()); s_log.debug(Kernel.getContext().getDebugInfo()); } @@ -248,6 +251,11 @@ public abstract class BaseServlet extends HttpServlet { * #doGet(HttpServletRequest,HttpServletResponse)} and {@link * #doPost(HttpServletRequest,HttpServletResponse)} call. This is * the extension point for users of this class.

+ * + * @param sreq + * @param sresp + * @throws javax.servlet.ServletException + * @throws java.io.IOException */ protected void doService(final HttpServletRequest sreq, final HttpServletResponse sresp) diff --git a/ccm-core/src/com/arsdigita/web/CCMDispatcherServlet.java b/ccm-core/src/com/arsdigita/web/CCMDispatcherServlet.java new file mode 100755 index 000000000..03b5eeaca --- /dev/null +++ b/ccm-core/src/com/arsdigita/web/CCMDispatcherServlet.java @@ -0,0 +1,567 @@ +/* + * Copyright (C) 2002-2004 Red Hat Inc. All Rights Reserved. + * Copyright (C) 2014 Peter Boy, Bremen University All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.web; + +import com.arsdigita.developersupport.DeveloperSupport; +import com.arsdigita.dispatcher.DispatcherHelper; +import com.arsdigita.dispatcher.RequestEvent; +import com.arsdigita.domain.DataObjectNotFoundException; +import com.arsdigita.persistence.SessionManager; +import com.arsdigita.persistence.TransactionContext; +import com.arsdigita.profiler.Profiler; +import com.arsdigita.util.Assert; +import com.arsdigita.util.StringUtils; + +import java.io.IOException; +import java.math.BigDecimal; + +import javax.servlet.ServletException; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + + +// NOTE +// Combines and replaces the classes DispatcherServlet and BaseDispatcher + + +/** + *

The CCM main dispatcher. This servlet serves as the main servlet / main + * entry point (mapped to "/someprefix/*") for requests to any CCM webapp.

+ * + *

Upon finding an {@link com.arsdigita.web.Application application} at the + * requested URL, this class sets a request attribute storing the ID of the + * application and forwards to the servlet associated with that application. + * If instead no application is found, a 404 response is generated.

+ * + *

This servlet has to be deployed using web.xml entries like these:

+ * + *
+ * <servlet>
+ *   <servlet-name>ccm-dispatcher</servlet-name>
+ *   <servlet-class>com.arsdigita.web.CCMDispatcherServlet</servlet-class>
+ * </servlet>
+ *
+ * <servlet-mapping>
+ *   <servlet-name>ccm-dispatcher</servlet-name>
+ *   <url-pattern>/ccm/*</url-pattern>
+ * </servlet-mapping>
+ * 
+ * + *

It's important to also edit the com.arsdigita.web.WebConfig m_servlet + * parameter to reflect where you've put your dispatcher.

+ * + *
+ * com.arsdigita.web.WebConfig:
+ *     ...
+ *      m_context = new StringParameter
+ *          ("waf.web.dispatcher_context_path", Parameter.REQUIRED, "");
+ *      m_servlet = new StringParameter
+ *          ("waf.web.dispatcher_servlet_path", Parameter.REQUIRED, "/ccm");
+ *     ...
+ * 
+ * + * @see com.arsdigita.web.BaseApplicationServlet + * @author Justin Ross <jross@redhat.com> + * @author Peter Boy <Peter Boy> + * @version $Id: DispatcherServlet.java 738 2005-09-01 12:36:52Z sskracic $ + */ +public class CCMDispatcherServlet extends BaseServlet { + + /** Internal logger instance to faciliate debugging. Enable logging output + * by editing /WEB-INF/conf/log4j.properties int hte runtime environment + * and set com.arsdigita.web.CCMDispatcherServlet=DEBUG by uncommenting + * or adding the line. */ + private static final Logger s_log = Logger.getLogger(CCMDispatcherServlet.class); + + static final String DISPATCHED_ATTRIBUTE = + CCMDispatcherServlet.class.getName() + ".dispatched"; + + /** Instance of the private Cache class */ + private final static Cache s_cache = new Cache(); + + /** String containing the web context path portion of the WEB application + * where this CCMDispatcherServlet is executed. (I.e. where the WEB-INF + * directory containing the web.xml configuring this CCMDispatcherServlet + * is located in the servlet container webapps directory. + * */ + private static String s_contextPath; + + public final boolean isApplicationInCache(String path) { + return s_cache.isCached(path); + } + + + /** + * Servlet initializer uses the extension point of parent class. + * @throws ServletException + */ + @Override + public void doInit() throws ServletException { + + ServletContext servletContext = getServletContext(); + s_contextPath = servletContext.getContextPath(); + // For backwords compatibility reasons register the web application + // context of the Core (root) application als "/" + Web.registerServletContext("/", + servletContext); + + } + + /** + * Extends the standard service() method of the parent BaseServlet class. + * Looks up and identifies the web application addressed in the url and + * forwards to that application's ApplicationServlet. + * (new style legacy free) + * + * @param sreq + * @param sresp + * @throws ServletException + * @throws IOException + */ + @Override + protected void doService(final HttpServletRequest sreq, + final HttpServletResponse sresp) + throws ServletException, IOException { + + DeveloperSupport.requestStart(new RequestEvent(sreq, sresp, + null, true, false)); + if (s_log.isDebugEnabled()) { + s_log.debug("Dispatching request " + sreq.getRequestURI() + " [" + + sreq.getContextPath() + "," + + sreq.getServletPath() + "," + + sreq.getPathInfo() + "," + + sreq.getQueryString() + "]"); + } + DeveloperSupport.startStage("CCMDispatcherServlet.doService"); + + + final String path = sreq.getPathInfo(); + + if (requiresTrailingSlash(path)) { + s_log.debug("The request URI needs a trailing slash; " + + "redirecting"); + + final String prefix = DispatcherHelper.getDispatcherPrefix(sreq); + String uri = sreq.getRequestURI(); + if (prefix != null && prefix.trim().length() > 0) { + uri = prefix + uri; + } + final String query = sreq.getQueryString(); + + String url = null; + + if (query == null) { + sresp.sendRedirect(sresp.encodeRedirectURL(uri + "/")); + } else { + sresp.sendRedirect + (sresp.encodeRedirectURL(uri + "/?" + query)); + } + + // return true; + } else { + + Assert.exists(path, String.class); + + s_log.debug("Storing the path elements of the current request as " + + "the original path elements"); + + sreq.setAttribute(BaseServlet.REQUEST_URL_ATTRIBUTE, new URL(sreq)); + + if (s_log.isDebugEnabled()) { + s_log.debug("Using path '" + path + "' to lookup application"); + } + + DeveloperSupport.startStage("CCMDispatcherServlet.lookupApplicationSpec"); + + final ApplicationSpec spec = lookupApplicationSpec(path); + + DeveloperSupport.endStage("CCMDispatcherServlet.lookupApplicationSpec"); + + if (spec == null) { + s_log.debug("No application was found; doing nothing"); + // return false; + // we have to create a 404 page here! + String requestUri = sreq.getRequestURI(); // same as ctx.getRemainingURLPart() + sresp.sendError(404, requestUri + " not found on this server."); + } else { + if (s_log.isDebugEnabled()) { + s_log.debug("Found application " + spec.getAppID() + "; " + + "dispatching to its servlet"); + } + + sreq.setAttribute + (BaseApplicationServlet.APPLICATION_ID_ATTRIBUTE, + spec.getAppID()); + sreq.setAttribute(DISPATCHED_ATTRIBUTE, Boolean.TRUE); + Profiler.startOp("APP"); // +spec.getAppID() XXX get app name? + forward(spec.getTypeContextPath(), spec.target(path), sreq, sresp); + Profiler.stopOp("APP"); // +spec.getAppID() + // return true; + } + + } + + DeveloperSupport.endStage("CCMDispatcherServlet.doService"); + + } + + + /** + * + * @param path + * @return + */ + private boolean requiresTrailingSlash(final String path) { + if (s_log.isDebugEnabled()) { + s_log.debug("Checking if this request needs a trailing slash"); + } + + if (path == null) { + s_log.debug("The path is null; the request needs a trailing " + + "slash"); + return true; + } + + if (path.endsWith("/")) { + s_log.debug("The path already ends in '/'"); + return false; + } + + if (path.lastIndexOf(".") < path.lastIndexOf("/")) { + s_log.debug("The last fragment of the path has no '.', so we " + + "assume a directory was requested; a trailing " + + "slash is required"); + return true; + } else { + s_log.debug("The last fragment of the path appears to be a file " + + "name; no trailing slash is needed"); + return false; + } + } + + /** + * + * @param contextPath + * @param target + * @param sreq + * @param sresp + * @throws ServletException + * @throws IOException + */ + private void forward(String contextPath, + final String target, + final HttpServletRequest sreq, + final HttpServletResponse sresp) + throws ServletException, IOException { + + if (s_log.isDebugEnabled()) { + s_log.debug("Forwarding by path to target '" + target + "'"); + } + s_log.debug("The context path is: " + contextPath); + if (StringUtils.emptyString(contextPath)) { + contextPath = "/"; + } + if (!contextPath.endsWith("/")) { + contextPath = contextPath + "/"; + } + // XXX We should pass servlet context down + final ServletContext context = Web.getServletContext(contextPath); + + if (s_log.isDebugEnabled()) { + s_log.debug("From context " + Web.getServletContext() + + " to context " + context); + } + + final RequestDispatcher rd = context.getRequestDispatcher(target); + + Assert.exists(rd, RequestDispatcher.class); + + forward(rd, sreq, sresp); + } + + /** + * + * @param rd + * @param sreq + * @param sresp + * @throws ServletException + * @throws IOException + */ + final void forward(final RequestDispatcher rd, + HttpServletRequest sreq, + final HttpServletResponse sresp) + throws ServletException, IOException { + s_log.debug("Checking if this request needs to be forwarded or " + + "included " + sreq); + + sreq = DispatcherHelper.restoreOriginalRequest(sreq); + + if (sreq.getAttribute("javax.servlet.include.request_uri") == null) { + s_log.debug("The attribute javax.servlet.include.request_uri " + + "is not set; forwarding " + sreq); + + rd.forward(sreq, sresp); + } else { + s_log.debug("The attribute javax.servlet.include.request_uri " + + "is set; including " + sreq); + + rd.include(sreq, sresp); + } + } + + /** + * + * @param path + * @return + */ + private ApplicationSpec lookupApplicationSpec(final String path) { + if (s_log.isDebugEnabled()) { + s_log.debug("*** Starting application lookup for path '" + + path + "' ***"); + } + + ApplicationSpec spec = s_cache.getAppSpec(path); + + if ( spec == null ) { + s_log.debug("There's no application to be found"); + } + return spec; + } + + /** + * + */ + static void scheduleRefresh() { + s_cache.scheduleRefresh(); + } + + public static String getContextPath() { + return s_contextPath; + } + + /** + * + */ + /* Nothing specifically to destroy here + @Override + protected void doDestroy() { + } + */ + + + + /** + * + */ + private static class ApplicationSpec { + private final BigDecimal m_id; + private final String m_instanceURI; + private final String m_typeURI; + private final String m_typeContextPath; + + /** + * + * @param app + */ + ApplicationSpec(Application app) { + if ( app == null ) { throw new NullPointerException("app"); } + + m_id = app.getID(); + m_instanceURI = app.getPath(); + m_typeURI = app.getServletPath(); + m_typeContextPath = app.getContextPath(); + + if (Assert.isEnabled()) { + Assert.exists(m_id, BigDecimal.class); + Assert.exists(m_instanceURI, String.class); + Assert.exists(m_typeURI, String.class); + Assert.exists(m_typeContextPath, String.class); + } + } + + /** + * + * @return + */ + BigDecimal getAppID() { return m_id; } + + /** + * + * @return + */ + String getTypeContextPath() { return m_typeContextPath; } + + /** + * + * @param path + * @return + */ + String target(final String path) { + if (s_log.isDebugEnabled()) { + s_log.debug("Building the target path from the request path '" + + path + "' and the spec " + this); + } + + final StringBuffer target = new StringBuffer(128); + + target.append(m_typeURI); + target.append(path.substring(m_instanceURI.length())); + target.append("?"); + target.append(BaseApplicationServlet.APPLICATION_ID_PARAMETER); + target.append("="); + target.append(m_id); + + if (s_log.isDebugEnabled()) { + s_log.debug("Returning target value '" + target + "'"); + } + + return target.toString(); + } + + /** + * + * @param obj + * @return + */ + @Override + public boolean equals(Object obj) { + if ( obj==null ) { return false; } + + ApplicationSpec other = (ApplicationSpec) obj; + return m_id.equals(other.m_id) && + equal(m_instanceURI, other.m_instanceURI) && + equal(m_typeURI, other.m_typeURI) && + equal(m_typeContextPath, other.m_typeContextPath); + + } + + /** + * + * @param s1 + * @param s2 + * @return + */ + private boolean equal(String s1, String s2) { + if (s1==s2) { return true; } + if (s1==null) { return equal(s2, s1); } + return s1.equals(s2); + } + + /** + * + * @return + */ + @Override + public int hashCode() { + return toString().hashCode(); + } + + /** + * + * @return + */ + @Override + public String toString() { + final String sep = ", "; + StringBuffer sb = new StringBuffer(); + sb.append("["); + sb.append("appID=").append(m_id).append(sep); + sb.append("instanceURI=").append(m_instanceURI).append(sep); + sb.append("typeURI=").append(m_typeURI).append(sep); + sb.append("typeContextPath=").append(m_typeContextPath); + return sb.append("]").toString(); + } + } + + + + /** + * Private class Cache caches (path, AppSpec) mappings. + */ + private static class Cache extends PathMapCache { + + private static final ThreadLocal s_handleHere = new ThreadLocal() { + @Override + protected Object initialValue() { + return Boolean.FALSE; + } + }; + + public Cache() { + super("BaseDispatcherCache"); + } + + // implements the PathMapCache interface + @Override + public String normalize(String path) { + if ( path==null ) { throw new NullPointerException("path"); } + if ( !path.startsWith("/") ) { + throw new DataObjectNotFoundException + ("The URL path specified must begin with a '/'."); + } + return path.endsWith("/") ? + path : path.substring(0, path.lastIndexOf('/') + 1); + } + + // implements the PathMapCache interface + @Override + public Object retrieve(String path) { + if ( "/".equals(path) ) { return null; } + + final TransactionContext context = + SessionManager.getSession().getTransactionContext(); + if ( !context.inTxn() ) { + s_log.debug("Beginning transaction"); + context.beginTxn(); + s_handleHere.set(Boolean.TRUE); + } + + Application app = Application.retrieveApplicationForPath(path); + + return app==null ? null : new ApplicationSpec(app); + } + + // implements the PathMapCache interface + @Override + public void refresh() { + s_cache.clearAll(); + } + + void scheduleRefresh() { + refreshAfterCommit(); + } + + synchronized ApplicationSpec getAppSpec(String path) { + try { + return (ApplicationSpec) super.get(path); + } finally { + if ( s_handleHere.get() == Boolean.TRUE ) { + s_handleHere.set(Boolean.FALSE); + SessionManager.getSession().getTransactionContext(). + commitTxn(); + } + } + } + } +} diff --git a/ccm-core/src/com/arsdigita/web/ContextRegistrationServlet.java b/ccm-core/src/com/arsdigita/web/ContextRegistrationServlet.java index b714240da..23ff21027 100755 --- a/ccm-core/src/com/arsdigita/web/ContextRegistrationServlet.java +++ b/ccm-core/src/com/arsdigita/web/ContextRegistrationServlet.java @@ -26,11 +26,11 @@ import javax.servlet.ServletException; /** *

- * Every application running in its own webapp should - * declare an instance of this servlet in their web.xml, - * marking it to load on startup. This is a work around - * for bz 114688 - Tomcat ServletContext#getContext(String) - * always returns the ROOT context in releases < 4.1.20 + Every application running in its own webapp should + declare an instance of this servlet in their web.xml, + marking it to load on startup. This is a work around + for bz 114688 - Tomcat ServletContext#getWebContext(String) + always returns the ROOT context in releases < 4.1.20 * Map into your web.xml as follows: *

*
@@ -56,6 +56,10 @@ import javax.servlet.ServletException;
  */
 public class ContextRegistrationServlet extends HttpServlet {
     
+    /**
+     * The uri on an application, manually configured as servlet parameter in
+     * web.xml
+     */
     private String m_uri;
 
     @Override
@@ -65,6 +69,14 @@ public class ContextRegistrationServlet extends HttpServlet {
         Assert.isTrue(m_uri.startsWith("/"), "uri starts with /");
         Assert.isTrue(m_uri.endsWith("/"), "uri ends with /");
 
+        /*
+         * Registers this web application providing
+         * (a) m_uri = this web application context as configured in web.xml
+         * (b) sconfig.getServletContext = this servlet's context object, 
+         *     bypassing a bug in early versions of tomcat (see above). Because
+         *     getServletContext is retrieved by the ContextRegistrationServlet
+         *     loaded first it is not affected by the bug.
+         */
         Web.registerServletContext(m_uri,
                                    sconfig.getServletContext());
     }
diff --git a/ccm-core/src/com/arsdigita/web/DefaultApplicationFileResolver.java b/ccm-core/src/com/arsdigita/web/DefaultApplicationFileResolver.java
index 9a752f168..4f8229bf0 100755
--- a/ccm-core/src/com/arsdigita/web/DefaultApplicationFileResolver.java
+++ b/ccm-core/src/com/arsdigita/web/DefaultApplicationFileResolver.java
@@ -42,6 +42,7 @@ public class DefaultApplicationFileResolver implements ApplicationFileResolver {
      * @param app
      * @return
      */
+    @Override
     public RequestDispatcher resolve(String templatePath,
                                      HttpServletRequest sreq,
                                      HttpServletResponse sresp,
diff --git a/ccm-core/src/com/arsdigita/web/DispatcherServlet.java b/ccm-core/src/com/arsdigita/web/DispatcherServlet.java.nolongerInUse
similarity index 93%
rename from ccm-core/src/com/arsdigita/web/DispatcherServlet.java
rename to ccm-core/src/com/arsdigita/web/DispatcherServlet.java.nolongerInUse
index 4d165f0ff..1b4194421 100755
--- a/ccm-core/src/com/arsdigita/web/DispatcherServlet.java
+++ b/ccm-core/src/com/arsdigita/web/DispatcherServlet.java.nolongerInUse
@@ -29,9 +29,8 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.log4j.Logger;
 
 /**
- * 

The CCM main dispatcher. This servlet serves as the main - * servlet (mapped to "/someprefix/*") for requests to the CCM - * webapp.

+ *

The CCM main dispatcher. This servlet serves as the main servlet + * (mapped to "/someprefix/*") for requests to any CCM webapp.

* *

Upon finding an {@link com.arsdigita.web.Application application} at the * requested URL, this class sets a request attribute storing the ID of the @@ -39,8 +38,7 @@ import org.apache.log4j.Logger; * application is found, the request is forwarded to the fallback servlet, * if defined.

* - *

This servlet may be deployed using web.xml entries like - * these:

+ *

This servlet has to be deployed using web.xml entries like these:

* *
  * <servlet>
@@ -130,9 +128,7 @@ public class DispatcherServlet extends BaseServlet {
             s_log.debug("Successfully dispatched to an application");
         } else {
             s_log.debug("Could not dispatch this request to an " +
-                        "application;  sending 404");
-            
-            sresp.sendError(HttpServletResponse.SC_NOT_FOUND);
+                        "application;  using the fallback servlet");
 /*
             sreq.setAttribute(FALLING_BACK_ATTRIBUTE, Boolean.TRUE);
 
@@ -145,8 +141,6 @@ public class DispatcherServlet extends BaseServlet {
             m_dispatcher.forward(fallbackDispatcher, sreq, sresp);
 
             DeveloperSupport.endStage("BaseDispatcher.forward");
-            
-            
 */   
         }
     }
diff --git a/ccm-core/src/com/arsdigita/web/InternalPrefixerServlet.java b/ccm-core/src/com/arsdigita/web/InternalPrefixerServlet.java
index f390ea13f..5a664803c 100755
--- a/ccm-core/src/com/arsdigita/web/InternalPrefixerServlet.java
+++ b/ccm-core/src/com/arsdigita/web/InternalPrefixerServlet.java
@@ -56,10 +56,12 @@ import org.apache.log4j.Logger;
  * </servlet-mapping>
  * 
* - * The above entry, in conjunction with a set of stylesheets - * that producedtext only output, would enable a text only - * part of the site with a /textonly/ URL prefix. + * The above entry, in conjunction with a set of stylesheets that produced + * text only output, would enable a text only part of the site with a /textonly/ + * URL prefix. * + * Today you will most likely use CSS capabilities to achieve that. The code is + * retained just in case it is of good use nevertheless. */ public class InternalPrefixerServlet extends HttpServlet { diff --git a/ccm-core/src/com/arsdigita/web/ResourceServlet.java b/ccm-core/src/com/arsdigita/web/ResourceServlet.java index d2b42e18e..b6341e362 100755 --- a/ccm-core/src/com/arsdigita/web/ResourceServlet.java +++ b/ccm-core/src/com/arsdigita/web/ResourceServlet.java @@ -32,10 +32,9 @@ import org.apache.log4j.Logger; /** - * A servlet that maps the ResourceManager#findResource - * method into the http:// URL space. This enables negotiated - * resolution of resources across webapps. For example, a request - * to: + * A servlet that maps the ResourceManager#findResource method into the + * http:// URL space. This enables negotiated resolution of resources + * across webapps. For example, a request to: *
  *   http://www.example.com/resource/myproj,ccm-cms,ROOT/packages/bebop/xsl/bebop.xsl
  * 
@@ -48,6 +47,10 @@ import org.apache.log4j.Logger; */ public class ResourceServlet extends BaseServlet { + /** Internal logger instance to faciliate debugging. Enable logging output + * by editing /WEB-INF/conf/log4j.properties int hte runtime environment + * and set com.arsdigita.web.ResourceServlet=DEBUG by + * uncommenting or adding the line. */ private static final Logger s_log = Logger.getLogger(ResourceServlet.class); @@ -61,7 +64,7 @@ public class ResourceServlet extends BaseServlet { @Override protected void doService(HttpServletRequest sreq, HttpServletResponse sresp) - throws ServletException, IOException { + throws ServletException, IOException { String path = sreq.getPathInfo(); InputStream stream = Web.findResourceAsStream(path); diff --git a/ccm-core/src/com/arsdigita/web/URL.java b/ccm-core/src/com/arsdigita/web/URL.java index b105210cd..72ea2a064 100755 --- a/ccm-core/src/com/arsdigita/web/URL.java +++ b/ccm-core/src/com/arsdigita/web/URL.java @@ -50,7 +50,7 @@ import org.apache.log4j.Logger; * getScheme() -> "http" * getServerName() -> "example.com" * getServerPort() -> 8080 - * getContextPath() -> "/ccmapp" + getWebContextPath() -> "/ccmapp" * getServletPath() -> "/forum" * getPathInfo() -> "/index.jsp" * getParameter("cat") -> "2" @@ -501,8 +501,8 @@ public class URL { * "/ccm/forum/thread.jsp".

* *

This method is defined to return the equivalent of - * getContextPath() + getServletPath() + - * getPathInfo().

+ * getWebContextPath() + getServletPath() + + getPathInfo().

* * @see javax.servlet.http.HttpServletRequest#getRequestURI() * @return a String comprised of the context path, @@ -623,7 +623,7 @@ public class URL { params.runListeners(sreq); } - final URL url = Web.getContext().getRequestURL(); + final URL url = Web.getWebContext().getRequestURL(); if (url == null) { // If the URL is being generated outside of a WebContext, @@ -841,7 +841,7 @@ public class URL { public static final URL here(final HttpServletRequest sreq, final String pathInfo, final ParameterMap params) { - final Application app = Web.getContext().getApplication(); + final Application app = Web.getWebContext().getApplication(); Assert.exists(app, "Application app"); @@ -850,7 +850,7 @@ public class URL { public static final URL here(final HttpServletRequest sreq, final String pathInfo) { - final Application app = Web.getContext().getApplication(); + final Application app = Web.getWebContext().getApplication(); Assert.exists(app, "Application app"); @@ -866,7 +866,7 @@ public class URL { final URL url = URL.there(sreq, path, params); - params.setParameter("return_url", Web.getContext().getRequestURL()); + params.setParameter("return_url", Web.getWebContext().getRequestURL()); return url; } diff --git a/ccm-core/src/com/arsdigita/web/Web.java b/ccm-core/src/com/arsdigita/web/Web.java index f61db7965..35b53d10a 100755 --- a/ccm-core/src/com/arsdigita/web/Web.java +++ b/ccm-core/src/com/arsdigita/web/Web.java @@ -45,9 +45,13 @@ import org.apache.log4j.Logger; */ public class Web { + /** Internal logger instance to faciliate debugging. Enable logging output + * by editing /WEB-INF/conf/log4j.properties int the runtime environment + * and set com.arsdigita.web.Web=DEBUG + * by uncommenting or adding the line. */ private static final Logger s_log = Logger.getLogger(Web.class); - public static final String ROOT_WEBAPP = "ROOT"; + private static WebConfig s_config = WebConfig.getInstanceOf(); private static final ThreadLocal s_request = new InternalRequestLocal(); @@ -55,13 +59,14 @@ public class Web { new InternalRequestLocal(); private static final ThreadLocal s_userContext = new InternalRequestLocal(); - - private static final Map s_contexts = new HashMap(); - - static final WebContext s_initialContext = new WebContext(); private static ThreadLocal s_context; - private static WebConfig s_config; + static final WebContext s_initialContext = new WebContext(); + + /** String containing the webapp context path portion of the WEB application + * where this CCM instance is executed. (I.e. where the WEB-INF directory + * is located in the servlet container webapps directory. */ + private static String s_contextPath; /** * @@ -76,35 +81,32 @@ public class Web { s_request.set(sreq); s_servletContext.set(sc); + s_contextPath = CCMDispatcherServlet.getContextPath(); s_userContext.set(uc); } + /** + * Provide the configuration record for code in the web package. + * + * @return A WebConfig configuration record; it + * cannot be null + */ + public static WebConfig getConfig() { + return s_config; + } + /** * Gets the web context object from the current thread. * * @return A WebContext object; it cannot be null */ - public static WebContext getContext() { + public static WebContext getWebContext() { if (s_context == null) { s_context = new WebContextLocal(); } return (WebContext) s_context.get(); } - /** - * Gets the configuration record for code in the web package. - * - * @return A WebConfig configuration record; it - * cannot be null - */ - public static WebConfig getConfig() { - if (s_config == null) { - s_config = new WebConfig(); - s_config.require("ccm-core/web.properties"); - } - return s_config; - } - /** * Gets the servlet request object of the current thread. * @@ -126,41 +128,30 @@ public class Web { } /** - * Gets the servlet context matching a URI. The URI - * is relative to the root of the server and must start - * and end with a '/'. + * Gets the webapp context path portion of the WEB application where this + * CCM instance is executed. (I.e. where the WEB-INF directory is located + * in the servlet container webapps directory, known as ServletContext in + * the Servlet API) * - * This should be used in preference to ServletContext#getContext(String) - * since on all versions of Tomcat, this fails if the path of the - * context requested is below the current context. - * @param uri the context URI - * @return the servlet context matching uri, or null + * @return web context path portion as a String, may be used to construct + * a URL (NOT the RealPath!). The ROOT context returns an empty + * String(""). */ - public static ServletContext getServletContext(String uri) { - Assert.isTrue(uri.startsWith("/"), "uri must start with /"); - Assert.isTrue(uri.endsWith("/"), "uri must end with /"); - return (ServletContext)s_contexts.get(uri); + public static String getWebappContextPath() { + return (String) s_contextPath; } /** - * Registers a servlet context against a URI. Only intended - * to be used by ContextRegistrationServlet + * Sets the webapp context path portion of the WEB application where this + * CCM instance is executed. (I.e. where the WEB-INF directory is located + * in the servlet container webapps directory, known as ServletContext in + * the Servlet API) + * Meant to be executed by CCMDispatcherServlet only. + * + * @param contextPath */ - static final void registerServletContext(String uri, - ServletContext ctx) { - s_log.debug("Mapping " + ctx + " to " + uri); - Assert.isTrue(s_contexts.get(uri) == null, - "a context mapping exists at " + uri); - s_contexts.put(uri, ctx); - } - - /** - * Unregisters the servlet context against a URI. Only intended - * to be used by ContextRegistrationServlet - */ - static final void unregisterServletContext(String uri) { - s_log.debug("Unmapping " + uri); - s_contexts.remove(uri); + protected static void setWebappContextPath(String contextPath) { + s_contextPath = contextPath; } /** @@ -174,37 +165,306 @@ public class Web { } /** - * Finds a concrete URL corresponding to an abstract - * webapp resource. The format of the resource is - * as follows: "/[webapp list]/[path]". The 'webapp - * list' component is a comma separate list of webapps - * to search for the second component 'path'. So, if the - * 'resource' is: - *
-     *  /myproj,ccm-cms,ROOT/themes/heirloom/apps/content-section/index.sl
-     * 
- * then this method will look for resources at - *
-     *  /myproj/themes/heirloom/apps/content-section/index.sl
-     *  /ccm-cms/themes/heirloom/apps/content-section/index.sl
-     *  /ROOT/themes/heirloom/apps/content-section/index.sl
-     * 
- * @param resource the resource name - * @return the URL for the resource, or null + * Processes an URL String trying to identify a corresponding recource + * which is mapped to the given path String. The resource may be stored at + * various sources (file system, jar file, database, etc) depending on the + * implementation of the URL handlers and URLConnection objects. + * + * + * @param resource Path to the resource as String. It may include the + * web context in its first part or may be relative to the + * current webapp document root (i.e. its context). + * Additionally, it the web application component (if any) + * may be a comma separate list of webapps to search for the + * rest of the path String. + * So, if the 'resource' is: + *
+     *                 /myproj,ccm-cms/themes/heirloom/admin/index.xsl
+     *                 
+ * then this method will look for resources at + *
+     *                 /myproj/themes/heirloom/admin/index.xsl
+     *                 /ccm-cms/themes/heirloom/admin/index.xsl
+     *                 
+ * + * @return the URL for the resource, or null if no resource is mapped to + * to the resource String */ public static URL findResource(String resource) { - ResourceSpec spec = parseResource(resource); - return findResource(spec.getWebapps(), - spec.getPath()); + if (resource == null) { + if (s_log.isDebugEnabled()) { + s_log.debug("Parameter resource is null. Giving up."); + } + return null; + } + // ensure a leading "/" + if (!resource.startsWith("/")) { + resource = "/" + resource; + } + if (resource.length() < 2) { + if (s_log.isDebugEnabled()) { + s_log.debug("Resource spec is too short: >" + resource + "<"); + } + return null; + } + + // determine my own webapp context + ServletContext myctx = getServletContext(); + + // Check for old style resource format including a comma seoarated list + // of webapps + if(resource.indexOf(",") <= 0 ) { + // no comma separated list found, process as normal + + // just try to find the resource in my own context + try { + URL url = myctx.getResource(resource); + if (url != null) { + if (s_log.isDebugEnabled()) { + s_log.debug("Got URL " + url + " for " + resource); + } + return url; // Return adjusted resource url + } + } catch (IOException ex) { + if (s_log.isDebugEnabled()) { + s_log.debug("Cannot get resource for " + resource); + } + int offset = resource.indexOf("/", 1); // search for second "/" + String testPath = resource.substring(1, offset); + String path = resource.substring(offset); + + if (s_log.isDebugEnabled()) { + s_log.debug("Try to find a context at " + testPath); + } + ServletContext ctx = myctx.getContext(testPath); + if (s_log.isDebugEnabled()) { + s_log.debug("Servlet context for " + testPath + + " is " + ctx); + } + if (ctx != null) { + try { + URL url = ctx.getResource(path); + if (url != null) { + if (s_log.isDebugEnabled()) { + s_log.debug("Got URL " + url + + " for " + path); + } + return url; // Return adjusted resource url + } else { + if (s_log.isDebugEnabled()) { + s_log.debug("No URL present for " + path); + } + } + } catch(IOException exc) { + if (s_log.isDebugEnabled()) { + s_log.debug("cannot get resource for " + path); + } + } + } + } + + return null; // fall through + + } else { + // comma separated list found + // processing old style, comma separated webapp list + int offset = resource.indexOf("/", 1); // search for second "/" + String webappList = resource.substring(1, offset); + String path = resource.substring(offset); + + String[] webapps = StringUtils.split(webappList, ','); + if (s_log.isDebugEnabled()) { + s_log.debug("Web app list " + webappList + " path " + path); + } + + for (int i = (webapps.length - 1) ; i >= 0 ; i--) { + + String ctxPath = webapps[i]; + if (!ctxPath.startsWith("/")) { + ctxPath = "/" + ctxPath; + } + // No trailing slash allowed by servlet API! + // if (!ctxPath.endsWith("/")) { + // ctxPath = ctxPath + "/"; + // } + + ServletContext ctx = myctx.getContext(ctxPath); + if (s_log.isDebugEnabled()) { + s_log.debug("Servlet context for " + ctxPath + + " is " + ctx); + } + if (ctx != null) { + try { + URL url = ctx.getResource(path); + if (url != null) { + if (s_log.isDebugEnabled()) { + s_log.debug("Got URL " + url + + " for " + path); + } + return url; // Return adjusted resource url + } else { + if (s_log.isDebugEnabled()) { + s_log.debug("No URL present for " + path); + } + } + } catch(IOException ex) { + if (s_log.isDebugEnabled()) { + s_log.debug("cannot get resource for " + path); + } + } + } + + } + + return null; // fall through when nothing found + } // end processing old style comma separated list + } + + /** + * Follows the same rules as findResource(String[], String), but instead + * returns an input stream for reading the resource + * @param resource Path to the resource as String. It may include the + * web context in its first part or may be relative to the + * current webapp document root (i.e. its context). + * Additionally, it the web application component (if any) + * may be a comma separate list of webapps to search for the + * rest of the path String. + * So, if the 'resource' is: + *
+     *                 /myproj,ccm-cms/themes/heirloom/admin/index.xsl
+     *                 
+ * then this method will look for resources at + *
+     *                 /myproj/themes/heirloom/admin/index.xsl
+     *                 /ccm-cms/themes/heirloom/admin/index.xsl
+     *                 
+ * + * @return the input stream for the resource, or null + * @throws java.io.IOException + */ + public static InputStream findResourceAsStream(String resource) + throws IOException { + + URL url = findResource(resource); + return url == null ? null : url.openStream(); } /** - * Finds a concrete URL corresponding to an abstract - * webapp resource. The first argument is a list of - * webapp paths to search through for the path. So - * if the webapps param is { 'myproj', 'ccm-cms', 'ROOT' } - * and the path parma is '/themes/heirloom/apps/content-section/index.xsl' + * Follows the same rules as findResource(String), but + * instead returns a request dispatcher for serving + * the resource + * + * @param resource the resource name + * @return the request dispatcher for the resource, or null + */ + public static RequestDispatcher findResourceDispatcher(String resource) { + + ResourceSpec spec = parseResource(resource); + + return findResourceDispatcher(spec.getWebapps(), + spec.getPath()); + } + + + + // /////////////////////////////////////////////////////////////////////// + // + // DEPRECATED METHODS + // ================== + // This method assume the main ccm application installed in the hosts root + // context and somme other ccm applications installed in its own context. + // It assumes futher that each ccm applications registers itself in a + // home made application directory and it is viable to query this + // directory to find the context for a given ccm application. + // + // /////////////////////////////////////////////////////////////////////// + + + /** Constant to denote the context of the ROOT application (main CCM app). + * Used by some classes to determine the application context (in terms of + * servlet specification, i.e. document root of the web application where + * all the code, specifically WEB-INF, is copied into when unpacking the + * WAR file. + * + * This results in a fixed location (context) for CCM which is no longer + * valid. Replace by invoking method getWebappContextPath + * + * @deprecated without direct replacement. See above + */ + private static final String ROOT_WEBAPP = "ROOT"; + + + /** Map containing a list of registered ccm webapps and corresponding + * webapp context (ServletContext in JavaEE terms). + * + * @deprecated without direct replacement, see above. + */ + private static final Map s_contexts = new HashMap(); + + + /** + * Gets the servlet context matching the provided URI. The URI + * is relative to the root of the server and must start + * and end with a '/'. It is provided by ContextRegistrationServlet as + * manually configured in web.xml + * + * This should be used in preference to ServletContext#getWebContext(String) + * since on all versions of Tomcat, this fails if the path of the + * context requested is below the current context. + * @param uri the context URI + * @return the servlet context matching uri, or null + * @deprecated currently without direct replacement + * The hash map s_contexts contains a kind of repository where + * (i.e. in which web application context) a resource may be + * found. Part of the code access the file system directly which + * is normally forbidden and violates the principle of isolation + * Previously it has been used to allow the installation of some + * modules in its own web application context (e.g. Themedirector) + * where each module used to register here via + * ContextRegistrationServlet. + * This mechanism has to be replaced by a inter-web-application + * communication, if modules should be enabled to execute in it's + * web application context. + * + */ + public static ServletContext getServletContext(String uri) { + Assert.isTrue(uri.startsWith("/"), "uri must start with /"); + Assert.isTrue(uri.endsWith("/"), "uri must end with /"); + return (ServletContext)s_contexts.get(uri); + } + + /** + * Registers a servlet context against a URI. Only intended + * to be used by ContextRegistrationServlet + * @deprecated without direct replacement. See getServletContext + */ + static final void registerServletContext(String uri, + ServletContext ctx) { + s_log.debug("Mapping " + ctx + " to " + uri); + Assert.isTrue(s_contexts.get(uri) == null, + "a context mapping exists at " + uri); + // Save the web context as manually configured in web.xml + // along with the context as provided by ServletContext. + s_contexts.put(uri, ctx); + } + + /** + * Unregisters the servlet context against a URI. Only intended + * to be used by ContextRegistrationServlet + * @deprecated without direct replacement. See getServletContext + */ + static final void unregisterServletContext(String uri) { + s_log.debug("Unmapping " + uri); + s_contexts.remove(uri); + } + + + /** + * Finds a concrete URL corresponding to an abstract webapp resource. + * The first argument is a list of webapp paths to search through for the + * path. So if the webapps param is { 'myproj', 'ccm-cms', 'ROOT' } and + * the path parma is '/themes/heirloom/apps/content-section/index.xsl' * then the paths that are searched are: *
      *  /myproj/themes/heirloom/apps/content-section/index.sl
@@ -214,9 +474,11 @@ public class Web {
      * @param webapps the list of webapps
      * @param path the resource path
      * @return the URL for the resource, or null
+     * @deprecated without direct replacement at the moment. 
      */
     public static URL findResource(String[] webapps,
                                    String path) {
+        
         ServletContext ctx = findResourceContext(webapps,
                                                  path);
         
@@ -240,14 +502,15 @@ public class Web {
      * resource
      * @param resource the resource name
      * @return the input stream for the resource, or null
+     * @deprecated without direct replacement at the moment. 
      */
-    public static InputStream findResourceAsStream(String resource) 
-        throws IOException {
-        ResourceSpec spec = parseResource(resource);
-
-        return findResourceAsStream(spec.getWebapps(),
-                                    spec.getPath());
-    }
+//  public static InputStream findResourceAsStream(String resource) 
+//      throws IOException {
+//      ResourceSpec spec = parseResource(resource);
+//
+//      return findResourceAsStream(spec.getWebapps(),
+//                                  spec.getPath());
+//  }
 
     /**
      * Follows the same rules as findResource(String[], String), but
@@ -256,16 +519,17 @@ public class Web {
      * @param webapps the list of webapps
      * @param path the resource path
      * @return the input stream for the resource, or null
+     * @deprecated without direct replacement at the moment. 
      */
-    public static InputStream findResourceAsStream(String[] webapps,
-                                                   String path)
-        throws IOException {
-
-        URL url = findResource(webapps, path);
-        
-        return url == null ? null :
-            url.openStream();
-    }
+//  public static InputStream findResourceAsStream(String[] webapps,
+//                                                 String path)
+//      throws IOException {
+//
+//      URL url = findResource(webapps, path);
+//        
+//      return url == null ? null :
+//          url.openStream();
+//  }
 
 
     /**
@@ -275,13 +539,14 @@ public class Web {
      *
      * @param resource the resource name
      * @return the request dispatcher for the resource, or null
+     * @deprecated without direct replacement at the moment. 
      */
-    public static RequestDispatcher findResourceDispatcher(String resource) {
-        ResourceSpec spec = parseResource(resource);
-        
-        return findResourceDispatcher(spec.getWebapps(),
-                                      spec.getPath());
-    }
+//  public static RequestDispatcher findResourceDispatcher(String resource) {
+//      ResourceSpec spec = parseResource(resource);
+//        
+//      return findResourceDispatcher(spec.getWebapps(),
+//                                    spec.getPath());
+//  }
 
     /**
      * Follows the same rules as findResource(String[], String), but
@@ -291,6 +556,7 @@ public class Web {
      * @param webapps the list of webapps
      * @param path the resource path
      * @return the request dispatcher for the resource, or null
+     * @deprecated without direct replacement at the moment. 
      */
     public static RequestDispatcher findResourceDispatcher(String[] webapps,
                                                            String path) {
@@ -301,17 +567,34 @@ public class Web {
     }
 
 
+    /**
+     * 
+     * @param webapps
+     * @param path  path to the resource, starting with "/" and relative to the 
+     *              current context root, or relative to the /META-INF/resources 
+     *              directory of a JAR file inside the web application's 
+     *              /WEB-INF/lib directory
+     * @return 
+     * @deprecated without direct replacement at the moment. 
+     */
     private static ServletContext findResourceContext(String[] webapps,
                                                       String path) {
         for (int i = (webapps.length - 1) ; i >= 0 ; i--) {
+
+            // trash here, depends of a kind of "home made" list of 
+            // webapps/webcontexts (or ServletContexts) which are part of CCM
+            // but installed in its own context (it is the structure of APLAWS
+            // until 1.0.4. 
             String ctxPath = ROOT_WEBAPP.equals(webapps[i]) ? 
                 "" : webapps[i];
+
             if (!ctxPath.startsWith("/")) {
                 ctxPath = "/" + ctxPath;
             }
             if (!ctxPath.endsWith("/")) {
                 ctxPath = ctxPath + "/";
             }
+
             ServletContext ctx = getServletContext(ctxPath);
             if (s_log.isDebugEnabled()) {
                 s_log.debug("Servlet context for " + ctxPath + " is " + ctx);
@@ -340,13 +623,34 @@ public class Web {
     }
 
 
-    //
+    // /////////////////////////////////////////////////////////////////////////
     // Private classes and methods
-    //
+    // /////////////////////////////////////////////////////////////////////////
 
+    
+    /**
+     * Splits the resource string into a StringArray of webapps (ServletContexts
+     * in terms of JavaEE) and a path to a resource inside a the that webapp.
+     * The part between the first and the second slash is always treated as
+     * webapp part! This part may consist of a comma separated list in which case
+     * the result is an array of webapps > 1.
+     * 
+     * As of version 6.6x CCM is installed into one webapp context by default
+     * and the assumption of the first part being a web app is nolonger
+     * reloiable. Therefore this routine provides invalid results in some 
+     * circumstances! In best cases it provides redundancy specifying just the
+     * local webapp.
+     * 
+     * Code may be refactored to ensure the first part is really a webapp by
+     * inquiring the servlet container using javax.management
+     * 
+     * @param resource
+     * @return
+     * @deprecated without direct replacement. 
+     */
     private static ResourceSpec parseResource(String resource) {
-        if (resource == null ||
-            resource.length() < 2) {
+
+        if (resource == null || resource.length() < 2) {
             throw new IllegalArgumentException(
                 "Resource spec is too short: " + resource);
         }
@@ -369,10 +673,23 @@ public class Web {
         return new ResourceSpec(webapps, path);
     }
 
+
+    /**
+     * Container to hold a pointer to a resource. The pointer specifically
+     * consists of an array of webapps probably containing the requested
+     * resource and a path to that resource that has to be equal for each 
+     * webapp.
+     * @deprecated without direct replacement at the moment. 
+     */
     private static class ResourceSpec {
-        private String[] m_webapps;
-        private String m_path;
+        private final String[] m_webapps;
+        private final String m_path;
             
+        /**
+         * Constructor. 
+         * @param webapps
+         * @param path 
+         */
         public ResourceSpec(String[] webapps,
                             String path) {
             m_webapps = webapps;
@@ -388,7 +705,11 @@ public class Web {
         }
     }
 
+    /**
+     * 
+     */
     private static class WebContextLocal extends InternalRequestLocal {
+        
         @Override
         protected Object initialValue() {
             return Web.s_initialContext.copy();
diff --git a/ccm-core/src/com/arsdigita/web/WebConfig.java b/ccm-core/src/com/arsdigita/web/WebConfig.java
index 0f3514530..f95e80e77 100755
--- a/ccm-core/src/com/arsdigita/web/WebConfig.java
+++ b/ccm-core/src/com/arsdigita/web/WebConfig.java
@@ -48,14 +48,40 @@ import org.apache.log4j.Logger;
  */
 public final class WebConfig extends AbstractConfig {
 
+    /** Internal logger instance to faciliate debugging. Enable logging output
+     *  by editing /WEB-INF/conf/log4j.properties int the runtime environment
+     *  and set com.arsdigita.web.WebConfig=DEBUG by uncommenting it  */
     private static final Logger s_log = Logger.getLogger(WebConfig.class);
+    
+	/** Private Object to hold one's own instance to return to users.   	 */
+    private static WebConfig s_config ;
+    
+	/**
+	 * Returns the singleton configuration record for the content section
+	 * environment.
+	 *
+	 * @return The CMSConfig record; it cannot be null
+	 */
+   public static synchronized WebConfig getInstanceOf() {
+		if (s_config == null) {
+			s_config = new WebConfig();
+			s_config.load();
+		}
 
+		return s_config;
+       
+   }    
+
+   // /////////////////////////////////////////////////////////////////////////
+   // Configuration parameter section
+   // /////////////////////////////////////////////////////////////////////////
+   
     private final Parameter m_scheme;
     private final Parameter m_server;
     private final Parameter m_secureServer;
     private final Parameter m_host;
     private final Parameter m_site;
-    private final Parameter m_context;
+    // private final Parameter m_context;
     private final Parameter m_servlet;
     private final Parameter m_policy;
     private final Parameter m_resolver;
@@ -64,6 +90,11 @@ public final class WebConfig extends AbstractConfig {
     private final Parameter m_secureRequired;
     private final Parameter m_secureSwitchBack;
 
+	/**
+	 * Constructor, but do NOT instantiate this class directly, use 
+     * getInstanceOf() instead. (Singelton pattern!)
+	 *
+	 */
     public WebConfig() {
         
         m_scheme = new DefaultSchemeParameter
@@ -96,9 +127,13 @@ public final class WebConfig extends AbstractConfig {
                 }
             };
 
-        m_context = new StringParameter
-            ("waf.web.dispatcher_context_path", Parameter.REQUIRED, "");
+   //  NO LONGER configured by configuration option but determined at runtime
+   //  by CCMDispatcherServlet itself.
+   //  // dispatcherContextPath option in old Initializer, set to ""
+   //   m_context = new StringParameter
+   //       ("waf.web.dispatcher_context_path", Parameter.REQUIRED, "");
 
+        // dispatcherServletPath option in old Initializer, set to "/ccm"
         m_servlet = new StringParameter
             ("waf.web.dispatcher_servlet_path", Parameter.REQUIRED, "/ccm");
 
@@ -127,7 +162,7 @@ public final class WebConfig extends AbstractConfig {
         register(m_secureServer);
         register(m_host);
         register(m_site);
-        register(m_context);
+        // register(m_context);
         register(m_servlet);
         register(m_policy);
         register(m_resolver);
@@ -187,8 +222,15 @@ public final class WebConfig extends AbstractConfig {
         return (String) get(m_site);
     }
 
+    /**
+     * 
+     * @return
+     * @deprecated use Web.getContextPath() instead. The installation context
+     *             must no longer manually configured
+     */
     public final String getDispatcherContextPath() {
-        return (String) get(m_context);
+        // return (String) get(m_context);
+        return CCMDispatcherServlet.getContextPath();
     }
 
     public final String getDispatcherServletPath() {
diff --git a/ccm-core/src/com/arsdigita/web/WebContext.java b/ccm-core/src/com/arsdigita/web/WebContext.java
index cf9e0c1f9..0d628bb91 100755
--- a/ccm-core/src/com/arsdigita/web/WebContext.java
+++ b/ccm-core/src/com/arsdigita/web/WebContext.java
@@ -39,7 +39,10 @@ import org.apache.log4j.Logger;
  */
 public final class WebContext extends Record {
 
-    /** Logger instance for debugging */
+    /** Internal logger instance to faciliate debugging. Enable logging output
+     *  by editing /WEB-INF/conf/log4j.properties int the runtime environment
+     *  and set com.arsdigita.web.WebContext=DEBUG 
+     *  by uncommenting or adding the line.                                                   */
     private static final Logger s_log = Logger.getLogger(WebContext.class);
 
     private Application m_application = null;
diff --git a/ccm-core/src/log4j.properties b/ccm-core/src/log4j.properties
index 052d33f8d..8e5aa9e2d 100755
--- a/ccm-core/src/log4j.properties
+++ b/ccm-core/src/log4j.properties
@@ -26,160 +26,55 @@ log4j.appender.console=org.apache.log4j.ConsoleAppender
 #log4j.appender.syslog.Facility=local5
 #log4j.appender.syslog.SyslogHost=loghost.example.com
 
+
 # Change logger priorities below here:
 
+# ==========================
+# Widely used logging output
+# ==========================
 # For seeing progress of container startup process
 log4j.logger.com.arsdigita.web.CCMApplicationContextListener=INFO
 
 # For seeing progress of main runtime initialization process
-log4j.logger.com.arsdigita.runtime.CCMResourceManager=INFO
-log4j.logger.com.arsdigita.runtime.Runtime=INFO
+#log4j.logger.com.arsdigita.runtime.CCMResourceManager=INFO
+#log4j.logger.com.arsdigita.runtime.Runtime=INFO
 
-log4j.logger.com.arsdigita.bundle.Loader=INFO
+#log4j.logger.com.arsdigita.bundle.Loader=INFO
 
 # For seeing progress of the 'ccm load' command
-log4j.logger.com.arsdigita.packaging.Loader=INFO
-# log4j.logger.com.arsdigita.core.Loader=INFO
-# log4j.logger.com.arsdigita.loader.CoreLoader=INFO
-# log4j.logger.com.arsdigita.core.Initializer=INFO
-# log4j.logger.com.arsdigita.cms.Loader=INFO
-# log4j.logger.com.arsdigita.cms.Initializer=INFO
- log4j.logger.com.arsdigita.forum.Loader=INFO
+#log4j.logger.com.arsdigita.packaging.Loader=INFO
+#log4j.logger.com.arsdigita.core.Loader=INFO
+#log4j.logger.com.arsdigita.loader.CoreLoader=INFO
+#log4j.logger.com.arsdigita.core.Initializer=INFO
+#log4j.logger.com.arsdigita.cms.Loader=INFO
+#log4j.logger.com.arsdigita.cms.Initializer=INFO
+#log4j.logger.com.arsdigita.forum.Loader=INFO
 
-# For seeing progress of legacy initialization process
-#log4j.logger.com.arsdigita.initializer.Script=INFO
 
+# ================================================
+# CORE classes
+# ================================================
+
+# Package redhat.persistence
+# ==========================
+# For debugging all queries run by persistence
+#log4j.logger.com.redhat.persistence.engine.rdbms.RDBMSEngine=INFO
+
+# Package templating
+# ==================
 # For debuging XSLT file resolution
-#log4j.logger.com.arsdigita.templating.PatternStylesheetResolver=INFO
+log4j.logger.com.arsdigita.templating.PatternStylesheetResolver=DEBUG
+log4j.logger.com.arsdigita.templating.PatternStylesheetResolver=DEBUG
 
+
+# Package web
+# ===========
 # For debugging the general dispatcher process:
-#log4j.logger.com.arsdigita.web.BaseDispatcher=DEBUG
 #log4j.logger.com.arsdigita.web.BaseServlet=DEBUG
-#log4j.logger.com.arsdigita.web.DispatcherServlet=DEBUG
+log4j.logger.com.arsdigita.web.CCMDispatcherServlet=DEBUG
 
 # For debugging the JSP file dispatcher
 #log4j.logger.com.arsdigita.web.ApplicationFileServlet=DEBUG
 #log4j.logger.com.arsdigita.web.DefaultApplicationFileResolver=DEBUG
 
-# For debugging all queries run by persistence
-#log4j.logger.com.redhat.persistence.engine.rdbms.RDBMSEngine=INFO
-
-#log4j.logger.com.arsdigita.cms.search.ContentPageMetadataProvider=DEBUG
-#log4j.logger.com.arsdigita.london.importer=DEBUG
-#log4j.logger.com.arsdigita.london.terms.importer.TermItemBuilder=DEBUG
-#log4j.logger.com.arsdigita.categorization.Category=DEBUG
-
-#For debugging static initalizer blocks (static {})
-#com.arsdigita.auth.http.HTTPAuth=DEBUG
-#com.arsdigita.auth.http.HTTPAuthConfig=DEBUG
-#com.arsdigita.auth.http.HTTPLoginModule=DEBUG
-#com.arsdigita.cms.dispatcher.SimpleXMLGenerator=DEBUG
-#com.arsdigita.cms.contenttypes.GenericAddress=DEBUG
-#com.arsdigita.cms.contenttypes.GenericContact=DEBUG
-#com.arsdigita.cms.publishtofile.LinkScanner=DEBUG
-#com.arsdigita.cms.ui.type.TypeElements=DEBUG
-#com.arsdigita.cms.ui.item.ItemLanguagesTable=DEBUG
-#com.arsdigita.cms.ui.templates.ItemTemplateListing=DEBUG
-#com.arsdigita.cms.ui.folder.FolderBrowser=DEBUG
-#com.arsdigita.cms.ui.authoring.TextAssetBody=DEBUG
-#com.arsdigita.cms.ContentSection=DEBUG
-#com.arsdigita.cms.CMS=DEBUG
-#com.arsdigita.cms.Loader=DEBUG
-#com.arsdigita.cms.Template=DEBUG
-#com.arsdigita.cms.Initalizer=DEBUG
-#com.arsdigita.cms.contentassets.FileAttachment=DEBUG
-#com.arsdigita.cms.contentassets.ItemImageAttachment=DEBUG
-#com.arsdigita.cms.contentassets.Note=DEBUG
-#com.arsdigita.cms.contentassets.ui=RelatedLinkPropertyForm=DEBUG
-#com.arsdigita.cms.contenttypes.Event=DEBUG
-#com.arsdigita.cms.contenttypes.GenericOrganization=DEBUG
-#com.arsdigita.cms.contenttypes.GlossaryItem=DEBUG
-#com.arsdigita.cms.contenttypes.HealthCareFacility=DEBUG
-#com.arsdigita.cms.contenttypes.MultiPartArticle=DEBUG
-#com.arsdigita.cms.contenttypes.NewsItem=DEBUG
-#com.arsdigita.cms.contenttypes.SimpleAddress=DEBUG
-#com.arsdigita.cms.dispatcherSiteProxyPanel=DEBUG
-#com.arsdigita.cms.contenttypes.Survey=DEBUG
-#com.arsdigita.kernel.security.KernelLoginException=DEBUG
-#com.arsdigita.kernel.security.URLLoginModule=DEBUG
-#com.arsdigita.kernel.security.Crypto=DEBUG
-#com.arsdigita.profiler.Profiler=DEBUG
-#com.arsdigita.categorization.Category=DEBUG
-#com.arsdigita.developersupport.#Comodifications=DEBUG
-#com.arsdigita.developersupport.Counter=DEBUG
-#com.arsdigita.developersupport.LoggingProxyFactory=DEBUG
-#com.arsdigita.navigation.ui.TemplateURLs=DEBUG
-#com.arsdigita.navigation.Navigation=DEBUG
-#com.arsdigita.navigation.ApplicationNavigationModel=DEBUG
-#com.arsdigita.persistence.pdl.PDL=DEBUG
-#com.arsdigita.persistence.pdl.SQLRegressionGenerator=DEBUG
-#com.arsdigita.persistence.SessionManager=DEBUG
-#com.arsdigita.packaging.HostInit=DEBUG
-#com.arsdigita.packaging.BaseCheck=DEBUG
-#com.arsdigita.packaging.Load=DEBUG
-#com.arsdigita.packaging.Get=DEBUG
-#com.arsdigita.packaging.Unload=DEBUG
-#com.arsdigita.packaging.CheckDB=DEBUG
-#com.arsdigita.packaging.Upgrade=DEBUG
-#com.arsdigita.packaging.Set=DEBUG
-#com.arsdigita.toolbox.CharsetEncodingProvider=DEBUG
-#com.arsdigita.bebop.demo.workflow.SampleProcess=DEBUG
-#com.arsdigita.bebop.page.PageTransformer=DEBUG
-#com.arsdigita.bebop.parameters.TidyHTMLValidationListener=DEBUG
-#com.arsdigita.bebop.Page=DEBUG
-#com.arsdigita.core.LibCheck=DEBUG
-#com.arsdigita.templating.html.XHTMLParser=DEBUG
-#com.arsdigita.templating.ApplyTemplates=DEBUG
-#com.arsdigita.templating.Templating=DEBUG
-#com.arsdigita.templating.PatternStylesheetResolver=DEBUG
-#com.arsdigita.search.QueryEngineRegistry=DEBUG
-#com.arsdigita.formbuilder.AttributeType=DEBUG
-#com.arsdigita.mail.Mail=DEBUG
-#com.arsdigita.versioning.DevSupport=DEBUG
-#com.arsdigita.versioning.Adapter=DEBUG
-#com.arsdigita.dispatcher.BaseDispatcherServlet=DEBUG
-#com.arsdigita.logging.ErrorReport=DEBUG
-#com.arsdigita.xml.XML=DEBUG
-#com.arsdigita.xml.Document=DEBUG
-#com.arsdigita.sitenode.ServletErrorReport=DEBUG
-#com.arsdigita.util.parameter.IntegerParameter=DEBUG
-#com.arsdigita.util.parameter.ClassParameter=DEBUG
-#com.arsdigita.util.parameter.StringParameter=DEBUG
-#com.arsdigita.util.parameter.ParameterPrinter=DEBUG
-#com.arsdigita.util.Assert=DEBUG
-#com.arsdigita.util.StringUtils=DEBUG
-#com.arsdigita.util.UncheckedWrapperException=DEBUG
-#com.arsdigita.util.WrappedError=DEBUG
-#com.arsdigita.util.ConcurrentDict=DEBUG
-#com.redhat.persistence.profiler.rdbms.SQLSummary=DEBUG
-#com.redhat.persistence.metadata.Column=DEBUG
-#com.redhat.persistence.ogl.Static=DEBUG
-#com.arsdigita.cms.docmgr.ui.CreateDocLinkSearchTable=DEBUG
-#com.arsdigita.formbuilder.pdf.PDFConfig=DEBUG
-#com.arsdigita.ui.TopicsList=DEBUG
-#com.arsdigita.forum.ForumPageFactory=DEBUG
-#com.arsdigita.forum.Forum=DEBUG
-#com.arsdigita.aplaws.ObjectTypeSchemaGenerator=DEBUG
-#com.arsdigita.london.atoz.AtoZ=DEBUG
-#com.arsdigita.london.cms.dublin.DublinCoreItem=DEBUG
-#com.arsdigita.london.exporter.Exporter=DEBUG
-#com.arsdigita.london.importer.cms.ItemParser=DEBUG
-#com.arsdigita.london.rss.RSS=DEBUG
-#com.arsdigita.london.rss.RSSService=DEBUG
-#com.arsdigita.london.search.Search=DEBUG
-#com.arsdigita.london.shortcuts.Shortcuts=DEBUG
-#kea.stemmers.LovinsStemmer=DEBUG
-#kea.stemmers.StopwordsFrench=DEBUG
-#kea.stemmers.StopwordsSpanish=DEBUG
-#kea.stemmers.StopwordsEnglish=DEBUG
-#kea.stemmers.StopwordsGerman=DEBUG
-#com.arsdigita.london.terms.Terms=DEBUG
-#com.arsdigita.london.theme.ThemeApplication=DEBUG
-#com.arsdigita.cms.contenttypes.ContactInitalizer=DEBUG
-#com.arsdigita.cms.contenttypes.SciDepartment=DEBUG
-#com.arsdigita.cms.contenttypes.SciOrganization=DEBUG
-#com.arsdigita.cms.contenttypes.SciProject=DEBUG
-#com.arsdigita.cms.contenttypes.SciMember=DEBUG
-#com.arsdigita.cms.webpage.installer.Initializer=DEBUG
-
-#com.arsdigita.subsite.Subsite=DEBUG
+log4j.logger.com.arsdigita.web.Web=DEBUG
diff --git a/ccm-core/web/WEB-INF/web.ccm-core.xml b/ccm-core/web/WEB-INF/web.ccm-core.xml
index 2ffb62c22..9b5359773 100644
--- a/ccm-core/web/WEB-INF/web.ccm-core.xml
+++ b/ccm-core/web/WEB-INF/web.ccm-core.xml
@@ -37,7 +37,7 @@
         BASE SERVLET DECLARATIONS SECTION
         basically requirred by ANY ccm-core application to work correctly!
         - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
+
+    
+        ccm-dispatcher
+        com.arsdigita.web.CCMDispatcherServlet
+        1
+    
     
         cache-manager
         com.arsdigita.caching.CacheServlet
@@ -83,51 +89,6 @@
         com.arsdigita.web.ResourceServlet
     
 
-    
-    
-        content-section
-        com.arsdigita.cms.ContentSectionServlet
-    
-
-    
-        content-type-xsl
-        com.arsdigita.cms.dispatcher.ContentTypeXSLServlet
-    
-
-    
-        content-item-xsl
-        com.arsdigita.cms.dispatcher.ContentItemXSLServlet
-    
-
-    
-        template-xsl
-        com.arsdigita.cms.dispatcher.TemplateXSLServlet
-    
-
-    
-        TextOnlyServlet
-        Text Only Servlet
-        com.arsdigita.web.InternalPrefixerServlet
-        
-            prefix
-            /text
-        
-    
-
-    
-        PrintFriendlyServlet
-        Printer Friendly Output Servlet
-        com.arsdigita.web.InternalPrefixerServlet
-        
-            prefix
-            /print
-        
-    
 
     
 
-    
-        reg
-        /themes/null/reg/*
-    
-
     
         ccm-dispatcher
         /ccm/*
@@ -176,42 +132,6 @@
         /resource/*
     
 
-    
-
-    
-        content-section
-        /themes/servlet/content-section/*
-    
-
-    
-        content-item-xsl
-        /themes/servlet/content-item/*
-    
-
-    
-        content-type-xsl
-        /themes/servlet/content-type/*
-    
-
-    
-        template-xsl
-        /themes/servlet/template/*
-    
-
-    
-        TextOnlyServlet
-        /text/*
-    
-
-    
-        PrintFriendlyServlet
-        /print/*
-    
 
     
@@ -419,11 +395,6 @@
      basically requirred by ccm-core
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 
-  
-    reg
-    /themes/null/reg/*
-  
-
   
     ccm-dispatcher
     /ccm/*
@@ -509,16 +480,6 @@
     /themes/servlet/template/*
   
 
- 
-     TextOnlyServlet
-     /text/*
- 
-
- 
-     PrintFriendlyServlet
-     /print/*
- 
-
 
diff --git a/ccm-sci-bundle/bundles/demo/cfg/web-sci.xml b/ccm-sci-bundle/bundles/demo/cfg/web-sci.xml
index c2e23772b..21310b174 100644
--- a/ccm-sci-bundle/bundles/demo/cfg/web-sci.xml
+++ b/ccm-sci-bundle/bundles/demo/cfg/web-sci.xml
@@ -173,30 +173,6 @@
     com.arsdigita.cms.dispatcher.TemplateXSLServlet
   
 
- 
-   TextOnlyServlet
-   Text Only Servlet
-   
-    com.arsdigita.web.InternalPrefixerServlet
-   
-   
-     prefix
-     /text
-   
- 
-
- 
-   PrintFriendlyServlet
-   Printer Friendly Output Servlet
-   
-    com.arsdigita.web.InternalPrefixerServlet
-   
-   
-     prefix
-     /print
-   
- 
-
 
@@ -419,11 +395,6 @@
      basically requirred by ccm-core
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 
-  
-    reg
-    /themes/null/reg/*
-  
-
   
     ccm-dispatcher
     /ccm/*
@@ -509,16 +480,6 @@
     /themes/servlet/template/*
   
 
- 
-     TextOnlyServlet
-     /text/*
- 
-
- 
-     PrintFriendlyServlet
-     /print/*
- 
-
 
diff --git a/ccm-sci-bundle/bundles/devel/cfg/integration.properties b/ccm-sci-bundle/bundles/devel/cfg/integration.properties
index 54669cd08..a0164b50e 100644
--- a/ccm-sci-bundle/bundles/devel/cfg/integration.properties
+++ b/ccm-sci-bundle/bundles/devel/cfg/integration.properties
@@ -188,7 +188,7 @@ com.arsdigita.subsite.root_category_picker=com.arsdigita.london.terms.ui.RootCat
 # ##############################################################################
 # Required to point to the package containing the theme to copy from when creating
 # a new theme! (In addition to default_theme_path. Otherwise no files are copied!
-themedirector.default_theme_manifest=ccm-bundle.web.mf
+themedirector.default_theme_manifest=ccm-sci-bundle.web.mf
 # Required to denote the dir containing the default theme!
 themedirector.default_theme_path=themes/mandalay
 
diff --git a/ccm-sci-bundle/bundles/devel/cfg/web-sci.xml b/ccm-sci-bundle/bundles/devel/cfg/web-sci.xml
index c2e23772b..27961f12b 100644
--- a/ccm-sci-bundle/bundles/devel/cfg/web-sci.xml
+++ b/ccm-sci-bundle/bundles/devel/cfg/web-sci.xml
@@ -76,7 +76,7 @@
      BASE SERVLET DECLARATIONS SECTION
      basically requirred by ccm-core
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
+
+
+  
+    ccm-dispatcher
+    com.arsdigita.web.CCMDispatcherServlet
+    1
+  
   
   
     cache-manager
@@ -173,30 +180,6 @@
     com.arsdigita.cms.dispatcher.TemplateXSLServlet
   
 
- 
-   TextOnlyServlet
-   Text Only Servlet
-   
-    com.arsdigita.web.InternalPrefixerServlet
-   
-   
-     prefix
-     /text
-   
- 
-
- 
-   PrintFriendlyServlet
-   Printer Friendly Output Servlet
-   
-    com.arsdigita.web.InternalPrefixerServlet
-   
-   
-     prefix
-     /print
-   
- 
-
 
@@ -419,11 +402,6 @@
      basically requirred by ccm-core
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 
-  
-    reg
-    /themes/null/reg/*
-  
-
   
     ccm-dispatcher
     /ccm/*
@@ -509,16 +487,6 @@
     /themes/servlet/template/*
   
 
- 
-     TextOnlyServlet
-     /text/*
- 
-
- 
-     PrintFriendlyServlet
-     /print/*
- 
-
 
diff --git a/ccm-sci-bundle/bundles/standard/cfg/web-sci.xml b/ccm-sci-bundle/bundles/standard/cfg/web-sci.xml
index ad8ba843b..85712b67a 100644
--- a/ccm-sci-bundle/bundles/standard/cfg/web-sci.xml
+++ b/ccm-sci-bundle/bundles/standard/cfg/web-sci.xml
@@ -172,30 +172,6 @@
     com.arsdigita.cms.dispatcher.TemplateXSLServlet
   
 
- 
-   TextOnlyServlet
-   Text Only Servlet
-   
-    com.arsdigita.web.InternalPrefixerServlet
-   
-   
-     prefix
-     /text
-   
- 
-
- 
-   PrintFriendlyServlet
-   Printer Friendly Output Servlet
-   
-    com.arsdigita.web.InternalPrefixerServlet
-   
-   
-     prefix
-     /print
-   
- 
-
 
@@ -418,11 +394,6 @@
      basically requirred by ccm-core
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 
-  
-    reg
-    /themes/null/reg/*
-  
-
   
     ccm-dispatcher
     /ccm/*
@@ -508,16 +479,6 @@
     /themes/servlet/template/*
   
 
- 
-     TextOnlyServlet
-     /text/*
- 
-
- 
-     PrintFriendlyServlet
-     /print/*
- 
-
 
diff --git a/ccm-sci-bundle/src/WEB-INF/resources/scientificCMS-stylesheet-paths.txt b/ccm-sci-bundle/src/WEB-INF/resources/scientificCMS-stylesheet-paths.txt
index c20c69738..fcc9a889d 100644
--- a/ccm-sci-bundle/src/WEB-INF/resources/scientificCMS-stylesheet-paths.txt
+++ b/ccm-sci-bundle/src/WEB-INF/resources/scientificCMS-stylesheet-paths.txt
@@ -3,27 +3,44 @@
 # "PatternStylesheetResolver". Please read the Javadoc for that file for
 # the full story.
 
-# Output type is for things such as text/javascript
-http://::host::/resource/::webapp::/themes/heirloom/apps/::application::/xsl/::url::-::outputtype::-::locale::.xsl
-http://::host::/resource/::webapp::/themes/heirloom/apps/::application::/xsl/::url::-::outputtype::.xsl
+# Currently the "resource" part is actually "short-circuited", see 
+# Templating#transformURL(url)
+# Additionally all modules are installed into one webapp context, so the
+# webapp tag is redundant.
 
-# Grabs custom item xsl for CMS
-http://::host::/themes/servlet/content-item/index.xsl?oid=::item_template_oid::&delegated=::item_delegated_url::
 
-# added by Quasimodo
 # Theme with single entry point (e.g Mandalay) managed by themedirector
-http://::host::/resource/::webapp::/themes/::themedir::/::theme::/start.xsl
+#http://::host::/resource/::webapp::/themes/::themedir::/::theme::/start.xsl
+http://::host::/::webapp::/themes/::themedir::/::theme::/start.xsl
 
 # Theme with single entry point (e.g Mandalay) unmanaged default
-http://::host::/resource/::webapp::/themes/mandalay/start.xsl
+#http://::host::/resource/::webapp::/themes/mandalay/start.xsl
+http://::host::/::webapp::/themes/mandalay/start.xsl
 
+
+
+
+# ==============================================================================
+# The following is for multi-entry themes, not used in ScientificCMS
+# ==============================================================================
+
+# Output type is for things such as text/javascript
+# NOT used by ScientificCMS, uses Mandalay only!
+#http://::host::/resource/::webapp::/themes/heirloom/apps/::application::/xsl/::url::-::outputtype::-::locale::.xsl
+#http://::host::/resource/::webapp::/themes/heirloom/apps/::application::/xsl/::url::-::outputtype::.xsl
+
+# Grabs custom item xsl for CMS
+# NOT used by ScientificCMS, uses Mandalay only!
+#http://::host::/themes/servlet/content-item/index.xsl?oid=::item_template_oid::&delegated=::item_delegated_url::
 # Theme, with optional locale & prefix
-http://::host::/resource/::webapp::/themes/::themedir::/::theme::/::application::-::url::-::prefix::-::locale::.xsl
-http://::host::/resource/::webapp::/themes/::themedir::/::theme::/::application::-::url::-::prefix::.xsl
+# NOT used by ScientificCMS, uses Mandalay only!
+#http://::host::/resource/::webapp::/themes/::themedir::/::theme::/::application::-::url::-::prefix::-::locale::.xsl
+#http://::host::/resource/::webapp::/themes/::themedir::/::theme::/::application::-::url::-::prefix::.xsl
 
 # Theme, with optional locale
-http://::host::/resource/::webapp::/themes/::themedir::/::theme::/::application::-::url::-::locale::.xsl
-http://::host::/resource/::webapp::/themes/::themedir::/::theme::/::application::-::url::.xsl
+# NOT used by ScientificCMS, uses Mandalay only!
+#http://::host::/resource/::webapp::/themes/::themedir::/::theme::/::application::-::url::-::locale::.xsl
+#http://::host::/resource/::webapp::/themes/::themedir::/::theme::/::application::-::url::.xsl
 
 # APLAWS generic default, with locale and prefix
 # XXX change ROOT -> ccm-ldn-aplaws
@@ -36,5 +53,6 @@ http://::host::/resource/::webapp::/themes/::themedir::/::theme::/::application:
 # http://::host::/resource/ROOT/themes/static/aplaws-generic/::application::-::url::.xsl
 
 # Global default, from application's own web app
-http://::host::/resource/::webapp::/themes/heirloom/apps/::application::/xsl/::url::-::locale::.xsl
-http://::host::/resource/::webapp::/themes/heirloom/apps/::application::/xsl/::url::.xsl
+# NOT used by ScientificCMS
+#http://::host::/resource/::webapp::/themes/heirloom/apps/::application::/xsl/::url::-::locale::.xsl
+#http://::host::/resource/::webapp::/themes/heirloom/apps/::application::/xsl/::url::.xsl
diff --git a/ccm-sci-bundle/src/com/arsdigita/bundle/ui/SimplePage.java b/ccm-sci-bundle/src/com/arsdigita/bundle/ui/SimplePage.java
index b316bbdb9..b1682641e 100644
--- a/ccm-sci-bundle/src/com/arsdigita/bundle/ui/SimplePage.java
+++ b/ccm-sci-bundle/src/com/arsdigita/bundle/ui/SimplePage.java
@@ -55,8 +55,8 @@ public class SimplePage extends com.arsdigita.ui.SimplePage {
          * Two xml attributes are added in addition to the bebop standard
          * implementation.
          */
-        if (Web.getContext().getRequestURL() != null) {
-            page.addAttribute("url", Web.getContext().getRequestURL().toString());
+        if (Web.getWebContext().getRequestURL() != null) {
+            page.addAttribute("url", Web.getWebContext().getRequestURL().toString());
             
             page.addAttribute("textOnly", "/text".equals(
                                   DispatcherHelper
diff --git a/ccm-simplesurvey/src/com/arsdigita/simplesurvey/ui/SimpleSurveyPanel.java b/ccm-simplesurvey/src/com/arsdigita/simplesurvey/ui/SimpleSurveyPanel.java
index a671341d2..265479a9e 100755
--- a/ccm-simplesurvey/src/com/arsdigita/simplesurvey/ui/SimpleSurveyPanel.java
+++ b/ccm-simplesurvey/src/com/arsdigita/simplesurvey/ui/SimpleSurveyPanel.java
@@ -29,12 +29,10 @@ import com.arsdigita.bebop.PageState;
 import com.arsdigita.bebop.SimpleContainer;
 import com.arsdigita.bebop.event.PrintListener;
 import com.arsdigita.bebop.event.PrintEvent;
-// import com.arsdigita.kernel.SiteNode;
 import com.arsdigita.ui.UI;
 import com.arsdigita.ui.login.UserAuthenticationListener;
 
 import com.arsdigita.web.Application;
-import com.arsdigita.web.Web;
 import javax.servlet.http.HttpServletRequest;
 
 
@@ -48,7 +46,7 @@ public abstract class SimpleSurveyPanel extends SimpleContainer {
 
     protected BoxPanel m_navBar;
 
-    private String m_title;
+    private final String m_title;
 
     protected SimpleSurveyPanel(String pageTitle) {
 	m_title = pageTitle;
@@ -87,7 +85,10 @@ public abstract class SimpleSurveyPanel extends SimpleContainer {
 	addWorkspaceToNavBar();
 
 	// Link to the index page
-	Link indexLink = new Link( new Label(GlobalizationUtil.globalize("simplesurvey.ui.simple_survey_index_page")),  new PrintListener() {
+	Link indexLink = new Link( new Label(GlobalizationUtil.globalize(
+                               "simplesurvey.ui.simple_survey_index_page")),  
+                               new PrintListener() {
+        @Override
 	    public void prepare(PrintEvent event) {
 		Link link = (Link)event.getTarget();
 		PageState pageState = event.getPageState();
@@ -104,7 +105,6 @@ public abstract class SimpleSurveyPanel extends SimpleContainer {
 
 	// Link to the workspace of the site
 	m_navBar.add(new Link("Workspace",UI.getWorkspaceURL()));
-    //  "/" + LegacyInitializer.getURL(LegacyInitializer.WORKSPACE_PAGE_KEY)));
     }
 
     protected abstract void addComponentsToPage();
@@ -127,7 +127,7 @@ public abstract class SimpleSurveyPanel extends SimpleContainer {
     //  }
     //  return siteNode.getURL();
 
-        // Application app = Web.getContext().getApplication();
+        // Application app = Web.getWebContext().getApplication();
         Application thisApp = Application.getCurrentApplication(request);
         return thisApp.getPrimaryURL();
     }
diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/Initializer.java b/ccm-themedirector/src/com/arsdigita/themedirector/Initializer.java
index f883aafdd..1bc11c9b2 100755
--- a/ccm-themedirector/src/com/arsdigita/themedirector/Initializer.java
+++ b/ccm-themedirector/src/com/arsdigita/themedirector/Initializer.java
@@ -52,8 +52,11 @@ import org.apache.log4j.Logger;
  */
 public class Initializer extends CompoundInitializer {
 
-    private static Logger s_log =
-            Logger.getLogger(Initializer.class);
+    /** Internal logger instance to faciliate debugging. Enable logging output
+     *  by editing /WEB-INF/conf/log4j.properties int the runtime environment
+     *  and set com.arsdigita.themedirector.Initializer=DEBUG 
+     *  by uncommenting or adding the line.                                                   */
+    private static final Logger s_log = Logger.getLogger(Initializer.class);
 
     public Initializer() {
         final String url = RuntimeConfig.getConfig().getJDBCURL();
@@ -78,19 +81,22 @@ public class Initializer extends CompoundInitializer {
             new ThemeDirectoryPatternGenerator()
         );
 
-        PageTransformer.registerXSLParameterGenerator
-            ("theme-prefix", new ThemeXSLParameterGenerator());
+        PageTransformer.registerXSLParameterGenerator(
+            "theme-prefix", 
+            new ThemeXSLParameterGenerator()
+        );
 
         // here we add instantiators for our DomainObjects that do
         // not extend ACSObject
         DomainObjectInstantiator instantiator =
             new DomainObjectInstantiator() {
+                @Override
                 public DomainObject doNewInstance(DataObject dataObject) {
                     return new ThemeFile(dataObject);
                 }
             };
         evt.getFactory().registerInstantiator(ThemeFile.BASE_DATA_OBJECT_TYPE,
-                                                 instantiator);
+                                              instantiator);
 
         evt.getFactory().registerInstantiator(
             ThemeDirector.BASE_DATA_OBJECT_TYPE,
diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirector.java b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirector.java
index c4f9c2ebc..bc909e915 100755
--- a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirector.java
+++ b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirector.java
@@ -42,7 +42,7 @@ public class ThemeDirector extends Application {
 
     /** Config object containing various parameter    */
     private static final ThemeDirectorConfig s_config = 
-                                             ThemeDirectorConfig.getConfig();
+                                             ThemeDirectorConfig.getInstance();
 
     /** Service method to provide clients access to configuration.            */
     public static ThemeDirectorConfig getConfig() {
diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorConfig.java b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorConfig.java
index be66cffe3..3b973899d 100755
--- a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorConfig.java
+++ b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorConfig.java
@@ -41,7 +41,10 @@ import org.apache.log4j.Logger;
  */
 public class ThemeDirectorConfig extends AbstractConfig {
     
-    /** A logger instance.  */
+    /** Internal logger instance to faciliate debugging. Enable logging output
+     *  by editing /WEB-INF/conf/log4j.properties int the runtime environment
+     *  and set com.arsdigita.themedirector.ThemeDirectorConfig=DEBUG 
+     *  by uncommenting or adding the line.                                                   */
     private static final Logger s_log = Logger.getLogger(ThemeDirectorConfig.class);
 
     /** Singelton config object.  */
@@ -54,12 +57,11 @@ public class ThemeDirectorConfig extends AbstractConfig {
      * constructor directly!
      * @return
      */
-    public static synchronized ThemeDirectorConfig getConfig() {
+    public static synchronized ThemeDirectorConfig getInstance() {
         if (s_conf == null) {
             s_conf = new ThemeDirectorConfig();
             s_conf.load();
         }
-
         return s_conf;
     }
 
@@ -73,11 +75,14 @@ public class ThemeDirectorConfig extends AbstractConfig {
                  Parameter.OPTIONAL, "/themes/master/");
 
     /** Servlet context path containing the default theme.
-        Previously ccm-themedirector used to be installed in its own 
-        web context. In this case the appropriate web context should 
-        be specified.
-        Currently, it is installed as part of the main application,
-        therefore it is empty by default.                                     */
+      * Previously ccm-themedirector used to be installed in its own 
+      * web context. In this case the appropriate web context should 
+      * be specified.
+      * Currently, it is installed as part of the main application,
+      * therefore it is empty by default.
+      * @deprecated without direct replacement. Themedirector's Webapp context
+      *             has to be determined at runtime.
+      */
     private final Parameter m_defaultThemeContext =
             new StringParameter
                 ("themedirector.default_theme_context",
@@ -134,7 +139,7 @@ public class ThemeDirectorConfig extends AbstractConfig {
     /** 
      * Constructor.
      * Singelton pattern, don't instantiate a config object using the
-     * constructor directly! Use getConfig() instead.
+ constructor directly! Use getInstance() instead.
      */
     public ThemeDirectorConfig() {
 
diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorConstants.java b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorConstants.java
index 34bac690c..e8f0d97ff 100755
--- a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorConstants.java
+++ b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorConstants.java
@@ -24,17 +24,24 @@ package com.arsdigita.themedirector;
  */
 public interface ThemeDirectorConstants {
 
-    /** Name of the base directory for all themes (usually themes)  */
-    public final static String THEMES_DIR = "themes";
-    /** Name of the directory for production themes (sub-dir of THEMES_DIR)  */
-    public final static String PROD_DIR_STUB = "published-themedir";
-    /** Name of the directory for themes under development (sub-dir of THEMES_DIR)  */
-    public final static String DEV_DIR_STUB = "devel-themedir";
+    /** Name of the base directory for all themes (usually themes).  
+     *  According to JavaEE spec with leading but without trailing "/"!       */
+    public final static String THEMES_DIR = "/themes";
+    /** Name of the directory for production themes (sub-dir of THEMES_DIR).  
+     *  According to JavaEE spec with leading but without trailing "/"!       */
+    public final static String PROD_DIR_STUB = "/published-themedir";
+    /** Name of the directory for themes under development (sub-dir of THEMES_DIR)
+     *  According to JavaEE spec with leading but without trailing "/"!       */
+    public final static String DEV_DIR_STUB = "/devel-themedir";
 
+    /** Path stub into directory for production themes (sub-dir of THEMES_DIR).  
+     *  According to JavaEE spec with leading but without trailing "/"!       */
     public final static String
-                 PROD_THEMES_BASE_DIR = THEMES_DIR + "/" + PROD_DIR_STUB+ "/";
+                 PROD_THEMES_BASE_DIR = THEMES_DIR  + PROD_DIR_STUB;
+    /** Path stub into directory for production themes (sub-dir of THEMES_DIR).  
+     *  According to JavaEE spec with leading but without trailing "/"!       */
     public final static String 
-                 DEV_THEMES_BASE_DIR =  THEMES_DIR + "/" + DEV_DIR_STUB + "/";
+                 DEV_THEMES_BASE_DIR =  THEMES_DIR  + DEV_DIR_STUB ;
 
  // ccm-themedirector (formerly ccm-ldn-theme) is no longer installed in its
  // own web context (ROOT or ccm-ldn-theme/ccm-themedirector) so it is not
diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/dispatcher/InternalThemePrefixerServlet.java b/ccm-themedirector/src/com/arsdigita/themedirector/dispatcher/InternalThemePrefixerServlet.java
index e989a7f6a..9eca078b5 100755
--- a/ccm-themedirector/src/com/arsdigita/themedirector/dispatcher/InternalThemePrefixerServlet.java
+++ b/ccm-themedirector/src/com/arsdigita/themedirector/dispatcher/InternalThemePrefixerServlet.java
@@ -32,34 +32,48 @@ import java.io.IOException;
 import org.apache.log4j.Logger;
 
 /**
- *  This class pulls out the theme information from the
- *  URL so that other sections can correctly allow "previewing".
- *  The big difference between this and the InternalPrefixerServlet
- *  is that the InternalPrefixerServlet only allows a single "/yyy/"
- *  where this file required "/theme/themename/"
+ * This class pulls out the theme information from the URL so that other
+ * sections can correctly allow "previewing".
+ * The big difference between this and the InternalPrefixerServlet
+ * is that the InternalPrefixerServlet only allows a single "/yyy/"
+ * where this file required "/theme/themename/"
  */
 public class InternalThemePrefixerServlet extends InternalPrefixerServlet {
 
-    /** A logger instance.  */
+    /** Internal logger instance to faciliate debugging. Enable logging output
+     *  by editing /WEB-INF/conf/log4j.properties int the runtime environment
+     *  and set 
+     *  com.arsdigita.themedirector.dispatcher.InternalThemePrefixerServlet=DEBUG 
+     *  by uncommenting or adding the line.                                                   */
     private static final Logger s_log =
         Logger.getLogger(InternalPrefixerServlet.class);
 
+    /** The web application context Themedirector is executing within. 
+     *  Dynamically determined at runtime.                                   */
+    private static ServletContext s_context;
+    /**  String containing the preview prefix as the servlet is actually
+     *   configured in web.xml (usually "/theme")                            */
     private String m_prefix;
-
-    /**
-     *  This value is placed as an attribute in the request when
-     *  this is actually a request where the user is previewing the
-     *  theme.  The value of the attribute is the URL of the theme
-     *  that is being previewed.
-     */
+    /** This value is placed as an attribute in the request when this is
+     *  actually a request where the user is previewing the theme.
+     *  The value of the attribute is the URL of the theme that is being
+     *  previewed.                                                           */
     public final static String THEME_PREVIEW_URL = "themePreviewURL";
 
+
+    /**
+     * Standard servlet intialization. Initializes required variables.
+     * 
+     * @throws ServletException 
+     */
     @Override
     public void init()
-        throws ServletException {
+                throws ServletException {
+        
         ServletConfig conf = getServletConfig();
-
         m_prefix = (String)conf.getInitParameter("prefix");
+        
+        s_context = getServletContext();
 
         if (s_log.isDebugEnabled()) {
             s_log.debug("Prefix is " + m_prefix);
@@ -120,9 +134,21 @@ public class InternalThemePrefixerServlet extends InternalPrefixerServlet {
      *  a theme and if so, it returns the url of the theme that
      *  is being previewed.  If this is not a "preview" request
      *  then this will return null.
+     * @param request
+     * @return 
      */
     public static String getThemePreviewURL(HttpServletRequest request) {
         return (String)request.getAttribute(THEME_PREVIEW_URL);
     }
+    
+    /**
+     * Service method to provide the actual context Themedirector is executing
+     * within.
+     * 
+     * @return the ServletContext Themedirector is executing within
+     */
+    public static ServletContext getThemedirectorContext() {
+        return s_context;
+    }
 
 }
diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeControlPanel.java b/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeControlPanel.java
index f298b6e37..3e23330e7 100755
--- a/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeControlPanel.java
+++ b/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeControlPanel.java
@@ -58,9 +58,12 @@ import org.apache.log4j.Logger;
  */
 public class ThemeControlPanel extends SelectionPanel implements ThemeDirectorConstants {
 
+    /** Internal logger instance to faciliate debugging. Enable logging output
+     *  by editing /WEB-INF/conf/log4j.properties int the runtime environment
+     *  and set com.arsdigita.templating.ui.ThemeControlPanel=DEBUG 
+     *  by uncommenting or adding the line.                                                   */
     private static final Logger LOGGER = Logger.getLogger(ThemeControlPanel.class);
     private final ThemeSelectionModel selectionModel;
-    //private final ThemeContainer themeContainer;
     private final Form themeForm;
     private final BigDecimalParameter defaultThemeParam = new BigDecimalParameter("defaultTheme");
 
@@ -81,6 +84,7 @@ public class ThemeControlPanel extends SelectionPanel implements ThemeDirectorCo
         themeForm = new ThemeForm("themeForm", selectionModel);
         themeForm.addSubmissionListener(new CancelListener((Cancellable) themeForm, getBody()));
         themeForm.addProcessListener(new FormProcessListener() {
+            @Override
             public void process(final FormSectionEvent event) throws FormProcessException {
                 resetPane(event.getPageState());
             }
@@ -89,6 +93,7 @@ public class ThemeControlPanel extends SelectionPanel implements ThemeDirectorCo
 
         final ActionLink addThemeLink = new ActionLink(new Label(GlobalizationUtil.globalize("theme.create_new_theme")));
         addThemeLink.addActionListener(new ActionListener() {
+            @Override
             public void actionPerformed(final ActionEvent event) {
                 selectionModel.setSelectedObject(event.getPageState(), null);
                 themeForm.setVisible(event.getPageState(), true);
@@ -125,6 +130,7 @@ public class ThemeControlPanel extends SelectionPanel implements ThemeDirectorCo
         themes.addOption(new Option(null, new Label(GlobalizationUtil.globalize("theme.none"))));
         try {
             themes.addPrintListener(new PrintListener() {
+                @Override
                 public void prepare(final PrintEvent event) {
                     final SingleSelect target = (SingleSelect) event.getTarget();
                     final DataCollection options = SessionManager.getSession().retrieve(Theme.BASE_DATA_OBJECT_TYPE);
@@ -138,17 +144,18 @@ public class ThemeControlPanel extends SelectionPanel implements ThemeDirectorCo
             });
         } catch (TooManyListenersException ex) {
             // Don't be stupid
-            throw new UncheckedWrapperException("An impossible, pointless exception occurred", ex);
+            throw new UncheckedWrapperException(
+                      "An impossible, pointless exception occurred", ex);
         }
         defaultThemeForm.add(themes);
 
         defaultThemeForm.add(new Submit(GlobalizationUtil.globalize("theme.save")));
 
         defaultThemeForm.addInitListener(new FormInitListener() {
+            @Override
             public void init(final FormSectionEvent event) {
                 final FormData data = event.getFormData();
 
-                //ThemeDirector app = (ThemeDirector) Web.getContext().getApplication();
                 final ThemeDirector app = ThemeDirector.getThemeDirector();
                 final Theme theme = app.getDefaultTheme();
 
@@ -160,16 +167,17 @@ public class ThemeControlPanel extends SelectionPanel implements ThemeDirectorCo
         });
 
         defaultThemeForm.addProcessListener(new FormProcessListener() {
+            @Override
             public void process(final FormSectionEvent event) {
                 final FormData data = event.getFormData();
-                final BigDecimal themeID = (BigDecimal) data.get(defaultThemeParam.getName());
+                final BigDecimal themeID = (BigDecimal) data.get(
+                                           defaultThemeParam.getName());
 
                 Theme theme = null;
                 if (null != themeID) {
                     theme = Theme.retrieve(themeID);
                 }
 
-                //ThemeDirector app = (ThemeDirector) Web.getContext().getApplication();
                 final ThemeDirector app = ThemeDirector.getThemeDirector();
                 app.setDefaultTheme(theme);
             }
diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeXSLParameterGenerator.java b/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeXSLParameterGenerator.java
index 08470bcb5..59f01d869 100755
--- a/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeXSLParameterGenerator.java
+++ b/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeXSLParameterGenerator.java
@@ -18,40 +18,92 @@
 
 package com.arsdigita.themedirector.ui;
 
+import com.arsdigita.subsite.Subsite;
+import com.arsdigita.subsite.SubsiteContext;
 import com.arsdigita.themedirector.dispatcher.InternalThemePrefixerServlet;
 import com.arsdigita.themedirector.ThemeDirectorConstants;
 import com.arsdigita.themedirector.ThemeDirectorConfig;
 import com.arsdigita.themedirector.ThemeDirector;
 import com.arsdigita.templating.XSLParameterGenerator;
-import javax.servlet.http.HttpServletRequest;
 import com.arsdigita.web.Web;
-import com.arsdigita.subsite.Subsite;
-import com.arsdigita.subsite.SubsiteContext;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.log4j.Logger;
 
 
 /**
- *  This looks at the request and is able to determine if it is 
- *  production or preview as well as the theme that is in use.
- *  Then, it returns the appropriate prefix that will be something
- *  similar to /themes-[devel|published]-themedir/[theme-name]/
- *
+ * A Core extension which integrates ThemeDirector into core's templating 
+ * system by providing an appropriate environment parameter ("theme-prefix") 
+ * to locate XSL files managed by ThemeDirector. 
+ * It looks at the request and is able to determine if it is production or 
+ * preview as well as the theme that is in use. Then, it returns the appropriate 
+ * prefix that will be something similar to 
+ * /themes-[devel|published]-themedir/[theme-name]/
  *  @author Randy Graebner (randyg@redhat.com)
+ *  @author Peter Boy (pboy@zes.uni-bremen.de)
  */
 public class ThemeXSLParameterGenerator implements XSLParameterGenerator,
                                                    ThemeDirectorConstants {
+
+    /** Internal logger instance to faciliate debugging. Enable logging output
+     *  by editing /WEB-INF/conf/log4j.properties int the runtime environment
+     *  and set com.arsdigita.themedirector.ui.ThemeXSLParameterGenerator=DEBUG 
+     *  by uncommenting or adding the line.                                                   */
+    private static final Logger s_log = 
+         Logger.getLogger(ThemeXSLParameterGenerator.class);
+
+    
     /**
-     *  This returns the correct value for the parameter.  This is the
-     *  value that is added to the transformer and is available to all
-     *  stylesheets 
+     * This returns the correct value for the parameter.  This is the
+     * value that is added to the transformer and is available to all
+     * stylesheets.
+     * 
+     * @param request
+     * @return 
      */
+    @Override
     public String generateValue(HttpServletRequest request) {
 
-        String themeURL = 
-            InternalThemePrefixerServlet.getThemePreviewURL(request);
+        // Extracted from the request we take for granted we'll find a proper
+        // leading slash as specified by JavaEE it it's not empty (null)
+        String themeURL = InternalThemePrefixerServlet
+                          .getThemePreviewURL(request);
+        // determine the webapp context (JEE: ServletContext) where themedirector
+        // is actually installed. Usually it's the same as the main CCM webapp
+        // If Themedirector is installed in it's own webapp context, we have to
+        // determine the context at runtime using an appropriate method!
+        String myContextPath = Web.getWebappContextPath();
+        if (!myContextPath.equals("")) {
+            // Themedirector lives in a NON-ROOT context
+            // ensure there is no trailing slash
+            if (myContextPath.endsWith("/")) {
+                myContextPath = myContextPath.substring(0, myContextPath
+                                                           .length()-1);
+            }
+            // ensure it starts with a "/"
+            if (!myContextPath.startsWith("/")) {
+                myContextPath = "/"+myContextPath;
+            }
+            
+        }
+
+        if (s_log.isDebugEnabled()) {
+            s_log.debug("Value for themeURL as retrieved from request "
+                        + "parameter >>" + themeURL + "<<]");
+            s_log.debug("Themedirector's webapp context >>" + 
+                        myContextPath + "<<]");
+        }
 
         String baseDir = null;
+        
 
         if (themeURL != null) {
+            // this means we are in a preview mode
+            if (s_log.isDebugEnabled()) {
+                s_log.debug("We are in preview mode. " +
+                            "Assigning >" + DEV_DIR_STUB + "< to baseDir.");
+            }
             baseDir = DEV_DIR_STUB;
             // we want to strip the final "/" and everything after it
             int index = themeURL.lastIndexOf("/");
@@ -59,39 +111,54 @@ public class ThemeXSLParameterGenerator implements XSLParameterGenerator,
                 themeURL = themeURL.substring(0, index);
             }
         } else {
+            // themeURL is null. we probably have to handle a default theme for
+            // the site or a subsite.
             baseDir = PROD_DIR_STUB;
             SubsiteContext context = Subsite.getContext();
-            if (context.hasSite() && 
-                context.getSite().getStyleDirectory() != null) {
+            if (context.hasSite() && context.getSite()
+                                            .getStyleDirectory() != null) {
                 themeURL = "/" + context.getSite().getStyleDirectory();
             }
 
             if( null == themeURL ) {
-                String defaultThemeURL = ThemeDirectorConfig.getDefaultThemeURL( request );
+                String defaultThemeURL = ThemeDirectorConfig
+                                         .getDefaultThemeURL( request );
 
                 if( null != defaultThemeURL ) themeURL = "/" + defaultThemeURL;
+                if (s_log.isDebugEnabled()) {
+                    s_log.debug("No managed theme associated. " +
+                                "Value for Default Theme >>" + themeURL + "<<]");
+                }
             }
         }
 
         if (themeURL != null) {
-        //  modified as ccm-themedirector (previously ccm-ldn-theme) is 
-        //  no longer installed in its own context
-        //  return "/" + WEB_APP_NAME + "/" + THEMES_DIR + "/" +
-        //  If we want to install it as a separate web application again we
-        //  should find a way to determine the name from a central configuration
-            return "/" + THEMES_DIR + "/" +
-                Web.getContext().getRequestURL().getContextPath() +
-                baseDir + themeURL;
+            if (s_log.isDebugEnabled()) {
+                s_log.debug("Constructing site's themeURL." );
+            }
+            themeURL =  myContextPath + THEMES_DIR + 
+                        baseDir + themeURL;
         } else {
             // this means that there is no theme associated with the
-            // given subsite, so we return the default theme
-            themeURL = 
-                ThemeDirector.getConfig().getDefaultThemeContext() +
-                ThemeDirector.getConfig().getDefaultThemePath();
+            // given site, so we return the default theme
+            themeURL = ThemeDirector.getConfig().getDefaultThemePath();
             if (themeURL.endsWith("/")) {
                 themeURL = themeURL.substring(0, themeURL.length()-1);
             }
-            return themeURL;
+            if (!themeURL.startsWith("/")) {
+                themeURL = "/" + themeURL;
+            }
+            themeURL = myContextPath + themeURL;
+                       
+            if (s_log.isDebugEnabled()) {
+                s_log.debug("No managed theme associated. "
+                            + "Value for Default Theme >>" + themeURL + "<<]");
+            }
         }
+        if (s_log.isDebugEnabled()) {
+            s_log.debug("Returned value for themeURL: " +
+                        ">>" + themeURL + "<<");
+        }
+        return themeURL;
     }
 } 
diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeDevelopmentFileManager.java b/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeDevelopmentFileManager.java
index ebc634e79..312887d47 100755
--- a/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeDevelopmentFileManager.java
+++ b/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeDevelopmentFileManager.java
@@ -49,6 +49,12 @@ public class ThemeDevelopmentFileManager extends ThemeFileManager {
     private static ThemeFileManager s_manager;
 
 
+    /**
+     * Constructor just delegates to super class.
+     * @param startupDelay
+     * @param pollDelay
+     * @param baseDirectory 
+     */
     protected ThemeDevelopmentFileManager(int startupDelay, int pollDelay, 
                                           String baseDirectory) {
         super(s_log, startupDelay, pollDelay, baseDirectory);
diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeFileManager.java b/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeFileManager.java
index 28397b1c4..8bfe3e676 100755
--- a/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeFileManager.java
+++ b/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeFileManager.java
@@ -15,6 +15,18 @@
 
 package com.arsdigita.themedirector.util;
 
+import com.arsdigita.themedirector.Theme;
+import com.arsdigita.themedirector.ThemeDirector;
+import com.arsdigita.themedirector.ThemeCollection;
+import com.arsdigita.themedirector.ThemeDirectorConstants;
+import com.arsdigita.themedirector.ThemeFileCollection;
+import com.arsdigita.persistence.SessionManager;
+import com.arsdigita.persistence.TransactionContext;
+import com.arsdigita.themedirector.dispatcher.InternalThemePrefixerServlet;
+import com.arsdigita.web.Application;
+import com.arsdigita.web.ApplicationCollection;
+import com.arsdigita.web.Web;
+
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -24,17 +36,6 @@ import javax.servlet.ServletContext;
 
 import org.apache.log4j.Logger;
 
-import com.arsdigita.themedirector.Theme;
-import com.arsdigita.themedirector.ThemeDirector;
-import com.arsdigita.themedirector.ThemeCollection;
-import com.arsdigita.themedirector.ThemeDirectorConstants;
-import com.arsdigita.themedirector.ThemeFileCollection;
-import com.arsdigita.persistence.SessionManager;
-import com.arsdigita.persistence.TransactionContext;
-import com.arsdigita.web.Application;
-import com.arsdigita.web.ApplicationCollection;
-import com.arsdigita.web.Web;
-
 
 /**
  *  Class for polling the database to look for new/updated files in
@@ -56,20 +57,22 @@ import com.arsdigita.web.Web;
  *
  * @version $Revision: #2 $ $DateTime: 2004/01/30 17:24:49 $
  */
-public abstract class ThemeFileManager extends Thread implements ThemeDirectorConstants {
+public abstract class ThemeFileManager extends Thread 
+                                       implements ThemeDirectorConstants {
 
-    private Logger m_log;
+    /** Internal logger instance to faciliate debugging                       */
+    private final Logger m_log;
 
     // The code in this class borrows heavily from
     // com.arsdigita.cms.publishToFile.FileManager
 
-    // Following true if should keep watching file
+    /** Following true if should keep watching file.                          */
     private boolean m_keepWatchingFiles = true;
 
     // Parameters involved in processing the file and their default values.
     // Set to values other than default by calling methods from an initializer.
-    private int m_startupDelay;
-    private int m_pollDelay;
+    private final int m_startupDelay;
+    private final int m_pollDelay;
     private String m_baseDirectory = null;
 
     // the m_ignoreInterrupt allows us to use the "interrupt" command to
@@ -78,6 +81,14 @@ public abstract class ThemeFileManager extends Thread implements ThemeDirectorCo
 
     private Date m_lastRunDate;
 
+    /**
+     * Constructor initializes internal properties.
+     * 
+     * @param log
+     * @param startupDelay
+     * @param pollDelay
+     * @param baseDirectory 
+     */
     protected ThemeFileManager(Logger log, int startupDelay, int pollDelay,
                              String baseDirectory) {
         m_log = log;
@@ -107,10 +118,10 @@ public abstract class ThemeFileManager extends Thread implements ThemeDirectorCo
         return m_lastRunDate;
     }
 
-    /***
+    /**
      * Watch file for entries to process.  The main routine that starts
      * file processing.
-     ***/
+     */
     public void run() {
         m_log.info("Start polling file in " + m_startupDelay + "s.");
         if (m_lastRunDate == null) {
@@ -187,7 +198,15 @@ public abstract class ThemeFileManager extends Thread implements ThemeDirectorCo
      *  THIS IS A HACK BECAUSE IT REQUIRES A SERVER TO BE RUNNING
      */
     protected String getBaseDirectory() {
+
         if (m_baseDirectory == null) {
+            // Because the constructor sets the base deirectory this should
+            // never happen, but just in case ....
+            // ThemeDirector may execute in a different web application context
+            // as core oder CMS. To determine the actual context we may ask
+            // Themedirector servlet.
+            
+            /*  OLD code depending on deprecated ContextRegiserServlet
             ApplicationCollection collection = Application.retrieveAllApplications();
             collection.filterToApplicationType(ThemeDirector.BASE_DATA_OBJECT_TYPE);
             Application app = null;
@@ -202,6 +221,10 @@ public abstract class ThemeFileManager extends Thread implements ThemeDirectorCo
             String webapp = app.getContextPath();
             ServletContext themeCtx = Web.getServletContext(webapp + '/');
             m_baseDirectory = themeCtx.getRealPath("/");
+            */
+            ServletContext themeCtx = InternalThemePrefixerServlet
+                                      .getThemedirectorContext();
+            m_baseDirectory = themeCtx.getRealPath("/");
         }
 
         return m_baseDirectory;
diff --git a/ccm-weblog/src/org/undp/weblog/ui/WebLogCommentEditForm.java b/ccm-weblog/src/org/undp/weblog/ui/WebLogCommentEditForm.java
index cd47abced..d6cb94105 100755
--- a/ccm-weblog/src/org/undp/weblog/ui/WebLogCommentEditForm.java
+++ b/ccm-weblog/src/org/undp/weblog/ui/WebLogCommentEditForm.java
@@ -117,7 +117,7 @@ public class WebLogCommentEditForm extends Form implements FormInitListener,
 					entity = new WebLogComment(enityID);
 				}
 
-				entity.setOwner(Web.getContext().getUser());
+				entity.setOwner(Web.getWebContext().getUser());
 				entity.setComment(comment);
 				entity.save();
 				processBack(ps);
diff --git a/ccm-weblog/src/org/undp/weblog/ui/WebLogCommentsList.java b/ccm-weblog/src/org/undp/weblog/ui/WebLogCommentsList.java
index 707a02b48..973262ab9 100755
--- a/ccm-weblog/src/org/undp/weblog/ui/WebLogCommentsList.java
+++ b/ccm-weblog/src/org/undp/weblog/ui/WebLogCommentsList.java
@@ -54,7 +54,7 @@ public class WebLogCommentsList extends Table implements TableActionListener {
 			WebLogComment entity = new WebLogComment(entityID);
 			if (entity != null) {
 				if (m_parent.canUserAdminApplication() || (/* m_parent.canUserEditApplication() && */
-				Web.getContext().getUser().equals(entity.getOwner()))) {
+				Web.getWebContext().getUser().equals(entity.getOwner()))) {
 
 					PageState ps = e.getPageState();
 					switch (col) {
diff --git a/ccm-weblog/src/org/undp/weblog/ui/WebLogCommentsListTableModel.java b/ccm-weblog/src/org/undp/weblog/ui/WebLogCommentsListTableModel.java
index 60ffe3536..a97715de3 100755
--- a/ccm-weblog/src/org/undp/weblog/ui/WebLogCommentsListTableModel.java
+++ b/ccm-weblog/src/org/undp/weblog/ui/WebLogCommentsListTableModel.java
@@ -39,8 +39,8 @@ public class WebLogCommentsListTableModel implements TableModel,
 		m_coll = webLog.getComments();
 		m_hasNext = true;
 
-		Application application = Web.getContext().getApplication();
-		m_user = Web.getContext().getUser();
+		Application application = Web.getWebContext().getApplication();
+		m_user = Web.getWebContext().getUser();
 		PermissionDescriptor perm = new PermissionDescriptor(
 				PrivilegeDescriptor.ADMIN, application, m_user);
 		m_userIsAdmin = PermissionService.checkPermission(perm);
diff --git a/ccm-weblog/src/org/undp/weblog/ui/WebLogEditForm.java b/ccm-weblog/src/org/undp/weblog/ui/WebLogEditForm.java
index e9547b3f4..142263e38 100755
--- a/ccm-weblog/src/org/undp/weblog/ui/WebLogEditForm.java
+++ b/ccm-weblog/src/org/undp/weblog/ui/WebLogEditForm.java
@@ -145,9 +145,9 @@ public class WebLogEditForm extends Form implements FormInitListener,
 				WebLog entity;
 				if (m_createNew) {
 					entity = new WebLog();
-					entity.setApplication((WebLogApplication) Web.getContext()
+					entity.setApplication((WebLogApplication) Web.getWebContext()
 							.getApplication());
-					entity.setOwner(Web.getContext().getUser());
+					entity.setOwner(Web.getWebContext().getUser());
 				} else {
 					BigDecimal enityID = (BigDecimal) m_parent
 							.getEntityIDParam().transformValue(
diff --git a/ccm-weblog/src/org/undp/weblog/ui/WebLogPage.java b/ccm-weblog/src/org/undp/weblog/ui/WebLogPage.java
index dff87bc08..18de42c8b 100755
--- a/ccm-weblog/src/org/undp/weblog/ui/WebLogPage.java
+++ b/ccm-weblog/src/org/undp/weblog/ui/WebLogPage.java
@@ -44,7 +44,7 @@ public class WebLogPage extends Page {
 		navbar.add(new Link(new PrintListener() {
 			public void prepare(PrintEvent e) {
 				Link link = (Link) e.getTarget();
-				Application currApp = Web.getContext().getApplication();
+				Application currApp = Web.getWebContext().getApplication();
 				Application prevApp = currApp.getParentApplication();
 				link.setChild(new Label(prevApp.getTitle()));
 				link.setTarget(prevApp.getPath());
@@ -53,7 +53,7 @@ public class WebLogPage extends Page {
 		navbar.add(new Link(new PrintListener() {
 			public void prepare(PrintEvent e) {
 				Link link = (Link) e.getTarget();
-				Application currApp = Web.getContext().getApplication();
+				Application currApp = Web.getWebContext().getApplication();
 				link.setChild(new Label(currApp.getTitle()));
 				link.setTarget(currApp.getPath());
 			}
diff --git a/ccm-weblog/src/org/undp/weblog/ui/WebLogView.java b/ccm-weblog/src/org/undp/weblog/ui/WebLogView.java
index c135464e9..61681ab03 100755
--- a/ccm-weblog/src/org/undp/weblog/ui/WebLogView.java
+++ b/ccm-weblog/src/org/undp/weblog/ui/WebLogView.java
@@ -191,8 +191,8 @@ public class WebLogView extends ModalContainer implements WebLogConstants {
 	}
 
 	protected boolean canUserAdminApplication() {
-		Application app = Web.getContext().getApplication();
-		User user = Web.getContext().getUser();
+		Application app = Web.getWebContext().getApplication();
+		User user = Web.getWebContext().getUser();
 		PermissionDescriptor perm = new PermissionDescriptor(
 				PrivilegeDescriptor.ADMIN, app, user);
 		boolean result = PermissionService.checkPermission(perm);
@@ -202,8 +202,8 @@ public class WebLogView extends ModalContainer implements WebLogConstants {
 
 	protected boolean canUserEditApplication() {
 		PermissionDescriptor perm = new PermissionDescriptor(
-				PrivilegeDescriptor.EDIT, Web.getContext().getApplication(),
-				Web.getContext().getUser());
+				PrivilegeDescriptor.EDIT, Web.getWebContext().getApplication(),
+				Web.getWebContext().getUser());
 		return PermissionService.checkPermission(perm);
 	}
 }
diff --git a/ccm-weblog/src/org/undp/weblog/ui/WebLogsList.java b/ccm-weblog/src/org/undp/weblog/ui/WebLogsList.java
index 08f71c629..353dc3294 100755
--- a/ccm-weblog/src/org/undp/weblog/ui/WebLogsList.java
+++ b/ccm-weblog/src/org/undp/weblog/ui/WebLogsList.java
@@ -51,7 +51,7 @@ public class WebLogsList extends Table implements TableActionListener {
 
 			public TableModel makeModel(Table t, PageState state) {
 				return new WebLogsListTableModel((WebLogApplication) Web
-						.getContext().getApplication(), HEADERS_ACTION.length);
+						.getWebContext().getApplication(), HEADERS_ACTION.length);
 			}
 
 			public void lock() {
diff --git a/ccm-weblog/src/org/undp/weblog/ui/WebLogsListTableModel.java b/ccm-weblog/src/org/undp/weblog/ui/WebLogsListTableModel.java
index a491ce43b..3f2f1d0ec 100755
--- a/ccm-weblog/src/org/undp/weblog/ui/WebLogsListTableModel.java
+++ b/ccm-weblog/src/org/undp/weblog/ui/WebLogsListTableModel.java
@@ -44,7 +44,7 @@ public class WebLogsListTableModel implements TableModel, WebLogConstants {
 		m_hasNext = true;
 		m_appURL = application.getPath();
 		PermissionDescriptor perm = new PermissionDescriptor(
-				PrivilegeDescriptor.ADMIN, application, Web.getContext()
+				PrivilegeDescriptor.ADMIN, application, Web.getWebContext()
 						.getUser());
 		m_userIsAdmin = PermissionService.checkPermission(perm);
 	}
diff --git a/ccm-webpage/src/com/arsdigita/cms/webpage/ui/AuthorLabelPrinter.java b/ccm-webpage/src/com/arsdigita/cms/webpage/ui/AuthorLabelPrinter.java
index db8d80d72..d0bb1ab95 100755
--- a/ccm-webpage/src/com/arsdigita/cms/webpage/ui/AuthorLabelPrinter.java
+++ b/ccm-webpage/src/com/arsdigita/cms/webpage/ui/AuthorLabelPrinter.java
@@ -17,7 +17,7 @@ public class AuthorLabelPrinter implements PrintListener {
 		Label label = (Label) e.getTarget();
 		PageState pageState = e.getPageState();
 		
-		User user = Web.getContext().getUser();
+		User user = Web.getWebContext().getUser();
 		if (user != null) {
 			label.setLabel("Author: (if not " + user.getName() + ")");
 		}
diff --git a/ccm-webpage/src/com/arsdigita/cms/webpage/ui/ContentPanelWebpageNode.java b/ccm-webpage/src/com/arsdigita/cms/webpage/ui/ContentPanelWebpageNode.java
index 057f85936..88488bcd4 100755
--- a/ccm-webpage/src/com/arsdigita/cms/webpage/ui/ContentPanelWebpageNode.java
+++ b/ccm-webpage/src/com/arsdigita/cms/webpage/ui/ContentPanelWebpageNode.java
@@ -42,7 +42,7 @@ public class ContentPanelWebpageNode extends ContentPanel {
 		if (isVisible(state)) {
 			super.generateXML(state, parent);
 
-			User user = Web.getContext().getUser();
+			User user = Web.getWebContext().getUser();
 			SecurityManager sm = new SecurityManager(section);
 			if (user != null && sm != null) {
 				modifyContentPanelElements(parent.getChildren(), section, user, sm);
diff --git a/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpageCMSEditorPage.java b/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpageCMSEditorPage.java
index d81987c53..6aa120cc7 100755
--- a/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpageCMSEditorPage.java
+++ b/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpageCMSEditorPage.java
@@ -376,7 +376,7 @@ public class WebpageCMSEditorPage extends CMSPage implements WebpageConstants {
 						throw new FormProcessException("ContentSection is null");
 					}
 					SecurityManager sm = new SecurityManager(section);
-					User user = Web.getContext().getUser();
+					User user = Web.getWebContext().getUser();
 					
 					if (webpage != null) {
 						if ( !sm.canAccess(user, SecurityConstants.EDIT_ITEM, webpage ) ) {
@@ -435,7 +435,7 @@ public class WebpageCMSEditorPage extends CMSPage implements WebpageConstants {
 								final WorkflowTemplate wfTemp = new WorkflowTemplate(task.getID());
 								final Workflow flow = wfTemp.instantiateNewWorkflow();
 				                flow.setObjectID(webpage.getID());
-				                flow.start(Web.getContext().getUser());
+				                flow.start(Web.getWebContext().getUser());
 				                flow.save();
 							}
 						}
@@ -450,7 +450,7 @@ public class WebpageCMSEditorPage extends CMSPage implements WebpageConstants {
 						
 						Engine engine = Engine.getInstance();
 						Assert.exists(engine, Engine.class);
-						Iterator i = engine.getEnabledTasks(Web.getContext().getUser(), workflow.getID()).iterator();
+						Iterator i = engine.getEnabledTasks(Web.getWebContext().getUser(), workflow.getID()).iterator();
 						CMSTask task;
 						do {
 							while (i.hasNext()) {
@@ -463,7 +463,7 @@ public class WebpageCMSEditorPage extends CMSPage implements WebpageConstants {
 								}
 							}
 							
-							i = engine.getEnabledTasks(Web.getContext().getUser(), workflow.getID()).iterator();
+							i = engine.getEnabledTasks(Web.getWebContext().getUser(), workflow.getID()).iterator();
 						}
 						while (i.hasNext());
 						
diff --git a/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpagePortlet.java b/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpagePortlet.java
index 04bd6307d..713b658bb 100755
--- a/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpagePortlet.java
+++ b/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpagePortlet.java
@@ -123,7 +123,7 @@ class WebpagePortletRenderer extends AbstractPortletRenderer {
 	protected void generateBodyXML(PageState pageState, Element parent) {
 
 		Webpage webpage = m_portlet.getWebpage();
-//		User user = (User) Kernel.getContext().getParty();
+//		User user = (User) Kernel.getWebContext().getParty();
 //		SecurityManager sm = new SecurityManager(webpage.getContentSection());
 //		if (sm.canAccess(user, SecurityConstants.EDIT_ITEM, webpage)) {
 
@@ -133,8 +133,8 @@ class WebpagePortletRenderer extends AbstractPortletRenderer {
         // have to add the application link to a new element
         // attributes set on the parent are lost, somehow
 		PermissionDescriptor perm = new PermissionDescriptor(PrivilegeDescriptor.EDIT,
-                                                             Web.getContext().getApplication(),
-                                                             Web.getContext().getUser());
+                                                             Web.getWebContext().getApplication(),
+                                                             Web.getWebContext().getUser());
 		if (PermissionService.checkPermission(perm)) {
 			StringBuffer appLinkURL = new StringBuffer(Web.getConfig().getDispatcherServletPath());
 			appLinkURL.append('/');
diff --git a/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpagePortletEditor.java b/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpagePortletEditor.java
index dec384e6f..d0dc8e939 100755
--- a/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpagePortletEditor.java
+++ b/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpagePortletEditor.java
@@ -170,7 +170,7 @@ public class WebpagePortletEditor extends PortletConfigFormSection {
 				}
                 
                 // FR: move reference from PortalSite to Application (could be Workspace)
-                Application app = Web.getContext().getApplication();
+                Application app = Web.getWebContext().getApplication();
 				String folderName = StringUtils.replace(app.getPath(), "/", "-");
 				Folder rootFolder = section.getRootFolder();
 				Folder folder = (Folder) rootFolder.getItem(folderName, true);
@@ -206,7 +206,7 @@ public class WebpagePortletEditor extends PortletConfigFormSection {
 						final WorkflowTemplate wfTemp = new WorkflowTemplate(task.getID());
 						final Workflow flow = wfTemp.instantiateNewWorkflow();
 		                flow.setObjectID(webpage.getID());
-		                flow.start(Web.getContext().getUser());
+		                flow.start(Web.getWebContext().getUser());
 		                flow.save();
 					}
 				}
@@ -221,7 +221,7 @@ public class WebpagePortletEditor extends PortletConfigFormSection {
 				
 				Engine engine = Engine.getInstance();
 				Assert.exists(engine, Engine.class);
-				Iterator i = engine.getEnabledTasks(Web.getContext().getUser(), workflow.getID()).iterator();
+				Iterator i = engine.getEnabledTasks(Web.getWebContext().getUser(), workflow.getID()).iterator();
 				CMSTask task;
 				do {
 					while (i.hasNext()) {
@@ -234,7 +234,7 @@ public class WebpagePortletEditor extends PortletConfigFormSection {
 						}
 					}
 					
-					i = engine.getEnabledTasks(Web.getContext().getUser(), workflow.getID()).iterator();
+					i = engine.getEnabledTasks(Web.getWebContext().getUser(), workflow.getID()).iterator();
 				}
 				while (i.hasNext());
 				
diff --git a/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpagePortletEditorPage.java b/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpagePortletEditorPage.java
index 6ad0822ce..784d09442 100755
--- a/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpagePortletEditorPage.java
+++ b/ccm-webpage/src/com/arsdigita/cms/webpage/ui/WebpagePortletEditorPage.java
@@ -207,7 +207,7 @@ public class WebpagePortletEditorPage extends CMSPage {
 				throw new FormProcessException("Illegal Webpage Portlet ID: " + portletID);
 			}
 
-			User user = Web.getContext().getUser();
+			User user = Web.getWebContext().getUser();
 			PermissionDescriptor perm = new PermissionDescriptor(PrivilegeDescriptor.EDIT,
 					portlet.getParentResource(), user);
 			if (!PermissionService.checkPermission(perm)) {