diff --git a/ccm-cms/src/com/arsdigita/cms/ContentCenter.java b/ccm-cms/src/com/arsdigita/cms/ContentCenter.java
index fb70be886..5001be709 100644
--- a/ccm-cms/src/com/arsdigita/cms/ContentCenter.java
+++ b/ccm-cms/src/com/arsdigita/cms/ContentCenter.java
@@ -16,6 +16,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
+
package com.arsdigita.cms;
import com.arsdigita.domain.DataObjectNotFoundException;
@@ -28,14 +29,15 @@ import java.math.BigDecimal;
import org.apache.log4j.Logger;
/**
- * Application domain class for the CMS module user entry page (content-center)
+ * Application domain class for the CMS module user entry page
+ * (content-center)
*
* @author pb
* @version $Id: ContentCenter.java $
*/
public class ContentCenter extends Application {
- /** A logger instance, primarily to assist debugging . */
+ /** A logger instance, primarily to assist debugging. */
private static final Logger s_log = Logger.getLogger(ContentSection.class);
// pdl stuff (constants)
public static final String BASE_DATA_OBJECT_TYPE =
@@ -43,8 +45,6 @@ public class ContentCenter extends Application {
// general constants
public static final String PACKAGE_KEY = "content-center";
public static final String INSTANCE_NAME = "Content Center";
-// public static final String DISPATCHER_CLASS =
-// "com.arsdigita.cms.dispatcher.ContentCenterDispatcher";
/**
* Constructor retrieving a workspace from the database usings its OID.
@@ -57,8 +57,9 @@ public class ContentCenter extends Application {
}
/**
- * Constructor retrieving the contained DataObject from the
- * persistent storage mechanism with an OID specified by id.
+ * Constructor retrieving the contained DataObject from
+ * the persistent storage mechanism with an OID specified
+ * by id.
*
* @param id The id for the retrieved
* DataObject.
@@ -91,8 +92,9 @@ public class ContentCenter extends Application {
String title,
Application parent) {
- ContentCenter app =
- (ContentCenter) Application.createApplication(BASE_DATA_OBJECT_TYPE, urlName, title, parent);
+ ContentCenter app = (ContentCenter) Application
+ .createApplication(BASE_DATA_OBJECT_TYPE,
+ urlName, title, parent);
app.save();
@@ -106,7 +108,8 @@ public class ContentCenter extends Application {
* Therefore we simply may return the URL used to load and initialise the
* Content Center.
*
- * @return The URL of the CMS ContentCenter (currently including trailing slash)
+ * @return The URL of the CMS ContentCenter (currently including trailing
+ * slash)
*/
public static String getURL() {
// quick 'nd dirty!
diff --git a/ccm-cms/src/com/arsdigita/cms/ContentCenterServlet.java b/ccm-cms/src/com/arsdigita/cms/ContentCenterServlet.java
index 5daf8d236..c36796bf6 100644
--- a/ccm-cms/src/com/arsdigita/cms/ContentCenterServlet.java
+++ b/ccm-cms/src/com/arsdigita/cms/ContentCenterServlet.java
@@ -21,6 +21,10 @@ package com.arsdigita.cms;
import com.arsdigita.bebop.Page;
import com.arsdigita.cms.dispatcher.CMSPage;
import com.arsdigita.cms.dispatcher.SimpleCache;
+import com.arsdigita.cms.ui.CMSApplicationPage;
+import com.arsdigita.cms.ui.CMSItemSearchPage;
+import com.arsdigita.cms.ui.CMSSearchResultRedirector;
+// Old version (dispatcher based) of CMSItemSearchPage
import com.arsdigita.cms.ui.ItemSearchPage;
import com.arsdigita.cms.ui.contentcenter.MainPage;
import com.arsdigita.developersupport.DeveloperSupport;
@@ -43,6 +47,7 @@ import java.util.Iterator;
import java.util.Map;
import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -91,19 +96,21 @@ public class ContentCenterServlet extends BaseApplicationServlet {
if (s_log.isDebugEnabled()) {
s_log.info("starting doInit method");
}
-// DEPRECATED STUFF for servlet internally process pages, maybe required
+
+ // DEPRECATED STUFF for servlet internally process pages, maybe required
// for JSP extension.
- m_trailingSlashList = new ArrayList();
- requireTrailingSlash("");
+ // m_trailingSlashList = new ArrayList();
+ // requireTrailingSlash("");
// NEW STUFF here used to process the pages in this servlet
// Addresses previously noted in WEB-INF/resources/content-center-map.xml
// Obviously not required.
- addPage("/", new MainPage()); // index page at address ~/ds
- // addPage("/index/", new MainPage());
- //addPage("/ItemSearchPage/", new ItemSearchPage());
+ addPage("/", new MainPage()); // index page at address ~/cc
+ addPage("/index", new MainPage());
+ // addPage("/item-search", new CMSItemSearchPage());
+ // Old style
addPage("/item-search", new ItemSearchPage());
- // addPage("/SearchResultRedirector/", new CCSearchResultRedirector());
+ addPage("/searchredirect", new CMSSearchResultRedirector());
// STUFF to use for JSP extension, i.e. jsp's to try for URLs which are not
@@ -122,27 +129,25 @@ public class ContentCenterServlet extends BaseApplicationServlet {
}
/**
- * Implements the (abstract) doService method of BaseApplicationServlet to
- * create the ContentCenter page.
+ * Implements the (abstract) doService method of BaseApplicationServlet
+ * to create the ContentCenter page.
*
* @see com.arsdigita.web.BaseApplicationServlet#doService
* (HttpServletRequest, HttpServletResponse, Application)
*/
protected void doService(HttpServletRequest sreq,
- HttpServletResponse sresp,
- Application app)
- throws ServletException, IOException {
+ HttpServletResponse sresp,
+ Application app)
+ throws ServletException, IOException {
if (s_log.isDebugEnabled()) {
s_log.info("starting doService method");
}
DeveloperSupport.startStage("ContentCenterServlet.doService");
- ContentCenter workspace = (ContentCenter) app;
+ // ContentCenter workspace = (ContentCenter) app;
- /*
- * Check user and privilegies
- */
+ /* Check user and privilegies */
if (Web.getContext().getUser() == null) { // user not logged in
throw new LoginSignal(sreq); // send to login page
}
@@ -165,14 +170,7 @@ public class ContentCenterServlet extends BaseApplicationServlet {
}
-
- RequestContext ctx = DispatcherHelper.getRequestContext();
- String url = ctx.getRemainingURLPart(); // here SiteNodeRequestContext
- String originalUrl = ctx.getOriginalURL();
-
- String requestUri = sreq.getRequestURI();
-
- // New way to tetch the page
+ // New way to fetch the page
String pathInfo = sreq.getPathInfo();
Assert.exists(pathInfo, "String pathInfo");
if (pathInfo.length() > 1 && pathInfo.endsWith("/")) {
@@ -188,10 +186,10 @@ public class ContentCenterServlet extends BaseApplicationServlet {
// probably want to redirect.
// Probably DEPRECATED with new access method or only relevant for jsp
// extension
- if (m_trailingSlashList.contains(url) && !originalUrl.endsWith("/")) {
- DispatcherHelper.sendRedirect(sresp, originalUrl + "/");
- return;
- }
+ // if (m_trailingSlashList.contains(url) && !originalUrl.endsWith("/")) {
+ // DispatcherHelper.sendRedirect(sresp, originalUrl + "/");
+ // return;
+ // }
final Page page = (Page) m_pages.get(pathInfo);
@@ -199,16 +197,18 @@ public class ContentCenterServlet extends BaseApplicationServlet {
// Check user access.
checkUserAccess(sreq, sresp);
- //Lock the page
if (page instanceof CMSPage) {
+ // backwards compatibility fix until migration completed
final CMSPage cmsPage = (CMSPage) page;
+ final RequestContext ctx = DispatcherHelper.getRequestContext();
cmsPage.init();
cmsPage.dispatch(sreq, sresp, ctx);
} else {
- page.lock();
+ final CMSApplicationPage cmsAppPage = (CMSApplicationPage) page;
+ cmsAppPage.init(sreq,sresp,app);
// Serve the page.
- final Document doc = page.buildDocument(sreq, sresp);
+ final Document doc = cmsAppPage.buildDocument(sreq, sresp);
PresentationManager pm = Templating.getPresentationManager();
pm.servePage(doc, sreq, sresp);
@@ -231,7 +231,9 @@ public class ContentCenterServlet extends BaseApplicationServlet {
sreq = DispatcherHelper.restoreOriginalRequest(sreq);
rd.forward(sreq, sresp);
} else {
- sresp.sendError(404, requestUri + " not found on this server.");
+ // String requestUri = sreq.getRequestURI();
+ sresp.sendError(404, sreq.getRequestURI() +
+ " not found on this server.");
}
}
@@ -244,7 +246,8 @@ public class ContentCenterServlet extends BaseApplicationServlet {
} // END doService()
/**
- * Adds one pair of Url - Page to the internal hash map, used as a cache.
+ * Internal service mechod, adds one pair of Url - Page to the internal
+ * hash map, used as a cache.
*
* @param pathInfo url stub for a page to display
* @param page Page object to display
@@ -271,7 +274,8 @@ public class ContentCenterServlet extends BaseApplicationServlet {
Iterator itr = s_pageURLs.keySet().iterator();
while (itr.hasNext()) {
String classname2 = (String) itr.next();
- s_log.debug("key: " + classname + " value: " + (String) s_pageURLs.get(classname2));
+ s_log.debug("key: " + classname + " value: "
+ + (String) s_pageURLs.get(classname2));
}
String url = (String) s_pageURLs.get(classname);
return url;
@@ -298,14 +302,13 @@ public class ContentCenterServlet extends BaseApplicationServlet {
* @param actx The request context
**/
protected void checkUserAccess(final HttpServletRequest request,
- final HttpServletResponse response //,
+ final HttpServletResponse response //,
/// final RequestContext actx
)
throws ServletException {
if (!Web.getUserContext().isLoggedIn()) {
throw new LoginSignal(request);
-
}
}
@@ -317,8 +320,8 @@ public class ContentCenterServlet extends BaseApplicationServlet {
* trying to redirect, wrap that exception in a ServletException
**/
protected void redirectToLoginPage(HttpServletRequest req,
- HttpServletResponse resp)
- throws ServletException {
+ HttpServletResponse resp)
+ throws ServletException {
String url = Util.getSecurityHelper()
.getLoginURL(req)
+ "?" + LoginHelper.RETURN_URL_PARAM_NAME
diff --git a/ccm-cms/src/com/arsdigita/cms/ContentSectionServlet.java b/ccm-cms/src/com/arsdigita/cms/ContentSectionServlet.java
index 4e9247846..87c54fa39 100755
--- a/ccm-cms/src/com/arsdigita/cms/ContentSectionServlet.java
+++ b/ccm-cms/src/com/arsdigita/cms/ContentSectionServlet.java
@@ -18,13 +18,16 @@
*/
package com.arsdigita.cms;
+import com.arsdigita.bebop.Page;
import com.arsdigita.caching.CacheTable;
import com.arsdigita.cms.dispatcher.CMSDispatcher;
+import com.arsdigita.cms.dispatcher.CMSPage;
import com.arsdigita.cms.dispatcher.ContentItemDispatcher;
import com.arsdigita.cms.dispatcher.ItemResolver;
import com.arsdigita.cms.dispatcher.TemplateResolver;
import com.arsdigita.cms.publishToFile.LocalRequestPassword;
import com.arsdigita.cms.lifecycle.Lifecycle;
+import com.arsdigita.cms.ui.CMSApplicationPage;
import com.arsdigita.dispatcher.AccessDeniedException;
import com.arsdigita.dispatcher.DispatcherHelper;
import com.arsdigita.dispatcher.RequestContext;
@@ -41,6 +44,8 @@ import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.Session;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.TransactionContext;
+import com.arsdigita.templating.PresentationManager;
+import com.arsdigita.templating.Templating;
import com.arsdigita.util.Assert;
import com.arsdigita.util.Classes;
import com.arsdigita.versioning.Versions;
@@ -49,6 +54,7 @@ import com.arsdigita.web.ApplicationFileResolver;
import com.arsdigita.web.BaseApplicationServlet;
import com.arsdigita.web.LoginSignal;
import com.arsdigita.web.Web;
+import com.arsdigita.xml.Document;
import java.io.IOException;
import java.math.BigDecimal;
@@ -130,8 +136,14 @@ public class ContentSectionServlet extends BaseApplicationServlet {
private static Map s_itemURLCacheMap = null;
private static boolean s_cacheItems = true;
- /** Path to directory containg ccm-cms template files */
+ // NEW STUFF here used to process the pages in this servlet
+ /** URL (pathinfo) -> Page object mapping. Based on it (and the http
+ * request url) the doService method selects a page to display */
+ private final Map m_pages = new HashMap();
+
+ /** Path to directory containg ccm-cms template (jsp) files */
private String m_templatePath;
+ // Probably compatibility stuff, based on dispatcher
/** Resolvers to find templages (JSP) and other stuff stored in file system.*/
private ApplicationFileResolver m_resolver;
@@ -172,6 +184,12 @@ public class ContentSectionServlet extends BaseApplicationServlet {
s_log.debug("Template path is " + m_templatePath +
" with resolver " + m_resolver.getClass().getName());
}
+
+ // NEW STUFF here used to process the pages in this servlet
+ // addPage("/admin", new MainPage()); // index page at address ~/cs
+ // addPage("/admin/index.jsp", new MainPage());
+ // addPage("/admin/item.jsp", new MainPage());
+
}
/**
@@ -183,30 +201,74 @@ public class ContentSectionServlet extends BaseApplicationServlet {
* (HttpServletRequest, HttpServletResponse, Application)}
*/
protected void doService( HttpServletRequest sreq,
- HttpServletResponse sresp,
- Application app)
+ HttpServletResponse sresp,
+ Application app)
throws ServletException, IOException {
ContentSection section = (ContentSection) app;
- String requestUri = sreq.getRequestURI();
+ // ////////////////////////////////////////////////////////////////////
+ // Prepare OLD style dispatcher based page service
+ // ////////////////////////////////////////////////////////////////////
/*
* NOTE:
* Resolves currently to SiteNodeRequestContext which will be removed.
+ * NOTE 2:
+ * SiteNodeRequestContext removed, resolves currently to
+ * KernelRequestContext which will be removed as well.
*/
RequestContext ctx = DispatcherHelper.getRequestContext();
- String url = ctx.getRemainingURLPart(); // here SiteNodeRequestContext
-
+ String url = ctx.getRemainingURLPart(); // here KernelRequestContext now
if (s_log.isInfoEnabled()) {
s_log.info("Resolving item URL " + url);
}
-
- //TODO: need to do a check for public page
-
final ItemResolver itemResolver = getItemResolver(section);
final ContentItem item = getItem(section, url, itemResolver);
- if (item != null) {
+
+ // ////////////////////////////////////////////////////////////////////
+ // Prepare NEW style servlet based bebpo page service
+ // ////////////////////////////////////////////////////////////////////
+ String pathInfo = sreq.getPathInfo();
+ Assert.exists(pathInfo, "String pathInfo");
+ if (pathInfo.length() > 1 && pathInfo.endsWith("/")) {
+ /* NOTE: ServletAPI specifies, pathInfo may be empty or will
+ * start with a '/' character. It currently carries a
+ * trailing '/' if a "virtual" page, i.e. not a real jsp, but
+ * result of a servlet mapping. But Application requires url
+ * NOT to end with a trailing '/' for legacy free applications. */
+ pathInfo = pathInfo.substring(0, pathInfo.length() - 1);
+ }
+ final Page page = (Page) m_pages.get(pathInfo);
+
+
+ // ////////////////////////////////////////////////////////////////////
+ // Serve the page
+ // ////////////////////////////////////////////////////////////////////
+ /* FIRST try new style servlet based service */
+ if (page != null) {
+
+ // Check user access.
+ // checkUserAccess(sreq, sresp); // done in individual pages ??
+
+ if (page instanceof CMSPage) {
+ // backwards compatibility fix until migration completed
+ final CMSPage cmsPage = (CMSPage) page;
+ // final RequestContext ctx = DispatcherHelper.getRequestContext();
+ cmsPage.init();
+ cmsPage.dispatch(sreq, sresp, ctx);
+ } else {
+ final CMSApplicationPage cmsAppPage = (CMSApplicationPage) page;
+ cmsAppPage.init(sreq,sresp,app);
+ // Serve the page.
+ final Document doc = cmsAppPage.buildDocument(sreq, sresp);
+
+ PresentationManager pm = Templating.getPresentationManager();
+ pm.servePage(doc, sreq, sresp);
+ }
+
+ /* SECONDLY try if we have to serve an item (old style dispatcher based */
+ } else if (item != null) {
/* We have to serve an item here */
String param = sreq.getParameter("transID");
@@ -229,15 +291,16 @@ public class ContentSectionServlet extends BaseApplicationServlet {
serveItem(sreq, sresp, section, item);
+ /* OTHERWISE delegate to a JSP in file system */
} else {
-
+
/* We have to deal with a content-section, folder or an other bit*/
if (s_log.isInfoEnabled()) {
s_log.info("NOT serving content item");
}
-
+
/* Store content section in http request to make it available
- * or admin index,jsp */
+ * for admin index,jsp */
sreq.setAttribute(CONTENT_SECTION, section);
RequestDispatcher rd = m_resolver.resolve(m_templatePath,
@@ -250,10 +313,12 @@ public class ContentSectionServlet extends BaseApplicationServlet {
rd.forward(sreq,sresp);
} else {
// sresp.sendError(404, packageURL + " not found on this server.");
+ String requestUri = sreq.getRequestURI(); // same as ctx.getRemainingURLPart()
sresp.sendError(404, requestUri + " not found on this server.");
}
}
- }
+ } // END doService
+
/**
*
@@ -334,6 +399,25 @@ public class ContentSectionServlet extends BaseApplicationServlet {
//use ContentItemDispatcher
m_disp.dispatch(sreq,sresp,ctx);
}
+
+ /**
+ * Internal service method, adds one pair of Url - Page to the internal
+ * hash map, used as a cache.
+ *
+ * @param pathInfo url stub for a page to display
+ * @param page Page object to display
+ */
+ private void addPage(final String pathInfo, final Page page) {
+
+ Assert.exists(pathInfo, String.class);
+ Assert.exists(page, Page.class);
+ // Current Implementation requires pathInfo to start with a leading '/'
+ // SUN Servlet API specifies: "PathInfo *may be empty* or will start
+ // with a '/' character."
+ Assert.isTrue(pathInfo.startsWith("/"), "path starts not with '/'");
+
+ m_pages.put(pathInfo, page);
+ }
/**
* Fetches the content section from the request attributes.
diff --git a/ccm-cms/src/com/arsdigita/cms/ui/CMSApplicationPage.java b/ccm-cms/src/com/arsdigita/cms/ui/CMSApplicationPage.java
index 091b27d6f..1ef2e2306 100755
--- a/ccm-cms/src/com/arsdigita/cms/ui/CMSApplicationPage.java
+++ b/ccm-cms/src/com/arsdigita/cms/ui/CMSApplicationPage.java
@@ -26,10 +26,13 @@ import com.arsdigita.cms.dispatcher.Utilities;
import com.arsdigita.kernel.Kernel;
import com.arsdigita.kernel.User;
import com.arsdigita.templating.PresentationManager;
+import com.arsdigita.web.Application;
import com.arsdigita.xml.Document;
import com.arsdigita.xml.Element;
import java.util.HashMap;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
@@ -44,20 +47,21 @@ import org.apache.log4j.Logger;
/**
- *
A CMSApplicationPage is a Bebop {@link com.arsdigita.bebop.Page} - * implementation serving as a base for any CMS pageElement served by a servlet.
+ * A CMSApplicationPage is a Bebop {@link com.arsdigita.bebop.Page} + * implementation serving as a base for any CMS pageElement served by a + * servlet. * - *It stores the current {@link com.arsdigita.cms.ContentSection} and, if - * applicable, the {@link com.arsdigita.cms.ContentItem} in the pageElement state as - * request local objects. Components that are part of the CMSPage - * may access these objects by calling:
+ * It stores the current {@link com.arsdigita.cms.ContentSection} and, if + * applicable, the {@link com.arsdigita.cms.ContentItem} in the pageElement + * state as request local objects. Components that are part of the + * CMSPage may access these objects by calling: *
* getContentSection(PageState state);
*
*
* @author Michael Pih (pihman@arsdigita.com)
* @author Uday Mathur (umathur@arsdigita.com)
- * @version $Id: CMSPage.java 2140 2011-01-16 12:04:20Z pboy $
+ * @version $Id: CMSApplicationPage.java 2140 2011-01-16 12:04:20Z pboy $
*/
public class CMSApplicationPage extends Page {
@@ -131,12 +135,18 @@ public class CMSApplicationPage extends Page {
}
/**
- * Finishes and locks the pageElement. If the pageElement is already locked, does nothing.
+ * Finishes and locks the pageElement. If the pageElement is already
+ * locked, does nothing.
+ *
+ * Client classes may overwrite this method to add context specific bits
+ * to the page before it is locked.
*
- * This method is called by the {@link com.arsdigita.dispatcher.Dispatcher}
- * that initializes this pageElement.
+ * This method is called by the various servlets serving the various pages
+ * of the CMS package, before serving and displaying the page.
*/
- public synchronized void init() {
+ public synchronized void init(HttpServletRequest sreq,
+ HttpServletResponse sresp,
+ Application app) {
s_log.debug("Initializing the page");
if (!isLocked()) {
diff --git a/ccm-cms/src/com/arsdigita/cms/ui/CMSItemSearchPage.java b/ccm-cms/src/com/arsdigita/cms/ui/CMSItemSearchPage.java
new file mode 100755
index 000000000..1733e0c2c
--- /dev/null
+++ b/ccm-cms/src/com/arsdigita/cms/ui/CMSItemSearchPage.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2003-2004 Red Hat Inc. 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.cms.ui;
+
+import com.arsdigita.bebop.Component;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.SimpleContainer;
+import com.arsdigita.bebop.TabbedPane;
+import com.arsdigita.bebop.event.RequestEvent;
+import com.arsdigita.bebop.event.RequestListener;
+import com.arsdigita.bebop.parameters.BigDecimalParameter;
+import com.arsdigita.bebop.parameters.BooleanParameter;
+import com.arsdigita.bebop.parameters.IntegerParameter;
+import com.arsdigita.bebop.parameters.StringParameter;
+import com.arsdigita.cms.*;
+import com.arsdigita.cms.dispatcher.CMSPage;
+import com.arsdigita.cms.util.GlobalizationUtil;
+import com.arsdigita.dispatcher.RequestContext;
+import com.arsdigita.domain.DataObjectNotFoundException;
+import com.arsdigita.templating.PresentationManager;
+import com.arsdigita.templating.Templating;
+import com.arsdigita.util.UncheckedWrapperException;
+import com.arsdigita.web.Application;
+import com.arsdigita.web.Web;
+import com.arsdigita.xml.Document;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * The Item Search page.
+ *
+ * @author Scott Seago (scott@arsdigita.com)
+ * @author Sören Bernstein (sbernstein@quasiweb.de)
+ * @author Jens Pelzetter (jens@jp-digital.de)
+ */
+public class CMSItemSearchPage extends CMSApplicationPage {
+
+ private final static String XSL_CLASS = "CMS Admin";
+ private TabbedPane m_tabbedPane;
+ private ItemSearchFlatBrowsePane m_flatBrowse;
+ private ItemSearchBrowsePane m_browse;
+ private ItemSearchPopup m_search;
+ private ItemSearchCreateItemPane m_create;
+ private BigDecimalParameter m_sectionId;
+ private int m_lastTab;
+ private static final CMSConfig s_conf = CMSConfig.getInstance();
+ private static final boolean LIMIT_TO_CONTENT_SECTION = false;
+ public static final String CONTENT_SECTION = "section_id";
+
+ /**
+ * Construct a new ItemSearchPage
+ */
+ public CMSItemSearchPage() {
+ super(GlobalizationUtil.globalize("cms.ui.item_search.page_title").localize().toString(), new SimpleContainer());
+
+ setClassAttr("cms-admin");
+
+ addGlobalStateParam(new BigDecimalParameter(ItemSearch.SINGLE_TYPE_PARAM));
+ addGlobalStateParam(new StringParameter(ItemSearchPopup.WIDGET_PARAM));
+ addGlobalStateParam(new StringParameter("searchWidget"));
+ addGlobalStateParam(new StringParameter("publishWidget"));
+ addGlobalStateParam(new StringParameter("defaultCreationFolder"));
+ addGlobalStateParam(new IntegerParameter("lastTab"));
+ addGlobalStateParam(new BooleanParameter("disableCreatePane"));
+ addGlobalStateParam(new BooleanParameter("editAfterCreate"));
+ m_sectionId = new BigDecimalParameter(CONTENT_SECTION);
+ addGlobalStateParam(m_sectionId);
+
+ m_flatBrowse = getFlatBrowsePane();
+ m_browse = getBrowsePane();
+ m_search = getSearchPane();
+ m_create = getCreatePane();
+
+ m_tabbedPane = createTabbedPane();
+ m_tabbedPane.setIdAttr("page-body");
+ add(m_tabbedPane);
+
+ addRequestListener(new RequestListener() {
+
+ public void pageRequested(final RequestEvent event) {
+ final PageState state = event.getPageState();
+
+ final String query = (String) state.getValue(new StringParameter(ItemSearchPopup.QUERY));
+ final Boolean disableCreatePane = (Boolean) state.getValue(new BooleanParameter("disableCreatePane"));
+
+ BigDecimal typeParam =
+ (BigDecimal) state.getValue(new BigDecimalParameter(ItemSearch.SINGLE_TYPE_PARAM));
+ if ((typeParam == null) || disableCreatePane) {
+ m_tabbedPane.setTabVisible(state, m_create, false);
+ m_create.setVisible(state, false);
+ } else {
+ m_tabbedPane.setTabVisible(state, m_create, true);
+ m_create.setVisible(state, true);
+ }
+
+ if (state.getValue(new IntegerParameter("lastTab")) == null) {
+ if ((query == null) || query.isEmpty()) {
+ m_tabbedPane.setSelectedIndex(state, 1);
+ } else {
+ m_tabbedPane.setSelectedIndex(state, 0);
+ }
+
+// m_tabbedPane.setTabVisible(state, m_create, false);
+// m_create.setVisible(state, false);
+
+ }
+
+ state.setValue(new IntegerParameter("lastTab"), m_tabbedPane.getSelectedIndex(state));
+
+ if (state.getValue(new StringParameter("defaultCreationFolder")) != null) {
+ m_create.setDefaultFolder((String) state.getValue(new StringParameter("defaultCreationFolder")));
+ }
+
+ if (state.getValue(new BooleanParameter("editAfterCreate")) != null) {
+ m_create.setEditAfterCreate((Boolean) state.getValue(new BooleanParameter("editAfterCreate")));
+ }
+
+// if (m_lastTab != m_tabbedPane.getSelectedIndex(state)) {
+// m_lastTab = m_tabbedPane.getSelectedIndex(state);
+// return;
+// }
+//
+// //If create pane is selected do nothing (else we don't stay in the create pane)
+// if (m_tabbedPane.getCurrentPane(state) == m_create) {
+// return;
+// }
+//
+// if ((query == null) || query.isEmpty()) {
+// m_tabbedPane.setSelectedIndex(state, 1);
+// } else {
+// m_tabbedPane.setSelectedIndex(state, 1);
+// }
+
+// if (m_tabbedPane.getCurrentPane(state) == m_create) {
+// m_tabbedPane.setTabVisible(state, m_create, false);
+// m_create.setVisible(state, false);
+// }
+//
+// m_lastTab = m_tabbedPane.getSelectedIndex(state);
+ }
+
+ });
+
+// m_tabbedPane.addActionListener(new ActionListener() {
+//
+// public void actionPerformed(final ActionEvent event) {
+// final PageState state = event.getPageState();
+//
+// }
+//
+// });
+
+// m_flatBrowse.addProcessListener(new FormProcessListener() {
+//
+// public void process(final FormSectionEvent fse) throws FormProcessException {
+// if (m_flatBrowse.getSubmit().isSelected(fse.getPageState())) {
+// enableCreatePane(fse.getPageState());
+// }
+// }
+//
+// });
+ } // END constructor
+
+
+ /**
+ * Creates, and then caches, the Browse pane.
+ *
+ * Overriding this method to return null will prevent this tab from
+ * appearing. Note: not implemented yet.
+ */
+ protected ItemSearchBrowsePane getBrowsePane() {
+ if (m_browse == null) {
+ m_browse = new ItemSearchBrowsePane();
+ }
+
+ return m_browse;
+ }
+
+ /**
+ *
+ * @return
+ */
+ protected ItemSearchFlatBrowsePane getFlatBrowsePane() {
+ if (m_flatBrowse == null) {
+ m_flatBrowse = new ItemSearchFlatBrowsePane("flatBrowse");
+ }
+
+ return m_flatBrowse;
+ }
+
+ /**
+ * Creates, and then caches, the Creation pane.
+ * Overriding this method to return null will prevent this tab from
+ * appearing.
+ */
+ protected ItemSearchPopup getSearchPane() {
+ if (m_search == null) {
+ // Always search in every content section
+// m_search = new ItemSearchPopup(ContentItem.DRAFT, CMS.getConfig().limitToContentSection());
+ m_search = new ItemSearchPopup(ContentItem.DRAFT, LIMIT_TO_CONTENT_SECTION);
+ }
+
+ return m_search;
+ }
+
+ /**
+ *
+ * @return
+ */
+ protected ItemSearchCreateItemPane getCreatePane() {
+ if (m_create == null) {
+ m_create = new ItemSearchCreateItemPane(this);
+ }
+
+ return m_create;
+ }
+
+ /**
+ * Created the TabbedPane to use for this page.
+ *
+ * Sets the class attribute for this tabbed pane. The default implementation
+ * uses a {@link com.arsdigita.bebop.TabbedPane} and sets the class
+ * attribute to "CMS Admin." This implementation also adds tasks,
+ * content sections, and search panes.
+ *
+ * Developers can override this method to add only the tabs they want,
+ * or to add additional tabs after the default CMS tabs are added.
+ */
+ protected TabbedPane createTabbedPane() {
+ TabbedPane pane = new TabbedPane();
+ pane.setClassAttr(XSL_CLASS);
+
+
+ addToPane(pane, "flatBrowse", getFlatBrowsePane());
+ addToPane(pane, "browse", getBrowsePane());
+ addToPane(pane, "search", getSearchPane());
+ addToPane(pane, "create", getCreatePane());
+
+ if ("browse".equals(s_conf.getItemSearchDefaultTab())) {
+ pane.setDefaultPane(m_browse);
+ }
+ if ("search".equals(s_conf.getItemSearchDefaultTab())) {
+ pane.setDefaultPane(m_search);
+ }
+
+ //pane.setDefaultPane(m_flatBrowse);
+ pane.setDefaultPane(m_browse);
+
+ return pane;
+ }
+
+ /**
+ * Adds the specified component, with the specified tab name, to the
+ * tabbed pane only if it is not null.
+ *
+ * @param pane The pane to which to add the tab
+ * @param tabName The name of the tab if it's added
+ * @param comp The component to add to the pane
+ */
+ protected void addToPane(TabbedPane pane, String tabName, Component comp) {
+ if (comp != null) {
+
+ pane.addTab(GlobalizationUtil
+ .globalize("cms.ui.item_search." + tabName)
+ .localize().toString()
+ ,comp);
+
+ }
+ }
+
+
+ /**
+ * This strange voodoo from Dan. No idea what it does.
+ */
+// @Override
+ public void dispatch(final HttpServletRequest request,
+ final HttpServletResponse response,
+ RequestContext actx)
+ throws IOException, ServletException {
+ new CMSExcursion() {
+
+ @Override
+ public void excurse()
+ throws IOException, ServletException {
+ ContentSection section = null;
+ Application app = Web.getContext().getApplication();
+ if (app instanceof ContentSection) {
+ section = (ContentSection) app;
+ } else {
+ try {
+ section = new ContentSection((BigDecimal) m_sectionId.transformValue(request));
+ } catch (DataObjectNotFoundException ex) {
+ throw new UncheckedWrapperException(ex);
+ }
+ }
+ setContentSection(section);
+
+ final Document doc = buildDocument(request, response);
+ final PresentationManager pm =
+ Templating.getPresentationManager();
+
+ pm.servePage(doc, request, response);
+ }
+
+ }.run();
+ }
+
+ protected void setTabActive(final PageState state, final Component component, final boolean value) {
+ m_tabbedPane.setTabVisible(state, component, value);
+ }
+
+ protected void setTabActive(final PageState state, final int index, final boolean value) {
+ m_tabbedPane.setTabVisible(state, index, value);
+ }
+
+ protected void setDefaultCreationFolder(final Folder folder) {
+ m_create.setDefaultFolder(folder.getOID().toString());
+ }
+
+ protected void setEditAfterCreate(final boolean editAfterCreate) {
+ m_create.setEditAfterCreate(editAfterCreate);
+ }
+
+}
diff --git a/ccm-cms/src/com/arsdigita/cms/ui/CMSSearchResultRedirector.java b/ccm-cms/src/com/arsdigita/cms/ui/CMSSearchResultRedirector.java
new file mode 100755
index 000000000..724e29922
--- /dev/null
+++ b/ccm-cms/src/com/arsdigita/cms/ui/CMSSearchResultRedirector.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2001-2004 Red Hat Inc. 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.cms.ui;
+
+
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.cms.ContentItem;
+import com.arsdigita.cms.ContentSection;
+import com.arsdigita.cms.dispatcher.CMSPage;
+import com.arsdigita.cms.dispatcher.ItemResolver;
+import com.arsdigita.cms.util.GlobalizationUtil;
+import com.arsdigita.dispatcher.DispatcherHelper;
+import com.arsdigita.dispatcher.RequestContext;
+import com.arsdigita.util.UncheckedWrapperException;
+import java.io.IOException;
+import java.math.BigDecimal;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.log4j.Logger;
+
+
+/**
+ * Page for redirecting results of Search to the item to be
+ * displayed.
+ *
+ * @author Jeff Teeters (teeters@arsdigita.com)
+ * @version $Id: SearchResultRedirector.java 287 2005-02-22 00:29:02Z sskracic $
+ *
+ */
+public class CMSSearchResultRedirector extends CMSApplicationPage {
+
+ /**
+ * Names of required parameters passed in the request
+ */
+ public static final String ITEM_ID = "item_id";
+ public static final String CONTEXT = "context";
+ private static final Logger s_log = Logger.getLogger(CMSSearchResultRedirector.class);
+
+ /**
+ * Construct a new SearchResultRedirector
+ */
+ public CMSSearchResultRedirector() {
+ super();
+ }
+
+
+ /***
+ * override dispatcher to do redirect to page displaying item.
+ ***/
+ public void dispatch(HttpServletRequest req,
+ HttpServletResponse resp, RequestContext actx) {
+
+ // Get item_id
+ BigDecimal id;
+
+ try {
+ id = new BigDecimal(getParam(ITEM_ID, req));
+ } catch (NumberFormatException e) {
+ s_log.error("Invalid CMS Item id", e);
+ String itemID = (String) getParam(ITEM_ID,req);
+ throw new RuntimeException( (String) GlobalizationUtil.globalize(
+ "cms.ui.invalid_item_id", new Object[] { itemID }).localize() + e.getMessage());
+ }
+
+ // Get context
+ String context = getParam(CONTEXT, req);
+
+ // Get section and item
+ ContentSection section;
+ ContentItem item = new ContentItem(id);
+ section = item.getContentSection();
+
+ // Get url
+ ItemResolver resolver = section.getItemResolver();
+ PageState state;
+ try {
+ state = new PageState(this, req, resp);
+ } catch (javax.servlet.ServletException ex) {
+ throw new UncheckedWrapperException("Servlet Error: " + ex.getMessage(), ex);
+ }
+ String url = resolver.generateItemURL ( state, item, section, context );
+
+ // redirect to url
+ try {
+ DispatcherHelper.sendRedirect(req, resp, url);
+ } catch (IOException e) {
+ UncheckedWrapperException.throwLoggedException(getClass(), "Could not redirect: " + e.getMessage(), e );
+ }
+ }
+
+
+ /**
+ * Get a parameter from the request
+ */
+
+ private String getParam ( String paramName, HttpServletRequest req) {
+ String [] params = req.getParameterValues(paramName);
+ if (params.length != 1) {
+ s_log.error("Not one " + paramName);
+ throw new RuntimeException("Not one " + paramName);
+ }
+ return params[0];
+ }
+}
diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionContextBar.java b/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionContextBar.java
index 811863931..252c6df83 100755
--- a/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionContextBar.java
+++ b/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionContextBar.java
@@ -30,19 +30,21 @@ import com.arsdigita.cms.Template;
import com.arsdigita.kernel.ACSObject;
import com.arsdigita.web.ParameterMap;
import com.arsdigita.web.URL;
-import org.apache.log4j.Logger;
import java.math.BigDecimal;
import java.util.List;
import java.util.Stack;
+import org.apache.log4j.Logger;
+
/**
- * The context bar of the content section UI.
+ * The context bar of the content section UI. * * @author Justin Ross <jross@redhat.com> * @version $Id: ContentSectionContextBar.java 287 2005-02-22 00:29:02Z sskracic $ */ -class ContentSectionContextBar extends WorkspaceContextBar { +// class ContentSectionContextBar extends WorkspaceContextBar { +public class ContentSectionContextBar extends WorkspaceContextBar { private static final Logger s_log = Logger.getLogger (ContentSectionContextBar.class); @@ -66,10 +68,12 @@ class ContentSectionContextBar extends WorkspaceContextBar { if (item == null) { s_log.warn("item is null"); } else if(item.getContentType() == null) { - s_log.warn("item.getContentType() returns null. item.class.getName(): " + item.getClass().getName()); + s_log.warn("item.getContentType() returns null. item.class.getName(): " + + item.getClass().getName()); } isTemplate = - item.getContentType().equals(ContentType.findByAssociatedObjectType(Template.BASE_DATA_OBJECT_TYPE)); + item.getContentType().equals(ContentType + .findByAssociatedObjectType(Template.BASE_DATA_OBJECT_TYPE)); if (isTemplate) { templateID = item.getID(); } @@ -104,7 +108,8 @@ class ContentSectionContextBar extends WorkspaceContextBar { parent = folder.getParent(); currentFolderLabel = folder.getLabel(); - if (parent != null || folder.equals(section.getRootFolder())) { + if (parent != null || folder.equals(section + .getRootFolder())) { params.setParameter (ContentSectionPage.SET_FOLDER, folder.getID()); } @@ -120,10 +125,12 @@ class ContentSectionContextBar extends WorkspaceContextBar { if (isTemplate) { params.setParameter - (ContentSectionPage.SET_TAB, new BigDecimal(ContentSectionPage.CONTENTTYPES_TAB)); + ( ContentSectionPage.SET_TAB, + new BigDecimal(ContentSectionPage.CONTENTTYPES_TAB) ); params.setParameter(ContentSectionPage.SET_TEMPLATE, templateID); } - // add section-level entry. if this is for an item page, the URL will be for the root folder. + // add section-level entry. if this is for an item page, the URL + // will be for the root folder. final URL url = URL.there (state.getRequest(), section.getPath() + "/" + PageLocations.SECTION_PAGE, diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionPage.java b/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionPage.java index 219a5bb49..4aaecbd9c 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionPage.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionPage.java @@ -34,7 +34,6 @@ import com.arsdigita.cms.ContentSection; import com.arsdigita.cms.PageLocations; import com.arsdigita.cms.SecurityManager; import com.arsdigita.cms.dispatcher.CMSPage; -import com.arsdigita.cms.util.SecurityConstants; import com.arsdigita.cms.ui.category.CategoryAdminPane; import com.arsdigita.cms.ui.cse.ContentSoonExpiredPane; import com.arsdigita.cms.ui.folder.FolderAdminPane; @@ -42,17 +41,18 @@ import com.arsdigita.cms.ui.lifecycle.LifecycleAdminPane; import com.arsdigita.cms.ui.role.RoleAdminPane; import com.arsdigita.cms.ui.type.ContentTypeAdminPane; import com.arsdigita.cms.ui.workflow.WorkflowAdminPane; +import com.arsdigita.cms.util.SecurityConstants; import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.kernel.User; import com.arsdigita.toolbox.ui.LayoutPanel; -import com.arsdigita.util.Assert; import com.arsdigita.ui.DebugPanel; +import com.arsdigita.util.Assert; import com.arsdigita.web.Web; -import org.apache.log4j.Logger; - import javax.servlet.http.HttpServletRequest; +import org.apache.log4j.Logger; + /** * Contains the entire admin UI for a content section. * @@ -68,7 +68,7 @@ public class ContentSectionPage extends CMSPage implements ActionListener { (ContentSectionPage.class); public static final String RESOURCE_BUNDLE = - "com.arsdigita.cms.CMSResources"; + "com.arsdigita.cms.CMSResources"; /** * The URL parameter that can be passed in in order to set the diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchCreateItemPane.java b/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchCreateItemPane.java index 2de091720..c2728401a 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchCreateItemPane.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchCreateItemPane.java @@ -1,7 +1,22 @@ /* - * To change this template, choose Tools | Templates - * and open the template in the editor. + * Copyright (C) 2011-2013 University of Bremen. 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.cms.ui; import com.arsdigita.bebop.BoxPanel; @@ -41,50 +56,101 @@ import java.math.BigDecimal; * @author Sören Bernstein (quasimodo)Created the TabbedPane to use for this page. Adds the tabs + * to the pane. The default implementation uses a {@link + * com.arsdigita.bebop.TabbedPane}. This implementation also adds + * browse, search, staff admin, viewers admin, workflow admin, + * category admin, and content type panes.
+ * + *Developers can override this method to add only the tabs + * they want, or to add additional tabs after the default CMS tabs + * are added.
+ */ + protected TabbedPane createTabbedPane() { + final TabbedPane pane = new TabbedPane(); + + //tab(pane, "cms.ui.folders", getFolderAdminPane()); + tab(pane, "cms.ui.browse", getBrowsePane()); + tab(pane, "cms.ui.search", getSearchPane()); + tab(pane, "cms.ui.images", getImagesPane()); + tab(pane, "cms.ui.roles", getRoleAdminPane()); + tab(pane, "cms.ui.workflows", getWorkflowAdminPane()); + tab(pane, "cms.ui.lifecycles", getLifecycleAdminPane()); + tab(pane, "cms.ui.categories", getCategoryAdminPane()); + tab(pane, "cms.ui.content_types", getContentTypeAdminPane()); + tab(pane, "cms.ui.user_admin", getUserAdminPane()); + tab(pane, "cms.ui.cse", getCSEPane()); + tab(pane, "cms.ui.reports", getReportPane()); + + return pane; + } + + /** + * Fetch the request-local content section. + * + * @param request The HTTP request + * @return The current content section + */ + public ContentSection getContentSection(HttpServletRequest request) { + // Resets all content sections associations. + // ContentSection section = super.getContentSection(request); + ContentSection section = ContentSectionServlet.getContentSection(request); + Assert.exists(section); + return section; + } + + /** + * When a new tab is selected, reset the state of the + * formerly-selected pane. + * + * @param event The event fired by selecting a tab + */ + public void actionPerformed(ActionEvent event) { + final PageState state = event.getPageState(); + + final Component pane = m_tabbedPane.getCurrentPane(state); + + if (pane == m_searchPane) { + m_searchPane.reset(state); + } else if (pane == m_imagesPane) { + m_imagesPane.reset(state); + } else if (pane == m_folderPane) { + m_folderPane.reset(state); + } else if (pane == m_browsePane) { + m_browsePane.reset(state); + } else if (pane == m_rolePane) { + m_rolePane.reset(state); + } else if (pane == m_workflowPane) { + m_workflowPane.reset(state); + } else if (pane == m_lifecyclePane) { + m_lifecyclePane.reset(state); + } else if (pane == m_categoryPane) { + m_categoryPane.reset(state); + } else if (pane == m_typePane) { + m_typePane.reset(state); + } else if (pane == m_userAdminPane) { + //m_userAdminPane.reset(state); + } else if (pane == m_csePane) { + //m_csePane.reset(state); + } + } + + /** + * Construct a URL for displaying the tab + * + * @param item The item from which we get the corresponding content section + * @param tab The index of the tab to display + */ + public static String getSectionURL(ContentItem item, int tab) { + // Get the content section associated with the content item. + ContentSection section = null; + + section = ContentSection.getContentSection(item); + + String url = section.getURL() + PageLocations.SECTION_PAGE + + "?" + SET_TAB + "=" + tab; + + return url; + } + + private static GlobalizedMessage gz(final String key) { + return new GlobalizedMessage(key, RESOURCE_BUNDLE); + } + + /** + * Getting the GlobalizedMessage using a CMS Class targetBundle. + * + * @param key The resource key + * @pre key != null + */ + public static GlobalizedMessage globalize(final String key) { + return new GlobalizedMessage(key, RESOURCE_BUNDLE); + } +} diff --git a/ccm-core/src/com/arsdigita/bebop/Completable.java b/ccm-core/src/com/arsdigita/bebop/Completable.java index 111da673e..48b9126ae 100755 --- a/ccm-core/src/com/arsdigita/bebop/Completable.java +++ b/ccm-core/src/com/arsdigita/bebop/Completable.java @@ -38,6 +38,7 @@ import org.apache.log4j.Logger; **/ public abstract class Completable implements Component { + private final static Logger s_log = Logger.getLogger(Completable.class); public Completable() {