diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/CMSDispatcher.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/CMSDispatcher.java deleted file mode 100755 index d5a83e93d..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/CMSDispatcher.java +++ /dev/null @@ -1,718 +0,0 @@ -/* - * 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.dispatcher; - -import com.arsdigita.dispatcher.ChainedDispatcher; -import com.arsdigita.dispatcher.Dispatcher; -import com.arsdigita.dispatcher.DispatcherHelper; -import com.arsdigita.dispatcher.JSPApplicationDispatcher; -import com.arsdigita.dispatcher.RedirectException; -import com.arsdigita.dispatcher.RequestContext; -import com.arsdigita.util.UncheckedWrapperException; -import com.arsdigita.web.LoginSignal; -import com.arsdigita.web.URL; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; - -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.shiro.authz.AuthorizationException; -import org.libreccm.cdi.utils.CdiUtil; -import org.libreccm.core.UnexpectedErrorException; -import org.libreccm.security.PermissionChecker; -import org.libreccm.security.Shiro; -import org.libreccm.security.User; -import org.librecms.CmsConstants; -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentSection; -import org.librecms.contentsection.ContentSectionManager; -import org.librecms.contentsection.ContentSectionRepository; -import org.librecms.contentsection.privileges.ItemPrivileges; -import org.librecms.dispatcher.ItemResolver; - -/** - *

- * The CMS Dispatcher serves all request made within a content section. This - * dispatcher is called by the Subsite dispatcher.

- * - *

- * Here are the steps for a request to - * http://yourserver/cms/cheese in excruciating detail:

- * - *
    - *
  1. - * A client sends a request to the web server, which passes it on to the global - * ACS dispatcher.

  2. - * - *
  3. - * The global ACS dispatcher examines the first part of the URL, notices that - * CMS is mounted at /cms and hands the request to the CMS - * dispatcher.

  4. - * - *
  5. - * The CMS dispatcher determines whether a Page has been registered to - * the URL /cheese in this section via its - * {@link com.arsdigita.cms.dispatcher.PageResolver}.

  6. - * - *
  7. - * Since no page is registered to the URL, the CMS dispatcher asks the content - * section (via its {@link com.arsdigita.cms.dispatcher.ItemResolver}) for a - * content item for /cheese in this content section. The result of this - * process is a {@link com.arsdigita.cms.ContentItem} object.

  8. - * - *
  9. - * The CMS dispatcher asks the content section for a Page - * to use as the "master template" for this item. The content section may apply - * item-, type-, or request-specific rules to make this decision (for example, - * check a user preference for normal or accessible style, or a query parameter - * for a printable version).

  10. - * - *
  11. - * The CMS dispatcher hands the master Page object to the - * {@link com.arsdigita.sitenode.SiteNodePresentationManager} to serve the - * page.

  12. - * - *
  13. - * The presentation manager asks the master Page object for an XML - * document representing the data for the page.

  14. - * - *
  15. - * The master template begins walking through its component hierarchy, - * converting each component to XML by calling its - * generateXML method. The component responsible for rendering the - * content item uses an {@link com.arsdigita.cms.dispatcher.XMLGenerator} to - * convert the content item to XML.

  16. - * - *
  17. - * The presentation manager receives the completed XML document, and selects an - * XSL transformer to use for generating the HTML. The stylesheet on which the - * transformer is based contains templates for all styles and all content types - * in the content section, in particular those from the file - * cms-item.xsl.

  18. - *
- * - * @author Michael Pih (pihman@arsdigita.com) - * @author Uday Mathur (umathur@arsdigita.com) - * @author Jack Chung (flattop@arsdigita.com) - * @author Jens Pelzetter - */ -public class CMSDispatcher implements Dispatcher, ChainedDispatcher { - - private static Logger LOGGER = LogManager.getLogger(CMSDispatcher.class); - - public static final String CONTENT_SECTION - = "com.arsdigita.cms.dispatcher.section"; - - public static final String CONTENT_ITEM - = "com.arsdigita.cms.dispatcher.item"; - - public static final String[] INDEX_FILES = { - "index.jsp", "index.html", "index.htm"}; - - private static final String DEBUG = "/debug"; - private static final String ADMIN_SECTION = "admin"; - - public static final String ADMIN_URL = "admin/index"; - - /** - * The context for previewing items - */ - public static final String PREVIEW = "preview"; - - // Content section cache - private static HashMap s_pageResolverCache = new HashMap(); -// private static HashMap s_itemResolverCache = new HashMap(); - private static HashMap s_xmlGeneratorCache = new HashMap(); - - private boolean m_adminPagesOnly = false; - - public CMSDispatcher() { - this(false); - } - - public CMSDispatcher(boolean adminOnly) { - m_adminPagesOnly = adminOnly; - } - - /** - * Handles requests made to a CMS package instance. 1) fetches the current - * content section 2) fetches the resource mapped to the current section/URL - * 3) if no resource, fetches the item associated with the current - * section/URL 4) if no item, passes request to the JSP dispatcher, which - * serves JSP's, HTML pages, and media from the cms/packages/www directory - * - * @param request The request - * @param response The response - * @param actx The request context - */ - public void dispatch(HttpServletRequest request, - HttpServletResponse response, - RequestContext actx) - throws IOException, ServletException { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Dispatching request for " + new URL(request) - .toDebugString()); - } - - // This is the path to the current site node. - String processedUrl = actx.getProcessedURLPart(); - String webappURLContext = request.getContextPath(); - if (processedUrl.startsWith(webappURLContext)) { - processedUrl = processedUrl.substring(webappURLContext.length()); - } - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Determined the path to the current site node; it " - + "is '" + processedUrl + "' according to the " - + "request context"); - } - - // This is the path within the site node. - String remainingUrl = actx.getRemainingURLPart(); - if (remainingUrl.endsWith("/")) { - remainingUrl = remainingUrl.substring(0, remainingUrl.length() - 1); - } else if (remainingUrl.endsWith(ItemDispatcher.FILE_SUFFIX)) { - remainingUrl = remainingUrl.substring(0, remainingUrl.length() - - ItemDispatcher.FILE_SUFFIX - .length()); - } else if (remainingUrl.equals("")) { - remainingUrl = "index"; - } - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Determined the path after the current site node; " - + "it is '" + remainingUrl + "'"); - } - - // Fetch the current content section. - ContentSection section = null; - try { - section = findContentSection(processedUrl); - } catch (Exception ex) { - throw new ServletException(ex); - } - request.setAttribute(CONTENT_SECTION, section); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Found content section '" + section + "'"); - } - - // Check user access to this page and deny access if necessary. - checkUserAccess(request, response, actx); - - // Look for a site-node-specific asset (if any). - // KG: This hack will be replaced by a ChainedDispatcher - try { - LOGGER.debug("Looking for a site node asset"); - - String siteNodeAssetURL = getSiteNodeAsset(request, actx); - if (siteNodeAssetURL != null) { - LOGGER.debug("Site node asset found at '" + siteNodeAssetURL - + "'"); - - DispatcherHelper.cacheDisable(response); - DispatcherHelper.setRequestContext(request, actx); - DispatcherHelper.forwardRequestByPath(siteNodeAssetURL, - request, response); - return; - } - - LOGGER.debug("No site node asset found; proceeding with normal " - + "dispatching"); - } catch (RedirectException e) { - throw new ServletException(e); - } - - // Fetch the requested resource (if any). - ResourceHandler resource = getResource(section, remainingUrl); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Got a resource '" + resource + "'"); - } - - if (resource != null) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Found resource '" + remainingUrl + "'; " - + "dispatching to it"); - } - - LOGGER.info("resource dispatch for " + remainingUrl); - // Found resource, now serve it. - // NB, ResouceHandler implementations should take care of caching options - resource.dispatch(request, response, actx); - - } else { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("No resource found at '" + remainingUrl + "'; " - + "searching for a previewable content item at " - + "this path"); - } - - // If the remaining URL starts with "preview/", then try and - // preview this item. Otherwise look for the live item. - boolean preview = false; - if (remainingUrl.startsWith(PREVIEW)) { - remainingUrl = remainingUrl.substring(PREVIEW.length()); - preview = true; - } - - // Check for published / previewable item. - ContentItem item = null; - - // Check if the user has access to view public pages - final PermissionChecker permissionChecker = CdiUtil.createCdiUtil() - .findBean(PermissionChecker.class); - - if (permissionChecker.isPermitted( - ItemPrivileges.VIEW_PUBLISHED, item)) { - if (preview) { - item = getContentItem(section, - remainingUrl, - CMSDispatcher.PREVIEW); - } else { - item = getContentItem(section, - remainingUrl, - "live"); - } - if (item != null) { - request.setAttribute(CONTENT_ITEM, item); - } - } - - if (item != null) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Found item " + item + "; serving it"); - } - - DispatcherHelper.cacheDisable(response); - preview(request, response, actx); - } else { - LOGGER.debug("No item to preview found; falling back to " - + "JSP dispatcher to look for some concrete " - + "resource in the file system"); - - // If no resource was found, look for a JSP page. - JSPApplicationDispatcher jsp = JSPApplicationDispatcher - .getInstance(); - //DispatcherHelper.cacheDisable(response); - jsp.dispatch(request, response, actx); - } - - } - - } - - public int chainedDispatch(HttpServletRequest request, - HttpServletResponse response, - RequestContext actx) - throws IOException, ServletException { - if (m_adminPagesOnly) { - String url = actx.getRemainingURLPart(); - - if (url.endsWith(ItemDispatcher.FILE_SUFFIX)) { - url = url.substring(0, url.length() - ItemDispatcher.FILE_SUFFIX - .length()); - } else if (url.endsWith("/")) { - url = url.substring(0, url.length() - 1); - } - - if (url.equals(ADMIN_URL)) { - if (LOGGER.isInfoEnabled()) { - LOGGER.info("Resolving admin URL '" + url + "'"); - } - - dispatch(request, response, actx); - - return ChainedDispatcher.DISPATCH_BREAK; - } else { - return ChainedDispatcher.DISPATCH_CONTINUE; - } - } - - dispatch(request, response, actx); - return ChainedDispatcher.DISPATCH_BREAK; - } - - /** - * Verify that the user is logged in and is able to view the page. - * Subclasses can override this method if they need to, but should always be - * sure to call super.checkUserAccess(...) - * - * @param request The HTTP request - * @param response The HTTP response - * @param actx The request context - * - * @throws javax.servlet.ServletException - * - */ - protected void checkUserAccess(HttpServletRequest request, - HttpServletResponse response, - RequestContext actx) - throws ServletException, AuthorizationException { - - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final Shiro shiro = cdiUtil.findBean(Shiro.class); - User user = shiro.getUser().get(); - final PermissionChecker permissionChecker = cdiUtil.findBean( - PermissionChecker.class); - - ContentSection section = getContentSection(request); - - if (isAdminPage(actx.getRemainingURLPart())) { - - // Handle admin page requests. - // If the user is not logged in, redirect to the login page. - // Otherwise, perform the Admin Pages access check. - if (user == null) { - redirectToLoginPage(request, response); - return; - } - //if (!sm.canAccess(user, SecurityManager.ADMIN_PAGES)) { - permissionChecker.checkPermission(ItemPrivileges.EDIT, - section.getRootDocumentsFolder()); - } else { - // For public page requests, use the SecurityManager to check access - // SecurityManager.canAccess(user, SecurityManager.PUBLIC_PAGES) must - permissionChecker.checkPermission( - ItemPrivileges.VIEW_PUBLISHED, - section.getRootDocumentsFolder()); - } - } - - /** - * Fetches the content section from the request attributes. - * - * @param request The HTTP request - * - * @return The content section - * - * @pre ( state != null ) - */ - public static ContentSection getContentSection(HttpServletRequest request) { - return (ContentSection) request.getAttribute(CONTENT_SECTION); - } - - /** - * Fetches the content item from the request attributes. - * - * @param request The HTTP request - * - * @return The content item - * - * @pre ( state != null ) - */ - public static ContentItem getContentItem(HttpServletRequest request) { - return (ContentItem) request.getAttribute(CONTENT_ITEM); - } - - /** - * Looks up the current content section using the remaining URL stored in - * the request context object and the SiteNode class. - * - * @param url The section URL stub - * - * @return The current Content Section - */ - protected ContentSection findContentSection(String url) { - - // MP: This is a hack to get the debugging info in - // SiteNodePresentationManager.servePage, but since it's - // debugging info... - // Remove /debug from the start of the URL if it exists. - if (url.startsWith(DEBUG)) { - url = url.substring(DEBUG.length()); - } - - final String debugXMLString = "/xml"; - if (url.startsWith(debugXMLString)) { - url = url.substring(debugXMLString.length()); - } - - final String debugXSLString = "/xsl"; - if (url.startsWith(debugXSLString)) { - url = url.substring(debugXSLString.length()); - } - - final String sectionLabel = url; - - // Fetch the current site node from the URL. - final ContentSectionRepository sectionRepo = CdiUtil.createCdiUtil() - .findBean(ContentSectionRepository.class); - final ContentSection section = sectionRepo - .findByLabel(url) - .orElseThrow(() -> new UnexpectedErrorException( - String.format("No ContentSection '%s' found.", sectionLabel))); - return section; - } - - /** - * Fetch a resource based on the URL stub. - * - * @param section The current content section - * @param url The section-relative URL - * - * @return A ResourceHandler resource or null if none exists. - * - * @pre (url != null) - */ - protected ResourceHandler getResource(ContentSection section, String url) - throws ServletException { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Searching for a resource for the URL fragment '" + url - + "' under " + section); - } - - final PageResolver pageResolver = CMSDispatcher.getPageResolver(section); - - final ResourceHandler handler = pageResolver.getPage(url); - - return handler; - } - - /** - * Lookup a content item by section and URL. - * - * @param section The content section - * @param url The URL relative to the content section - * @param context The use context - * - * @return The item associated with the URL, or null if no such item exists - * - * @throws javax.servlet.ServletException - */ - protected ContentItem getContentItem(ContentSection section, String url, - String context) - throws ServletException { - - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final ContentSectionManager sectionManager = cdiUtil.findBean( - ContentSectionManager.class); - final ItemResolver itemResolver = sectionManager - .getItemResolver(section); - - return itemResolver.getItem(section, url, context); - } - - /** - * Preview the current content item. - * - * @param request The HTTP request - * @param response The HTTP response - * @param actx The request context - */ - protected void preview(HttpServletRequest request, - HttpServletResponse response, - RequestContext actx) - throws IOException, ServletException { - - ContentSection section = getContentSection(request); - ContentItem item = getContentItem(request); - - ItemResolver itemResolver = CMSDispatcher.getItemResolver(section); - CMSPage page = itemResolver.getMasterPage(item, request); - page.dispatch(request, response, actx); - } - - /** - * Flushes the page resolver cache. - * - * @param section The current content section - * @param url The section-relative URL - */ - public static void releaseResource(ContentSection section, String url) { - final String pageResolverClassName = section.getPageResolverClass(); - final PageResolver pageResolver; - try { - pageResolver = (PageResolver) Class.forName(pageResolverClassName) - .newInstance(); - } catch (ClassNotFoundException - | IllegalAccessException - | InstantiationException ex) { - throw new RuntimeException(ex); - } - pageResolver.releasePage(url); - } - - /** - * Fetches the PageResolver for a content section. Checks cache first. - * - * @param section The content section - * - * @return The PageResolver associated with the content section - */ - public static PageResolver getPageResolver(ContentSection section) { - LOGGER.debug("Getting the page resolver"); - - final String name = section.getLabel(); - PageResolver pr = (PageResolver) s_pageResolverCache.get(name); - - if (pr == null) { - LOGGER.debug("The page resolver was not cached; fetching a new " - + "one and placing it in the cache"); - - final String pageResolverClassName = section.getPageResolverClass(); - final PageResolver pageResolver; - try { - pageResolver = (PageResolver) Class.forName( - pageResolverClassName) - .newInstance(); - } catch (ClassNotFoundException - | IllegalAccessException - | InstantiationException ex) { - throw new RuntimeException(ex); - } - s_pageResolverCache.put(name, pageResolver); - } - - return pr; - } - - /** - * Fetches the ItemResolver for a content section. Checks cache first. - * - * @param section The content section - * - * @return The ItemResolver associated with the content section - */ - public static ItemResolver getItemResolver(ContentSection section) { - - final Class clazz; - try { - clazz = Class.forName(section.getItemResolverClass()); - } catch (ClassNotFoundException ex) { - throw new UncheckedWrapperException(ex); - } - - return (ItemResolver) CdiUtil.createCdiUtil().findBean(clazz); - - } - - /** - * Fetches the XMLGenerator for a content section. Checks cache first. - * - * @param section The content section - * - * @return The XMLGenerator associated with the content section - */ - public static XMLGenerator getXMLGenerator(ContentSection section) { - String name = section.getLabel(); - XMLGenerator xmlGenerator = (XMLGenerator) s_xmlGeneratorCache.get(name); - if (xmlGenerator == null) { - final String xmlGeneratorClassName = section.getXmlGeneratorClass(); - try { - xmlGenerator = (XMLGenerator) Class.forName( - xmlGeneratorClassName).newInstance(); - } catch (ClassNotFoundException - | IllegalAccessException - | InstantiationException ex) { - throw new RuntimeException(ex); - } - s_xmlGeneratorCache.put(name, xmlGenerator); - } - - return xmlGenerator; - } - - /** - * Does this URL correspond to an admin page? - */ - protected boolean isAdminPage(String url) { - - // MP: This is a hack to get the debugging info in - // SiteNodePresentationManager.servePage, but since it's - // debugging info... - // Remove /debug from the start of the URL if it exists. - if (url.startsWith(DEBUG)) { - url = url.substring(DEBUG.length()); - } - - return (url != null && (url.startsWith(ADMIN_SECTION) || url.startsWith( - PREVIEW))); - } - - /** - * Redirects the client to the login page, setting the return url to the - * current request URI. - * - * @exception ServletException If there is an exception thrown while trying - * to redirect, wrap that exception in a - * ServletException - * - */ - protected void redirectToLoginPage(HttpServletRequest req, - HttpServletResponse resp) - throws ServletException { - throw new LoginSignal(req); - } - - // modified from JSPApplicationDispatcher - private String getSiteNodeAsset(HttpServletRequest request, - RequestContext actx) - throws RedirectException { - - String siteNodeAssetURL = null; - - ServletContext sctx = actx.getServletContext(); - String processedURL = actx.getProcessedURLPart(); - String remainingURL = actx.getRemainingURLPart(); - // REMOVE THIS HACK ONCE we have working publish to file code in the build - //String templateRoot = PublishToFile.getDefaultDestinationForType(Template.class); - String templateRoot = null; - - /* Allow a graceful early exit if publishToFile is not initialized */ - if (null == templateRoot) { - return null; - } - - File siteNodeAssetRoot = new File(templateRoot, processedURL); - File assetFile = new File(siteNodeAssetRoot, remainingURL); - - String contextPath = request.getContextPath(); - - if (assetFile.isDirectory()) { - - if (remainingURL.endsWith("/")) { - throw new RedirectException(actx.getOriginalURL() + "/"); - } - - for (int i = 0; i < INDEX_FILES.length; i++) { - File indexFile = new File(assetFile, INDEX_FILES[i]); - if (indexFile.exists()) { - assetFile = indexFile; - } - } - } - - if (assetFile.exists()) { - siteNodeAssetURL = contextPath + "/" + templateRoot - + processedURL + remainingURL; - } - - return siteNodeAssetURL; - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/CMSPage.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/CMSPage.java deleted file mode 100755 index dd8d401af..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/CMSPage.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * 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.dispatcher; - -import com.arsdigita.bebop.BebopConfig; -import com.arsdigita.bebop.Container; -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.Page; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.page.PageTransformer; -import com.arsdigita.cms.CMS; -import com.arsdigita.dispatcher.RequestContext; -import com.arsdigita.templating.PresentationManager; -import com.arsdigita.web.Web; -import com.arsdigita.xml.Document; -import com.arsdigita.xml.Element; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.libreccm.cdi.utils.CdiUtil; -import org.libreccm.security.PermissionChecker; -import org.libreccm.security.Shiro; -import org.libreccm.security.User; -import org.libreccm.web.CcmApplication; -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentItemRepository; -import org.librecms.contentsection.ContentSection; -import org.librecms.contentsection.ContentSectionServlet; -import org.librecms.contentsection.privileges.ItemPrivileges; - -import java.util.Optional; - -/** - *

- * A CMSPage is a Bebop {@link com.arsdigita.bebop.Page} implementation - * of the {@link com.arsdigita.cms.dispatcher.ResourceHandler} interface.

- * - *

- * It stores the current {@link com.arsdigita.cms.ContentSection} and, if - * applicable, the {@link com.arsdigita.cms.ContentItem} in the page 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) - */ -public class CMSPage extends Page implements ResourceHandler { - - private static final Logger LOGGER = LogManager.getLogger(CMSPage.class); - - /** - * The global assets URL stub XML parameter name. - */ - public final static String ASSETS = "ASSETS"; - - /** - * The XML page class. - */ - public final static String PAGE_CLASS = "CMS"; - - /** - * Map of XML parameters - */ - private HashMap m_params; - - /** - * */ - private PageTransformer m_transformer; - - public CMSPage() { - super(); - buildPage(); - } - - public CMSPage(String title) { - super(title); - buildPage(); - } - - public CMSPage(String title, Container panel) { - super(title, panel); - buildPage(); - } - - public CMSPage(Label title) { - super(title); - buildPage(); - } - - public CMSPage(Label title, Container panel) { - super(title, panel); - buildPage(); - } - - /** - * Builds the page. - */ - protected void buildPage() { - // Set the class attribute value. May be overwritten by child class - // to hold a more specific value - setClassAttr(PAGE_CLASS); - - // Global XML params. - // MP: This only works with older versions of Xalan. - m_params = new HashMap(); - setXMLParameter(ASSETS, Utilities.getGlobalAssetsURL()); - - // MP: This is a hack to so that the XML params work with the newer - // version of Xalan. - // Sets attribute in SimpleComponent, attributes of the same name will - // be overweritten. - setAttribute(ASSETS, Utilities.getGlobalAssetsURL()); - - // Make sure the error display gets rendered. - getErrorDisplay().setIdAttr("page-body"); - - final Class presenterClass = BebopConfig - .getConfig().getPresenterClass(); - final PresentationManager pm; - try { - pm = presenterClass.getDeclaredConstructor().newInstance(); - } catch (InstantiationException - | IllegalAccessException - | InvocationTargetException - | NoSuchMethodException ex) { - throw new RuntimeException(ex); - } - - if (pm instanceof PageTransformer) { - m_transformer = (PageTransformer) pm; - } else { - m_transformer = new PageTransformer(); - } - } - - /** - * Finishes and locks the page. If the page is already locked, does nothing. - * - * This method is called by the {@link com.arsdigita.dispatcher.Dispatcher} - * that initializes this page. - */ - @Override - public synchronized void init() { - LOGGER.debug("Initializing the page"); - - if (!isLocked()) { - LOGGER.debug("The page hasn't been locked; locking it now"); - - lock(); - } - } - - /** - * Fetches the value of the XML parameter. - * - * @param name The parameter name - * - * @return The parameter value - * - * @pre (name != null) - */ - public String getXMLParameter(String name) { - return (String) m_params.get(name); - } - - /** - * Set an XML parameter. - * - * @param name The parameter name - * @param value The parameter value - * - * @pre (name != null) - */ - public void setXMLParameter(String name, String value) { - m_params.put(name, value); - } - - /** - * Fetch the request-local content section. - * - * @param request The HTTP request - * - * @return The current content section - * - * @deprecated use com.arsdigita.cms.CMS.getContext().getContentSection() - * instead Despite of being deprecated it can not be removed because it is - * required by the interface Resourcehandler which is implemented by this - * class. 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); - throw new UnsupportedOperationException(); - } - - /** - * Fetch the request-local content section. - * - * @param state The page state - * - * @return The current content section - * - * @deprecated use com.arsdigita.cms.CMS.getContext().getContentSection() - * instead Despite of being deprecated it can not be removed because it is - * required by ContentItemPage which extends CMSPage and uses this method. - */ - public ContentSection getContentSection(PageState state) { - return getContentSection(state.getRequest()); - } - - /** - * Fetch the request-local content item. - * - * @param request The HTTP request - * - * @return The current content item - * - * @deprecated use com.arsdigita.cms.CMS.getContext().getContentItem() - * instead Despite of being deprecated it can not be removed because it is - * required by the interface Resourcehandler which is implemented by this - * class. On the other hand, if deprecated, implementing ResourceHandler may - * not be required - */ - public ContentItem getContentItem(HttpServletRequest request) { - // resets all content item associations - return ContentSectionDispatcher.getContentItem(request); - } - - /** - * Fetch the request-local content item. - * - * @param state The page state - * - * @return The current content item - * - * @deprecated use com.arsdigita.cms.CMS.getContext().getContentItem() - * instead. Despite of being deprecated it can not be removed because it is - * required by ContentItemPage which extends CMSPage and uses this method. - */ - public ContentItem getContentItem(PageState state) { - return getContentItem(state.getRequest()); - } - - /** - * Services the Bebop page. - * - * @param request The servlet request object - * @param response the servlet response object - * @param actx The request context - * - * @pre m_transformer != null - */ - @Override - public void dispatch(final HttpServletRequest request, - final HttpServletResponse response, - final RequestContext actx) - throws IOException, ServletException { - - final CcmApplication app = Web.getWebContext().getApplication(); - ContentSection section = null; - - if (app == null) { - //Nothing to do - } else if (app instanceof ContentSection) { - section = (ContentSection) app; - } - - if (section != null) { - CMS.getContext().setContentSection(section); - } - - final String itemId = request.getParameter("item_id"); - - if (itemId != null) { - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final ContentItemRepository itemRepo = cdiUtil.findBean( - ContentItemRepository.class); - final ContentItem item = itemRepo - .findById(Long.parseLong(itemId)).get(); - final PermissionChecker permissionChecker = cdiUtil.findBean( - PermissionChecker.class); - permissionChecker.checkPermission(ItemPrivileges.PREVIEW, - item); - CMS.getContext().setContentItem(item); - } - - final Document document = buildDocument(request, response); - - m_transformer.servePage(document, request, response); - } - - /** - * Overwrites bebop.Page#generateXMLHelper to add the name of the user - * logged in to the page (displayed as part of the header). - * - * @param ps - * @param parent - * - * @return - */ - @Override - protected Element generateXMLHelper(PageState ps, Document parent) { - Element page = super.generateXMLHelper(ps, parent); - final Optional user = CdiUtil.createCdiUtil() - .findBean(Shiro.class).getUser(); - if (user.isPresent()) { - page.addAttribute("name", user.get().getName()); - } - - return page; - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ContentItemDispatcher.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ContentItemDispatcher.java deleted file mode 100755 index 5296089a2..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ContentItemDispatcher.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * 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.dispatcher; - -import com.arsdigita.dispatcher.Dispatcher; -import com.arsdigita.dispatcher.DispatcherHelper; -import com.arsdigita.dispatcher.RequestContext; -import com.arsdigita.util.Assert; -import com.arsdigita.web.Web; - -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentSection; - -/** - * This is the dispatcher for content-sections. It maintains a - * ContentItem-to-Template cache Code that modifies a published ContentItem's - * template must update the cache in this class by calling the appropriate cache - * methods. - * - * @author bche@redhat.com - */ -public class ContentItemDispatcher implements Dispatcher { - - /** cache for the template resolver */ - public static Map s_templateResolverCache = Collections - .synchronizedMap(new HashMap()); - - /** */ - protected ItemXML m_itemXML; - - /** - * */ - public ContentItemDispatcher() { - m_itemXML = new ItemXML(); - } - - /** - * @see com.arsdigita.dispatcher.Dispatcher#dispatch (HttpServletRequest, - * HttpServletResponse, RequestContext) - */ - public void dispatch(final HttpServletRequest request, - final HttpServletResponse response, - final RequestContext actx) - throws IOException, ServletException { - - Boolean bXMLMode = (Boolean) request - .getAttribute("xmlMode"); - if (bXMLMode != null && bXMLMode.booleanValue()) { - //if this is XML mode, then use itemXML - m_itemXML.dispatch(request, response, actx); - } else { - //this is normal dispatching - - //get the Content Item - //final ContentItem item = (ContentItem) request.getAttribute - // (ContentSectionServlet.CONTENT_ITEM); - final ContentItem item = getContentItem(request); - //get the Content Section - final ContentSection section = (ContentSection) Web.getWebContext() - .getApplication(); - - Assert.exists(item); - - //get the item's template -// final String sTemplateURL = getTemplatePath(item, request, actx); - - //dispatch to the template - DispatcherHelper.setRequestContext(request, actx); - DispatcherHelper.forwardRequestByPath(null, request, - response); - - } - } - - /** - * Fetches the content item from the request attributes. - * - * @param request The HTTP request - * - * @return The content item - * - * @pre ( request != null ) - */ - public static ContentItem getContentItem(HttpServletRequest request) { - return (ContentItem) request.getAttribute( - "com.arsdigita.cms.dispatcher.item"); - } - -// //synchronize access to the cache -// private static synchronized void cachePut(BigDecimal contentItemID, -// String sTemplatePath) { -// s_cache.put(contentItemID, sTemplatePath); -// } -// -// private static synchronized void cacheRemove(BigDecimal contentItemID) { -// s_cache.remove(contentItemID); -// } -// -// /** -// * Method cacheRemove. Removes the cached template path for the contentItem -// * item -// * -// * @param item -// */ -// public static void cacheRemove(ContentItem item) { -// if (item == null) { -// return; -// } -// if (s_log.isDebugEnabled()) { -// s_log.debug("removing cached entry for item " + item.getName() -// + " with ID " + item.getID()); -// } -// s_cache.remove(item.getID()); -// } - - /** - * Method cachePut. Maps the ContentItem item to the template t in the cache - * - * @param item - * @param t - */ -// public static void cachePut(ContentItem item, Template t) { -// ContentSection section = item.getContentSection(); -// String sPath = getTemplatePath(section, t); -// -// //only cache live items -// if (item == null || item.getVersion().compareTo(ContentItem.LIVE) != 0) { -// return; -// } -// -// if (s_log.isDebugEnabled()) { -// s_log.debug("updating mapping for item " + item.getName() -// + " with ID " + item.getID() + " in section " + section -// .getName() + " of type " + item.getContentType().getName() -// + " to template " + sPath); -// } -// -// cachePut(item.getID(), sPath); -// } - - /** - * Method cachePut. Maps all the content items of ContentType type and in - * ContentSection section that don't have their own templates to the - * template t in the cache - * - * @param section - * @param type - * @param t - */ -// public static void cachePut(ContentSection section, -// ContentType type, -// Template t) { -// s_log.debug("updating cache for section " + section.getName() -// + " and type " + type.getName()); -// -// //get all the items in the section -// ItemCollection items = section.getItems(); -// -// //filter items by content type -// BigDecimal typeID = type.getID(); -// Filter filter = items.addFilter("type.id = :typeID"); -// filter.set("typeID", typeID); -// -// //get only live items -// Filter liveFilter = items.addFilter("version = '" + ContentItem.LIVE -// + "'"); -// -// //filter out content items in ContentSection section of -// //ContentType type with a template for the "public" context -// Filter itemsFilter = items.addNotInSubqueryFilter("id", -// "com.arsdigita.cms.ItemsWithTemplateMapping"); -// itemsFilter.set("sectionId", section.getID()); -// itemsFilter.set("typeId", type.getID()); -// -// //TODO: FILTER OUT CONTENT ITEMS IN THIS SECTION OF THIS TYPE -// //WITH A TEMPLATE FOR THE "PUBLIC" CONTEXT -// /* -// * select items.item_id -// * from cms_items items, cms_item_template_map map -// * where items.item_id = map.item_id -// * and use_context = 'public' -// * and items.version = 'live' -// * and items.section_id = :section_id -// * and items.type_id = :type_id -// */ -// synchronized (s_cache) { -// //update the cache for all items -// while (items.next()) { -// cachePut(items.getContentItem(), t); -// } -// } -// } - -// private static String getTemplatePath(ContentSection section, -// Template template) { -// //the template path is -// // TEMPLATE_ROOT/[content-section-name]/[template-path] -// final String sep = java.io.File.separator; -// String sPath = ContentSectionConfig.getConfig().getTemplateRoot() + sep -// + section.getName() + sep + template.getPath(); -// return sPath; -// } -// -// private static void updateTemplateCache(ContentSection section, -// ContentItem item, -// String sTemplatePath) { -// //use the live version of the item for the cache -// item = item.getLiveVersion(); -// s_log.debug("updating mapping for item " + item.getName() + " with ID " -// + item.getID() + " in section " + item.getContentSection() -// .getName() + " of type " + item.getContentType().getName() -// + " to template " + sTemplatePath); -// cachePut(item.getID(), sTemplatePath); -// } -// -// private String cacheGet(BigDecimal key) { -// return (String) s_cache.get(key); -// } - -// private String getTemplatePath(ContentItem item, -// HttpServletRequest req, -// RequestContext ctx) { -// -// //check if the template path is cached -// //BigDecimal id = item.getID(); -// //String sPath = cacheGet(id); -// //return from cache -// // current cache scheme doesn't work when there are -// //multiple templates per item, as would happen with -// // multiple template contexts or in the case of -// //category item resolution, more than one category for -// //the item. -// //if (sPath != null) { -// //s_log.debug("returning template path from cache"); -// // return sPath; -// //} -// //s_log.debug("template path not in cache, so fecthing"); -// //template is not in the cache, so retrieve it and place it in -// //the cache -// String sPath = fetchTemplateURL(item, req, ctx); -// //cachePut(id, sPath); -// -// return sPath; -// } - - /** - * Fetches the URL of a template for an item. The returned URL is relative - * to the webapp context. - */ -// public String fetchTemplateURL(ContentItem item, -// HttpServletRequest request, -// RequestContext actx) { -// if (s_log.isDebugEnabled()) { -// s_log.debug("fetching URL for item " + item.getName() + " with ID " -// + item.getID()); -// } -// -// ContentSection section = item.getContentSection(); -// String templateURL = getTemplateResolver(section).getTemplate(section, -// item, -// request); -// -// if (s_log.isDebugEnabled()) { -// s_log.debug("templateURL is " + templateURL); -// } -// return templateURL; -// -// } -// -// /** -// * Fetches the TemplateResolver for a content section. Checks cache first. -// * -// * @param section The content section -// * -// * @return The TemplateResolver associated with the content section -// */ -// public TemplateResolver getTemplateResolver(ContentSection section) { -// -// String name = section.getName(); -// TemplateResolver ir = (TemplateResolver) s_templateResolverCache.get( -// name); -// -// if (ir == null) { -// ir = section.getTemplateResolver(); -// s_templateResolverCache.put(name, ir); -// } -// -// return ir; -// } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ContentPanel.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ContentPanel.java deleted file mode 100755 index 200f1cd46..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ContentPanel.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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.dispatcher; - -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.SimpleComponent; -import com.arsdigita.cms.CMS; -import com.arsdigita.dispatcher.DispatcherHelper; -import com.arsdigita.util.Assert; -import com.arsdigita.xml.Element; - -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentSection; -import org.librecms.dispatcher.ItemResolver; - - -/** - *

- * This ContentPanel component fetches the - * {@link com.arsdigita.cms.dispatcher.XMLGenerator} for the content - * section.

- * - * @author Michael Pih (pihman@arsdigita.com) - * @version $Revision$ $Date$ - * @version $Id$ - */ -public class ContentPanel extends SimpleComponent { - - public ContentPanel() { - super(); - } - - /** - * Fetches an XML Generator. This method can be overridden to fetch any - * {@link com.arsdigita.cms.dispatcher.XMLGenerator}, but by default, it - * fetches the XMLGenerator registered to the current - * {@link com.arsdigita.cms.ContentSection}. - * - * @param state The page state - * - * @return The XMLGenerator used by this Content Panel - */ - protected XMLGenerator getXMLGenerator(PageState state) { - ContentSection section = CMS.getContext().getContentSection(); - Assert.exists(section); - try { - return (XMLGenerator) Class.forName(section.getXmlGeneratorClass()) - .newInstance(); - } catch (ClassNotFoundException | - InstantiationException | - IllegalAccessException ex) { - throw new RuntimeException(ex); - } - } - - /** - * Generates XML that represents a content item. - * - * @param state The page state - * @param parent The parent DOM element - * - * @see com.arsdigita.cms.dispatcher.XMLGenerator - */ - @Override - public void generateXML(PageState state, Element parent) { - if (isVisible(state)) { - Element content = parent.newChildElement("cms:contentPanel", - CMS.CMS_XML_NS); - exportAttributes(content); - - // Generate path information about the content item - generatePathInfoXML(state, content); - - // Take advantage of caching in the CMS Dispatcher. - XMLGenerator xmlGenerator = getXMLGenerator(state); - - xmlGenerator.generateXML(state, content, null); - } - } - - /** - * Generate information about the path to this content item. - * - * @param state the page state - * @param parent the element that will contain the path info - */ - protected void generatePathInfoXML(PageState state, Element parent) { - Element pathInfo = parent - .newChildElement("cms:pathInfo", CMS.CMS_XML_NS); - - if (CMS.getContext().hasContentSection()) { - pathInfo.newChildElement("cms:sectionPath", CMS.CMS_XML_NS).setText( - CMS.getContext().getContentSection().getPrimaryUrl()); - } - String url = DispatcherHelper.getRequestContext().getRemainingURLPart(); - if (url.startsWith(CMSDispatcher.PREVIEW)) { - pathInfo.newChildElement("cms:previewPath", CMS.CMS_XML_NS).setText( - "preview"); - } - pathInfo.newChildElement("cms:templatePrefix", CMS.CMS_XML_NS).setText( - "/" + ItemResolver.TEMPLATE_CONTEXT_PREFIX); - - if (CMS.getContext().hasContentItem()) { - ContentItem item = CMS.getContext().getContentItem(); - pathInfo.newChildElement("cms:itemPath", CMS.CMS_XML_NS).setText("/" - + item.getName()); - } - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ContentSectionDispatcher.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ContentSectionDispatcher.java deleted file mode 100755 index b77290f96..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ContentSectionDispatcher.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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.dispatcher; - -import com.arsdigita.dispatcher.Dispatcher; -import com.arsdigita.dispatcher.DispatcherChain; -import com.arsdigita.dispatcher.RequestContext; -import com.arsdigita.util.Assert; -import com.arsdigita.web.Web; - -import org.libreccm.cdi.utils.CdiUtil; -import org.libreccm.security.PermissionChecker; -import org.libreccm.web.ApplicationManager; -import org.librecms.CmsConstants; -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentSection; -import org.librecms.contentsection.privileges.ItemPrivileges; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Unsupported Refactored content section - * dispatcher (under development). - * - * @author Karl Goldstein (karlg@arsdigita.com) - * @version $Revision$ $DateTime: 2004/08/17 23:15:09 $ - * @version $Id$ - */ -public class ContentSectionDispatcher implements Dispatcher { - - public static final String CONTENT_ITEM - = "com.arsdigita.cms.dispatcher.item"; - - static final String CONTENT_SECTION = "com.arsdigita.cms.dispatcher.section"; - - private DispatcherChain dispatcherChain = new DispatcherChain(); - - public ContentSectionDispatcher() { - -// dispatcherChain.addChainedDispatcher(new CMSDispatcher(true)); -// dispatcherChain.addChainedDispatcher(new FileDispatcher()); -// dispatcherChain.addChainedDispatcher(new ItemDispatcher()); -// dispatcherChain.addChainedDispatcher(new CMSDispatcher()); - } - - public void dispatch(HttpServletRequest request, - HttpServletResponse response, - RequestContext context) - throws IOException, ServletException { - - setContentSection(request, context); - dispatcherChain.dispatch(request, response, context); - } - - /** - * Fetches the content section from the request attributes. - * - * @param request The HTTP request - * - * @return The content section - * - * @pre ( request != null ) - */ - public static ContentSection getContentSection(HttpServletRequest request) { - return (ContentSection) request.getAttribute(CONTENT_SECTION); - } - - /** - * Fetches the content item from the request attributes. - * - * @param request The HTTP request - * - * @return The content item - * - * @pre ( request != null ) - */ - public static ContentItem getContentItem(HttpServletRequest request) { - return (ContentItem) request.getAttribute(CONTENT_ITEM); - } - - /** - * Looks up the current content section using the remaining URL stored in - * the request context object and the SiteNode class. - * - * @param url The section URL stub - * - * @return The current Content Section - */ - private void setContentSection(HttpServletRequest request, - // SiteNodeRequestContext actx) - RequestContext actx) - throws ServletException { - - final ContentSection section = (ContentSection) Web.getWebContext() - .getApplication(); - request.setAttribute(CONTENT_SECTION, section); - } - - /** - * Checks that the current user has permission to access the admin pages. - * - * @param request - * @param section - */ - public static boolean checkAdminAccess(HttpServletRequest request, - ContentSection section) { - - return CdiUtil.createCdiUtil().findBean(PermissionChecker.class) - .isPermitted(ItemPrivileges.EDIT, section - .getRootDocumentsFolder()); - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ItemDispatcher.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ItemDispatcher.java deleted file mode 100755 index 1d4ea4cb4..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ItemDispatcher.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * 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.dispatcher; - -import com.arsdigita.dispatcher.ChainedDispatcher; -import com.arsdigita.dispatcher.DispatcherHelper; -import com.arsdigita.dispatcher.RequestContext; -import com.arsdigita.web.LoginSignal; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.libreccm.cdi.utils.CdiUtil; -import org.libreccm.security.PermissionChecker; -import org.libreccm.security.Shiro; -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentSection; -import org.librecms.contentsection.ContentSectionManager; -import org.librecms.contentsection.ContentSectionServlet; -import org.librecms.contentsection.privileges.ItemPrivileges; -import org.librecms.dispatcher.ItemResolver; - -/** - * Dispatches to the JSP or Servlet for rendering a content item. - * - * @author Karl Goldstein (karlg@arsdigita.com) - * - */ -public class ItemDispatcher implements ChainedDispatcher { - - private static Logger LOGGER = LogManager.getLogger(ItemDispatcher.class); - - public static Map s_itemResolverCache = Collections.synchronizedMap( - new HashMap()); - public static Map s_templateResolverCache = Collections.synchronizedMap( - new HashMap()); - - public static final String FILE_SUFFIX = ".jsp"; - public static final String INDEX_FILE = "/index"; -// public static final String TEMPLATE_ROOT = -// "/packages/content-section/templates"; -// public static final String DEFAULT_ITEM_TEMPLATE = "/default/item.jsp"; -// public static final String DEFAULT_FOLDER_TEMPLATE = "/default/folder.jsp"; - - public static final String XML_SUFFIX = ".xml"; - public static final String XML_MODE = "xmlMode"; - - private static boolean m_cacheItems = true; - - /** - * The context for previewing items - */ - public static final String PREVIEW = "/preview"; - - protected ItemXML m_itemXML; - - public ItemDispatcher() { - super(); - m_itemXML = new ItemXML(); - } - - public static void setCacheItems(boolean value) { - m_cacheItems = value; - } - - public int chainedDispatch(final HttpServletRequest request, - final HttpServletResponse response, - final RequestContext actx) - throws IOException, ServletException { - String queryString = request.getQueryString(); - String url = actx.getRemainingURLPart(); - - LOGGER.info("Resolving item URL " + url); - - if (url.endsWith(XML_SUFFIX)) { - request.setAttribute(XML_MODE, Boolean.TRUE); - LOGGER.debug("StraightXML Requested"); - url = "/" + url.substring(0, url.length() - XML_SUFFIX.length()); - } else { - request.setAttribute(XML_MODE, Boolean.FALSE); - // it's neither a .jsp or a .xml, thus its an error - if (url.endsWith(FILE_SUFFIX)) { - url = "/" + url - .substring(0, url.length() - FILE_SUFFIX.length()); - } else if (url.endsWith("/")) { - url = "/" + url.substring(0, url.length() - 1); - } else { - LOGGER.warn("Fail: URL doesn't have right suffix."); - return ChainedDispatcher.DISPATCH_CONTINUE; - } - } - - final ContentSection section = ContentSectionServlet.getContentSection( - request); - // ContentSectionDispatcher.getContentSection(request); - - final ContentItem item = getItem(section, url); - if (item == null) { - LOGGER.warn("Fail: No live item found matching " + url); - return ChainedDispatcher.DISPATCH_CONTINUE; - } - - request.setAttribute(ContentSectionDispatcher.CONTENT_ITEM, item); - - LOGGER.debug("MATCHED " + item.getObjectId()); - - // Work out how long to cache for.... - // We take minimum(default timeout, lifecycle expiry) - //ToDo -// Lifecycle cycle = item.getLifecycle(); - int expires = DispatcherHelper.getDefaultCacheExpiry(); -// if (cycle != null) { -// Date endDate = cycle.getEndDate(); -// -// if (endDate != null) { -// int maxAge = (int) ( ( endDate.getTime() - System.currentTimeMillis() ) / 1000l ); -// if (maxAge < expires) { -// expires = maxAge; -// } -// } -// } -//ToDo end - // NB, this is not the same as the security check previously - // We are checking if anyone can access - ie can we allow - // this page to be publically cached - if (m_cacheItems && !url.startsWith(PREVIEW)) { -// if (sm.canAccess((User)null, SecurityManager.PUBLIC_PAGES, item)) { - if (CdiUtil.createCdiUtil().findBean(PermissionChecker.class) - .isPermitted( - ItemPrivileges.VIEW_PUBLISHED, item)) { - DispatcherHelper.cacheForWorld(response, expires); - } else { - DispatcherHelper.cacheForUser(response, expires); - } - } else { - DispatcherHelper.cacheDisable(response); - } - - if (((Boolean) request.getAttribute(XML_MODE)).booleanValue()) { - m_itemXML.dispatch(request, response, actx); - return ChainedDispatcher.DISPATCH_BREAK; - } else { - - // normal dispatching - // This part assumes the template is JSP. -// final String templateURL = getTemplateURL(section, item, request, -// actx); -// s_log.debug("TEMPLATE " + templateURL); - DispatcherHelper.setRequestContext(request, actx); - DispatcherHelper.forwardRequestByPath(null, request, - response); - return ChainedDispatcher.DISPATCH_BREAK; - } - } - - public ContentItem getItem(ContentSection section, String url) { - - ItemResolver itemResolver = getItemResolver(section); - ContentItem item; - // Check if the user has access to view public or preview pages - boolean hasPermission = true; - HttpServletRequest request = DispatcherHelper.getRequest(); - - // If the remaining URL starts with "preview/", then try and - // preview this item. Otherwise look for the live item. - boolean preview = false; - if (url.startsWith(PREVIEW)) { - url = url.substring(PREVIEW.length()); - preview = true; - } - - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final PermissionChecker permissionChecker = cdiUtil.findBean( - PermissionChecker.class); - - if (preview) { - item = itemResolver.getItem(section, url, "draft"); - if (item != null) { - hasPermission = permissionChecker.isPermitted( - ItemPrivileges.PREVIEW, item); - } - } else { - item = itemResolver.getItem(section, url, "live"); - if (item != null) { - hasPermission = permissionChecker.isPermitted( - ItemPrivileges.VIEW_PUBLISHED, item); - } - } - - if (item == null && url.endsWith(INDEX_FILE)) { - - // look up folder if it's an index - url = url.substring(0, url.length() - INDEX_FILE.length()); - LOGGER.info("Attempting to match folder " + url); - item = itemResolver.getItem(section, url, "live"); - if (item != null) { - hasPermission = permissionChecker.isPermitted( - ItemPrivileges.VIEW_PUBLISHED, item); - } - } - // chris.gilbert@westsussex.gov.uk - if user is not logged in, give them a chance to do that, else show them the door - if (!hasPermission && !cdiUtil.findBean(Shiro.class).getSubject() - .isAuthenticated()) { - throw new LoginSignal(request); - } - if (!hasPermission) { - throw new com.arsdigita.dispatcher.AccessDeniedException(); - } - - return item; - } - - /** - * Fetches the ItemResolver for a content section. - * - * @param section The content section - * - * @return The ItemResolver associated with the content section - */ - public ItemResolver getItemResolver(ContentSection section) { - - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final ContentSectionManager sectionManager = cdiUtil.findBean( - ContentSectionManager.class); - - return sectionManager.getItemResolver(section); - } - - /** - * Fetches the ItemResolver for a content section. Checks cache first. - * - * @param section The content section - * - * @return The ItemResolver associated with the content section - */ -// public TemplateResolver getTemplateResolver(ContentSection section) { -// -// String name = section.getName(); -// TemplateResolver ir = (TemplateResolver) s_templateResolverCache.get( -// name); -// -// if (ir == null) { -// ir = section.getTemplateResolver(); -// s_templateResolverCache.put(name, ir); -// } -// -// return ir; -// } - /** - * Fetches the URL of a template for an item. The returned URL is relative - * to the webapp context. - */ -// public String getTemplateURL(ContentSection section, -// ContentItem item, -// HttpServletRequest request, -// RequestContext actx) { -// -// String templateURL = getTemplateResolver(section).getTemplate(section, -// item, -// request); -// -// return templateURL; -// } -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ItemXML.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ItemXML.java deleted file mode 100755 index d859ef41e..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ItemXML.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2002-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.dispatcher; - - -import com.arsdigita.cms.CMS; -import com.arsdigita.dispatcher.RequestContext; -import com.arsdigita.xml.Document; -import com.arsdigita.xml.Element; - -import org.librecms.contentsection.ContentItem; - -import java.io.IOException; -import java.io.OutputStream; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - - -/*** - * - * XMLPage - * - * Designed to allow you to output straight XML directly from the ContentItem - * that implements XMLGenerator, with none of the surrounding headers, footers, etc - * - * @author slater@arsdigita.com - * - ***/ - -public class ItemXML extends ResourceHandlerImpl { - - public ItemXML() { - super(); - } - - public void dispatch(HttpServletRequest request, - HttpServletResponse response, - RequestContext actx) - throws IOException, ServletException { - - ContentItem item = getContentItem(request); - - Element content = new Element("cms:item", CMS.CMS_XML_NS); - -// ContentItemXMLRenderer renderer = -// new ContentItemXMLRenderer(content); - //ToDo -// renderer.setWrapAttributes(true); -// renderer.setWrapRoot(false); -// renderer.setWrapObjects(false); -// -// renderer.walk(item, SimpleXMLGenerator.ADAPTER_CONTEXT); -//ToDo End - - Document doc; - try { - doc = new Document(content); - } catch (javax.xml.parsers.ParserConfigurationException e) { - throw new javax.servlet.ServletException(e); - } - - OutputStream out = response.getOutputStream(); - try { - out.write(doc.toString(true).getBytes()); - } catch (IOException e) { - throw new ServletException(e); - } finally { - out.close(); - } - } -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/MasterPage.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/MasterPage.java deleted file mode 100755 index 2278982b1..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/MasterPage.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.dispatcher; - -import com.arsdigita.bebop.SimpleContainer; -import com.arsdigita.util.Assert; - -import org.librecms.contentsection.ContentSection; - -import javax.servlet.http.HttpServletRequest; - - -/** - *

A {@link com.arsdigita.cms.dispatcher.CMSPage} used for serving - * content items.

- * - *

This page contains a ContentPanel component which fetches - * the {@link com.arsdigita.cms.dispatcher.XMLGenerator} for the content - * section.

- * - * @author Michael Pih (pihman@arsdigita.com) - * @version $Revision$ $DateTime: 2004/08/17 23:15:09 $ - * @version $Id$ - */ -public class MasterPage extends CMSPage { - - public MasterPage() { - super("Master", new SimpleContainer()); - setIdAttr("master_page"); - - add(new ContentPanel()); - } - - /** - * 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); - Assert.exists(section); - return section; - } - - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/PageResolver.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/PageResolver.java deleted file mode 100755 index 9ea2c6581..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/PageResolver.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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.dispatcher; - - -import java.math.BigDecimal; -import java.util.HashMap; - - -/** - *

This class contains methods for registering and resolving {@link - * ResourceHandler CMS resources} in a specific content section.

- * - *

The PageResolver includes methods for caching resource - * mappings.

- * - * @author Michael Pih (pihman@arsdigita.com) - * @version $Revision$ $Date$ - * @version $Id$ - */ -public abstract class PageResolver { - - private BigDecimal m_sectionID; - - // Used for caching pages - private HashMap m_pages; - - - public PageResolver() { - m_pages = new HashMap(); - } - - public void setContentSectionID(BigDecimal id) { - m_sectionID = id; - } - - protected BigDecimal getContentSectionID() { - return m_sectionID; - } - - - /** - * Fetch the page associated with the request URL. - * - * @param url The content section-relative URL stub - * @return The resource - */ - public ResourceHandler getPage(String url) { - return (ResourceHandler) m_pages.get(url); - } - - /** - * Register a page to the content section. - * - * @param page The master page - * @param url The desired URL of the page - */ - public abstract void registerPage(ResourceHandler page, String url); - - - /** - * Register a page to the content section. - * - * @param page The master page - * @param url The desired URL of the page - */ - public abstract void unregisterPage(ResourceHandler page, String url); - - - /** - * Loads a page into the page resolver cache. - * - * @param url The URL of the resource to load into the cache - * @param page The resource - */ - public void loadPage(String url, ResourceHandler page) { - m_pages.put(url, page); - } - - /** - * Flushes a page from the page resolver cache. - * - * @param url The URL of the resource to remove from the cache - */ - public void releasePage(String url) { - m_pages.remove(url); - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ResourceHandler.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ResourceHandler.java deleted file mode 100755 index 72efec6dd..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ResourceHandler.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.dispatcher; - -import com.arsdigita.dispatcher.Dispatcher; - -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentSection; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; - - -/** - * An interface for resources that can be served. - * - * @author Michael Pih (pihman@arsdigita.com) - * @version $Revision$ $DateTime: 2004/08/17 23:15:09 $ - * @version $Id$ - **/ -public interface ResourceHandler extends Dispatcher { - - /** - * This method is called by the {@link com.arsdigita.dispatcher.Dispatcher} - * that initializes this page. - */ - public void init() throws ServletException; - - /** - * Fetches the content section context for this resource. - * - * @param request The HTTP request - * @return A content section or null if there is none - * @pre ( request != null ) - */ - public ContentSection getContentSection(HttpServletRequest request); - - /** - * Fetches the content item context for this resource. - * - * @param request The HTTP request - * @return A content item or null if there is none - * @pre ( request != null ) - */ - public ContentItem getContentItem(HttpServletRequest request); - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ResourceHandlerImpl.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ResourceHandlerImpl.java deleted file mode 100755 index 5ba96df8a..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/ResourceHandlerImpl.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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.dispatcher; - -import com.arsdigita.dispatcher.RequestContext; -import com.arsdigita.util.Assert; - -import org.apache.shiro.authz.AuthorizationException; -import org.libreccm.cdi.utils.CdiUtil; -import org.libreccm.security.PermissionChecker; -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentSection; -import org.librecms.contentsection.privileges.ItemPrivileges; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * An interface for resources that can be served. - * - * @author Michael Pih (pihman@arsdigita.com) - * @version $Revision$ $DateTime: 2004/08/17 23:15:09 $ - * @version $Id$ - * - */ -public abstract class ResourceHandlerImpl implements ResourceHandler { - - /** - * This method is called by the {@link com.arsdigita.dispatcher.Dispatcher} - * that initializes this page. - */ - public void init() throws ServletException { - // Do nothing. - } - - /** - * 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 = CMSDispatcher.getContentSection(request); - Assert.exists(section); - return section; - } - - /** - * Fetch the request-local content item. - * - * @param request The HTTP request - * - * @return The current content item - */ - public ContentItem getContentItem(HttpServletRequest request) { - // resets all content item associations - return CMSDispatcher.getContentItem(request); - } - - public void checkUserAccess(HttpServletRequest request, - HttpServletResponse response, - RequestContext actx, - ContentItem item) { - if (!CdiUtil.createCdiUtil().findBean(PermissionChecker.class) - .isPermitted(ItemPrivileges.VIEW_PUBLISHED, item)) { - throw new AuthorizationException( - "cms.dispatcher.no_permission_to_access_resource"); - } - } - - /** - * Services this resource. - * - * @param request The servlet request object - * @param response the servlet response object - * @param actx The request context - */ - public abstract void dispatch(HttpServletRequest request, - HttpServletResponse response, - RequestContext actx) - throws IOException, ServletException; - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/Utilities.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/Utilities.java deleted file mode 100755 index 4a2956d50..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/Utilities.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * 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.dispatcher; - -import com.arsdigita.bebop.PageState; -import com.arsdigita.cms.CMS; -import com.arsdigita.dispatcher.DispatcherHelper; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import javax.servlet.http.HttpServletResponse; - -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import org.librecms.CmsConstants; -import org.librecms.assets.BinaryAsset; -import org.librecms.assets.Image; -import org.librecms.contentsection.ContentSection; - -/** - *

- * This class provides many utility functions for the Content Management - * System.

- * Specifically used by various JSP templates. - * - * @author Michael Pih (pihman@arsdigita.com) - */ -public class Utilities { - - public static final Logger LOGGER = LogManager.getLogger(Utilities.class); - - // Used for caching util lookups - private static HashMap m_cache = new HashMap(); - - private static Date s_lastSectionRefresh = null; - private static Map s_sectionRefreshTimes = Collections.synchronizedMap( - new HashMap()); - - /** - * Fetch the location of the CMS ContentCenter package. - * - * @return The URL of the CMS ContentCenter package - * - * @deprecated use ContentCenter.getURL() instead - */ - public static String getWorkspaceURL() { - - return CmsConstants.CONTENT_CENTER_URL; - - } - - /** - * Fetch the location (URL) of the CMS Services package. Caches the result. - * - * @return The URL of the CMS Services package - * - * @deprecated Use Service.getURL( instead - */ - public static String getServiceURL() { - String url = (String) m_cache.get(CmsConstants.SERVICE_PACKAGE_KEY); - if (url == null) { - // chris.gilbert@westsussex.gov.uk - // We don't want application context in this url, especially when - // it gets cached in a static variable - if I have a - // file that is maintained by a non cms application eg - // forum, then I can end up with a url that doesn't work - // and so breaks file links everywhere - // url = getSingletonPackageURLSansContext(CMS.SERVICE_PACKAGE_KEY); - url = CmsConstants.SERVICE_URL; - m_cache.put(CmsConstants.SERVICE_PACKAGE_KEY, url); - } - - return url; - } - - /** - * The URL to log out. - * - * @return The logout URL - */ - public static String getLogoutURL() { - //StringBuffer buf = new StringBuffer(getServiceURL()); - StringBuilder buf = new StringBuilder(CmsConstants.SERVICE_URL); - buf.append("logout"); - return buf.toString(); - } - - /** - * Construct a URL which serves a binary asset. - * - * @param asset The binary asset - * - * @return the URL which will serve the specified binary asset - * - * @deprecated Use Service.getAssetURL(BinaryAsset asset) instead - */ - public static String getAssetURL(BinaryAsset asset) { - return getAssetURL(asset.getObjectId()); - } - - /** - * Constuct a URL which serves a binary asset. - * - * @param assetId The asset ID - * - * @return the URL which will serve the specified binary asset - * - * @deprecated Use Service.getAssetURL(BigDecimal assetId) instead - */ - public static String getAssetURL(long assetId) { - // StringBuffer buf = new StringBuffer(getServiceURL()); - StringBuilder buf = new StringBuilder(CmsConstants.SERVICE_URL); - buf.append("stream/asset?"); - buf.append(CmsConstants.ASSET_ID).append("=").append(assetId); - return buf.toString(); - } - - /** - * Construct a URL which serves an image. - * - * @param asset The image asset whose image is to be served - * - * @return the URL which will serve the specified image asset - * - * @deprecated Use Service.getImageURL(ImageAsset) instead! - */ - public static String getImageURL(Image asset) { - // StringBuffer buf = new StringBuffer(getServiceURL()); - StringBuilder buf = new StringBuilder(CmsConstants.SERVICE_URL); - buf.append("stream/image/?"); - buf.append(CmsConstants.IMAGE_ID).append("=") - .append(asset.getObjectId()); - return buf.toString(); - } - - public static String getGlobalAssetsURL() { - return getWebappContext(); - } - - /** - * Fetch the context path of the request. This is typically "/". - * - * @return The webapp context path - */ - public static String getWebappContext() { - return DispatcherHelper.getWebappContext(); - } - - /** - * Check for the last refresh on authoring kits or content types in a - * section. - * - */ - public static synchronized Date - getLastSectionRefresh(ContentSection section) { - - // cache by URL string instead of by section object to avoid - // holding the reference. - String sectionURL = section.getPrimaryUrl(); - - Date lastModified = (Date) s_sectionRefreshTimes.get(sectionURL); - if (lastModified == null) { - lastModified = new Date(); - s_lastSectionRefresh = lastModified; - s_sectionRefreshTimes.put(sectionURL, lastModified); - } - - return lastModified; - } - - /** - * Check for the last refresh on authoring kits or content types in any - * section. - * - */ - public static Date getLastSectionRefresh() { - - // instantiate last refresh lazily to ensure that first result is - // predictable. - if (s_lastSectionRefresh == null) { - s_lastSectionRefresh = new Date(); - } - return s_lastSectionRefresh; - } - - /** - * Force the authoring UI to reload. This should be done every time an - * authoring kit or a content type are updated. - */ - public static void refreshItemUI(PageState state) { - // Drop the authoring kit UI to force it to refresh - // THE URL SHOULD NOT BE HARDCODED ! - - ContentSection section = CMS.getContext().getContentSection(); - - // OLD APPROACH: used in conjunction with CMSDispatcher. This - // shouldn't do any harm even if CMSDispatcher is not being used. - CMSDispatcher.releaseResource(section, "admin/item"); - refreshAdminUI(state); - - // NEW APPROACH: used in conjunction with - // ContentSectionDispatcher. cache by URL string instead of by - // section object to avoid holding the reference. This shouldn't - // do any harm even if ContentSectionDispatcher is not being used. - s_lastSectionRefresh = new Date(); - s_sectionRefreshTimes.put(section.getPrimaryUrl(), - s_lastSectionRefresh); - } - - /** - * Force the authoring UI to reload. This should be done every time an - * authoring kit or a content type are updated. - */ - public static void refreshAdminUI(PageState state) { - // Drop the admin UI to force it to refresh - // THE URL SHOULD NOT BE HARDCODED ! - - ContentSection section = CMS.getContext().getContentSection(); - - CMSDispatcher.releaseResource(section, "admin"); - CMSDispatcher.releaseResource(section, "admin/index"); - CMSDispatcher.releaseResource(section, ""); - } - - /** - * Add the "pragma: no-cache" header to the HTTP response to make sure the - * browser does not cache tha page - * - * @param response The HTTP response - * - * @deprecated use - * com.arsdigita.dispatcher.DispatcherHelper.cacheDisable(HttpServletResponse) - */ - public static void disableBrowserCache(HttpServletResponse response) { - response.addHeader("pragma", "no-cache"); - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/XMLGenerator.java b/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/XMLGenerator.java deleted file mode 100755 index dabc5e599..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/dispatcher/XMLGenerator.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.dispatcher; - -import com.arsdigita.bebop.PageState; -import com.arsdigita.xml.Element; - - -/** - *

Generates XML representing a Content Item.

- * - *

As the last step of servicing a page, the - * {@link com.arsdigita.cms.dispatcher.MasterPage} will go through the - * hierarchy of its components and ask each of them to convert themselves - * to XML. A MasterPage contains a special component that knows how to ask - * its content section for the XML generator that should be applied. The - * XML generator's generateXML method in turn asks the - * containing page for the content item, the one that the - * {@link com.arsdigita.cms.dispatcher.ItemResolver} found before, and - * formats it as an XML document.

- * - * @author Michael Pih (pihman@arsdigita.com) - * @version $Id$ - */ -public interface XMLGenerator { - - /** - * Generates the XML to render the content panel. - * - * @param state The page state - * @param parent The parent DOM element - * @param useContext The use context - */ - public void generateXML(PageState state, Element parent, String useContext); - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/lifecycle/Duration.java b/ccm-cms/src/main/java/com/arsdigita/cms/lifecycle/Duration.java deleted file mode 100755 index 4ece2dcfe..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/lifecycle/Duration.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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.lifecycle; - -import com.arsdigita.util.Assert; - -/** - * Utility methods for lifecycle durations. - * - * @author Michael Pih - * @author 0) { - buffer.append(dhm[0]).append(" days"); - } - - if (dhm[1] > 0) { - if (dhm[0] > 0) { - buffer.append(", "); - } - buffer.append(dhm[1]).append(" hours"); - } - - if (dhm[0] > 0 || dhm[1] > 0) { - buffer.append(", "); - } - buffer.append(dhm[2]).append(" minutes"); - - return buffer.toString(); - } - - /** - * Formats time in minutes longo a days/hours/minutes format. - * - * @param minutes - * @return - */ - public static long[] formatDHM(final long minutes) { - long[] dhm = new long[3]; - - long days = minutes / (60 * 24); - long hours = minutes / 60; // no pun longended - long mins = minutes; - - if (days > 0) { - hours -= (days * 24); - mins -= (days * 24 * 60); - } - if (hours > 0) { - mins -= (hours * 60); - } - - dhm[0] = days; - dhm[1] = hours; - dhm[2] = mins; - return dhm; - } - - /** - * Formats time in minutes longo a days/hours/minutes format. - * - * @return - * @see #formatDHM(long) - * @param minutes timespan in minutes - */ - public static Long[] formatDHM(final Long minutes) { - long dhm[] = formatDHM(minutes.longValue()); - return copyArray(dhm); - } - - private static Long[] copyArray(long[] from) { - Assert.exists(from, "from"); - Long[] to = new Long[from.length]; - for (int ii = 0; ii < from.length; ii++) { - to[ii] = from[ii]; - } - return to; - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseDeleteForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseDeleteForm.java deleted file mode 100755 index 65adf39f8..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseDeleteForm.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.Label; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.event.FormProcessListener; -import com.arsdigita.bebop.form.Submit; -import com.arsdigita.globalization.GlobalizedMessage; - -/** - * @author Justin Ross - */ -public abstract class BaseDeleteForm extends BaseForm - implements FormProcessListener { - - protected final Submit m_delete; - protected final Submit m_cancel; - - public BaseDeleteForm(final Component message) { - super("delete", new Label(gz("cms.ui.attention"))); - - addComponent(message); - - m_delete = new Submit("delete", gz("cms.ui.delete")); - addAction(m_delete); - - m_cancel = new Submit("cancel", gz("cms.ui.cancel")); - addAction(m_cancel); - - addProcessListener(this); - } - - public BaseDeleteForm(final GlobalizedMessage message) { - this(new Label(message)); - } - - @Override - public final boolean isCancelled(final PageState state) { - return m_cancel.isSelected(state); - } -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseForm.java deleted file mode 100755 index b1b991738..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseForm.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * 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.BoxPanel; -import com.arsdigita.bebop.Component; -import com.arsdigita.bebop.Form; -import com.arsdigita.bebop.GridPanel; -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.SimpleContainer; -import com.arsdigita.bebop.form.FormErrorDisplay; -import com.arsdigita.bebop.form.Submit; -import com.arsdigita.bebop.form.TextArea; -import com.arsdigita.bebop.form.TextField; -import com.arsdigita.bebop.parameters.NotEmptyValidationListener; -import com.arsdigita.bebop.parameters.NotNullValidationListener; -import com.arsdigita.bebop.parameters.StringLengthValidationListener; -import com.arsdigita.bebop.parameters.TrimmedStringParameter; -import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.toolbox.ui.Cancellable; -import com.arsdigita.toolbox.ui.Section; -import com.arsdigita.util.Assert; - -import org.librecms.CmsConstants; - -/** - * A convenience class for CMS forms. - * - * @author Jens Pelzetter - * @author Justin Ross - */ -public abstract class BaseForm extends Form implements Cancellable { - - private final BodySection m_body; - private final BoxPanel m_actions; - private Cancel m_cancel; - - protected BaseForm(final String name, final Label heading) { - super(name, new GridPanel(1)); - - setRedirecting(true); - - m_body = new BodySection(heading); - m_actions = new BoxPanel(BoxPanel.HORIZONTAL); - - add(m_body); - add(m_actions); - - addComponent(new FormErrorDisplay(this)); - } - - protected BaseForm(final String name, - final GlobalizedMessage heading) { - this(name, new Label(heading)); - } - - private class BodySection extends Section { - - final SimpleContainer m_container; - - BodySection(final Label heading) { - setHeading(heading); - - m_container = new GridPanel(2); - setBody(m_container); - } - - final void add(final Component component) { - m_container.add(component); - } - - final void add(final Component component, int hints) { - m_container.add(component, hints); - } - - } - - protected final void addComponent(final Component component) { - m_body.add(component, GridPanel.FULL_WIDTH); - } - - protected final void addField(final Label name, final Component widget) { - m_body.add(name); - m_body.add(widget); - } - - protected final void addField(final GlobalizedMessage name, - final Component widget) { - addField(new Label(name), widget); - } - - protected final void addAction(final Submit button) { - m_actions.add(button); - } - - protected final void addAction(final Cancel button) { - m_cancel = button; - m_actions.add(button); - } - - protected final void addSecurityListener(final String action) { - addSubmissionListener(new FormSecurityListener(action)); - } - - protected final void addSecurityListener(final String action, - final ContentItemRequestLocal item) { - addSubmissionListener(new FormSecurityListener(action, item)); - } - - @Override - public boolean isCancelled(final PageState state) { - return m_cancel != null && m_cancel.isSelected(state); - } - - protected final class Name extends TextField { - - public Name(final String key, final int max, final boolean required) { - super(new TrimmedStringParameter(key)); - - if (required) { - addValidationListener(new NotEmptyValidationListener()); - } - - setSize(40); - setMaxLength(max); - } - - } - - protected final class Description extends TextArea { - - public Description(final String key, - final int maxLength, - final boolean isRequired) { - super(new TrimmedStringParameter(key)); - Assert.isTrue(maxLength > 0, "Max length cannot be negative"); - - if (isRequired) { - addValidationListener(NotNullValidationListener.DEFAULT); - } - addValidationListener(new StringLengthValidationListener(maxLength)); - setCols(40); - setRows(5); - setWrap(TextArea.SOFT); - } - - } - - protected final class Finish extends Submit { - - public Finish() { - super("finish", gz("cms.ui.finish")); - } - - } - - protected final class Cancel extends Submit { - - public Cancel() { - super("cancel", gz("cms.ui.cancel")); - } - - } - - protected static final GlobalizedMessage gz(final String key) { - return new GlobalizedMessage(key, CmsConstants.CMS_BUNDLE); - } - - protected static final String lz(final String key) { - return (String) gz(key).localize(); - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseItemPane.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseItemPane.java deleted file mode 100755 index 9e9ec1a4d..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseItemPane.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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.globalization.GlobalizedMessage; -import com.arsdigita.toolbox.ui.ModalPanel; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.librecms.CmsConstants; - -/** - * @author Justin Ross - * @author Jens Pelzetter - */ -public abstract class BaseItemPane extends ModalPanel { - - private static final Logger LOGGER = LogManager.getLogger - (BaseItemPane.class); - - protected BaseItemPane() { - super(); - } - - protected final static GlobalizedMessage gz(final String key) { - return new GlobalizedMessage(key, CmsConstants.CMS_BUNDLE); - } - - protected final static String lz(final String key) { - return (String) gz(key).localize(); - } -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSContainer.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSContainer.java deleted file mode 100755 index e9b898b2a..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSContainer.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.SimpleContainer; - - - -/** - * A simple container with XML wrapper tags. - * - * @author Michael Pih (pihman@arsdigita.com) - * @version $Id$ - */ -public class CMSContainer extends SimpleContainer { - - public final static String CMS_XML_NS = "http://www.arsdigita.com/cms/1.0"; - - - public CMSContainer() { - super("cms:container", CMS_XML_NS); - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSDHTMLEditor.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSDHTMLEditor.java deleted file mode 100755 index f26d5d37f..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSDHTMLEditor.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 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.form.DHTMLEditor; -import com.arsdigita.bebop.parameters.ParameterModel; -import com.arsdigita.bebop.parameters.StringParameter; -import com.arsdigita.cms.CMS; - -import org.librecms.CMSConfig; -import org.libreccm.cdi.utils.CdiUtil; -import org.libreccm.l10n.GlobalizationHelper; -import org.librecms.contentsection.ContentSection; - -/** - * - * - */ -public class CMSDHTMLEditor extends DHTMLEditor { - - public CMSDHTMLEditor(final String name) { - super(new StringParameter(name), - CMSConfig.getConfig().getDHTMLEditorConfig()); - addPlugins(); - hideButtons(); - - final ContentSection section = CMS.getContext().getContentSection(); - final GlobalizationHelper globalizationHelper = CdiUtil - .createCdiUtil() - .findBean(GlobalizationHelper.class); - setAttribute("current-contentsection-id", - Long.toString(section.getObjectId())); - setAttribute("current-contentsection-primaryurl", - section.getPrimaryUrl()); - setAttribute("current-contentsection-title", - globalizationHelper - .getValueFromLocalizedString(section.getTitle())); - - } - - public CMSDHTMLEditor(final ParameterModel model) { - super(model, - CMSConfig.getConfig().getDHTMLEditorConfig()); - - addPlugins(); - hideButtons(); - } - - private void addPlugins() { - - CMSConfig - .getConfig() - .getDhtmlEditorPlugins() - .forEach(plugin -> addPlugin(plugin)); - } - - private void hideButtons() { - - CMSConfig - .getConfig() - .getDhtmlEditorHiddenButtons() - .forEach(hiddenButton -> hideButton(hiddenButton)); - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSForm.java deleted file mode 100755 index 782190e37..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSForm.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.Container; -import com.arsdigita.bebop.Form; -import com.arsdigita.bebop.PageState; -import com.arsdigita.toolbox.ui.Cancellable; - -/** - * A convenience class for CMS forms. The "CMS Admin" class eliminates - * the nested tables created by the Bebop ColumnPanel. This is mainly - * to increase form rendering. - * - * @author Michael Pih - */ -public class CMSForm extends Form implements Cancellable { - - public static final String CLASS = "CMS Admin"; - - public CMSForm(final String name) { - super(name); - - setClassAttr(CLASS); - getPanel().setClassAttr(CLASS); - } - - public CMSForm(final String name, final Container panel) { - super(name, panel); - - setClassAttr(CLASS); - panel.setClassAttr(CLASS); - } - - /** - * Determines whether the form has been cancelled. - * Override this method if the form can be cancelled. - * - * @param state The page state - * @return true if the form is cancelled, false otherwise - */ - @Override - public boolean isCancelled(final PageState state) { - return false; - } -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/ContentItemPage.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/ContentItemPage.java deleted file mode 100755 index 3aad95602..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/ContentItemPage.java +++ /dev/null @@ -1,670 +0,0 @@ -/* - * 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.Component; -import com.arsdigita.bebop.FormData; -import com.arsdigita.bebop.FormProcessException; -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.Link; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.Resettable; -import com.arsdigita.bebop.SimpleContainer; -import com.arsdigita.bebop.TabbedPane; -import com.arsdigita.bebop.event.ActionEvent; -import com.arsdigita.bebop.event.ActionListener; -import com.arsdigita.bebop.event.FormSectionEvent; -import com.arsdigita.bebop.event.FormValidationListener; -import com.arsdigita.bebop.event.PrintEvent; -import com.arsdigita.bebop.event.PrintListener; -import com.arsdigita.bebop.parameters.LongParameter; -import com.arsdigita.bebop.parameters.NotNullValidationListener; -import com.arsdigita.bebop.parameters.StringParameter; -import com.arsdigita.cms.CMS; -import com.arsdigita.cms.ItemSelectionModel; -import com.arsdigita.cms.PageLocations; -import com.arsdigita.cms.dispatcher.CMSPage; -import com.arsdigita.cms.ui.authoring.WizardSelector; -import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.kernel.KernelConfig; -import com.arsdigita.kernel.ui.ACSObjectSelectionModel; -import com.arsdigita.util.Assert; -import com.arsdigita.xml.Document; -import com.arsdigita.xml.Element; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.librecms.CMSConfig; -import org.libreccm.cdi.utils.CdiUtil; -import org.librecms.CmsConstants; -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentItemL10NManager; -import org.librecms.contentsection.ContentItemRepository; -import org.librecms.contentsection.ContentItemVersion; -import org.librecms.contentsection.ContentSection; -import org.librecms.contentsection.ContentType; - -import java.io.IOException; -import java.util.Locale; -import java.util.Objects; -import java.util.Optional; - -import javax.servlet.http.HttpServletRequest; - -/** - * Page for administering a content item. - * - * @author Michael Pih - * @author Stanislav Freidin - * @author Jack Chung - * @author Sören Bernstein - * @author Jens Pelzetter - * - */ -public class ContentItemPage extends CMSPage implements ActionListener { - - /** - * Private Logger instance for debugging purpose. - */ - private static final Logger LOGGER = LogManager.getLogger( - ContentItemPage.class); - - /** - * The URL parameter that must be passed in in order to set the current tab. - * This is a KLUDGE right now because the TabbedDialog's current tab is - * selected with a local state parameter - */ - public static final String SET_TAB = "set_tab"; - - /** - * The name of the global state parameter that holds the item id. - */ - public static final String ITEM_ID = "item_id"; - - /** - * The name of th global state parameter that holds the selected language. - */ - public static final String SELECTED_LANGUAGE = "selected_language"; - - /** - * The name of the global state parameter which holds the return URL. - */ - public static final String RETURN_URL = "return_url"; - - /** - * The name of the global state parameter that determines whether or not to - * use the streamlined authoring process (assuming the option is turned on). - * - */ - public static final String STREAMLINED_CREATION = "streamlined_creation"; - - public static final String STREAMLINED_CREATION_ACTIVE = "active"; - - public static final String STREAMLINED_CREATION_INACTIVE = "active"; - - /** - * Index of the summary tab - */ - public static final int SUMMARY_TAB = 0; - - /** - *

- * The name of the state parameter which indicates the content type of the - * item the user wishes to create. or edit.

- * - *

- * The parameter must be a BigDecimalParameter which encodes the id of the - * content type.

- */ - public static final String CONTENT_TYPE = "content_type"; - - public static final int AUTHORING_TAB = 1; - - public static final int LANGUAGE_TAB = 2; - - public static final int WORKFLOW_TAB = 3; - - public static final int PUBLISHING_TAB = 4; - - public static final int HISTORY_TAB = 5; - - public static final int TEMPLATES_TAB = 6; - - private final TabbedPane tabbedPane; - - private final StringParameter returnUrlParameter; - - private final ItemSelectionModel itemSelectionModel; -// private final SingleSelectionModel selectedLanguageModel; - - private final ACSObjectSelectionModel typeSelectionModel; - - private final ContentItemRequestLocal itemRequestLocal; - - - private final WizardSelector wizardPane; - - private final Link previewLink; - - private final GlobalNavigation globalNavigation; - - private final StringParameter selectedLanguageParam; - - private class ItemRequestLocal extends ContentItemRequestLocal { - - @Override - protected final Object initialValue(final PageState state) { - return CMS.getContext().getContentItem(); - } - - } - - private class TitlePrinter implements PrintListener { - - @Override - public final void prepare(final PrintEvent event) { - - final PageState state = event.getPageState(); - - final Label label = (Label) event.getTarget(); - final ContentItem item = itemRequestLocal.getContentItem(event. - getPageState()); - - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final ContentItemL10NManager l10nManager = cdiUtil - .findBean(ContentItemL10NManager.class); - final String selectedLanguage = (String) state - .getValue(selectedLanguageParam); - final Locale selectedLocale; - if (selectedLanguage == null - || selectedLanguage.isEmpty()) { - selectedLocale = KernelConfig.getConfig().getDefaultLocale(); - } else { - selectedLocale = new Locale(selectedLanguage); - } - - final String language; - if (l10nManager.hasLanguage(item, selectedLocale)) { - language = selectedLanguage; - } else { - state.setValue(selectedLanguageParam, - KernelConfig.getConfig().getDefaultLanguage()); - language = KernelConfig.getConfig().getDefaultLanguage(); - } - - final StringBuffer title = new StringBuffer(item.getDisplayName()); - if (language != null) { - title - .append(" (") - .append(language) - .append(")"); - } - - label.setLabel(title.toString()); - } - - } - - /** - * Constructs a new ContentItemPage. - */ - public ContentItemPage() { - super("", new SimpleContainer()); - - itemRequestLocal = new ItemRequestLocal(); - - setClassAttr("cms-admin"); - setTitle(new Label(new TitlePrinter())); - - // Add the item id global state parameter - final LongParameter itemId = new LongParameter(ITEM_ID); - itemId.addParameterListener(new NotNullValidationListener(ITEM_ID)); - addGlobalStateParam(itemId); - itemSelectionModel = new ItemSelectionModel(itemId); - - // Add the selected item language as parameter - selectedLanguageParam = new StringParameter(SELECTED_LANGUAGE); - selectedLanguageParam.addParameterListener( - new NotNullValidationListener(SELECTED_LANGUAGE)); - addGlobalStateParam(selectedLanguageParam); -// selectedLanguageModel = new ParameterSingleSelectionModel<>( -// selectedLanguageParam); -// selectedLanguageParam -// .setDefaultValue(KernelConfig.getConfig().getDefaultLanguage()); - - // Add the content type global state parameter - final LongParameter contentType = new LongParameter(CONTENT_TYPE); - addGlobalStateParam(contentType); - - // Add the streamlined creation global state parameter - final StringParameter streamlinedCreation = new StringParameter( - STREAMLINED_CREATION); - addGlobalStateParam(streamlinedCreation); - - typeSelectionModel = new ACSObjectSelectionModel(ContentType.class - .getName(), - ContentType.class - .getName(), - contentType); - - // Validate the item ID parameter (caches the validation). - getStateModel().addValidationListener( - event -> validateItemID(event.getPageState())); - - // Add the return url global state parameter - returnUrlParameter = new StringParameter(RETURN_URL); - addGlobalStateParam(returnUrlParameter); - - globalNavigation = new GlobalNavigation(); - add(globalNavigation); - - // Create panels. - wizardPane = new WizardSelector(itemSelectionModel, typeSelectionModel); - - // Create tabbed pane. - tabbedPane = new TabbedPane(); - add(tabbedPane); - - tabbedPane.setIdAttr("page-body"); - - tabbedPane. - addTab(new Label(gz("cms.ui.item.authoring")), wizardPane); - - - tabbedPane.addActionListener(new ActionListener() { - - @Override - public final void actionPerformed(final ActionEvent event) { - - final PageState state = event.getPageState(); - final Component pane = tabbedPane.getCurrentPane(state); - - if (pane instanceof Resettable) { - ((Resettable) pane).reset(state); - } - } - - }); - - // Build the preview link. - previewLink = new Link(new Label(gz("cms.ui.preview")), - new PrintListener() { - - @Override - public final void prepare( - final PrintEvent event) { - final Link link = (Link) event.getTarget(); - link.setTarget(getPreviewURL(event. - getPageState())); - link.setTargetFrame(Link.NEW_FRAME); - } - - }); - previewLink.setIdAttr("preview_link"); - add(previewLink); - - addActionListener(this); - - // Add validation to make sure we are not attempting to edit a live item - getStateModel().addValidationListener(new FormValidationListener() { - - @Override - public void validate(final FormSectionEvent event) - throws FormProcessException { - - PageState s = event.getPageState(); - FormData data = event.getFormData(); - final ContentItem item = itemRequestLocal.getContentItem(s); - if (item != null - && ContentItemVersion.LIVE == item.getVersion()) { - LOGGER.error(String.format( - "The item %d is live and cannot be edited.", item. - getObjectId())); - throw new FormProcessException(new GlobalizedMessage( - "cms.ui.live_item_not_editable", - CmsConstants.CMS_BUNDLE)); - } - } - - }); - } - - /** - * Ensures that the item_id parameter references a valid {@link - * com.arsdigita.cms.ContentItem}. - * - * @param state The page state - * - * @pre state != null - * @exception FormProcessException if the item_id is not valid - */ - protected void validateItemID(final PageState state) throws - FormProcessException { - final ContentItem item = itemRequestLocal.getContentItem(state); - - if (item == null) { - throw new FormProcessException(new GlobalizedMessage( - "cms.ui.invalid_item_id", CmsConstants.CMS_BUNDLE)); - } - } - - /** - * Fetch the request-local content section. - * - * @deprecated use com.arsdigita.cms.CMS.getContext().getContentSection() - * instead - * @param request The HTTP request - * - * @return The current content section - */ - @Override - public ContentSection getContentSection(final HttpServletRequest request) { - // Resets all content sections associations. - ContentSection section = super.getContentSection(request); - Assert.exists(section); - return section; - } - - /** - * Overrides CMSPage.getContentItem(PageState state) to get the current - * content item from the page state. - * - * @deprecated Use the ItemSelectionModel - * @param state The page state - * - * @return The current content item, null if there is none - */ - @Override - public ContentItem getContentItem(final PageState state) { - return (ContentItem) itemSelectionModel.getSelectedObject(state); - } - - /** - * Set the current tab, if necessary - * - * @param event - */ - @Override - public void actionPerformed(final ActionEvent event) { - final PageState state = event.getPageState(); - final String setTab = state.getRequest().getParameter(SET_TAB); - - // Hide the templates tab, the workflow tab, and the preview - // link if the current item is a template. - final ContentItem item = itemRequestLocal.getContentItem(state); - - // ToDo: Reenable when Templates have been ported. Not clear yet if - // Templates will be ContentItems in LibreCMS... -// if (item instanceof Template) { -// tabbedPane.setTabVisible(state, templatesPane, false); -// tabbedPane.setTabVisible(state, workflowPane, false); -// tabbedPane.setTabVisible(state, languagesPane, false); -// m_previewLink.setVisible(state, false); -// } else { -// tabbedPane.setTabVisible(state, -// templatesPane, -// !ContentSectionConfig.getConfig().getHideTemplatesTab()); -// } - // Set the current tab based on parameters - if (setTab != null) { - Integer tab; - - try { - tab = Integer.valueOf(setTab); - } catch (NumberFormatException ex) { - // Stop processing set_tab parameter. - LOGGER.warn("Stopping processing of set_tab parameter.", ex); - return; - } - - if (tab < tabbedPane.size()) { - tabbedPane.setSelectedIndex(state, tab); - } - } - } - - /** - * Construct a URL for displaying a certain item - * - * @param nodeURL The URL where this page is mounted - * @param itemId The id of the item to display - * @param tab The index of the tab to display - * - * @return - */ - public static String getItemURL(final String nodeURL, - final Long itemId, - final int tab) { - return getItemURL(nodeURL, itemId, tab, false); - } - - /** - * Construct a URL for displaying a certain item - * - * @param nodeURL The URL where this page is mounted - * @param itemId The id of the item to display - * @param tab The index of the tab to display - * @param streamlinedCreation Whether to activate Streamlined item authoring - * - * @return - */ - public static String getItemURL(final String nodeURL, - final Long itemId, - final int tab, - final boolean streamlinedCreation) { - final StringBuilder urlBuilder = new StringBuilder(); - - urlBuilder - .append(nodeURL) - .append(PageLocations.ITEM_PAGE) - .append("?") - .append(ITEM_ID) - .append("=") - .append(itemId.toString()) - .append("&") - .append(SET_TAB) - .append("=") - .append(tab); - - if (streamlinedCreation - && CMSConfig.getConfig().isUseStreamlinedCreation()) { - - urlBuilder - .append("&") - .append(STREAMLINED_CREATION) - .append("=") - .append(STREAMLINED_CREATION_ACTIVE); - } - - return urlBuilder.toString(); - } - - /** - * @param itemId - * @param tab - * - * @return - * - * @deprecated Use getItemURL instead - */ - public static String getRelativeItemURL(final Long itemId, final int tab) { - final StringBuilder url = new StringBuilder(); - url - .append(PageLocations.ITEM_PAGE) - .append("?") - .append(ITEM_ID) - .append("=") - .append(itemId.toString()) - .append("&") - .append(SET_TAB) - .append("=") - .append(tab); - - return url.toString(); - } - - /** - * Constructs a URL for displaying a certain item. - * - * @param item the ContentItem object to display - * @param tab The index of the tab to display - * - * @return - */ - public static String getItemURL(final ContentItem item, - final int tab) { - - final ContentSection section = item.getContentType().getContentSection(); - - if (section == null) { - return null; - } else { - final String nodeURL = section.getPrimaryUrl() + "/"; - - return getItemURL(nodeURL, item.getObjectId(), tab); - } - } - - /** - * Constructs a URL for displaying a certain item. - * - * @param itemId the id of the ContentItem object to display - * @param tab The index of the tab to display - * - * @return - */ - public static String getItemURL(final long itemId, - final int tab) { - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final ContentItemRepository itemRepo = cdiUtil.findBean( - ContentItemRepository.class); - - final Optional item = itemRepo.findById(itemId); - - if (item.isPresent()) { - return getItemURL(item.get(), tab); - } else { - return null; - } - } - - /** - * Redirect back to wherever the user came from, using the value of the - * return_url parameter. - * - * @param state The current page state - */ - public void redirectBack(final PageState state) { - try { - final String returnUrl = (String) state.getValue(returnUrlParameter); - state.getResponse().sendRedirect(returnUrl); - } catch (IOException ex) { - LOGGER.error("IO Error redirecting back", ex); - // do nothing - } - } - - /** - * Fetch the preview URL. - */ - private String getPreviewURL(final PageState state) { - final ContentItem item = itemRequestLocal.getContentItem(state); - throw new UnsupportedOperationException(); - } - - /** - * - * @param state - * @param item - * - * @return - */ - private String getDefaultPreviewLink(final PageState state, - final ContentItem item) { - final ContentSection section = CMS.getContext().getContentSection(); - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); -// final ContentSectionManager sectionManager = cdiUtil.findBean( -// ContentSectionManager.class); -// final ItemResolver itemResolver = sectionManager -// .getItemResolver(section); - - // Pass in the "Live" context since we need it for the preview -// return itemResolver.generateItemURL(state, -// item, -// section, -// CMSDispatcher.PREVIEW); - final ContentItemPageController controller = cdiUtil - .findBean(ContentItemPageController.class); - - return controller.getDefaultPreviewLink(section, item, state); - } - - protected final static GlobalizedMessage gz(final String key) { - return new GlobalizedMessage(key, CmsConstants.CMS_BUNDLE); - } - - protected final static String lz(final String key) { - return (String) gz(key).localize(); - } - - public static boolean isStreamlinedCreationActive(final PageState state) { - return CMSConfig.getConfig().isUseStreamlinedCreation() - && STREAMLINED_CREATION_ACTIVE.equals(state.getRequest(). - getParameter(STREAMLINED_CREATION)); - } - - protected TabbedPane getTabbedPane() { - return tabbedPane; - } - - protected WizardSelector getWizardPane() { - return wizardPane; - } - - /** - * Adds the content type to the output. - * - * @param state PageState - * @param parent Parent document - * - * @return page - */ - @Override - protected Element generateXMLHelper(final PageState state, - final Document parent) { - - Objects.requireNonNull(itemRequestLocal.getContentItem(state), - "No ContentItem in current request."); - - final Element page = super.generateXMLHelper(state, parent); - final Element contenttype = page.newChildElement("bebop:contentType", - BEBOP_XML_NS); - - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - - final ContentItemPageController controller = cdiUtil - .findBean(ContentItemPageController.class); - contenttype - .setText(controller - .getContentTypeLabel(itemRequestLocal.getContentItem(state))); - - return page; - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/ContentItemPageController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/ContentItemPageController.java deleted file mode 100644 index 8d504dd12..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/ContentItemPageController.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2017 LibreCCM Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package com.arsdigita.cms.ui; - -import com.arsdigita.bebop.PageState; -import com.arsdigita.cms.dispatcher.CMSDispatcher; - -import org.libreccm.l10n.GlobalizationHelper; -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentItemRepository; -import org.librecms.contentsection.ContentSection; -import org.librecms.contentsection.ContentSectionManager; -import org.librecms.contentsection.ContentSectionRepository; -import org.librecms.dispatcher.ItemResolver; - -import javax.enterprise.context.RequestScoped; -import javax.inject.Inject; -import javax.transaction.Transactional; - -/** - * - * @author Jens Pelzetter - */ -@RequestScoped -class ContentItemPageController { - - @Inject - private GlobalizationHelper globalizationHelper; - - @Inject - private ContentSectionRepository sectionRepo; - - @Inject - private ContentSectionManager sectionManager; - @Inject - private ContentItemRepository itemRepo; - - @Transactional(Transactional.TxType.REQUIRED) - protected String getContentTypeLabel(final ContentItem item) { - - final ContentItem theItem = itemRepo - .findById(item.getObjectId()) - .orElseThrow(() -> new IllegalArgumentException(String - .format("No ContentItem with ID %d in the database.", - item.getObjectId()))); - - return theItem - .getContentType() - .getLabel() - .getValue(globalizationHelper.getNegotiatedLocale()); - } - - @Transactional(Transactional.TxType.REQUIRED) - protected String getDefaultPreviewLink(final ContentSection section, - final ContentItem item, - final PageState state) { - - final ContentSection contentSection = sectionRepo - .findById(section.getObjectId()) - .orElseThrow(() -> new IllegalArgumentException(String - .format("No ContentSectio with ID %d in the database.", - section.getObjectId()))); - - final ContentItem contentItem = itemRepo - .findById(item.getObjectId()) - .orElseThrow(() -> new IllegalArgumentException(String - .format("No ContentItem with ID %d in the database.", - item.getObjectId()))); - - final ItemResolver itemResolver = sectionManager - .getItemResolver(contentSection); - - return itemResolver.generateItemURL(state, - contentItem, - contentSection, - CMSDispatcher.PREVIEW); - - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/ContentItemRequestLocal.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/ContentItemRequestLocal.java deleted file mode 100755 index e33167548..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/ContentItemRequestLocal.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.PageState; -import com.arsdigita.bebop.RequestLocal; - -import org.librecms.contentsection.ContentItem; - -import com.arsdigita.util.Assert; - -/** - * {@link RequestLocal} storing a content item. - */ -public abstract class ContentItemRequestLocal extends RequestLocal { - - public final ContentItem getContentItem(final PageState state) { - final ContentItem item = (ContentItem) get(state); - - Assert.exists(item, "ContentItem item"); - - return item; - } -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/FileUploadSection.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/FileUploadSection.java deleted file mode 100755 index 90439fecb..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/FileUploadSection.java +++ /dev/null @@ -1,488 +0,0 @@ -/* - * 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.ColumnPanel; -import com.arsdigita.bebop.Container; -import com.arsdigita.bebop.FormData; -import com.arsdigita.bebop.FormSection; -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.event.FormSectionEvent; -import com.arsdigita.bebop.form.FileUpload; -import com.arsdigita.bebop.form.Option; -import com.arsdigita.bebop.form.OptionGroup; -import com.arsdigita.bebop.form.SingleSelect; -import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.dispatcher.MultipartHttpServletRequest; -import java.io.File; -import javax.activation.MimeType; -import javax.activation.MimeTypeParseException; -import javax.activation.MimetypesFileTypeMap; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import org.librecms.CmsConstants; - -/** - * A form section with two widgets: a mime-type selection widget and a file - * upload widget. The section will attempt to automatically guess the mime type - * from the filename (if necessary), and return the mime type. - * - * @author Stanislav Freidin (sfreidin@arsdigita.com) - * @author Jens Pelzetter - */ -public class FileUploadSection extends FormSection { - - private SingleSelect mimeWidget; - private FileUpload fileWidget; - private String mimePrefix; - private String defaultMimeType; - private String parameterPrefix; - - /** - * The mime type widget - */ - public static final String MIME_TYPE = "mime_type"; - - /** - * The file upload widget - */ - public static final String FILE_UPLOAD = "file_upload"; - - /** - * Automatically guess the mime type - */ - public static final String GUESS_MIME = "-guess-"; - - /** - * Construct a new FileUploadSection - * - * @param mimeLabel The label for the mime type widget - * - * @param mimePrefix Populate the mime type widget with all mime types that - * match the prefix. Some of the possible prefixes are "text", "image", - * "binary", etc. - * - * @param defaultMimeType The default mime type that should be assumed if - * the guessing fails - * - * @param panel The panel that is to be used to lay out the components - * - */ - public FileUploadSection(final GlobalizedMessage mimeLabel, - final String mimePrefix, - final String defaultMimeType, - final Container panel) { - this(mimeLabel, mimePrefix, defaultMimeType, "", panel); - } - - /** - * Construct a new FileUploadSection - * - * @param mimeLabel The label for the mime type widget - * - * @param mimePrefix Populate the mime type widget with all mime types that - * match the prefix. Some of the possible prefixes are "text", "image", - * "binary", etc. - * - * @param defaultMimeType The default mime type that should be assumed if - * the guessing fails - * - * @param panel The panel that is to be used to lay out the components - * - * @deprecated use the same constructor but with the GlobalizedMessage for - * the mimeLabel - */ - public FileUploadSection(final String mimeLabel, - final String mimePrefix, - final String defaultMimeType, - final Container panel) { - // This takes advantage of the fact that the "key" is returned - // when it is not present in the message bundle - this(new GlobalizedMessage(mimeLabel), - mimePrefix, - defaultMimeType, - panel); - } - - /** - * Construct a new FileUploadSection - * - * @param mimeLabel The label for the mime type widget - * - * @param mimePrefix Populate the mime type widget with all mime types that - * match the prefix. Some of the possible prefixes are "text", "image", - * "binary", etc. - * - * @param defaultMimeType The default mime type that should be assumed if - * the guessing fails - * - * @param parameterPrefix Prepended to MIME_TYPE and FILE_UPLOAD for - * parameter names so that more than 1 file upload widgets may be used per - * form - * - * @param panel The panel that is to be used to lay out the components - * - * @deprecated use the same constructor but with the GlobalizedMessage for - * the mimeLabel - */ - public FileUploadSection(final String mimeLabel, - final String mimePrefix, - final String defaultMimeType, - final String parameterPrefix, - final Container panel - ) { - // This takes advantage of the fact that the "key" is returned - // when it is not present in the message bundle - this(new GlobalizedMessage(mimeLabel, CmsConstants.CMS_BUNDLE), - mimePrefix, - defaultMimeType, - parameterPrefix, - panel); - } - - /** - * Construct a new FileUploadSection - * - * @param mimeLabel The label for the mime type widget - * - * @param mimePrefix Populate the mime type widget with all mime types that - * match the prefix. Some of the possible prefixes are "text", "image", - * "binary", etc. - * - * @param defaultMimeType The default mime type that should be assumed if - * the guessing fails - * - * @param parameterPrefix Prepended to MIME_TYPE and FILE_UPLOAD for - * parameter names so that more than 1 file upload widgets may be used per - * form - * - * @param panel The panel that is to be used to lay out the components - * - */ - public FileUploadSection(final GlobalizedMessage mimeLabel, - final String mimePrefix, - final String defaultMimeType, - final String parameterPrefix, - final Container panel) { - - super(panel); - - this.mimePrefix = mimePrefix; - this.defaultMimeType = defaultMimeType; - if (parameterPrefix == null) { - this.parameterPrefix = ""; - } else { - this.parameterPrefix = parameterPrefix; - } - - add(new Label(mimeLabel, false)); - mimeWidget = new SingleSelect(getMimeTypeWidgetName()); - addMimeOptions(mimeWidget, mimePrefix); - mimeWidget - .addOption(new Option(GUESS_MIME, - new Label(new GlobalizedMessage( - "cms.ui.authoring.file_upload.auto_detect", - CmsConstants.CMS_BUNDLE)))); - - mimeWidget.setDefaultValue(GUESS_MIME); - add(mimeWidget); - - add(new Label(new GlobalizedMessage("cms.ui.upload_new_content", - CmsConstants.CMS_BUNDLE))); - fileWidget = new FileUpload(getFileUploadWidgetName()); - add(fileWidget); - } - - /** - * Construct a new FileUploadSection - * - * @param mimeLabel The label for the mime type widget - * - * @param mimePrefix Populate the mime type widget with all mime types that - * match the prefix. Some of the possible prefixes are "text", "image", - * "binary", etc. - * - * @param defaultMimeType The default mime type that should be assumed if - * the guessing fails - * - * @param parameterPrefix Prepended to MIME_TYPE and FILE_UPLOAD for - * parameter names so that more than 1 file upload widgets may be used per - * form - * - */ - public FileUploadSection(final GlobalizedMessage mimeLabel, - final String mimePrefix, - final String defaultMimeType, - final String parameterPrefix) { - this(mimeLabel, - mimePrefix, - defaultMimeType, - parameterPrefix, - new ColumnPanel(2, true)); - final ColumnPanel panel = (ColumnPanel) getPanel(); - panel.setBorder(false); - panel.setPadColor("#FFFFFF"); - } - - /** - * Construct a new FileUploadSection - * - * @param mimeLabel The label for the mime type widget - * - * @param mimePrefix Populate the mime type widget with all mime types that - * match the prefix. Some of the possible prefixes are "text", "image", - * "binary", etc. - * - * @param defaultMimeType The default mime type that should be assumed if - * the guessing fails - * - * @param parameterPrefix Prepended to MIME_TYPE and FILE_UPLOAD for - * parameter names so that more than 1 file upload widgets may be used per - * form - * - * @deprecated use the same constructor but with the GlobalizedMessage for - * the mimeLabel - */ - public FileUploadSection(final String mimeLabel, - final String mimePrefix, - final String defaultMimeType, - final String parameterPrefix) { - // This takes advantage of the fact that the "key" is returned - // when it is not present in the message bundle - this(new GlobalizedMessage(mimeLabel, CmsConstants.CMS_BUNDLE), - mimePrefix, - defaultMimeType, - parameterPrefix); - } - - /** - * Construct a new FileUploadSection - * - * @param mimeLabel The label for the mime type widget - * - * @param mimePrefix Populate the mime type widget with all mime types that - * match the prefix. Some of the possible prefixes are "text", "image", - * "binary", etc. - * - * @param defaultMimeType The default mime type that should be assumed if - * the guessing fails - * - * @deprecated use the same constructor but with the GlobalizedMessage for - * the mimeLabel - */ - public FileUploadSection(final String mimeLabel, - final String mimePrefix, - final String defaultMimeType) { - - // This takes advantage of the fact that the "key" is returned - // when it is not present in the message bundle - this(new GlobalizedMessage(mimeLabel, CmsConstants.CMS_BUNDLE), - mimePrefix, - defaultMimeType, - ""); - } - - /** - * Construct a new FileUploadSection - * - * @param mimeLabel The GlobalizedMessage for the label for the mime type - * widget - * - * @param mimePrefix Populate the mime type widget with all mime types that - * match the prefix. Some of the possible prefixes are "text", "image", - * "binary", etc. - * - * @param defaultMimeType The default mime type that should be assumed if - * the guessing fails - * - */ - public FileUploadSection(GlobalizedMessage mimeLabel, - String mimePrefix, - String defaultMimeType) { - this(mimeLabel, mimePrefix, defaultMimeType, ""); - } - - /** - * Try to guess the mime type from the filename, and return it. The parent - * form should call this method in its process listener. Note that this - * method may return null if the mime type could not be guessed. - * - * @param event The form section event - * @return The mime type of the file. - */ - public MimeType getMimeType(final FormSectionEvent event) { - - final FormData data = event.getFormData(); - - final String fileName = (String) data.get(getFileUploadWidgetName()); - final String mimeTypeName = (String) data.get(getMimeTypeWidgetName()); - - // Guess the mime type from the filename - MimeType mimeType = null; - if (fileName != null) { - try { - if (GUESS_MIME.equals(mimeTypeName)) { - // Guess the mime type from the file extension - mimeType = new MimeType(MimetypesFileTypeMap - .getDefaultFileTypeMap() - .getContentType(fileName)); - } else { - mimeType = new MimeType(mimeTypeName); - } - } catch (MimeTypeParseException ex) { - mimeType = null; - } - } - - // Failed to guess it, failed to load it, fall back on the default - if (mimeType == null) { - try { - mimeType = new MimeType(defaultMimeType); - } catch (MimeTypeParseException ex) { - mimeType = null; - } - } - - return mimeType; - } - - /** - * Obtain a File object from the file upload widget. The containing form - * should call this method in its process listener. - * - * @param event The form section event - * @return - */ - public File getFile(final FormSectionEvent event) { - - final String fileName = getFileName(event); - - if (fileName != null && fileName.length() > 0) { - return ((MultipartHttpServletRequest) unwrapRequest(event - .getPageState() - .getRequest())) - .getFile(getFileUploadWidgetName()); - } - - return null; - } - - private ServletRequest unwrapRequest(final HttpServletRequest request) { - - ServletRequest current = request; - while (current instanceof HttpServletRequestWrapper) { - current = ((HttpServletRequestWrapper) current).getRequest(); - } - - return current; - } - - /** - * Obtain a filename from the file upload widget. The containing form should - * call this method in its process listener. - * - * @param event The form section event - * @return - */ - public String getFileName(final FormSectionEvent event) { - - return event - .getFormData() - .getString(getFileUploadWidgetName()); - } - - /** - * Set the value for the mime type widget. The containing form should call - * this method in its init listener - * - * @param event The form section event - * @param mimeType The mime type to set, such as "text/html" or "img/jpeg" - * - */ - public void setMimeType(final FormSectionEvent event, - final String mimeType) { - event - .getFormData() - .put(getMimeTypeWidgetName(), mimeType); - } - - /** - * @return the mime type widget - */ - public SingleSelect getMimeTypeWidget() { - return mimeWidget; - } - - /** - * @return the file upload widget - */ - public FileUpload getFileUploadWidget() { - return fileWidget; - } - - /** - * @return the parameter name prefix - */ - public String getParameterPrefix() { - return parameterPrefix; - } - - /** - * @return the file upload parameter name - */ - public String getFileUploadWidgetName() { - return parameterPrefix + FILE_UPLOAD; - } - - /** - * @return the mime typeparameter name - */ - public String getMimeTypeWidgetName() { - return parameterPrefix + MIME_TYPE; - } - - /** - * Add mime-type options to the option group by loading all mime types which - * match a certain prefix from the database - * - * @param mimeTypeOptions The mime type widget to which options should be - * added - * - * @param mimePrefix Populate the mime type widget with all mime types that - * match the prefix. Some of the possible prefixes are "text", "image", - * "binary", etc. - * - */ - public static void addMimeOptions(final OptionGroup mimeTypeOptions, - final String mimePrefix) { - -// MimeTypeCollection types; -// if (mimePrefix == null || mimePrefix.equals("")) { -// types = MimeType.getAllMimeTypes(); -// } else { -// types = MimeType.searchMimeTypes(mimePrefix + "/"); -// } -// while (types.next()) { -// MimeType type = types.getMimeType(); -// mimeTypeOptions.addOption(new Option(type.getMimeType(), type.getLabel())); -// } - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/FormSecurityListener.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/FormSecurityListener.java deleted file mode 100755 index 97240dfa4..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/FormSecurityListener.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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.FormProcessException; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.event.FormSectionEvent; -import com.arsdigita.bebop.event.FormSubmissionListener; - -import org.librecms.contentsection.ContentItem; - -import com.arsdigita.dispatcher.AccessDeniedException; - -import com.arsdigita.util.Assert; - -import org.libreccm.cdi.utils.CdiUtil; -import org.libreccm.security.PermissionChecker; - -/** - * @author Justin Ross <jross@redhat.com> - */ -public class FormSecurityListener implements FormSubmissionListener { - - private final String m_action; - private final ContentItemRequestLocal m_item; - - public FormSecurityListener(final String action, - final ContentItemRequestLocal item) { - Assert.exists(action, String.class); - - m_action = action; - m_item = item; - } - - public FormSecurityListener(final String action) { - this(action, null); - } - - @Override - public final void submitted(final FormSectionEvent event) - throws FormProcessException { - - final PageState state = event.getPageState(); - - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final PermissionChecker permissionChecker = cdiUtil.findBean( - PermissionChecker.class); - - if (m_item == null) { - if (permissionChecker.isPermitted(m_action)) { - return; - } - } else { - final ContentItem item = m_item.getContentItem(state); - - if (permissionChecker.isPermitted(m_action, item)) { - return; - } - } - - throw new AccessDeniedException(); - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/GlobalNavigation.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/GlobalNavigation.java deleted file mode 100755 index a0b22979c..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/GlobalNavigation.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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.PageState; -import com.arsdigita.bebop.SimpleComponent; -import com.arsdigita.cms.CMS; -import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.ui.UI; -import com.arsdigita.ui.admin.AdminUiConstants; -import com.arsdigita.ui.login.LoginServlet; -import com.arsdigita.web.URL; -import com.arsdigita.xml.Element; - -import org.libreccm.cdi.utils.CdiUtil; -import org.libreccm.core.CoreConstants; -import org.libreccm.security.PermissionChecker; -import org.libreccm.web.ApplicationManager; -import org.libreccm.web.ApplicationRepository; -import org.libreccm.web.ApplicationType; -import org.libreccm.web.CcmApplication; -import org.librecms.CmsConstants; - -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; - -/** - *

- * Global navigation elements for the CMS admin UIs.

- * - * @author Justin Ross <jross@redhat.com> - */ -// Made public (instead of unspecified, resulting in protected) in 6.6.8 -public class GlobalNavigation extends SimpleComponent { - - - private final String m_adminPath; - private final String m_centerPath; - private final String m_changePasswordPath; - private final String m_helpPath; - private final String m_signOutPath; - private final String m_wspcPath; - - /** - * - */ - public GlobalNavigation() { - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final ApplicationManager appManager = cdiUtil.findBean( - ApplicationManager.class); - final ApplicationRepository appRepo = cdiUtil.findBean( - ApplicationRepository.class); - final Map appTypes = appManager - .getApplicationTypes(); - final ApplicationType adminAppType = appTypes.get( - AdminUiConstants.ADMIN_APP_TYPE); - final List adminApps = appRepo.findByType(adminAppType - .name()); - final ApplicationType contentCenterAppType = appTypes.get( - CmsConstants.CONTENT_CENTER_APP_TYPE); - final List contentCenterApps = appRepo.findByType( - contentCenterAppType.name()); - - m_adminPath = adminApps.get(0).getPrimaryUrl(); - m_centerPath = contentCenterApps.get(0).getPrimaryUrl(); - m_changePasswordPath = LoginServlet.getChangePasswordPageURL(); - m_helpPath = "/nowhere"; // We don't have this yet XXX. - m_signOutPath = LoginServlet.getLogoutPageURL(); - m_wspcPath = UI.getWorkspaceURL(); - } - - /** - * - * @param state - * @param parent - */ - @Override - public void generateXML(final PageState state, final Element parent) { - if (isVisible(state)) { - final HttpServletRequest sreq = state.getRequest(); - - final Element nav = parent.newChildElement("cms:globalNavigation", - CMS.CMS_XML_NS); - final String centerTitle = (String) new GlobalizedMessage( - "cms.ui.content_center", CmsConstants.CMS_BUNDLE).localize(); - final String adminTitle = (String) new GlobalizedMessage( - "cms.ui.admin_center", CmsConstants.CMS_BUNDLE).localize(); - final String wspcTitle = (String) new GlobalizedMessage( - "cms.ui.my_workspace", CmsConstants.CMS_BUNDLE).localize(); - final String signOutTitle = (String) new GlobalizedMessage( - "cms.ui.sign_out", CmsConstants.CMS_BUNDLE).localize(); - final String helpTitle = (String) new GlobalizedMessage( - "cms.ui.help", CmsConstants.CMS_BUNDLE).localize(); - final String changePasswordTitle = (String) new GlobalizedMessage( - "cms.ui.change_password", CmsConstants.CMS_BUNDLE).localize(); - - link(sreq, nav, "cms:contentCenter", m_centerPath, centerTitle); - - /* If the current user has admin permissions, insert a link to the admin center */ - if (CdiUtil.createCdiUtil().findBean(PermissionChecker.class) - .isPermitted(CoreConstants.PRIVILEGE_ADMIN)) { - link(sreq, nav, "cms:adminCenter", m_adminPath, adminTitle); - } - - link(sreq, nav, "cms:workspace", m_wspcPath, wspcTitle); - link(sreq, nav, "cms:changePassword", m_changePasswordPath, - changePasswordTitle); - link(sreq, nav, "cms:signOut", m_signOutPath, signOutTitle); - link(sreq, nav, "cms:help", m_helpPath, helpTitle); - } - } - - /** - * - * @param sreq - * @param parent - * @param name - * @param path - * @param title - * - * @return - */ - private static Element link(final HttpServletRequest sreq, - final Element parent, - final String name, - final String path, - final String title) { - final Element link = parent.newChildElement(name, CMS.CMS_XML_NS); - - link.addAttribute("href", URL.there(sreq, path).toString()); - link.addAttribute("title", title); - - return link; - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/ListOptionPrintListener.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/ListOptionPrintListener.java deleted file mode 100755 index 82a6fa705..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/ListOptionPrintListener.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.bebop.event.PrintEvent; -import com.arsdigita.bebop.event.PrintListener; -import com.arsdigita.bebop.form.Option; -import com.arsdigita.bebop.form.OptionGroup; - -import java.util.List; - -/** - * Migrated from the {@code DataQueryOptionPrintListener} in the old system. - * Renamed and refactored to operate on a list. - * - * @author Jens Pelzetter - * - * @param Type of the objects in the list. - */ -public abstract class ListOptionPrintListener implements PrintListener { - - public ListOptionPrintListener() { - } - - protected abstract List getDataQuery(final PageState state); - - @Override - public void prepare(final PrintEvent event) { - final PageState state = event.getPageState(); - final OptionGroup target = (OptionGroup) event.getTarget(); - final List dataQuery = getDataQuery(state); - - target.clearOptions(); - - dataQuery.forEach(item -> target.addOption( - new Option(getKey(item), - getValue(item)))); - } - - public abstract String getKey(final T object); - - public String getValue(final T object) { - return getKey(object); - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/SecurityPropertyEditor.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/SecurityPropertyEditor.java deleted file mode 100755 index 91fd9ecb3..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/SecurityPropertyEditor.java +++ /dev/null @@ -1,392 +0,0 @@ -/* - * 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.Component; -import com.arsdigita.bebop.Form; -import com.arsdigita.bebop.FormProcessException; -import com.arsdigita.bebop.FormSection; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.PropertyEditor; -import com.arsdigita.bebop.PropertyEditorModel; -import com.arsdigita.bebop.event.FormSectionEvent; -import com.arsdigita.bebop.event.FormSubmissionListener; -import com.arsdigita.bebop.form.Submit; -import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.toolbox.ui.ComponentAccess; -import com.arsdigita.util.Assert; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.librecms.CmsConstants; - -/** - * Extends {@link com.arsdigita.bebop.PropertyEditor} to provide access control - * features. Each link may be associated with a {@link - * com.arsdigita.toolbox.ui.ComponentAccess} object; if the current does not - * have sufficient privileges, the link will be hidden. - *

- * The simple use pattern for this component is as follows: - * - *


- * SecurityPropertyEditor editor = new SecurityPropertyEditor();
- * editor.setDisplayComponent(new FooComponent());
- * NameEditForm n = new NameEditForm();
- * ComponentAccess ca1 = new ComponentAccess(n);
- * ca1.addAccessCheck(WORKFLOW_ADMIN);
- * ca1.addAccessCheck(CATEGORY_ADMIN);
- * editor.add("name", "Edit Name", ca, n.getCancelButton());
- * AddressEditForm a = new AddressEditForm();
- * ComponentAccess ca2 = new ComponentAccess(a);
- * editor.add("address", "Edit Address", ca2, a.getCancelButton());
- * 
- * - * @author Michael Pih (pihman@arsdigita.com) - * @author Stanislav Freidin (sfreidin@arsdigita.com) - * @author Jens Pelzetter - */ -public class SecurityPropertyEditor extends PropertyEditor { - - private final Map accessChecks; - - /** - * Construct a new, empty PropertyEditor. The {@link - * #setDisplayComponent(Component)} method must be called before this - * component is locked. - */ - public SecurityPropertyEditor() { - this(null); - } - - /** - * Construct a new, PropertyEditor with the given display - * component - * - * @param display The display component - */ - public SecurityPropertyEditor(final Component display) { - super(display); - accessChecks = new HashMap<>(); - setModelBuilder(new AccessListModelBuilder()); - } - - /** - * Add a component to the property editor. The component will be completely - * invisible; it is up to the user to call {@link #showComponent(PageState, - * String)} to display the component, and to call {@link - * #showDisplayPane(PageState)} when the component needs to be hidden. - * - * @param key The symbolic key for the component; must be unique for this - * PropertyEditor - * @param componentAccess The {@link ComponentAccess} object which contains - * the child component, along with security restrictions - */ - public void addComponent(final String key, - final ComponentAccess componentAccess) { - super.addComponent(key, componentAccess.getComponent()); - accessChecks.put(key, componentAccess); - } - - /** - * Add a component to the list of links. It is up to the component to - * correctly call showDisplayPane when it's done. - * - * @param key The symbolic key for the component; must be unique for this - * PropertyEditor - * @param label The label for the link - * @param componentAccess The component access - * @deprecated use addComponent(String,GlobalizedMessage,ComponentAccess) - * instead. - */ - public void addComponent(final String key, - final String label, - final ComponentAccess componentAccess) { - addComponent(key, componentAccess); - getLabelsMap().put(key, label); - } - - /** - * Add a component to the list of links. It is up to the component to - * correctly call showDisplayPane when it's done. - * - * @param key The symbolic key for the component; must be unique for this - * PropertyEditor - * @param label The label for the link - * @param componentAccess The component access - */ - public void addComponent(final String key, - final GlobalizedMessage label, - final ComponentAccess componentAccess) { - addComponent(key, componentAccess); - getLabelsMap().put(key, label); - } - - /** - * Specify a new {@link ComponentAccess} for a component which has already - * been added to the SecurityPropertyEditor. - * - * @param key the key under which the component was added - * @param componentAccess the ComponentAccess instance that - * will determine when the link for the specified component should be - * visible - * @pre access.getComponent() == m_forms.get(key) - */ - public void setComponentAccess(final String key, - final ComponentAccess componentAccess) { - Assert.isUnlocked(this); - final Component component = getComponent(key); - Assert.exists(component, "the specified component"); - Assert.isTrue(componentAccess.getComponent().equals(component), - "The specified component does not match the component that" - + " id already in the PropertyEditor"); - accessChecks.put(key, componentAccess); - } - - /** - * Add a form to the set of forms which could be used to edit the - * properties. - * - * @param key The symbolic key for the form; must be unique for this - * PropertyEditor - * @param label The label for the link to access the form - * @param componentAccess The form ComponentAccess - * - * @deprecated use add(String,GlobalizedMessage,ComponentAccess) - */ - public void add(final String key, - final String label, - final ComponentAccess componentAccess) { - final Component component = componentAccess.getComponent(); - if (component instanceof Form) { - final Form form = (Form) component; - accessChecks.put(key, componentAccess); - add(key, label, form); - addSecurityListener(form); - } else if (component instanceof FormSection) { - final FormSection section = (FormSection) componentAccess. - getComponent(); - accessChecks.put(key, componentAccess); - add(key, label, section); - addSecurityListener(section); - } else { - throw new IllegalArgumentException( - "The ComponentAccess object does " - + "not contain a form section."); - } - } - - /** - * Add a form to the set of forms which could be used to edit the - * properties. - * - * @param key The symbolic key for the form; must be unique for this - * PropertyEditor - * @param label The label for the link to access the form - * @param componentAccess The form ComponentAccess - */ - public void add(final String key, - final GlobalizedMessage label, - final ComponentAccess componentAccess) { - final Component component = componentAccess.getComponent(); - if (component instanceof Form) { - final Form form = (Form) component; - accessChecks.put(key, componentAccess); - add(key, label, form); - addSecurityListener(form); - } else if (component instanceof FormSection) { - final FormSection section = (FormSection) componentAccess. - getComponent(); - accessChecks.put(key, componentAccess); - add(key, label, section); - addSecurityListener(section); - } else { - throw new IllegalArgumentException( - "The ComponentAccess object does " - + "not contain a form section."); - } - } - - /** - * Add a form to the set of forms which could be used to edit the properties - * - * @param key The symbolic key for the form; must be unique for this - * PropertyEditor - * @param label The label for the link to access the form. - * @param componentAccess The form ComponentAccess - * @param cancelButton The Cancel button on the form. - * - * @deprecated use add(String,GlobalizedMessage,ComponentAccess,Submit) - * instead - */ - public void add(final String key, - final String label, - final ComponentAccess componentAccess, - final Submit cancelButton) { - add(key, label, componentAccess); - addCancelListener((FormSection) componentAccess.getComponent(), - cancelButton); - } - - /** - * Add a form to the set of forms which could be used to edit the properties - * - * @param key The symbolic key for the form; must be unique for this - * PropertyEditor - * @param label The label for the link to access the form. - * @param componentAccess The form ComponentAccess - * @param cancelButton The Cancel button on the form. - */ - public void add(final String key, - final GlobalizedMessage label, - final ComponentAccess componentAccess, - final Submit cancelButton) { - add(key, label, componentAccess); - addCancelListener((FormSection) componentAccess.getComponent(), - cancelButton); - } - - /** - * Add a submission listener to the form that will hide all components and - * show the display pane. This method should be used to add submission - * listeners to forms which are buried deep inside some component, and are - * not members of this PropertyEditor. - * - * @param form The form - */ - public void addSecurityListener(final FormSection form) { - form.addSubmissionListener(new FormSubmissionListener() { - - @Override - public void submitted(final FormSectionEvent event) throws - FormProcessException { - - final PageState state = event.getPageState(); - - // Cancel the form if the user does not pass the access checks. - final String key = (String) getList().getSelectedKey(state); - final ComponentAccess componentAccess - = (ComponentAccess) accessChecks.get(key); - - if (key == null || componentAccess == null) { - // no components currently selected and therefore - // no access checks to run for visibility - // or - // there are no access restrictions on the form - return; - } - - if (!componentAccess.canAccess()) { - showDisplayPane(state); - throw new FormProcessException(new GlobalizedMessage( - "cms.ui.insufficient_privileges", - CmsConstants.CMS_BUNDLE)); - } - } - }); - } - - /** - * Add all required listeners to the form to ensure that if the form is - * submitted successfully or cancelled, the display pane will be shown. This - * method should be used to add listeners to forms which are buried deep - * inside some component, and are not members of this - * PropertyEditor. - * - * @param form The form - * @param cancelButton the "Cancel" button on the form - */ - @Override - public void addListeners(final FormSection form, - final Submit cancelButton) { - addSecurityListener(form); - super.addListeners(form, cancelButton); - } - - /** - * Return the map of keys to access checks - * - * @return Map of keys to access check - */ - protected final Map getAccessMap() { - return accessChecks; - } - - /** - * Returns an {@link SecurityPropertyEditor.AccessListModel} during each - * request - */ - protected static class AccessListModelBuilder extends DefaultModelBuilder { - - public AccessListModelBuilder() { - super(); - } - - @Override - public PropertyEditorModel makeModel( - final PropertyEditor propertyEditor, final PageState state) { - - return new AccessListModel( - getProperties(propertyEditor), - ((SecurityPropertyEditor) propertyEditor).getAccessMap(), - state); - } - } - - /** - * Performs access checks for each property; skips the properties that the - * user is not allowed to access - */ - protected static class AccessListModel extends DefaultModel { - - private final Map accessMap; - private final PageState state; - - public AccessListModel(final Iterator iter, - final Map accessMap, - final PageState state) { - super(iter); - this.accessMap = accessMap; - this.state = state; - } - - @Override - public boolean next() { - - while (super.next()) { - final Object key = getKey(); - final ComponentAccess ca = accessMap.get(key.toString()); - - if (ca == null) { - return true; - } - - if (ca.canAccess()) { - return true; - } - - // Otherwise, skip the property - } - - return false; - } - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/UserAddForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/UserAddForm.java deleted file mode 100755 index 269b57d7b..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/UserAddForm.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * 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.ColumnPanel; -import com.arsdigita.bebop.Form; -import com.arsdigita.bebop.FormData; -import com.arsdigita.bebop.FormProcessException; -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.RequestLocal; -import com.arsdigita.bebop.SimpleContainer; -import com.arsdigita.bebop.event.FormProcessListener; -import com.arsdigita.bebop.event.FormSectionEvent; -import com.arsdigita.bebop.event.PrintEvent; -import com.arsdigita.bebop.event.PrintListener; -import com.arsdigita.bebop.form.CheckboxGroup; -import com.arsdigita.bebop.form.Hidden; -import com.arsdigita.bebop.form.Option; -import com.arsdigita.bebop.form.OptionGroup; -import com.arsdigita.bebop.form.Submit; -import com.arsdigita.bebop.form.Widget; -import com.arsdigita.bebop.parameters.NotNullValidationListener; -import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.xml.Element; - -import org.libreccm.security.User; -import org.librecms.CmsConstants; - -import java.util.List; -import java.util.TooManyListenersException; - -/** - * Form for adding multiple users to a role. - * - * @author Michael Pih - * @author Uday Mathur - * @author Jens Pelzetter - */ -public abstract class UserAddForm extends SimpleContainer - implements FormProcessListener { - - private final static String SEARCH_QUERY = "searchQuery"; - private final static String USERS = "users"; - private final static String SUBMIT = "addSubmit"; - private final static String CANCEL = "addCancel"; - - private final static String DQ_USER_ID = "userId"; - private final static String DQ_NAME = "name"; - - private Widget m_search; - private RequestLocal m_query; - private String m_label; - private String m_submitText; - - private CMSContainer m_noMatches; - private CMSContainer m_matches; - - private Form m_form; - private Hidden m_searchQuery; - private CheckboxGroup m_users; - private Submit m_submit; - private Submit m_cancel; - - /** - * Constructor. - * - * @param search The widget on the search form that contains the value of - * the search string. - */ - public UserAddForm(final Widget search) { - this(search, "AddUsers"); - } - - public UserAddForm(final Widget search, final String name) { - this(search, name, - "Check the box next to the name of the person(s) to assign.", - "Add Members"); - } - - public UserAddForm(final Widget search, - final String name, - final String text, - final String submitText) { - m_label = text; - m_submitText = submitText; - m_search = search; - - m_query = new RequestLocal() { - - @Override - protected Object initialValue(final PageState state) { - return makeQuery(state); - } - - }; - - m_form = makeForm(name); - - final Label title = new Label(new GlobalizedMessage("cms.ui.matches", - CmsConstants.CMS_BUNDLE)); - title.setFontWeight(Label.BOLD); - - final Label label = new Label(new GlobalizedMessage( - "cms.ui.there_was_no_one_matching_the_search_criteria", - CmsConstants.CMS_BUNDLE)); - label.setFontWeight("em"); - - m_noMatches = new CMSContainer(); - m_noMatches.add(title); - m_noMatches.add(label); - add(m_noMatches); - - m_matches = new CMSContainer(); - m_matches.add(title); - m_matches.add(m_form); - add(m_matches); - } - - /** - * Build the form used to add users. - * - * @param name - * - * @return The form - */ - protected Form makeForm(final String name) { - final CMSForm form = new CMSForm(name) { - - public final boolean isCancelled(final PageState state) { - return m_cancel.isSelected(state); - } - - }; - - // This hidden field will store the search query. A hidden widget is - // used instead of a request local variable because the search query - // should only be updated when the search form is submitted. - m_searchQuery = new Hidden(SEARCH_QUERY); - form.add(m_searchQuery, ColumnPanel.FULL_WIDTH); - - Label l = new Label(m_label); - form.add(l, ColumnPanel.FULL_WIDTH); - - // Add the list of users that can be added. - m_users = new CheckboxGroup(USERS); - m_users.addValidationListener(new NotNullValidationListener()); - try { - m_users.addPrintListener(new PrintListener() { - - @Override - public void prepare(PrintEvent event) { - CheckboxGroup target = (CheckboxGroup) event.getTarget(); - PageState state = event.getPageState(); - // Ensures that the init listener gets fired before the - // print listeners. - FormData data = m_form.getFormData(state); - addUsers(state, target); - } - - }); - } catch (TooManyListenersException ex) { - throw new RuntimeException(ex); - } - form.add(m_users, ColumnPanel.FULL_WIDTH); - - // Submit and Cancel buttons. - SimpleContainer s = new SimpleContainer(); - m_submit = new Submit(SUBMIT, m_submitText); - s.add(m_submit); - m_cancel = new Submit(CANCEL, "Cancel"); - s.add(m_cancel); - form.add(s, ColumnPanel.FULL_WIDTH | ColumnPanel.CENTER); - - form.addProcessListener(this); - - return form; - } - - /** - * Fetches the form for adding users. - * - * @return The "add user" form - */ - public Form getForm() { - return m_form; - } - - /** - * Fetches the widget that contains the search string. - * - * @return The widget that contains the search string - */ - protected Widget getSearchWidget() { - return m_searchQuery; - } - - /** - * Return true if the form is cancelled, false otherwise. - * - * @param state The page state - * - * @return true if the form is cancelled, false otherwise. - * - * @pre ( state != null ) - */ - public boolean isCancelled(final PageState state) { - return m_cancel.isSelected(state); - } - - /** - * Adds users to the option group. - * - * @param state The page state - * @param target The option group - * - * @pre ( state != null && target != null ) - */ - protected void addUsers(final PageState state, final OptionGroup target) { - - @SuppressWarnings("unchecked") - final List users = (java.util.List) m_query.get(state); - - users.forEach(user -> target.addOption( - new Option(Long.toString(user.getPartyId()), - user.getName()))); - } - - /** - * Generates a {@link List} that encapsulates search results. - * - * @param state The page state - * - * @return - */ - protected abstract List makeQuery(final PageState state); - - /** - * Process listener for the "Add users" form. - * - * @param event The form event - * - * @throws com.arsdigita.bebop.FormProcessException - */ - @Override - public abstract void process(final FormSectionEvent event) - throws FormProcessException; - - /** - * Displays the appropriate frame. - * - * @param state The page state - * @param parent The parent DOM element - */ - @Override - public void generateXML(final PageState state, - final Element parent) { - - m_searchQuery.setValue(state, m_search.getValue(state)); - @SuppressWarnings("unchecked") - final List searchResults = (List) m_query.get(state); - - if (searchResults.size() > 0) { - m_matches.generateXML(state, parent); - } else { - m_noMatches.generateXML(state, parent); - } - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/UserSearchForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/UserSearchForm.java deleted file mode 100755 index 5192688c4..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/UserSearchForm.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.ColumnPanel; -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.form.Submit; -import com.arsdigita.bebop.form.TextField; -import com.arsdigita.bebop.parameters.StringParameter; -import com.arsdigita.globalization.GlobalizedMessage; - -import org.librecms.CmsConstants; - -/** - * Form to search for users to be added to a staff group. - * - * - * @author Michael Pih - */ -public class UserSearchForm extends CMSForm { - - private final static String SEARCH_LABEL = "Search"; - - private TextField m_search; - - public UserSearchForm(String name) { - this(name, - new Label(new GlobalizedMessage( - "cms.ui.search_to_add_new_members", - CmsConstants.CMS_BUNDLE))); - - } - - public UserSearchForm(String name, Label heading) { - super(name, new ColumnPanel(3)); - heading.setFontWeight(Label.BOLD); - add(heading, ColumnPanel.FULL_WIDTH); - - add(new Label(new GlobalizedMessage( - "cms.ui.enter_first_name_last_name_andor_email_address", - CmsConstants.CMS_BUNDLE))); - - m_search = new TextField(new StringParameter("query")); - m_search.setSize(20); - add(m_search, ColumnPanel.RIGHT); - - Submit submit = new Submit("submit"); - submit.setButtonLabel(SEARCH_LABEL); - add(submit, ColumnPanel.LEFT); - } - - public TextField getSearchWidget() { - return m_search; - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/VisibilityComponent.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/VisibilityComponent.java deleted file mode 100755 index db0375357..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/VisibilityComponent.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.toolbox.ui.ProxyComponent; -import com.arsdigita.util.Assert; - -import org.libreccm.cdi.utils.CdiUtil; -import org.libreccm.security.PermissionChecker; - -/** - * @author Justin Ross - * @author Jens Pelzetter - */ -public class VisibilityComponent extends ProxyComponent { - - private final String m_action; - - public VisibilityComponent(final Component child, final String action) { - super(child); - - m_action = action; - } - - @Override - public boolean isVisible(final PageState state) { - return super.isVisible(state) && hasPermission(state); - } - - public boolean hasPermission(final PageState state) { - Assert.exists(m_action, String.class); - - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final PermissionChecker permissionChecker = cdiUtil.findBean( - PermissionChecker.class); - - return permissionChecker.isPermitted(m_action); - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AdditionalDisplayComponent.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AdditionalDisplayComponent.java deleted file mode 100644 index bef38563b..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AdditionalDisplayComponent.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2007 Chris Gilbert 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.authoring; - -import com.arsdigita.bebop.Component; -import com.arsdigita.cms.ItemSelectionModel; - -/** - * class used for decoupled display components that caters for a callback to - * provide them with a handle on the ItemSelectionModel - * - * @author chris.gilbert@westsussex.gov.uk - * - */ -public interface AdditionalDisplayComponent extends Component { - - public void setItemSelectionModel(ItemSelectionModel model); - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/ApplyWorkflowController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/ApplyWorkflowController.java deleted file mode 100644 index 0000eccd4..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/ApplyWorkflowController.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2017 LibreCCM Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package com.arsdigita.cms.ui.authoring; - -import org.libreccm.security.PermissionChecker; -import org.libreccm.workflow.AssignableTask; -import org.libreccm.workflow.AssignableTaskManager; -import org.libreccm.workflow.Workflow; -import org.libreccm.workflow.WorkflowManager; -import org.libreccm.workflow.WorkflowRepository; -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentSection; -import org.librecms.contentsection.ContentSectionRepository; -import org.librecms.contentsection.ContentType; -import org.librecms.contentsection.ContentTypeRepository; -import org.librecms.contentsection.Folder; -import org.librecms.contentsection.privileges.ItemPrivileges; - -import java.nio.charset.IllegalCharsetNameException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import javax.enterprise.context.RequestScoped; -import javax.inject.Inject; -import javax.transaction.Transactional; - -/** - * - * @author Jens Pelzetter - */ -@RequestScoped -class ApplyWorkflowController { - - @Inject - private ContentTypeRepository typeRepo; - - @Inject - private ContentSectionRepository sectionRepo; - - @Inject - private WorkflowRepository templateRepo; - - @Inject - private WorkflowManager workflowManager; - - @Inject - private AssignableTaskManager assignableTaskManager; - - @Inject - private PermissionChecker permissionChecker; - - @Transactional(Transactional.TxType.REQUIRED) - protected Workflow getDefaultWorkflow(final ContentType contentType) { - - Objects.requireNonNull(contentType); - - final ContentType type = typeRepo - .findById(contentType.getObjectId()) - .orElseThrow(() -> new IllegalCharsetNameException(String.format( - "No ContentType with ID %d in the database. Where did that ID come from?", - contentType.getObjectId()))); - - return type.getDefaultWorkflow(); - } - - @Transactional(Transactional.TxType.REQUIRED) - Long getDefaultWorkflowId(final ContentType contentType) { - final Workflow workflowTemplate - = getDefaultWorkflow(contentType); - if (workflowTemplate == null) { - return null; - } else { - return workflowTemplate.getWorkflowId(); - } - } - - @Transactional(Transactional.TxType.REQUIRED) - protected List getWorkflowTemplates( - final ContentSection section) { - - final ContentSection contentSection = sectionRepo - .findById(section.getObjectId()) - .orElseThrow(() -> new IllegalArgumentException(String.format( - "No ContentSection with ID %d in the database. " - + "Where did that ID come from?", - section.getObjectId()))); - - return new ArrayList<>(contentSection.getWorkflowTemplates()); - } - - @Transactional(Transactional.TxType.REQUIRED) - protected void applyWorkflow(final ContentItem item, - final Folder folder, - final Long workflowTemplateId) { - - Objects.requireNonNull(item); - Objects.requireNonNull(folder); - Objects.requireNonNull(workflowTemplateId); - - final Workflow workflowTemplate; - if (workflowTemplateId == null - && permissionChecker - .isPermitted(ItemPrivileges.APPLY_ALTERNATE_WORKFLOW, folder)) { - - workflowTemplate = templateRepo - .findById(workflowTemplateId) - .orElseThrow(() -> new IllegalArgumentException(String.format( - "No WorkflowTemplate with ID %d in database. " - + "Where did that ID come from?", - workflowTemplateId))); - } else { - workflowTemplate = item.getContentType().getDefaultWorkflow(); - } - - if (workflowTemplate != null) { - - final Workflow workflow = workflowManager - .createWorkflow(workflowTemplate, item); - workflowManager.start(workflow); - - if (!workflow.getTasks().isEmpty()) { - - if (workflow.getTasks().get(0) instanceof AssignableTask) { - - final AssignableTask task = (AssignableTask) workflow - .getTasks() - .get(0); - assignableTaskManager.lockTask(task); - } - } - - } - - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringKitSelector.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringKitSelector.java deleted file mode 100755 index 8368b2adf..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringKitSelector.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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.authoring; - -import com.arsdigita.bebop.Component; - -import com.arsdigita.bebop.MapComponentSelectionModel; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.SimpleContainer; -import com.arsdigita.bebop.SingleSelectionModel; - -import com.arsdigita.cms.ItemSelectionModel; -import com.arsdigita.xml.Element; - -import org.apache.logging.log4j.LogManager; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.logging.log4j.Logger; -import org.libreccm.cdi.utils.CdiUtil; -import org.librecms.contenttypes.AuthoringKitInfo; -import org.librecms.contenttypes.ContentTypeInfo; -import org.librecms.contenttypes.ContentTypesManager; - -import java.util.List; -import java.util.Objects; - -/** - * Selects a component based on content type. Helper class for {@link - * com.arsdigita.cms.ui.authoring.WizardSelector}. - * - * @author unknown - * @author Jens Pelzetter - */ -public abstract class AuthoringKitSelector extends SimpleContainer { - - private static final Logger LOGGER = LogManager.getLogger( - AuthoringKitSelector.class); - private final Map components; - private final MapComponentSelectionModel selectionModel; - private final List types; - - /** - * Construct a new AuthoringKitSelector. Load all the possible authoring - * kits from the database and construct components for them. - * - * @param model the {@link ItemSelectionModel} which will supply the - * selector with the id of a content type - * - * @pre itemModel != null - */ - public AuthoringKitSelector(final SingleSelectionModel model) { - super(); - - components = new HashMap<>(); - selectionModel = new MapComponentSelectionModel<>(model, components); - - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final ContentTypesManager typesManager = cdiUtil.findBean( - ContentTypesManager.class); - types = typesManager.getAvailableContentTypes(); - - if (types.isEmpty()) { - throw new RuntimeException("No Content Types were found."); - } - } - - // Overloaded add methods - @Override - public void add(final Component component) { - throw new UnsupportedOperationException(); - } - - // Overloaded add methods - @Override - public void add(final Component component, final int constraints) { - throw new UnsupportedOperationException(); - } - - /** - * Instantiate all the authoring kit wizards. The child class should call - * this method after it is done with initialisation. - */ - protected void processKit() { - for (final ContentTypeInfo type : types) { - final AuthoringKitInfo kit = type.getAuthoringKit(); - if (kit != null) { - final Component component = instantiateKitComponent(kit, type); - if (component != null) { - super.add(component); - components.put(type.getContentItemClass().getName(), - component); - LOGGER.info("Added component {} for {}", - Objects.toString(component), - type.getContentItemClass().getName()); - } - } - } - } - - /** - * Instantiate an authoring kit component. Child classes should override - * this to do the right thing. It is permissible for this method to return - * null. - * - * @param kit for this kit - * @param type for this type - * - * @return - */ - protected abstract Component instantiateKitComponent( - final AuthoringKitInfo kit, final ContentTypeInfo type); - - /** - * - * @param typeClass - * - * @return The component the given type id - */ - public Component getComponent(final String typeClass) { - return components.get(typeClass); - } - - /** - * @return The selection model used by this wizard - */ - public MapComponentSelectionModel getComponentSelectionModel() { - return selectionModel; - } - - // Choose the right component and run it - @Override - public void generateXML(final PageState state, final Element parent) { - if (isVisible(state)) { - final Component component = selectionModel.getComponent(state); - if (component == null) { - throw new IllegalStateException("No component for " - + selectionModel - .getSelectedKey(state)); - } - component.generateXML(state, parent); - } - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringKitWizard.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringKitWizard.java deleted file mode 100755 index c82292639..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringKitWizard.java +++ /dev/null @@ -1,564 +0,0 @@ -/* - * 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.authoring; - -import com.arsdigita.bebop.Component; -import com.arsdigita.bebop.ControlLink; -import com.arsdigita.bebop.GridPanel; -import com.arsdigita.bebop.List; -import com.arsdigita.bebop.Page; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.Resettable; -import com.arsdigita.bebop.SimpleContainer; -import com.arsdigita.bebop.SingleSelectionModel; -import com.arsdigita.bebop.event.ActionEvent; -import com.arsdigita.bebop.event.ActionListener; -import com.arsdigita.bebop.event.ChangeEvent; -import com.arsdigita.bebop.event.ChangeListener; -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.list.ListCellRenderer; -import com.arsdigita.bebop.parameters.StringParameter; - -import org.librecms.contentsection.ContentType; - -import com.arsdigita.cms.ItemSelectionModel; -import com.arsdigita.cms.ui.ContentItemPage; -import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.toolbox.ui.LayoutPanel; -import com.arsdigita.toolbox.ui.ModalPanel; -import com.arsdigita.toolbox.ui.Section; -import com.arsdigita.util.Assert; -import com.arsdigita.util.SequentialMap; -import com.arsdigita.util.UncheckedWrapperException; - -import org.apache.logging.log4j.Logger; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.Iterator; -import java.util.Objects; -import java.util.ResourceBundle; - -import org.apache.logging.log4j.LogManager; -import org.librecms.CMSConfig; -import org.libreccm.cdi.utils.CdiUtil; -import org.libreccm.configuration.ConfigurationManager; -import org.libreccm.core.UnexpectedErrorException; -import org.libreccm.l10n.GlobalizationHelper; -import org.libreccm.workflow.Task; -import org.libreccm.workflow.TaskRepository; -import org.librecms.CmsConstants; -import org.librecms.contenttypes.AuthoringKit; -import org.librecms.contenttypes.AuthoringKitInfo; -import org.librecms.contenttypes.AuthoringStepInfo; -import org.librecms.contenttypes.ContentTypeInfo; -import org.librecms.ui.authoring.ContentItemAuthoringStepInfo; -import org.librecms.ui.authoring.ContentItemAuthoringStepManager; - -/** - * This class represents a single authoring kit. The wizard accepts a - * {@link ContentType} in the constructor; it then extracts the - * {@link AuthoringKit} for the content type, and creates the components for all - * the steps in the kit. - * - * Note that the individual authoring kit steps must provide the following - * constructor: - * - *

- * public TheClass(ItemSelectionModel model, AuthoringKitWizard parent) { ... }
- * 
- * - * This constructor will be called when the component is automatically - * instantiated by the AuthoringKitWizard. - * - */ -public class AuthoringKitWizard extends LayoutPanel implements Resettable { - - /** - * Private Logger instance for this class - */ - private static final Logger LOGGER = LogManager - .getLogger(AuthoringKitWizard.class); - - private final static Class[] ARGUMENTS = new Class[]{ - ItemSelectionModel.class, - AuthoringKitWizard.class, - StringParameter.class - }; - - private static final Class[] USER_DEFINED_ARGS = new Class[]{ - ItemSelectionModel.class, - AuthoringKitWizard.class, - ContentType.class - }; - - private final Object[] values; - - private final ContentTypeInfo typeInfo; - - private final AuthoringKitInfo kitInfo; - - private final ItemSelectionModel selectionModel; - - - - private final SequentialMap labels; - - private final List list; - - private String defaultKey; - - private final GridPanel leftPanel; - - private final ModalPanel bodyPanel; - - private final SimpleContainer stepsContainer; - - - private final StringParameter selectedLanguageParam; - - /** - * The name of the state parameter that determines whether the wizard is in - * item creation mode or item editing mode. - */ - public static final String IS_EDITING = "is_edit"; - - /** - * The key for the item creation step. - */ - public static final String CREATION = "_creation_"; - - private final static String SEC_PAGE_EDIT_DYN - = "com.arsdigita.cms.ui.authoring.SecondaryPageEditDynamic"; - - private final static String PAGE_EDIT_DYN - = "com.arsdigita.cms.ui.authoring.PageEditDynamic"; - - /** - * Construct a new AuthoringKitWizard. Add all the steps in the authoring - * kit to the wizard. - * - * @param typeInfo The content type of the items that this wizard will - * handle - * @param selectionModel - */ - public AuthoringKitWizard(final ContentTypeInfo typeInfo, - final ItemSelectionModel selectionModel) { - LOGGER.debug("Authoring kit wizard for type {} undergoing creation...", - Objects.toString(typeInfo)); - - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final ConfigurationManager confManager = cdiUtil.findBean( - ConfigurationManager.class); - - selectedLanguageParam = new StringParameter( - ContentItemPage.SELECTED_LANGUAGE); - final GlobalizationHelper globalizationHelper = cdiUtil - .findBean(GlobalizationHelper.class); - selectedLanguageParam.setDefaultValue(globalizationHelper - .getNegotiatedLocale() - .toString()); - - this.typeInfo = typeInfo; - kitInfo = typeInfo.getAuthoringKit(); - this.selectionModel = selectionModel; - values = new Object[]{selectionModel, this, selectedLanguageParam}; - labels = new SequentialMap(); - - leftPanel = new GridPanel(1); - setLeft(leftPanel); - - final Section stepSection = new Section( - new GlobalizedMessage("cms.ui.authoring.steps", - CmsConstants.CMS_BUNDLE)); - leftPanel.add(stepSection); - - list = new List(); - stepSection.setBody(list); - - list.setListData(labels); - list.setCellRenderer(new ListCellRenderer() { - - @Override - public Component getComponent(final List list, - final PageState state, - final Object value, - final String key, - final int index, - final boolean isSelected) { - final Label label; - if (value instanceof GlobalizedMessage) { - label = new Label((GlobalizedMessage) value); - } else { - label = new Label((String) value); - } - if (isSelected) { - label.setFontWeight(Label.BOLD); - return label; - } - return new ControlLink(label); - } - - }); - - bodyPanel = new ModalPanel(); - setBody(bodyPanel); - - stepsContainer = new SimpleContainer(); - bodyPanel.add(stepsContainer); - bodyPanel.setDefault(stepsContainer); - - final java.util.List steps = kitInfo. - getAuthoringSteps(); - - if (Assert.isEnabled()) { - Assert.isTrue(!steps.isEmpty(), - String.format("The authoring kit for content type " - + "s\"%s\" has no steps.", - typeInfo.getContentItemClass().getName())); - } - - final CMSConfig cmsConfig = confManager.findConfiguration( - CMSConfig.class); - - StepComponent panel = null; - for (final AuthoringStepInfo step : steps) { - final String key = step.getComponent().getName(); - - if (defaultKey == null) { - defaultKey = key; - } - - /** - * The "label" and "description" are only here for backwards - * compatibility - */ - final ResourceBundle labelBundle = ResourceBundle - .getBundle(step.getLabelBundle()); - final ResourceBundle descBundle = ResourceBundle - .getBundle(step.getDescriptionBundle()); - final String labelKey = step.getLabelKey(); - final String label = labelBundle.getString(labelKey); - final String descriptionKey = step.getDescriptionKey(); - - final Class componentClass = step. - getComponent(); - final String compClassName = componentClass.getName(); - - if (panel != null) { - panel.setNextStepKey(key); - } - panel = new StepComponent(compClassName); - stepsContainer.add(panel); - final Component component; - - if (compClassName.equals(SEC_PAGE_EDIT_DYN) - || compClassName.equals(PAGE_EDIT_DYN)) { - component = instantiateUserDefinedStep(compClassName, typeInfo); - } else { - component = instantiateStep(compClassName); - } - panel.add(component); - if (component instanceof AuthoringStepComponent) { - ((AuthoringStepComponent) component).addCompletionListener( - new StepCompletionListener()); - } - - final GlobalizedMessage gzLabel; - if (labelKey != null) { - if (step.getLabelBundle() == null) { - gzLabel = new GlobalizedMessage(labelKey, - CmsConstants.CMS_BUNDLE); - } else { - gzLabel = new GlobalizedMessage(labelKey, - step.getLabelBundle()); - } - } else { - gzLabel = null; - } - if (gzLabel == null) { - labels.put(key, label); - } else { - labels.put(key, gzLabel); - } - } - - final java.util.List skipSteps = cmsConfig.getSkipAssetSteps(); - if (LOGGER.isDebugEnabled()) { - for (final String step : skipSteps) { - LOGGER.debug("skip step \"{}\"...", step); - } - } - - for (final ContentItemAuthoringStepInfo stepInfo - : getContentItemAuthoringSteps()) { - - if (panel != null) { - panel.setNextStepKey(stepInfo.getStep()); - } - - panel = new StepComponent(stepInfo.getStep()); - stepsContainer.add(panel); - - final Component component = instantiateStep(stepInfo - .getStep().getName()); - if (component instanceof AuthoringStepComponent) { - ((AuthoringStepComponent) component) - .addCompletionListener(new StepCompletionListener()); - } - panel.add(component); - - labels.put(stepInfo.getStep(), - new GlobalizedMessage(stepInfo.getLabelKey(), - stepInfo.getLabelBundle())); - } - - list.addChangeListener(new StepListener()); - - - - } - - private final class StepListener implements ChangeListener { - - @Override - public final void stateChanged(final ChangeEvent event) { - final PageState state = event.getPageState(); - final String key = list.getSelectedKey(state).toString(); - - final Iterator iter = stepsContainer.children(); - - while (iter.hasNext()) { - final StepComponent step = (StepComponent) iter.next(); - - if (step.getStepKey().toString().equals(key)) { - step.setVisible(state, true); - } else { - step.setVisible(state, false); - } - } - } - - } - - /** - * - */ - private final class StepCompletionListener implements ActionListener { - - @Override - @SuppressWarnings("unchecked") - public final void actionPerformed(final ActionEvent event) { - final PageState state = event.getPageState(); - if (ContentItemPage.isStreamlinedCreationActive(state)) { - final String key = list.getSelectedKey(state).toString(); - - final Iterator iter = stepsContainer.children(); - - while (iter.hasNext()) { - final StepComponent step = (StepComponent) iter.next(); - if (step.getStepKey().toString().equals(key)) { - Object nextStep = step.getNextStepKey(); - if (nextStep != null) { - list - .getSelectionModel() - .setSelectedKey(state, nextStep.toString()); - } - } - } - } - } - - } - - @Override - public final void register(final Page page) { - super.register(page); - - final Iterator iter = stepsContainer.children(); - - while (iter.hasNext()) { - final StepComponent child = (StepComponent) iter.next(); - - page.setVisibleDefault(child, false); - } - - page.addGlobalStateParam(selectedLanguageParam); - - page.addActionListener(new ActionListener() { - - @Override - public final void actionPerformed(final ActionEvent event) { - final PageState state = event.getPageState(); - - if (state.isVisibleOnPage(AuthoringKitWizard.this)) { - @SuppressWarnings("unchecked") - final SingleSelectionModel model = list - .getSelectionModel(); - - if (!model.isSelected(state)) { - model.setSelectedKey(state, defaultKey); - } - } - } - - }); - } - - private java.util.List getContentItemAuthoringSteps() { - - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final ContentItemAuthoringStepManager manager = cdiUtil - .findBean(ContentItemAuthoringStepManager.class); - - return manager.getContentItemAuthoringStepInfos(); - } - - /** - * @return The content type handled by this wizard - */ - public ContentTypeInfo getContentType() { - return typeInfo; - } - - public List getList() { - return list; - } - - /** - * @return The authoring kit which is represented by this wizard - */ - public AuthoringKitInfo getAuthoringKit() { - return kitInfo; - } - - /** - * @return The ItemSelectionModel used by the steps in this wizard - */ - public ItemSelectionModel getItemSelectionModel() { - return selectionModel; - } - - /** - * Instantiate the specified authoring kit step. Will throw a - * RuntimeException on failure. - * - * @param className The Java class name of the step - * - * @return The instance of the component. - */ - protected Component instantiateStep(final String className) { - - LOGGER.debug("Instantiating kit wizard \"{}\" with arguments {}...", - className, - ARGUMENTS); - - try { - // Get the creation component - final Class createClass = Class.forName(className); - final Constructor constr = createClass.getConstructor(ARGUMENTS); - final Component component = (Component) constr.newInstance(values); - - return component; - } catch (ClassNotFoundException - | IllegalAccessException - | IllegalArgumentException - | InstantiationException - | InvocationTargetException - | NoSuchMethodException - | SecurityException ex) { - LOGGER.error( - "Failed to instantiate authoring kit component \"{}\"...", - className); - LOGGER.error("Exception is: ", ex); - throw new UncheckedWrapperException(String.format( - "Failed to instantiate authoring kit component \"%s\".", - className), - ex); - } - } - - /** - * Instantiate the specified authoring kit step for a user defined content - * type. Will throw a RuntimeException on failure. - * - * @param className The Java class name of the step - * @param originatingType - * - * @return - */ - protected Component instantiateUserDefinedStep( - final String className, final ContentTypeInfo originatingType) { - - try { - // Get the creation component - final Class createClass = Class.forName(className); - final Constructor constr = createClass.getConstructor( - USER_DEFINED_ARGS); - final Object[] userDefinedVals = new Object[]{selectionModel, - this, - originatingType}; - final Component component = (Component) constr.newInstance( - userDefinedVals); - - return component; - } catch (ClassNotFoundException - | NoSuchMethodException - | InstantiationException - | IllegalAccessException - | InvocationTargetException ex) { - throw new UncheckedWrapperException(ex); - } - } - - /** - * Reset the state of this wizard - */ - @Override - public final void reset(final PageState state) { - list.setSelectedKey(state, defaultKey); - } - - private final class StepComponent extends SimpleContainer { - - private final Object key; - - private Object nextKey; - - public StepComponent(final Object key) { - this.key = key; - } - - public Object getStepKey() { - return key; - } - - public Object getNextStepKey() { - return nextKey; - } - - public void setNextStepKey(final Object nextKey) { - this.nextKey = nextKey; - } - - } - - - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringStepComponent.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringStepComponent.java deleted file mode 100755 index 12e4ed642..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringStepComponent.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.authoring; - -import com.arsdigita.bebop.event.ActionListener; - -/** - * Interface which authoring step components should implement. It's - * currently an optional interface. - * - * @author Scott Seago (sseago@redhat.com) - */ -public interface AuthoringStepComponent { - - /** - * Add a completion listener to this component - */ - void addCompletionListener(ActionListener listener); - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/BasicItemForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/BasicItemForm.java deleted file mode 100755 index 017470a22..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/BasicItemForm.java +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Copyright (C) 2002-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.authoring; - -import com.arsdigita.bebop.ColumnPanel; -import com.arsdigita.bebop.Component; -import com.arsdigita.bebop.FormData; -import com.arsdigita.bebop.FormProcessException; -import com.arsdigita.bebop.FormSection; -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.SaveCancelSection; -import com.arsdigita.bebop.event.FormInitListener; -import com.arsdigita.bebop.event.FormProcessListener; -import com.arsdigita.bebop.event.FormSectionEvent; -import com.arsdigita.bebop.event.FormValidationListener; -import com.arsdigita.bebop.form.Hidden; -import com.arsdigita.bebop.form.TextField; -import com.arsdigita.bebop.parameters.NotNullValidationListener; -import com.arsdigita.bebop.parameters.StringParameter; -import com.arsdigita.bebop.parameters.TrimmedStringParameter; -import com.arsdigita.bebop.parameters.URLTokenValidationListener; -import com.arsdigita.cms.ItemSelectionModel; -import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.web.Web; -import com.arsdigita.xml.Element; - -import org.libreccm.categorization.Category; -import org.libreccm.cdi.utils.CdiUtil; -import org.librecms.CmsConstants; -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentItemRepository; - -import java.util.Objects; - -/** - * A form for editing subclasses of ContentItem. This is just a convenience - * class. - * - * @author Stanislav Freidin - * @author Jens Pelzetter - */ -public abstract class BasicItemForm extends FormSection - implements FormInitListener, - FormProcessListener, - FormValidationListener { - - public static final String CONTENT_ITEM_ID = "ContentItemId"; - public static final String NAME = "ContentItemName"; - public static final String TITLE = "ContentPageTitle"; - public static final String LANGUAGE = "ContentItemLanguage"; - - private final ItemSelectionModel itemSelectionModel; - private final StringParameter selectedLanguageParam; - - private SaveCancelSection saveCancelSection; - private final FormSection widgetSection; - /** - * Currently, to insert JavaScript code the Label Widget is "abused". - */ - private final Label script = new Label(String - .format("", - Web.getWebappContextPath()), - false); - - /** - * Construct a new BasicItemForm with 2 ColumnPanels and add basic content. - * The left Panel is used for Labels, the right Panel for values. - * - * @param formName the name of this form - * @param itemSelectionModel The {@link ItemSelectionModel} which will be - * responsible for loading the current item - * @param selectedLanguageParam - */ - public BasicItemForm(final String formName, - final ItemSelectionModel itemSelectionModel, - final StringParameter selectedLanguageParam) { - - super(new ColumnPanel(2)); - - Objects.requireNonNull(selectedLanguageParam); - - widgetSection = new FormSection(new ColumnPanel(2, true)); - - super.add(widgetSection, ColumnPanel.INSERT); - this.itemSelectionModel = itemSelectionModel; - this.selectedLanguageParam = selectedLanguageParam; - - /* Prepare Panel design */ - final ColumnPanel panel = (ColumnPanel) getPanel(); - panel.setBorder(false); - panel.setPadColor("#FFFFFF"); - panel.setColumnWidth(1, "20%"); - panel.setColumnWidth(2, "80%"); - panel.setWidth("100%"); - - /* Add basic contents */ - addWidgets(); - - saveCancelSection = new SaveCancelSection(); - super.add(saveCancelSection, - ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT); - - addInitListener(this); - addProcessListener(this); - addValidationListener(this); - } - - /** - * Construct a new BasicItemForm with a specified number of ColumnPanels and - * without any content. - * - * @param formName the name of this form - * @param columnPanel the column panel of the form - * @param itemSelectionModel The {@link ItemSelectionModel} which will be - * responsible for loading the current item - * @param selectedLanguageParam - */ - public BasicItemForm(final String formName, - final ColumnPanel columnPanel, - final ItemSelectionModel itemSelectionModel, - final StringParameter selectedLanguageParam) { - - super(columnPanel); - - Objects.requireNonNull(selectedLanguageParam); - - widgetSection = new FormSection(new ColumnPanel(columnPanel. - getNumCols(), - true)); - super.add(widgetSection, ColumnPanel.INSERT); - this.itemSelectionModel = itemSelectionModel; - this.selectedLanguageParam = selectedLanguageParam; - } - - /** - * create and add the save/cancel section for this form - */ - public void addSaveCancelSection() { - saveCancelSection = new SaveCancelSection(); - super.add(saveCancelSection, - ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT); - } - - /** - * Add basic widgets to the form. - * - * Widgets added are 'title' and 'name (url)' which are part of any content - * item. Child classes will override this method to perform all their - * widget-adding needs but are supposed to use super() to add the basic - * widgets. - */ - protected void addWidgets() { - //add(new FormErrorDisplay(this), ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT); - - final Hidden id = new Hidden(CONTENT_ITEM_ID); - add(id); - - // JavaScript auto-name generation is off by default. - // It is turned on under the following circumstances - // - // * If the name is null, upon starting edit of the title - // * If the name is null, upon finishing edit of name - // - // The rationale is that, auto-name generation is useful - // if the name is currently null, but once a name has been - // created you don't want to subsequently change it since - // it breaks URLs & potentially overwrites the user's - // customizations. - final TextField titleWidget = new TextField(new TrimmedStringParameter( - TITLE)); - titleWidget.setLabel(getTitleLabel()); - titleWidget.setHint(getTitleHint()); - titleWidget.addValidationListener(new NotNullValidationListener()); - titleWidget.setOnFocus("if (this.form." + NAME + ".value == '') { " - + " defaulting = true; this.form." + NAME - + ".value = urlize(this.value); }"); - titleWidget.setOnKeyUp( - "if (defaulting) { this.form." + NAME - + ".value = urlize(this.value) }"); - add(titleWidget); - - // For some content types it may be useful to change the label of - // the name (or URL) field to something different than 'name (url)'. - // This can now be accomplished by overwriting the getNameLabel() method. - // (jensp 2011-01-28) -// add(new Label(getNameLabel())); - final TextField nameWidget = new TextField(new TrimmedStringParameter( - NAME)); - nameWidget.setLabel(getNameLabel()); - nameWidget.setHint(getNameHint()); - // We just check parameter specific properties here! Additionally, - // context properties as uniqueness in folder must be validated - // for the form es the whole (using the validate method required by - // implementing FormValidationListener in this form. - nameWidget.addValidationListener(new NotNullValidationListener()); - nameWidget.addValidationListener(new URLTokenValidationListener()); - nameWidget.setMaxLength(190); - nameWidget.setOnFocus("defaulting = false"); - nameWidget.setOnBlur( - "if (this.value == '') " - + "{ defaulting = true; this.value = urlize(this.form." - + TITLE - + ".value) } " - + " else { this.value = urlize(this.value); }"); - add(nameWidget); - - } - - @Override - public void generateXML(final PageState state, - final Element parent) { - script.generateXML(state, parent); - super.generateXML(state, parent); - } - - /** - * @return the item selection model used in this form - */ - public ItemSelectionModel getItemSelectionModel() { - return itemSelectionModel; - } - - /** - * @return the save/cancel section for this form - */ - public SaveCancelSection getSaveCancelSection() { - return saveCancelSection; - } - - /** - * Perform form initialisation. Children should override this this method to - * pre-fill the widgets with data, instantiate the content item, etc. - * - * @param event - * - * @throws FormProcessException - */ - @Override - public abstract void init(final FormSectionEvent event) throws FormProcessException; - - /** - * Process the form. Children have to override this method to save the - * user's changes to the database. - * - * @param event - * - * @throws FormProcessException - */ - @Override - public abstract void process(final FormSectionEvent event) throws FormProcessException; - - /** - * Validate the form. Children have to override this method to provide - * context form validation, specifically name (url) uniqueness in a folder! - * - * @param event - * - * @throws com.arsdigita.bebop.FormProcessException - */ - @Override - public void validate(final FormSectionEvent event) throws FormProcessException { - // do nothing - } - - /** - * Adds a component to this container. - * - * @param component the component to add to this BasicPageForm - * - */ - @Override - public void add(final Component component) { - widgetSection.add(component); - } - - /** - * Adds a component with the specified layout constraints to this container. - * Layout constraints are defined in each layout container as static ints. - * Use a bitwise OR to specify multiple constraints. - * - * @param component the component to add to this container - * @param constraints layout constraints (a bitwise OR of static ints in the - * particular layout) - */ - @Override - public void add(final Component component, - final int constraints) { - widgetSection.add(component, constraints); - } - - /** - * This method can be overridden to change the label of the title field. To - * change to label of the title field can be useful for some content types. - * For example, for an organisation the label "Title" for the field may be - * confusing for the normal user. For such a content type, the label would - * be changed to something like "Name of the organisation". - * - * @return (Content for the) Label for the title field as string - */ - protected GlobalizedMessage getTitleLabel() { - return new GlobalizedMessage("cms.contenttypes.ui.title", - CmsConstants.CMS_BUNDLE); - } - - /** - * Provides the text for the user hint providing some detailed information - * how to use this widget. This method can be overwritten to adjust the text - * for some content types. {@link #getTitleLabel()} - * - * @return - */ - protected GlobalizedMessage getTitleHint() { - return new GlobalizedMessage("cms.contenttypes.ui.title_hint", - CmsConstants.CMS_BUNDLE); - } - - /** - * This method does the same as {@link #getTitleLabel() } for the labe l of - * the name (URL) field. - * - * @return (Content for the) Label for the name field as string - */ - protected GlobalizedMessage getNameLabel() { - return new GlobalizedMessage("cms.contenttypes.ui.name", - CmsConstants.CMS_BUNDLE); - } - - /** - * Provides the text for the user hint providing some detailed information - * how to use this widget. This method can be overwritten to adjust the text - * for some content types. {@link #getNameLabel()} - * - * @return - */ - protected GlobalizedMessage getNameHint() { - return new GlobalizedMessage("cms.contenttypes.ui.name_hint", - CmsConstants.CMS_BUNDLE); - } - - // ////////////////////////////////////////////////////////////////////// - // - // VALIDATION helper methods - // - // ////////////////////////////////////////////////////////////////////// - /** - * Ensure that the name of an item is unique within a folder. A "New item" - * form should call this method in the validation listener. - * - * @param parent the folder in which to check - * @param event the {@link FormSectionEvent} which was passed to the - * validation listener - */ - public void validateNameUniqueness(final Category parent, - final FormSectionEvent event) { - - final FormData data = event.getFormData(); - final String newName = (String) data.get(NAME); - - validateNameUniqueness(parent, event, newName); - } - - /** - * - * @param parent - * @param event - * @param newName - */ - public void validateNameUniqueness(final Category parent, - final FormSectionEvent event, - final String newName) { - - final String ERR_MSG = "cms.ui.authoring.an_item_with_this_name_exists"; - - if (newName != null) { - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final ContentItemRepository itemRepo = cdiUtil - .findBean(ContentItemRepository.class); - - final long result = itemRepo.countByNameInFolder(parent, newName); - - if (result > 0) { - // Try to get a currently selected content item - final ContentItem item; - if (getItemSelectionModel() == null) { - item = null; - } else { - item = getItemSelectionModel() - .getSelectedObject(event.getPageState()); - } - if (item == null) { // The content item being null - // means it is a creation form. - // Therefore finding any item of the same name is a fault. - event.getFormData() - .addError(new GlobalizedMessage(ERR_MSG, - CmsConstants.CMS_BUNDLE)); - } else { - // means we are in a edit form. - // We need to add all of the items that are different - // versions of this item to the list so that we do not mark - // an error if those are the only problems. - event.getFormData() - .addError(new GlobalizedMessage( - ERR_MSG, - CmsConstants.CMS_BUNDLE, - new Object[]{item.getUuid()})); - } - } - } - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/BasicPageForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/BasicPageForm.java deleted file mode 100755 index 46b0ec8f7..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/BasicPageForm.java +++ /dev/null @@ -1,360 +0,0 @@ -/* - * 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.authoring; - -import com.arsdigita.bebop.ColumnPanel; -import com.arsdigita.bebop.FormData; -import com.arsdigita.bebop.FormProcessException; -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.event.FormSectionEvent; -import com.arsdigita.bebop.event.ParameterEvent; -import com.arsdigita.bebop.event.ParameterListener; -import com.arsdigita.bebop.parameters.DateParameter; -import com.arsdigita.bebop.parameters.ParameterData; -import com.arsdigita.bebop.parameters.ParameterModel; -import com.arsdigita.bebop.parameters.StringParameter; - -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentSection; -import org.librecms.contentsection.Folder; - -import com.arsdigita.cms.ItemSelectionModel; -import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.util.Assert; - -import org.librecms.CMSConfig; -import org.libreccm.cdi.utils.CdiUtil; -import org.libreccm.workflow.Workflow; -import org.librecms.CmsConstants; -import org.librecms.contentsection.ContentItemInitializer; -import org.librecms.contentsection.ContentType; - -import java.util.Date; -import java.util.Locale; -import java.util.Objects; -import java.util.Optional; - -/** - * A form for editing basic properties of documents (that is subclasses of class - * ContentPage). - * - * Document specific classes inherit from this class which provides the basic - * widgets for title, name launch date to use by those classes. - * - * This is just a convenience class. It uses parent class to construct the form - * including basic widgets (i.e. title and name/URL as well as save/cancel - * buttons) and adds optional launch date. - * - * Note: It is for editing existing content (specifically due to its validation - * method). - * - * @author Stanislav Freidin (stas@arsdigita.com) - * @author Jens Pelzetter - */ -public abstract class BasicPageForm extends BasicItemForm { - - private static final String LAUNCH_DATE = "launch_date"; - - private final StringParameter selectedLanguageParam; - - /** - * Construct a new BasicPageForm - * - * @param formName the name of this form - * @param itemModel The {@link ItemSelectionModel} which will be - * responsible for loading the current item - * @param selectedLanguageParam - */ - public BasicPageForm(final String formName, - final ItemSelectionModel itemModel, - final StringParameter selectedLanguageParam) { - - super(formName, itemModel, selectedLanguageParam); - Objects.requireNonNull(selectedLanguageParam); - this.selectedLanguageParam = selectedLanguageParam; - } - - /** - * Construct a new BasicPageForm with nothing on it - * - * @param formName the name of this form - * @param columnPanel the column panel of the form - * @param itemModel The {@link ItemSelectionModel} which will be - * responsible for loading the current item - * @param selectedLanguageParam - */ - public BasicPageForm(final String formName, - final ColumnPanel columnPanel, - final ItemSelectionModel itemModel, - final StringParameter selectedLanguageParam) { - - super(formName, columnPanel, itemModel, selectedLanguageParam); - this.selectedLanguageParam = selectedLanguageParam; - } - - /** - * Add various widgets to the form. Child classes should override this - * method to perform all their widget-adding needs - */ - @Override - protected void addWidgets() { - - /* Add basic widgets title/name which are part of any content item */ - super.addWidgets(); - - final CMSConfig cmsConfig = CMSConfig.getConfig(); - - /* Optionally add Lunchdate */ - if (!cmsConfig.isHideLaunchDate()) { - add(new Label(new GlobalizedMessage( - "cms.ui.authoring.page_launch_date", - CmsConstants.CMS_BUNDLE))); - final ParameterModel launchDateParam - = new DateParameter(LAUNCH_DATE); - com.arsdigita.bebop.form.Date launchDate - = new com.arsdigita.bebop.form.Date( - launchDateParam); - if (CMSConfig.getConfig().isRequireLaunchDate()) { - launchDate.addValidationListener( - new LaunchDateValidationListener()); - // if launch date is required, help user by suggesting today's date - launchDateParam.setDefaultValue(new Date()); - } - add(launchDate); - } - } - - /** - * Utility method to initialise the name/title widgets. Child classes may - * call this method from the init listener - * - * @param event the {@link FormSectionEvent} which was passed to the init - * listener - * - * @return the ContentPage instance which was extracted from the - * ItemSelectionModel - */ - public ContentItem initBasicWidgets(final FormSectionEvent event) { - Assert.exists(getItemSelectionModel()); - - final FormData data = event.getFormData(); - final PageState state = event.getPageState(); - final ContentItem item = getItemSelectionModel() - .getSelectedObject(state); - - final Locale selectedLocale = SelectedLanguageUtil - .selectedLocale(state, selectedLanguageParam); - - if (item != null) { - // Preset fields - data.put(CONTENT_ITEM_ID, Long.toString(item.getObjectId())); - data.put(NAME, item.getName().getValue(selectedLocale)); - data.put(TITLE, item.getTitle().getValue(selectedLocale)); - final CMSConfig cmsConfig = CMSConfig.getConfig(); - if (!cmsConfig.isHideLaunchDate()) { - data.put(LAUNCH_DATE, item.getLaunchDate()); - // if launch date is required, help user by suggesting today's date - if (cmsConfig.isRequireLaunchDate() - && item.getLaunchDate() == null) { - data.put(LAUNCH_DATE, new Date()); - } - } - } - - return item; - } - - /** - * Class specific implementation of FormValidationListener interface - * (inherited from BasicItemForm). - * - * @param event - * - * @throws FormProcessException - */ - @Override - public void validate(final FormSectionEvent event) - throws FormProcessException { - - super.validate(event); - - final PageState state = event.getPageState(); - - final ContentItem item = getItemSelectionModel() - .getSelectedItem(event.getPageState()); - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final BasicPageFormController controller = cdiUtil - .findBean(BasicPageFormController.class); - - final Optional folder = controller.getItemFolder(item); - if (folder.isPresent()) { - final String name = event.getFormData().getString(NAME); - final String selectedLang = (String) state - .getValue(selectedLanguageParam); - final Locale selectedLocale = new Locale(selectedLang); - if (!item.getName().hasValue(selectedLocale) - || !item.getName().getValue(selectedLocale).equals(name)) { - validateNameUniqueness(folder.get(), event); - } - } - } - - /** - * Utility method to process the name/title widgets. Child classes may call - * this method from the process listener. - * - * @param event the {@link FormSectionEvent} which was passed to the process - * listener - * - * @return - */ - public ContentItem processBasicWidgets(final FormSectionEvent event) { - Assert.exists(getItemSelectionModel()); - - final FormData data = event.getFormData(); - final PageState state = event.getPageState(); - final ContentItem item = getItemSelectionModel() - .getSelectedObject(state); - - if (item != null) { - - final Locale selectedLocale = SelectedLanguageUtil - .selectedLocale(state, selectedLanguageParam); - - item.getName().putValue(selectedLocale, (String) data.get(NAME)); - item.getTitle().putValue(selectedLocale, (String) data.get(TITLE)); - if (!CMSConfig.getConfig().isHideLaunchDate()) { - item.setLaunchDate((Date) data.get(LAUNCH_DATE)); - } - } - - return item; - } - - /** - * A utility method that will create a new item and tell the selection model - * to select the new item. - * - * Creation components may call this method in the process listener of their - * form. See {@link PageCreate} for an example. - * - * @param - * @param state - * @param name - * @param section - * @param folder - * @param initializer - * @param locale - * - * @return the new content item (or a proper subclass thereof) - * - * @throws com.arsdigita.bebop.FormProcessException - */ - public T createContentPage( - final PageState state, - final String name, - final ContentSection section, - final Folder folder, - final ContentItemInitializer initializer, - final Locale locale) throws FormProcessException { - - return createContentItemPage(state, - name, - section, - folder, - null, - initializer, - locale); - } - - public T createContentItemPage( - final PageState state, - final String name, - final ContentSection section, - final Folder folder, - final Workflow workflowTemplate, - final ContentItemInitializer initializer, - final Locale locale) throws FormProcessException { - - final ItemSelectionModel selectionModel = getItemSelectionModel(); - final ContentType contentType = selectionModel.getContentType(); - - // Create new item - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final BasicPageFormController controller = cdiUtil - .findBean(BasicPageFormController.class); - - final T item; - try { - @SuppressWarnings("unchecked") - final Class clazz = (Class) Class - .forName(contentType.getContentItemClass()); - - if (workflowTemplate == null) { - item = controller - .createContentItem(name, - section, - folder, - clazz, - initializer, - locale); - } else { - item = controller.createContentItem(name, - section, - folder, - workflowTemplate, - clazz, - initializer, - locale); - } - } catch (ClassNotFoundException ex) { - throw new FormProcessException( - "Couldn't create contentpage", - new GlobalizedMessage( - "cms.ui.authoring.couldnt_create_contentpage", - CmsConstants.CMS_BUNDLE), - ex); - } - - // Make sure the item will be remembered across requests - selectionModel.setSelectedKey(state, item.getObjectId()); - - return item; - } - - /** - * Constructs a new LaunchDateValidationListener. - */ - private class LaunchDateValidationListener implements ParameterListener { - - @Override - public void validate(final ParameterEvent event) { - - final ParameterData data = event.getParameterData(); - final Object value = data.getValue(); - - if (value == null) { - data.addError("launch date is required"); - } - } - - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/BasicPageFormController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/BasicPageFormController.java deleted file mode 100644 index 4dade5733..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/BasicPageFormController.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2017 LibreCCM Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package com.arsdigita.cms.ui.authoring; - -import org.libreccm.workflow.Workflow; -import org.libreccm.workflow.WorkflowRepository; -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentItemInitializer; -import org.librecms.contentsection.ContentItemManager; -import org.librecms.contentsection.ContentItemRepository; -import org.librecms.contentsection.ContentSection; -import org.librecms.contentsection.ContentSectionRepository; -import org.librecms.contentsection.Folder; -import org.librecms.contentsection.FolderRepository; - -import java.util.Locale; -import java.util.Optional; - -import javax.enterprise.context.RequestScoped; -import javax.inject.Inject; -import javax.transaction.Transactional; - -/** - * - * @author Jens Pelzetter - */ -@RequestScoped -class BasicPageFormController { - - @Inject - private ContentSectionRepository sectionRepo; - - @Inject - private ContentItemRepository itemRepo; - - @Inject - private ContentItemManager itemManager; - - @Inject - private FolderRepository folderRepo; - - @Inject - private WorkflowRepository workflowRepo; - - @Transactional(Transactional.TxType.REQUIRED) - protected T createContentItem( - final String name, - final ContentSection section, - final Folder folder, - final Class clazz, - final ContentItemInitializer initializer, - final Locale locale) { - - return createContentItem(name, - section, - folder, - null, - clazz, - initializer, - locale); - } - - @Transactional(Transactional.TxType.REQUIRED) - protected T createContentItem( - final String name, - final ContentSection section, - final Folder folder, - final Workflow workflowTemplate, - final Class clazz, - final ContentItemInitializer initializer, - final Locale locale) { - - final ContentSection contentSection = sectionRepo - .findById(section.getObjectId()) - .orElseThrow(() -> new IllegalArgumentException(String - .format("No ContentSection with ID %d in the database.", - section.getObjectId()))); - - final Folder itemFolder = folderRepo - .findById(folder.getObjectId()) - .orElseThrow(() -> new IllegalArgumentException(String - .format("No Folder with ID %d in the database.", - folder.getObjectId()))); - - final T item; - if (workflowTemplate == null) { - - item = itemManager.createContentItem(name, - contentSection, - itemFolder, - clazz, - initializer, - locale); - - } else { - final Workflow itemWorkflowTemplate = workflowRepo - .findById(workflowTemplate.getWorkflowId()) - .orElseThrow(() -> new IllegalArgumentException(String - .format("No WorkflowTemplate with ID %d in the database.", - workflowTemplate.getWorkflowId()))); - - item = itemManager.createContentItem(name, - contentSection, - itemFolder, - itemWorkflowTemplate, - clazz, - initializer, - locale); - } - - return item; - } - - @Transactional(Transactional.TxType.REQUIRED) - protected Optional getItemFolder(final ContentItem item) { - - final Optional contentItem = itemRepo - .findById(item.getObjectId()); - - if (contentItem.isPresent()) { - return itemManager.getItemFolder(contentItem.get()); - } else { - return Optional.empty(); - } - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/CategoryWidget.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/CategoryWidget.java deleted file mode 100755 index 6dbd4b1bf..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/CategoryWidget.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (C) 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.authoring; - -import com.arsdigita.bebop.form.Widget; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.parameters.ArrayParameter; -import com.arsdigita.bebop.parameters.StringParameter; -import com.arsdigita.bebop.parameters.BigDecimalParameter; -import com.arsdigita.bebop.parameters.LongParameter; -import com.arsdigita.xml.Element; -import com.arsdigita.xml.XML; - -import org.libreccm.categorization.Category; - -import com.arsdigita.cms.CMS; -import com.arsdigita.kernel.KernelConfig; - -import org.librecms.CMSConfig; -import org.libreccm.categorization.CategoryRepository; -import org.libreccm.cdi.utils.CdiUtil; -import org.librecms.contentsection.ContentSection; - -import java.util.Arrays; -import java.util.Set; -import java.util.HashSet; -import java.util.Map; -import java.util.HashMap; -import java.util.List; -import java.util.ArrayList; -import java.util.Iterator; -import java.math.BigDecimal; - -import static javax.naming.ldap.SortControl.*; - -public class CategoryWidget extends Widget { - - private LongParameter rootParameter; - private StringParameter modeParameter; - - public CategoryWidget(final String name, - final LongParameter rootParameter, - final StringParameter modeParameter) { - - super(new ArrayParameter(new BigDecimalParameter(name))); - - this.rootParameter = rootParameter; - this.modeParameter = modeParameter; - } - - @Override - protected String getType() { - return "category"; - } - - @Override - public boolean isCompound() { - return false; - } - - @Override - protected void generateWidget(final PageState state, - final Element parent) { - - Element widget = parent.newChildElement("cms:categoryWidget", - CMS.CMS_XML_NS); - exportAttributes(widget); - - widget.addAttribute("mode", (String) state.getValue(modeParameter)); - widget.addAttribute("name", getName()); - - final Set selectedCategories = new HashSet<>(); - - final Long[] values = (Long[]) getValue(state); - if (values != null) { - selectedCategories.addAll(Arrays.asList(values)); - } - - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final CategoryRepository categoryRepo = cdiUtil - .findBean(CategoryRepository.class); - final Category rootCategory = categoryRepo - .findById((Long) state.getValue(rootParameter)) - .orElseThrow(() -> new IllegalArgumentException( - String.format( - "No Category with ID %d in the database. " - + "Where did that ID come from?", - state.getValue(rootParameter)))); - - final List categories = rootCategory.getSubCategories(); - - final Map children = new HashMap(); -// ToDo, I don't understand was is done here... -// while (categories.next()) { -// final Category cat = categories.getCategory(); -// final BigDecimal parentID = (BigDecimal) categories -// .get("parents.id"); -// -// List childList = (List) children.get(parentID); -// if (childList == null) { -// childList = new ArrayList(); -// children.put(parentID, childList); -// } -// -// childList.add( -// new CategorySortKeyPair(cat, (BigDecimal) categories.get( -// "parents.link.sortKey"))); -// } - - generateCategory(widget, null, rootCategory, null, selectedCategories, - children); - } - - public void generateCategory(final Element parent, - final String path, - final Category category, - final Long sortKey, - final Set selected, - final Map children) { - - final Element element = new Element("cms:category", - CMS.CMS_XML_NS); - - element.addAttribute("id", XML.format(category.getObjectId())); - element.addAttribute("name", category.getName()); - element.addAttribute("description", - category - .getDescription() - .getValue(KernelConfig - .getConfig() - .getDefaultLocale())); - if (selected.contains(category.getObjectId())) { - element.addAttribute("isSelected", "1"); - } else { - element.addAttribute("isSelected", "0"); - } - if (category.isAbstractCategory()) { - element.addAttribute("isAbstract", "1"); - } else { - element.addAttribute("isAbstract", "0"); - } - if (category.isEnabled()) { - element.addAttribute("isEnabled", "1"); - } else { - element.addAttribute("isEnabled", "0"); - } - if (sortKey != null) { - element.addAttribute("sortKey", sortKey.toString()); - } - // sort order attribute added to every node in order that same xsl may - // be used to transform xml fragments returned by ajax in the Aplaws - // extension -// element.addAttribute("order", -// CMSConfig.getConfig().getCategoryTreeOrder()); - - String fullname = path == null ? "/" : path + " > " + category.getName(); - element.addAttribute("fullname", fullname); - StringBuilder nodeID = new StringBuilder(parent.getAttribute("node-id")); - if (nodeID.length() > 0) { - nodeID.append("-"); - } - nodeID.append(category.getObjectId()); - element.addAttribute("node-id", nodeID.toString()); - parent.addContent(element); - - List c = (List) children.get(category.getObjectId()); - if (c != null) { - Iterator i = c.iterator(); - while (i.hasNext()) { - CategorySortKeyPair pair = (CategorySortKeyPair) i.next(); - Category child = pair.getCategory(); - Long childSortKey = pair.getSortKey(); - generateCategory(element, - fullname, - child, - childSortKey, - selected, - children); - } - } - } - - private class CategorySortKeyPair { - - private Category category; - private Long sortKey; - - public CategorySortKeyPair(final Category category, - final Long sortKey) { - this.category = category; - this.sortKey = sortKey; - } - - public Category getCategory() { - return category; - } - - public Long getSortKey() { - return sortKey; - } - - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/CreationSelectorController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/CreationSelectorController.java deleted file mode 100644 index 60974a12c..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/CreationSelectorController.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2017 LibreCCM Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package com.arsdigita.cms.ui.authoring; - -import org.librecms.contentsection.ContentSection; -import org.librecms.contentsection.ContentSectionRepository; -import org.librecms.contentsection.Folder; -import org.librecms.contentsection.FolderRepository; - -import javax.enterprise.context.RequestScoped; -import javax.inject.Inject; -import javax.transaction.Transactional; - -/** - * - * @author Jens Pelzetter - */ -@RequestScoped -class CreationSelectorController { - - @Inject - private FolderRepository folderRepo; - - @Inject - private ContentSectionRepository sectionRepo; - - @Transactional(Transactional.TxType.REQUIRED) - protected ContentSection getContentSectionForFolder(final Folder folder) { - - final Folder theFolder = folderRepo - .findById(folder.getObjectId()) - .orElseThrow(() -> new IllegalArgumentException(String.format( - "No Folder with ID %d in the database. Where did that ID come from?", - folder.getObjectId()))); - - final ContentSection section = theFolder.getSection(); - - return sectionRepo - .findById(section.getObjectId()) - .orElseThrow(() -> new IllegalArgumentException(String.format( - "No ContentSection with ID %d in the database.", - section.getObjectId()))); - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/ItemCategoryExtension.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/ItemCategoryExtension.java deleted file mode 100644 index 619903445..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/ItemCategoryExtension.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2017 LibreCCM Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package com.arsdigita.cms.ui.authoring; - -import com.arsdigita.bebop.SimpleComponent; - -/** - * NOOP base implementation of category authoring step extension. - * Summary component returned by #getSummary() is show on category summary page, - * usually an ActionLink which activates the Form component returned by #getForm(). - * - * @author Alan Pevec - */public class ItemCategoryExtension { - - public SimpleComponent[] getSummary() { - return new SimpleComponent[0]; - } - - public SimpleComponent[] getForm() { - return new SimpleComponent[0]; - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/LanguageWidget.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/LanguageWidget.java deleted file mode 100755 index f484cbc65..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/LanguageWidget.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.authoring; - -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.form.Option; -import com.arsdigita.bebop.form.SingleSelect; -import com.arsdigita.bebop.parameters.ParameterModel; -import com.arsdigita.bebop.parameters.StringParameter; -import org.librecms.util.LanguageUtil; -import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.util.Pair; - -import java.util.List; -import org.libreccm.cdi.utils.CdiUtil; - -/** - * Language picker for the multilingual content items. - */ -public class LanguageWidget extends SingleSelect { - - public LanguageWidget(String name) { - this(new StringParameter(name)); - } - - public LanguageWidget(ParameterModel model) { - super(model); - setupOptions(); - } - - /** - * Adds list of languages. Default version shows all supported languages for - * this CMS installation, as defined in the enterprise.init: - * com.arsdigita.cms.installer.Initializer: languages - */ - protected void setupOptions() { - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final LanguageUtil languageUtil = cdiUtil.findBean(LanguageUtil.class); - final List languages = languageUtil.convertToG11N(languageUtil. - getSupportedLanguages2LA()); - for(final Pair pair : languages) { - final String langCode = (String) pair.getKey(); - final GlobalizedMessage langName = (GlobalizedMessage) pair.getValue(); - - addOption(new Option(langCode, new Label(langName))); - } - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/PageFileForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/PageFileForm.java deleted file mode 100644 index 39d96464e..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/PageFileForm.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright (C) 2021 LibreCCM Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package com.arsdigita.cms.ui.authoring; - -import com.arsdigita.bebop.BoxPanel; -import com.arsdigita.bebop.Form; -import com.arsdigita.bebop.FormData; -import com.arsdigita.bebop.FormProcessException; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.RequestLocal; -import com.arsdigita.bebop.SaveCancelSection; -import com.arsdigita.bebop.event.FormProcessListener; -import com.arsdigita.bebop.event.FormSectionEvent; -import com.arsdigita.bebop.event.FormValidationListener; -import com.arsdigita.bebop.form.FormErrorDisplay; -import com.arsdigita.bebop.parameters.NotNullValidationListener; -import com.arsdigita.cms.ItemSelectionModel; -import com.arsdigita.cms.ui.FileUploadSection; -import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.util.UncheckedWrapperException; - -import org.libreccm.l10n.LocalizedString; -import org.librecms.CmsConstants; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.UnsupportedEncodingException; - -import javax.activation.MimeType; - -/** - * A form for editing TextAsset items. Displays a "file upload" widget, - * auto-guesses mime type - */ -class PageFileForm extends Form implements FormProcessListener, - FormValidationListener { - - private final TextBody textBody; - - private SaveCancelSection saveCancelSection; - private FileUploadSection fileUploadSection; - // Variables saved by validate for processing - private RequestLocal fileUploadContent; - private RequestLocal fileUploadUsedINSO; - /** - * The text entry widget - */ - public static final String TEXT_ENTRY = "text_entry"; - - /** - * Construct a new PageFileForm - * - * @param itemSelectionModel - */ - public PageFileForm(final TextBody textBody) { - - super("PageFileUpload", new BoxPanel(BoxPanel.VERTICAL)); - - this.textBody = textBody; - - setMethod(Form.POST); - setEncType("multipart/form-data"); - - addWidgets(); - } - - private void addWidgets() { - - fileUploadSection = new FileUploadSection( - new GlobalizedMessage("cms.ui.authoring.text.mime_type"), - "text", - textBody.getDefaultMimeType()); - - fileUploadSection - .getFileUploadWidget() - .addValidationListener(new NotNullValidationListener()); - fileUploadSection - .getMimeTypeWidget() - .setDefaultValue(FileUploadSection.GUESS_MIME); - add(fileUploadSection); - - saveCancelSection = new SaveCancelSection(); - add(saveCancelSection); - - final FormErrorDisplay errorDisplay = new FormErrorDisplay(this); - add(errorDisplay); - - addValidationListener(this); - addProcessListener(this); - - fileUploadContent = new RequestLocal(); - fileUploadUsedINSO = new RequestLocal(); - - } - - protected String getFileUploadContent(PageState state) { - return (String) fileUploadContent.get(state); - } - - /** - * Make sure that files of this type can be uploaded - */ - private void validateFileType(final MimeType mime, final boolean textType) - throws FormProcessException { - // boolean validType = textType || ((mime instanceof TextMimeType) - // && ((TextMimeType) mime). - // allowINSOConvert().booleanValue()); - boolean validType = true; //ToDo - if (!validType) { - throw new FormProcessException(new GlobalizedMessage( - "cms.ui.authoring.invalid_file_type", - CmsConstants.CMS_BUNDLE)); - } - // boolean insoWorks = MimeTypeStatus.getMimeTypeStatus(). - // getInsoFilterWorks().intValue() == 1; - boolean insoWorks = true; //ToDo - if (!textType && !insoWorks) { - // Can't convert. inso filter is not working. Give message. - throw new FormProcessException(new GlobalizedMessage( - "cms.ui.authoring.couldnt_convert_missing_inso", - CmsConstants.CMS_BUNDLE)); - } - } - - /** - * read in the content of the file (in bytes). - */ - private byte[] readFileBytes(final File file) throws FormProcessException { - byte[] fileBytes; - try (final FileInputStream fs = new FileInputStream(file)) { - fileBytes = new byte[fs.available()]; - fs.read(fileBytes); - } catch (IOException ex) { - throw new FormProcessException(new GlobalizedMessage( - "cms.ui.authoring.unable_to_load_file", - CmsConstants.CMS_BUNDLE)); - } - return fileBytes; - } - - /** - * Convert bytes to String, possibly using INSO filter to convert to HTML - * type - */ - private String convertBytes(final byte[] fileBytes, final boolean textType, - final boolean[] usedInso) throws - FormProcessException { - String fileContent; - // If mime type is not text type, try to convert to html - if (!textType) { - fileContent = new String(fileBytes); - if (fileContent != null) { - // Converted successfully, flag type should be html - usedInso[0] = true; - } else { - throw new FormProcessException(new GlobalizedMessage( - "cms.ui.authoring.couldnt_convert_inso_failed", - CmsConstants.CMS_BUNDLE)); - } - } else { - // Text type, no need to convert - final String enc = "UTF-8"; - try { - fileContent = new String(fileBytes, enc); - } catch (UnsupportedEncodingException ex) { - throw new UncheckedWrapperException( - "cannot convert to encoding " + enc, ex); - } - usedInso[0] = false; - } - return fileContent; - } - - /** - * Extract the contents of the HTML Body tag. (Done to prevent base and - * other header tags from interfering with page display). - */ - private String extractHTMLBody(final String htmlText) throws - FormProcessException { - final String lowerCase = htmlText.toLowerCase(); - int bodyStart = lowerCase.indexOf("", bodyStart); - int bodyEnd = lowerCase.indexOf("", bodyStart_v); - if (bodyStart == -1 || bodyEnd == -1) { - throw new FormProcessException(new GlobalizedMessage( - "cms.ui.authoring.html_file_missing_body_tags", - CmsConstants.CMS_BUNDLE)); - } - return htmlText.substring(bodyStart_v + 1, bodyEnd); - } - - /** - * Validate file upload - * - * @throws com.arsdigita.bebop.FormProcessException - */ - @Override - public void validate(final FormSectionEvent event) throws - FormProcessException { - MimeType mime = fileUploadSection.getMimeType(event); - // boolean textType = mime.getPrefix().equals(TextMimeType.TEXT_PREFIX); - final boolean textType = true; //ToDo - validateFileType(mime, textType); - // Convert the file to HTML, if possible - File file = fileUploadSection.getFile(event); - byte[] file_bytes = readFileBytes(file); - boolean[] usedInso = new boolean[1]; - String file_content = convertBytes(file_bytes, textType, usedInso); - // ToDo if (TextMimeType.MIME_TEXT_HTML.equals(mime.getMimeType())) { - file_content = extractHTMLBody(file_content); - // } - final PageState state = event.getPageState(); - fileUploadContent.set(state, file_content); - fileUploadUsedINSO.set(state, usedInso[0]); - } - - /** - * Process file upload. Must be validated first. - */ - @Override - public void process(final FormSectionEvent event) - throws FormProcessException { - - final FormData data = event.getFormData(); - final PageState state = event.getPageState(); - // Get the text asset or create a new one - final String text = textBody.getText(state); - final File file = fileUploadSection.getFile(event); - // Get info created during validation - final String uploadContent = (String) fileUploadContent.get(state); - boolean usedINSO = (Boolean) fileUploadUsedINSO.get(state); - // Set the mime type - // final MimeType mime = fileUploadSection.getMimeType(event); - // if (usedINSO) { - // mime = MimeType.loadMimeType("text/html"); - // } - // if (mime != null) { - // text.setMimeType(mime); - // } - // Save the uploaded content - //ToDo text.setText(uploadContent); - //t.setName(fileName); // ??? - // file = null; - // Save everything - textBody.updateText(state, text); - // if (text.isNew() || text.isModified()) { - // text.save(); - // } - } - - /** - * @return the save/cancel section for this form - */ - public SaveCancelSection getSaveCancelSection() { - return saveCancelSection; - } - - /** - * @return the save/cancel section for this form - */ - public FileUploadSection getFileUploadSection() { - return fileUploadSection; - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/PageTextForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/PageTextForm.java deleted file mode 100644 index 0ffd6d471..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/PageTextForm.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (C) 2021 LibreCCM Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package com.arsdigita.cms.ui.authoring; - -import com.arsdigita.bebop.ColumnPanel; -import com.arsdigita.bebop.Form; -import com.arsdigita.bebop.FormData; -import com.arsdigita.bebop.FormProcessException; -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.SaveCancelSection; -import com.arsdigita.bebop.event.FormInitListener; -import com.arsdigita.bebop.event.FormProcessListener; -import com.arsdigita.bebop.event.FormSectionEvent; -import com.arsdigita.bebop.event.FormSubmissionListener; -import com.arsdigita.bebop.form.TextArea; -import com.arsdigita.cms.ui.CMSDHTMLEditor; -import com.arsdigita.globalization.GlobalizedMessage; - -import org.librecms.CMSConfig; -import org.libreccm.l10n.LocalizedString; -import org.librecms.CmsConstants; - -/** - * A form for editing the body of the text. - */ -public class PageTextForm - extends Form - implements FormInitListener, - FormProcessListener, - FormSubmissionListener { - - private final TextBody textBody; - - // private SingleSelect mimeWidget; - // private Label mimeLabel; - private TextArea textWidget; - private SaveCancelSection saveCancelSection; - /** - * The text entry widget - */ - public static final String TEXT_ENTRY = "text_entry"; - /** - * The mime type widget - */ - public static final String MIME_TYPE = "mime_type"; - - /** - * Construct a new PageTextForm - * - */ - public PageTextForm(final TextBody textBody) { - - super("PageTextForm", new ColumnPanel(2)); - - this.textBody = textBody; - - setMethod(Form.POST); - setEncType("multipart/form-data"); - - addWidgets(); - } - - private void addWidgets() { - - final ColumnPanel panel = (ColumnPanel) getPanel(); - panel.setBorder(false); - panel.setPadColor("#FFFFFF"); - panel.setColumnWidth(1, "20%"); - panel.setColumnWidth(2, "80%"); - panel.setWidth("100%"); - - add(new Label(new GlobalizedMessage( - "cms.ui.authoring.edit_body_text", - CmsConstants.CMS_BUNDLE)), - ColumnPanel.LEFT | ColumnPanel.FULL_WIDTH); - - textWidget = new CMSDHTMLEditor(PageTextForm.TEXT_ENTRY); - textWidget.setRows(25); - textWidget.setCols(40); - // cg - sets editor size - closer to actual published page - // width, and similar size as htmlarea. - // could be configurable - unset means default 100% x 400px - textWidget.setMetaDataAttribute("width", "575"); - textWidget.setMetaDataAttribute("height", "500"); - textWidget.setWrap(CMSDHTMLEditor.SOFT); - add(textWidget, ColumnPanel.LEFT - | ColumnPanel.FULL_WIDTH); - - saveCancelSection = new SaveCancelSection(); - add(saveCancelSection, ColumnPanel.FULL_WIDTH); - - // optionally, we clear the text of MSWord tags every time - // the text is submitted/saved - if (CMSConfig.getConfig().isSaveTextCleansWordTags()) { - saveCancelSection.getSaveButton().setOnClick( - "wordClean_" - + PageTextForm.TEXT_ENTRY - + "();"); - } - - addInitListener(this); - addProcessListener(this); - - } - - // These are here so that TemplateBody can set them. - // public final void setMimeWidget(final SingleSelect widget) { - // mimeWidget = widget; - // } - public final void setTextWidget(final TextArea widget) { - textWidget = widget; - } - - public final void setSaveCancel(final SaveCancelSection widget) { - saveCancelSection = widget; - } - - /** - * Initialise the text area with the current value. - * - * @param event - * - * @throws FormProcessException - */ - public void init(final FormSectionEvent event) throws FormProcessException { - - final FormData data = event.getFormData(); - final PageState state = event.getPageState(); - - final String text = textBody.getText(state); - - if (text != null) { - data.put(TEXT_ENTRY, text); - } - } - - /** - * Cancels streamlined editing. - * - * @param event - */ - @Override - public void submitted(final FormSectionEvent event) { - - if (getSaveCancelSection() - .getCancelButton() - .isSelected(event.getPageState())) { - - textBody.cancelStreamlinedCreation(event.getPageState()); - } - } - - // process: update the mime type and content - @Override - public void process(final FormSectionEvent event) throws - FormProcessException { - - final FormData data = event.getFormData(); - final PageState state = event.getPageState(); - final String text = (String) data.get(TEXT_ENTRY); - textBody.updateText(state, text); - - textBody.maybeForwardToNextStep(event.getPageState()); - } - - /** - * @return the save/cancel section for this form - */ - public SaveCancelSection getSaveCancelSection() { - return saveCancelSection; - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/SelectedLanguageUtil.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/SelectedLanguageUtil.java deleted file mode 100644 index 9e005c042..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/SelectedLanguageUtil.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2017 LibreCCM Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package com.arsdigita.cms.ui.authoring; - -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.parameters.StringParameter; -import com.arsdigita.kernel.KernelConfig; - -import java.util.Locale; - -/** - * - * @author Jens Pelzetter - */ -public class SelectedLanguageUtil { - - private SelectedLanguageUtil() { - //Nothing - } - - public static final Locale selectedLocale( - final PageState state, - final StringParameter selectedLanguageParam) { - - final String selectedLanguage = (String) state - .getValue(selectedLanguageParam); - if (selectedLanguage == null) { - return KernelConfig.getConfig().getDefaultLocale(); - } else { - return new Locale(selectedLanguage); - } - } -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/TextAssetBodyLabelCellRenderer.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/TextAssetBodyLabelCellRenderer.java deleted file mode 100755 index 33f734be3..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/TextAssetBodyLabelCellRenderer.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 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.authoring; - -import com.arsdigita.bebop.PageState; - - -import com.arsdigita.bebop.table.TableCellRenderer; -import com.arsdigita.bebop.Table; -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.Component; - -import org.libreccm.l10n.LocalizedString; - -// Renders strings as labels -public class TextAssetBodyLabelCellRenderer implements TableCellRenderer { - - @Override - public Component getComponent(final Table table, - final PageState state, - final Object value, - final boolean isSelected, - final Object key, - final int row, - final int column) { - - throw new UnsupportedOperationException("ToDo"); - -// final Label label; -// if ("content".equals(key) && value instanceof LocalizedString) { -// // We have different styles for different mime types -// final LocalizedString asset = (LocalizedString )value; -// label = new Label(asset.getText()); -// label.setIdAttr("webPage"); -// String type = asset.getMimeType().getMimeType() -// .toLowerCase(); -// if (type.indexOf("text/xml") > -1 || -// type.indexOf("text/xsl") > -1 || -// type.indexOf("text/x-jsp") > -1) { -// label.setClassAttr("preformatted"); -// label.setOutputEscaping(true); -// } else { -// label.setOutputEscaping(false); -// } -// } else if (MIME_TYPE_KEY.equals(key) && value instanceof TextAsset) { -// label = new Label(((TextAsset)value).getMimeType().getLabel(), -// false); -// } else { -// label = new Label(value.toString()); -// label.setOutputEscaping(false); -// } -// -// return label; - } -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/TextBody.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/TextBody.java deleted file mode 100755 index 5c275030e..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/TextBody.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * 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.authoring; - -import com.arsdigita.bebop.Page; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.Resettable; -import com.arsdigita.bebop.event.RequestEvent; -import com.arsdigita.bebop.event.RequestListener; -import com.arsdigita.bebop.form.SingleSelect; -import com.arsdigita.bebop.parameters.StringParameter; - -import com.arsdigita.cms.ItemSelectionModel; -import com.arsdigita.cms.ui.ContentItemPage; -import com.arsdigita.cms.ui.FileUploadSection; -import com.arsdigita.cms.ui.SecurityPropertyEditor; -import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.toolbox.ui.DomainObjectPropertySheet; - -import org.librecms.CMSConfig; -import org.libreccm.l10n.LocalizedString; -import org.librecms.CmsConstants; - -/** - * Displays the mime-type and the body of a single {@code TextAsset}. Maintains - * a form or uploading files into the text body of the asset, and a form for - * editing the text of the asset. - *

- * Unlike most other authoring components, this component does not require the - * asset to exist. If the asset does not exist (i.e., if - * !m_assetModel.isSelected(state)), the upload and editing forms - * will create a new asset and set it in the model by calling - * setSelectedObject on the asset selection model. Child classes - * should override the {@link #createTextAsset(PageState)} method in to create a - * valid text asset. - *

- * This component is used primarily in {@link GenericArticleBody} and - * {@link com.arsdigita.cms.ui.templates.TemplateBody} - * - * Note: In CCM NG (version 7 and newer) {@code TextAsset} does not - * longer exist. Instead fields of type {@link LocalizedString} are used. This - * class has been adapted to use {@link LocalizedString}. The name of the class - * etc. has been kept to make the migration easier. - * - * @author Stanislav Freidin (sfreidin@arsdigita.com) - * @version Jens Pelzetter - */ -public abstract class TextBody - extends SecurityPropertyEditor - implements Resettable, AuthoringStepComponent, RequestListener { - - public static final String FILE_UPLOAD = "file"; - public static final String TEXT_ENTRY = "text"; - - private static final String STREAMLINED_DONE = "1"; - private static final CMSConfig CMS_CONFIG = CMSConfig.getConfig(); - - private final StringParameter streamlinedCreationParam; - private final StringParameter selectedLanguageParam; - private final ItemSelectionModel itemSelectionModel; - - /** - * Construct a new GenericArticleBody component - * - * @param assetModel The {@link ItemSelectionModel} which will be - * responsible for maintaining the current - * asset - * @param selectedLanguageParam Parameter for the currently selected locale. - */ - public TextBody(final ItemSelectionModel assetModel, - final StringParameter selectedLanguageParam) { - - this(assetModel, null, selectedLanguageParam); - } - - /** - * Construct a new GenericArticleBody component - * - * @param itemSelectionModel The {@link ItemSelectionModel} which will be - * responsible for maintaining the current asset - * @param authoringKitWizard The parent wizard which contains the form. - * The form may use the wizard's methods, such - * as stepForward and stepBack, in its process - * listener. - * @param selectedLangugeParam Parameter for the currently selected locale. - */ - public TextBody(final ItemSelectionModel itemSelectionModel, - final AuthoringKitWizard authoringKitWizard, - final StringParameter selectedLangugeParam) { - - super(); - this.itemSelectionModel = itemSelectionModel; - - if (authoringKitWizard == null) { - streamlinedCreationParam = new StringParameter("item_body_done"); - } else { - streamlinedCreationParam = new StringParameter( - String.format("%s_body_done", - authoringKitWizard - .getContentType() - .getContentItemClass() - .getName())); - } - - this.selectedLanguageParam = selectedLangugeParam; - - if (!CMS_CONFIG.isHideTextAssetUploadFile()) { - final PageFileForm pageFileForm = getPageFileForm(); - add(FILE_UPLOAD, - new GlobalizedMessage("cms.ui.upload", CmsConstants.CMS_BUNDLE), - pageFileForm, - pageFileForm.getSaveCancelSection().getCancelButton()); - } - - final PageTextForm pageTextForm = new PageTextForm(this); - add(TEXT_ENTRY, - new GlobalizedMessage("cms.ui.edit", CmsConstants.CMS_BUNDLE), - pageTextForm, - pageTextForm.getSaveCancelSection().getCancelButton()); - - // Specify full path to properties of the text asset - final DomainObjectPropertySheet sheet = getTextBodyPropertySheet( - itemSelectionModel); - sheet.add(new GlobalizedMessage("cms.ui.article.text", - CmsConstants.CMS_BUNDLE), - getTextPropertyName()); - - setDisplayComponent(sheet); - - getDisplayPane().setClassAttr("invertedPropertyDisplay"); - - } - - /** - * Determines the name of the property holding the text. - * - * @return The name of the property holding the text. - */ - protected abstract String getTextPropertyName(); - - protected DomainObjectPropertySheet getTextBodyPropertySheet( - final ItemSelectionModel itemSelectionModel) { - - final DomainObjectPropertySheet sheet = new DomainObjectPropertySheet( - itemSelectionModel); - - return sheet; - -// return new TextBodyPropertySheet(itemSelectionModel, -// selectedLanguageParam); - } - - /** - * Adds the options for the mime type select widget of - * GenericArticleForm and sets the default mime type. - * - * @param mimeSelect - */ - protected void setMimeTypeOptions(final SingleSelect mimeSelect) { - FileUploadSection.addMimeOptions(mimeSelect, "text"); - mimeSelect.setOptionSelected("text/html"); - } - - /** - * To be overwritten by subclasses, should return the text for the currently - * selected locale. - * - * @param state The current page state - * - * @return The text of the currently selected locale. - */ - public abstract String getText(final PageState state); - - /** - * Reset this component to its original state - * - * @param state the current page state - */ - @Override - public void reset(final PageState state) { - showDisplayPane(state); - } - - /** - * Update the text for the currently selected locale. - * - * @param state the current page state - * @param text the new next text for the currently selected locale. - */ - protected abstract void updateText(PageState state, String text); - - /** - * Return the ItemSelectionModel which will be used to maintain - * the current text asset - * - * @return - */ - public ItemSelectionModel getItemSelectionModel() { - return itemSelectionModel; - } - - /** - * Forward to the next step if the streamlined creation parameter is turned - * on _and_ the streamlined_creation global state parameter is set to - * 'active' - * - * @param state the PageState - */ - protected void maybeForwardToNextStep(final PageState state) { - if (ContentItemPage.isStreamlinedCreationActive(state) - && !STREAMLINED_DONE. - equals(state.getValue(streamlinedCreationParam))) { - state.setValue(streamlinedCreationParam, STREAMLINED_DONE); - fireCompletionEvent(state); - } - } - - /** - * Cancel streamlined creation for this step if the streamlined creation - * parameter is turned on _and_ the streamlined_creation global state param - * is set to 'active' - * - * @param state the PageState - */ - protected void cancelStreamlinedCreation(final PageState state) { - if (ContentItemPage.isStreamlinedCreationActive(state)) { - state.setValue(streamlinedCreationParam, STREAMLINED_DONE); - } - } - - /** - * Open the edit component if the streamlined creation parameter is turned - * on _and_ the streamlined_creation global state param is set to 'active' - * - * @param event - */ - @Override - public void pageRequested(final RequestEvent event) { - - final PageState state = event.getPageState(); - - if (ContentItemPage.isStreamlinedCreationActive(state) - && !STREAMLINED_DONE. - equals(state.getValue(streamlinedCreationParam))) { - showComponent(state, TEXT_ENTRY); - } - //} - - } - - /** - * This is the form that is used to upload files. This method can be used so - * that a subclass can use their own subclass of PageFileForm. - * - * @return The form for uploading a text. - */ - protected PageFileForm getPageFileForm() { - return new PageFileForm(this); - } - - protected String getDefaultMimeType() { - return "text/plain"; - } - - /** - * Registers global state parameter for cancelling streamlined creation - */ - @Override - public void register(final Page page) { - super.register(page); - page.addGlobalStateParam(streamlinedCreationParam); - page.addRequestListener(this); - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/WizardSelector.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/WizardSelector.java deleted file mode 100755 index b5d990d37..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/WizardSelector.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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.authoring; - -import com.arsdigita.bebop.Component; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.Resettable; -import com.arsdigita.bebop.SingleSelectionModel; -import com.arsdigita.bebop.parameters.LongParameter; - -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentType; - -import com.arsdigita.cms.ItemSelectionModel; -import com.arsdigita.kernel.ui.ACSObjectSelectionModel; -import com.arsdigita.util.UncheckedWrapperException; -import com.arsdigita.xml.Element; - -import org.libreccm.cdi.utils.CdiUtil; -import org.librecms.contenttypes.AuthoringKitInfo; -import org.librecms.contenttypes.ContentTypeInfo; - - -/** - * An invisible component which contains all the possible authoring kits. The - * kits are loaded from the database at construction time. The selector chooses - * which kit to display at page rendering time based on the value of the - * content_type state parameter. - * - * Essentially, this component is a hack which is used to get around the fact - * that we cannot instantiate stateful components dynamically. - * - * @author unknown - * @author Jens Pelzetter - */ -public class WizardSelector extends AuthoringKitSelector - implements Resettable { - - private final ItemSelectionModel itemSelectionModel; - - /** - * Construct a new WizardSelector. Load all the possible authoring kits from - * the database and construct wizards for them. - * - * @param model the {@link ItemSelectionModel} which will supply the - * wizard with its item - * - * @param typeModel the {@link ACSObjectSelectionModel} which will supply - * the default content type - * - * @pre itemModel != null - */ - public WizardSelector(final ItemSelectionModel model, - final SingleSelectionModel typeModel) { - super(typeModel); - itemSelectionModel = model; - super.processKit(); - } - - /** - * Get the wizard for the given kit. - * - * @param kit - * @param type - * - * @return - */ - @Override - public Component instantiateKitComponent(final AuthoringKitInfo kit, - final ContentTypeInfo type) { - - final ItemSelectionModel itemModel = new ItemSelectionModel( - type, (LongParameter) itemSelectionModel.getStateParameter()); - - final AuthoringKitWizard wizard - = new AuthoringKitWizard(type, itemModel); - return wizard; - } - - /** - * @return The item selection model used by this wizard - */ - public ItemSelectionModel getSelectionModel() { - return itemSelectionModel; - } - - // Determine the current wizard - private Component getCurrentWizard(PageState state) { - - // Get the current item and extract its content type - if (!itemSelectionModel.isSelected(state)) { - throw new UncheckedWrapperException("No item selected."); - } - - final ContentItem item = itemSelectionModel.getSelectedObject(state); - -// final ContentType type = item.getContentType(); -// final String typeClass; -// -// if (type == null) { -// // Try to get the default content type -// typeClass = getComponentSelectionModel().getSelectedKey(state); -// if (typeClass == null || typeClass.isEmpty()) { -// throw new UncheckedWrapperException("Content type is missing"); -// } -// } else { -// typeClass = type.getContentItemClass(); -// } - - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final WizardSelectorController controller = cdiUtil - .findBean(WizardSelectorController.class); - - final String typeClass = controller.getTypeClass(item); - - // Return the selected wizard - return getComponent(typeClass); - } - - // Choose the right wizard and run it - @Override - public void generateXML(final PageState state, final Element parent) { - - final Component component = getCurrentWizard(state); - - if (component == null) { - throw new UncheckedWrapperException("No Wizard."); - } - - component.generateXML(state, parent); - } - - /** - * Reset the state of the current wizard - */ - @Override - public void reset(final PageState state) { - final Resettable resettable = (Resettable) getCurrentWizard(state); - if (resettable != null) { - resettable.reset(state); - } - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/WizardSelectorController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/WizardSelectorController.java deleted file mode 100644 index 0494697aa..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/WizardSelectorController.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2017 LibreCCM Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package com.arsdigita.cms.ui.authoring; - -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentItemRepository; -import org.librecms.contentsection.ContentType; - -import java.util.Objects; - -import javax.enterprise.context.RequestScoped; -import javax.inject.Inject; -import javax.transaction.Transactional; - -/** - * - * @author Jens Pelzetter - */ -@RequestScoped -public class WizardSelectorController { - - @Inject - private ContentItemRepository itemRepo; - - @Transactional(Transactional.TxType.REQUIRED) - public String getTypeClass(final ContentItem item) { - - Objects.requireNonNull(item); - - final ContentItem contentItem = itemRepo - .findById(item.getObjectId()) - .orElseThrow(() -> new IllegalArgumentException(String - .format("No ContentItem with ID %d in the database.", - item.getObjectId()))); - - final ContentType type = contentItem.getContentType(); - - return type.getContentItemClass(); - } - -} diff --git a/ccm-cms/src/main/java/org/librecms/CMSConfig.java b/ccm-cms/src/main/java/org/librecms/CMSConfig.java index 9cd2f083c..e9174b9ba 100644 --- a/ccm-cms/src/main/java/org/librecms/CMSConfig.java +++ b/ccm-cms/src/main/java/org/librecms/CMSConfig.java @@ -19,15 +19,12 @@ package org.librecms; import com.arsdigita.bebop.form.DHTMLEditor; -import com.arsdigita.cms.ui.authoring.ItemCategoryExtension; import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.configuration.Configuration; import org.libreccm.configuration.ConfigurationManager; import org.libreccm.configuration.Setting; import org.libreccm.core.UnexpectedErrorException; -import org.librecms.dispatcher.ItemResolver; -import org.librecms.dispatcher.SimpleItemResolver; import java.util.ArrayList; import java.util.Arrays; @@ -406,21 +403,6 @@ public class CMSConfig { private String contentCenterMap = "/WEB-INF/resources/content-center-map.xml"; - @Setting( - descKey = "defaultItemResolverClassNames.desc", - labelKey = "defaultItemResolverClassNames.label" - ) - private List defaultItemResolverClassNames = Arrays.asList( - new String[]{ - SimpleItemResolver.class.getName() - }); - -// @Setting -// private List defaultTemplateResolverClassNames = Arrays.asList( -// new String[]{ -// DefaultTemplateResolver.class.getName(), -// TemplateResolver.class.getName() -// }); @Setting( descKey = "itemSearchDefaultTab.desc", labelKey = "itemSearchDefaultTab.label" @@ -553,13 +535,6 @@ public class CMSConfig { ) private int xmlCacheAge = 60 * 60 * 24; - @Setting( - descKey = "categoryAuthoringExtension.desc", - labelKey = "categoryAuthoringExtension.label" - ) - private String categoryAuthoringExtension = ItemCategoryExtension.class - .getName(); - @Setting( descKey = "categoryPickerAjaxExpandAll.desc", labelKey = "categoryPickerAjaxExpandAll.label" @@ -887,55 +862,6 @@ public class CMSConfig { this.contentCenterMap = contentCenterMap; } - public List getDefaultItemResolverClassNames() { - return new ArrayList<>(defaultItemResolverClassNames); - } - - public void setDefaultItemResolverClassNames( - final List defaultItemResolverClassNames) { - this.defaultItemResolverClassNames - = new ArrayList<>(defaultItemResolverClassNames); - } - - @SuppressWarnings("unchecked") - public List> getDefaultItemResolverClasses() { - final List> resolverClasses = new ArrayList<>(); - for (final String className : getDefaultItemResolverClassNames()) { - try { - resolverClasses.add((Class) Class.forName( - className)); - } catch (ClassNotFoundException ex) { - throw new UnexpectedErrorException(String.format( - "ItemResolver class \"%s\" not found.", className), ex); - } - } - return resolverClasses; - } - -// public List getDefaultTemplateResolverClassNames() { -// return new ArrayList<>(defaultTemplateResolverClassNames); -// } -// -// public void setDefaultTemplateResolverClassNames( -// List defaultTemplateResolverClassNames) { -// this.defaultTemplateResolverClassNames = new ArrayList<>( -// defaultTemplateResolverClassNames); -// } -// -// @SuppressWarnings("unchecked") -// public List> getDefaultTemplateResolverClasses() { -// final List> resolverClasses = new ArrayList<>(); -// for (final String className : getDefaultTemplateResolverClassNames()) { -// try { -// resolverClasses.add((Class) Class.forName( -// className)); -// } catch (ClassNotFoundException ex) { -// throw new UnexpectedErrorException(String.format( -// "ItemResolver class \"%s\" not found.", className), ex); -// } -// } -// return resolverClasses; -// } public String getItemSearchDefaultTab() { return itemSearchDefaultTab; } @@ -1129,15 +1055,6 @@ public class CMSConfig { this.linkDescMaxLength = linkDescMaxLength; } - public String getCategoryAuthoringExtension() { - return categoryAuthoringExtension; - } - - public void setCategoryAuthoringExtension( - final String categoryAuthoringExtension) { - this.categoryAuthoringExtension = categoryAuthoringExtension; - } - public boolean isCategoryPickerAjaxExpandAll() { return categoryPickerAjaxExpandAll; } diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionManager.java b/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionManager.java index ea0bc9704..0be21cd48 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionManager.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionManager.java @@ -52,7 +52,6 @@ import org.librecms.lifecycle.LifecycleDefinition; import java.util.Optional; import org.librecms.contentsection.privileges.TypePrivileges; -import org.librecms.dispatcher.ItemResolver; import java.util.Collections; import java.util.Objects; @@ -97,9 +96,6 @@ public class ContentSectionManager { @Inject private ConfigurationManager confManager; - @Inject - private Instance itemResolvers; - /** * Creates a new content section including the default roles. This operation * requries {@code admin} privileges. @@ -458,36 +454,6 @@ public class ContentSectionManager { sectionRepo.save(section); } - /** - * Retrieves the {@link ItemResolver} for the provided content section. - * - * @param section The section for which the {@link ItemResolver} is - * retrieved. - * - * @return The {@link ItemResolver} for the provided content section. - */ - public ItemResolver getItemResolver(final ContentSection section) { - try { - @SuppressWarnings("unchecked") - final Class itemResolverClazz - = (Class) Class. - forName(section.getItemResolverClass()); - - final Instance instance = itemResolvers.select( - itemResolverClazz); - - if (instance.isUnsatisfied()) { - throw new UnexpectedErrorException(String.format( - "No ItemResolver \"{}\" found.", - itemResolverClazz.getName())); - } else { - return instance.get(); - } - } catch (ClassNotFoundException ex) { - throw new UnexpectedErrorException(ex); - } - } - /** * Adds a new {@link ContentType} to a content section, making items of that * type available in the content section. This operation requires diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionServlet.java b/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionServlet.java deleted file mode 100644 index d04f12b2d..000000000 --- a/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionServlet.java +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Copyright (C) 2016 LibreCCM Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package org.librecms.contentsection; - -import com.arsdigita.bebop.Page; -import com.arsdigita.cms.dispatcher.CMSPage; -import com.arsdigita.cms.dispatcher.ContentItemDispatcher; -import com.arsdigita.dispatcher.AccessDeniedException; -import com.arsdigita.dispatcher.DispatcherHelper; -import com.arsdigita.dispatcher.RequestContext; -import com.arsdigita.templating.PresentationManager; -import com.arsdigita.templating.Templating; -import com.arsdigita.util.Assert; -import com.arsdigita.util.Classes; -import com.arsdigita.web.ApplicationFileResolver; -import com.arsdigita.web.BaseApplicationServlet; -import com.arsdigita.web.LoginSignal; -import com.arsdigita.web.Web; -import com.arsdigita.web.WebConfig; -import com.arsdigita.xml.Document; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.librecms.CMSConfig; -import org.libreccm.cdi.utils.CdiUtil; -import org.libreccm.l10n.GlobalizationHelper; -import org.libreccm.security.PermissionChecker; -import org.libreccm.security.Shiro; -import org.libreccm.web.CcmApplication; -import org.librecms.CmsConstants; -import org.librecms.contentsection.privileges.ItemPrivileges; -import org.librecms.dispatcher.ItemResolver; -import org.librecms.lifecycle.Lifecycle; - -import java.util.Date; - -import javax.inject.Inject; -import javax.servlet.RequestDispatcher; - -/* - * This servlet will maybe removed. Our current plan is to integrate the navigation - * application into ccm-cms, and to deliver all content using that app. Then - * this servlet becomes useless. - */ - - /* - * NOTE: - * Repaired ItemURLCache to save multilingual items with automatic - * language negotiation. The cache now uses the remaining url part - * and the language concatinated as a hash table key. The delimiter - * is CACHE_KEY_DELIMITER. - */ - - /* - * NOTE 2: - * In a process of refactoring from legacy compatible to legacy free applications. - * TODO: - * - replace url check using RequestContext which resolves to SiteNodeRequest - * implementation (due to SiteNodeRequest used in BaseApplicationServlet). - * - Refactor content item UI bebop ApplicationPage or PageFactory instead of - * legacy infected sitenode / package dispatchers. - */ -/** - * Content Section's Application Servlet according CCM core web application - * structure { - * - * @see com.arsdigita.web.Application} implements the content section UI. - * - * It handles the UI for content items and delegates the UI for sections and - * folders to jsp templates. - * - * @author unknown - * @author Peter Boy - * @author Jens Pelzetter - */ -@WebServlet(urlPatterns = {CmsConstants.CONTENT_SECTION_SERVLET_PATH, - "/templates/servlet/content-section/", - "/templates/servlet/content-section", - CmsConstants.CMS_SERVICE_SERVLET_PATH, - CmsConstants.CONTENT_ITEM_SERVLET_PATH}) -public class ContentSectionServlet extends BaseApplicationServlet { - - private static final long serialVersionUID = 8061725145564728637L; - - private static final Logger LOGGER = LogManager.getLogger( - ContentSectionServlet.class); - - /** - * Literal for the prefix (in url) for previewing items - */ - public static final String PREVIEW = "/preview"; - /** - * Literal Template files suffix - */ - public static final String FILE_SUFFIX = ".jsp"; - /** - * Literal of URL Stub for index file name (includes leading slash) - */ - public static final String INDEX_FILE = "/index"; - public static final String XML_SUFFIX = ".xml"; - public static final String XML_MODE = "xmlMode"; - public static final String MEDIA_TYPE = "templateContext"; - private static final String CACHE_KEY_DELIMITER = "%"; - - public static final String CONTENT_ITEM - = "com.arsdigita.cms.dispatcher.item"; - public static final String CONTENT_SECTION - = "com.arsdigita.cms.dispatcher.section"; - - private final ContentItemDispatcher m_disp = new ContentItemDispatcher(); -// private static Map itemResolverCache = Collections -// .synchronizedMap(new HashMap<>()); - private static Map s_itemURLCacheMap = null; - /** - * Whether to cache the content items - */ -// private static final boolean s_cacheItems = true; - // 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; - - /** - * Resolver to actually use to find templates (JSP). JSP may be stored in - * file system or otherwise, depends on resolver. Resolver is retrieved from - * configuration. (probably used for other stuff as JSP's as well) - */ - private ApplicationFileResolver m_resolver; - - @Inject - private ContentSectionManager sectionManager; - - /** - * Init method overwrites parents init to pass in optional parameters - * {@link com.arsdigita.web.BaseServlet}. If not specified system wide - * defaults are used. - * - * @param config - * - * @throws javax.servlet.ServletException - */ - @Override - public void init(ServletConfig config) throws ServletException { - - super.init(config); - - // optional init-param named template-path from ~/WEB-INF/web.xml - // may overwrite configuration parameters - String templatePath = config.getInitParameter("template-path"); - if (templatePath == null) { - m_templatePath = CMSConfig.getConfig().getTemplateRootPath(); - } else { - m_templatePath = config.getInitParameter("template-path"); - } - - // optional init-param named file-resolver from ~/WEB-INF/web.xml - String resolverName = config.getInitParameter("file-resolver"); - - if (resolverName == null) { - m_resolver = WebConfig.getConfig().getResolver(); - } else { - m_resolver = (ApplicationFileResolver) Classes.newInstance( - resolverName); - } - LOGGER.debug("Template path is {} with resolver {}", - m_templatePath, - m_resolver.getClass().getName()); - - // NEW STUFF here will be used to process the pages in this servlet - // Currently NOT working -// addPage("/admin", new MainPage()); // index page at address ~/cs - // addPage("/admin/index.jsp", new MainPage()); - // addPage("/admin/item.jsp", new MainPage()); - } - - /** - * 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) { - m_pages.put(pathInfo, page); - } - - /** - * Implementation of parent's (abstract) doService method checks HTTP - * request to determine whether to handle a content item or other stuff - * which is delegated to jsp templates. { - * - * @see com.arsdigita.web.BaseApplicationServlet#doService - * (HttpServletRequest, HttpServletResponse, Application)} - * - * @param request - * @param response - * @param app - * - * @throws javax.servlet.ServletException - * @throws java.io.IOException - */ - @Override - protected void doService(final HttpServletRequest request, - final HttpServletResponse response, - final CcmApplication app) - throws ServletException, IOException { - - if (!(app instanceof ContentSection)) { - throw new IllegalArgumentException( - "The provided application instance is not a content section."); - } - - final ContentSection section = (ContentSection) app; - - final RequestContext ctx = DispatcherHelper.getRequestContext(); - final String url = ctx.getRemainingURLPart(); - - //Only for testing PageModel - if (url != null && url.endsWith("page-model/")) { - getServletContext() - .getRequestDispatcher("/page-model.bebop") - .include(request, response); - return; - } - //End Test PageModel - - LOGGER.info("Resolving URL {} and trying as item first.", url); - final ItemResolver itemResolver = getItemResolver(section); - - String pathInfo = request.getPathInfo(); - if (pathInfo == null) { - pathInfo = "/"; - } - - final ContentItem item = getItem(section, pathInfo, itemResolver); - - 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(request, response); // 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(request, response, ctx); - } - - /* 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 = request.getParameter("transID"); - - serveItem(request, response, section, item); - - /* OTHERWISE delegate to a JSP in file system */ - } else { - /* We have to deal with a content-section, folder or another bit */ - if (LOGGER.isInfoEnabled()) { - LOGGER.info("NOT serving content item"); - } - - /* Store content section in http request to make it available - * for admin/index.jsp */ - request.setAttribute(CONTENT_SECTION, section); - - RequestDispatcher rd = m_resolver.resolve(m_templatePath, - request, - response, - app); - if (rd != null) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Got dispatcher " + rd); - } - rd.forward(DispatcherHelper.restoreOriginalRequest(request), - response); - } else { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("No dispatcher found for " + rd); - } - String requestUri = request.getRequestURI(); // same as ctx.getRemainingURLPart() - response.sendError(404, requestUri - + " not found on this server."); - } - } - - } - - private void serveItem(final HttpServletRequest request, - final HttpServletResponse response, - final ContentSection section, - final ContentItem item) - throws ServletException, IOException { - - if (LOGGER.isInfoEnabled()) { - LOGGER.info("serving content item"); - } - - RequestContext ctx = DispatcherHelper.getRequestContext(); - String url = ctx.getRemainingURLPart(); - - final ItemResolver itemResolver = getItemResolver(section); - - //set the content item in the request - request.setAttribute(CONTENT_ITEM, item); - - //set the template context -// ToDo -// final TemplateResolver templateResolver = m_disp.getTemplateResolver( -// section); -// -// String templateURL = url; -// if (!templateURL.startsWith("/")) { -// templateURL = "/" + templateURL; -// } -// if (templateURL.startsWith(PREVIEW)) { -// templateURL = templateURL.substring(PREVIEW.length()); -// } -// -// final String sTemplateContext = itemResolver.getTemplateFromURL( -// templateURL); -// LOGGER.debug("setting template context to {}", sTemplateContext); -// -// templateResolver.setTemplateContext(sTemplateContext, request); -// ToDo End - // Work out how long to cache for.... - // We take minimum(default timeout, lifecycle expiry) - Lifecycle cycle = item.getLifecycle(); - int expires = DispatcherHelper.getDefaultCacheExpiry(); - if (cycle != null) { - Date endDate = cycle.getEndDateTime(); - - if (endDate != null) { - int maxAge = (int) ((endDate.getTime() - System - .currentTimeMillis()) / 1000l); - if (maxAge < expires) { - expires = maxAge; - } - } - } - - //use ContentItemDispatcher - m_disp.dispatch(request, response, ctx); - } - - /** - * Fetches the content section from the request attributes. - * - * @param request The HTTP request - * - * @return The content section - * - * @pre ( request != null ) - */ - public static ContentSection getContentSection(HttpServletRequest request) { - return (ContentSection) request.getAttribute(CONTENT_SECTION); - } - - public static boolean checkAdminAccess(final HttpServletRequest request, - final ContentSection section) { - final PermissionChecker permissionChecker = CdiUtil.createCdiUtil() - .findBean(PermissionChecker.class); - - return permissionChecker.isPermitted(ItemPrivileges.PREVIEW, - section) - || permissionChecker.isPermitted(ItemPrivileges.EDIT, - section) - || permissionChecker.isPermitted(ItemPrivileges.APPROVE, - section); - } - - @SuppressWarnings("unchecked") - public ItemResolver getItemResolver(final ContentSection section) { - - return sectionManager.getItemResolver(section); - } - - public ContentItem getItem(final ContentSection section, - final String url, - final ItemResolver itemResolver) { - - LOGGER.debug("getting item at url {}", url); - final HttpServletRequest request = Web.getRequest(); - - //first sanitize the url - String itemUrl = url; - if (url.endsWith(XML_SUFFIX)) { - request.setAttribute(XML_MODE, Boolean.TRUE); - LOGGER.debug("StraightXML Requested"); - itemUrl = "/" + url.substring(1, url.length() - XML_SUFFIX.length()); - } else { - request.setAttribute(XML_MODE, Boolean.FALSE); - if (url.endsWith(FILE_SUFFIX)) { - itemUrl = String.format( - "/%s", - url.substring(1, url.length() - FILE_SUFFIX.length())); - } else if (url.endsWith("/")) { - itemUrl = String.format("/%s", - url.substring(0, url.length() - 1)); - } - } - - if (!itemUrl.startsWith("/")) { - itemUrl = String.format("/%s", itemUrl); - } - - ContentItem item; - final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final PermissionChecker permissionChecker = cdiUtil.findBean( - PermissionChecker.class); - final ContentItemManager itemManager = cdiUtil.findBean( - ContentItemManager.class); - // Check if the user has access to view public or preview pages - boolean hasPermission = true; - - // If the remaining URL starts with "preview/", then try and - // preview this item. Otherwise look for the live item. - boolean preview = false; - if (itemUrl.startsWith(PREVIEW)) { - itemUrl = itemUrl.substring(PREVIEW.length()); - preview = true; - } - - if (preview) { - LOGGER.info("Trying to get item for PREVIEW"); - - item = itemResolver.getItem(section, - itemUrl, - ContentItemVersion.DRAFT.toString()); - if (item != null) { - hasPermission = permissionChecker.isPermitted( - ItemPrivileges.PREVIEW, item); - } - } else { - LOGGER.info("Trying to get LIVE item"); - - //check if this item is in the cache - //we only cache live items - LOGGER.debug("Trying to get content item for URL {}from cache", - itemUrl); - - // Get the negotiated locale - final GlobalizationHelper globalizationHelper = cdiUtil.findBean( - GlobalizationHelper.class); - final String lang = globalizationHelper.getNegotiatedLocale() - .getLanguage(); - - // XXX why assign a value and afterwards null?? - // Effectively it just ignores the cache and forces a fallback to - // itemResover in any case. Maybe otherwise language selection / - // negotiation doesn't work correctly? - item = null; - - if (item == null) { - LOGGER.debug("Did not find content item in cache, so trying " - + "to retrieve and cache..."); - //item not cached, so retreive it and cache it - item = itemResolver.getItem(section, - itemUrl, - ContentItemVersion.LIVE.toString()); - - if (LOGGER.isDebugEnabled() && item != null) { - LOGGER.debug("Sanity check: item.getPath() is {}", - itemManager.getItemPath(item)); - } - - if (item != null) { - LOGGER.debug("Content Item is not null"); - - hasPermission = permissionChecker.isPermitted( - ItemPrivileges.VIEW_PUBLISHED, item); - } - } - - } - - if (item == null && itemUrl.endsWith(INDEX_FILE)) { - - if (item == null) { - LOGGER.info("no item found"); - } - - // look up folder if it's an index - itemUrl = itemUrl.substring(0, itemUrl.length() - INDEX_FILE - .length()); - LOGGER.info("Attempting to match folder " + itemUrl); - - item = itemResolver.getItem(section, - itemUrl, - ContentItemVersion.LIVE.toString()); - if (item != null) { - hasPermission = permissionChecker.isPermitted( - ItemPrivileges.VIEW_PUBLISHED, item); - } - } - - if (!hasPermission) { - - // first, check if the user is logged-in - // if he isn't, give him a chance to do so... - final Shiro shiro = cdiUtil.findBean(Shiro.class); - - if (shiro.getSubject().isAuthenticated()) { - throw new LoginSignal(request); - } - - throw new AccessDeniedException(); - } - - return item; - } - - public ContentItem getItem(final ContentSection section, final String url) { - final ItemResolver itemResolver = getItemResolver(section); - - return getItem(section, url, itemResolver); - } - - // synchronize access to the item-url cache -// private static synchronized void itemURLCachePut( -// final ContentSection section, -// final String sURL, -// final String lang, -// final Long itemID) { -// -// getItemURLCache(section).put(String.format( -// "%s" + CACHE_KEY_DELIMITER + "%s", sURL, lang), itemID); -// } -// -// /** -// * Maps the content item to the URL in a cache -// * -// * @param section the content section in which the content item is published -// * @param url the URL at which the content item s published -// * @param lang -// * @param item the content item at the URL -// */ -// public static synchronized void itemURLCachePut( -// final ContentSection section, -// final String url, -// final String lang, -// final ContentItem item) { -// -// if (url == null || item == null) { -// return; -// } -// LOGGER.debug("adding cached entry for url {} and language {}", -// url, -// lang); -// -// itemURLCachePut(section, url, lang, item.getObjectId()); -// } -// -// /** -// * Removes the cache entry for the URL, sURL -// * -// * @param section the content section in which to remove the key -// * @param url the cache entry key to remove -// * @param lang -// */ -// public static synchronized void itemURLCacheRemove( -// final ContentSection section, -// final String url, -// final String lang) { -// -// LOGGER.debug("removing cached entry for url {} and language {} ", -// url, -// lang); -// -// getItemURLCache(section).remove(url + CACHE_KEY_DELIMITER + lang); -// } -// -// /** -// * Fetches the ContentItem published at that URL from the cache. -// * -// * @param section the content section in which the content item is published -// * @param url the URL for the item to fetch -// * @param lang -// * @return the ContentItem in the cache, or null -// */ -// public static ContentItem itemURLCacheGet(final ContentSection section, -// final String url, -// final String lang) { -// final Long itemID = (Long) getItemURLCache(section).get( -// url + CACHE_KEY_DELIMITER + lang); -// -// if (itemID == null) { -// return null; -// } else { -// final ContentItemRepository itemRepo = CdiUtil.createCdiUtil().findBean(ContentItemRepository.class); -// try { -// return itemRepo.findById(itemID); -// } catch(NoResultException ex) { -// return null; -// } -// } -// } -// -// private static synchronized CacheTable getItemURLCache(ContentSection section) { -// Assert.exists(section, ContentSection.class); -// if (s_itemURLCacheMap == null) { -// initializeItemURLCache(); -// } -// -// if (s_itemURLCacheMap.get(section.getPath()) == null) { -// final CacheTable cache = new CacheTable("ContentSectionServletItemURLCache" + -// section.getID().toString()); -// s_itemURLCacheMap.put(section.getPath(), cache); -// } -// -// return (CacheTable) s_itemURLCacheMap.get(section.getPath()); -// } -} diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionSetup.java b/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionSetup.java index 1259711c1..29a6dad10 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionSetup.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionSetup.java @@ -39,7 +39,6 @@ import org.librecms.contenttypes.Article; import org.librecms.contenttypes.Event; import org.librecms.contenttypes.MultiPartArticle; import org.librecms.contenttypes.News; -import org.librecms.dispatcher.MultilingualItemResolver; import java.util.Arrays; @@ -102,16 +101,6 @@ public class ContentSectionSetup extends AbstractCcmApplicationSetup { section.setDisplayName(sectionName); section.setLabel(sectionName); - if (getIntegrationProps().getProperty(DEFAULT_ITEM_RESOLVER) == null - || getIntegrationProps().getProperty(DEFAULT_ITEM_RESOLVER) - .trim().isEmpty()) { - section.setItemResolverClass(getIntegrationProps().getProperty( - DEFAULT_ITEM_RESOLVER)); - } else { - section.setItemResolverClass(MultilingualItemResolver.class - .getName()); - } - LOGGER.debug("New content section properties: " + "uuid = {}; " + "applicationType = \"{}\"; " @@ -283,34 +272,6 @@ public class ContentSectionSetup extends AbstractCcmApplicationSetup { getEntityManager().persist(lifecycleDefinition); getEntityManager().persist(workflow); - LOGGER.debug("Setting ItemResolver for content section '{}'...", - sectionName); - final String itemResolverClassName; - if (getIntegrationProps().containsKey(String.format("%s.item_resolver", - sectionName))) { - - itemResolverClassName = getIntegrationProps().getProperty( - String.format("%s.item_resolver", - sectionName)); - LOGGER.debug("integration.properties contains setting for the item " - + "resolver of content section '{}'. Using " - + "item resolver '{}'.", - sectionName, itemResolverClassName); - } else if (getIntegrationProps().containsKey("default_item_resolver")) { - itemResolverClassName = getIntegrationProps().getProperty( - "default_item_resolver_name"); - LOGGER.debug("integration.properties contains setting for the " - + "default item resolver. Using item " - + "resolver '{}'.", - itemResolverClassName); - } else { - itemResolverClassName = MultilingualItemResolver.class.getName(); - LOGGER.debug("integration.properties contains *no* setting for item " - + "resolver. Using default item resolver '{}'.", - itemResolverClassName); - } - section.setItemResolverClass(itemResolverClassName); - LOGGER.debug("Adding default content types to content section '{}'...", sectionName); final String[] types; diff --git a/ccm-cms/src/main/java/org/librecms/dispatcher/ItemResolver.java b/ccm-cms/src/main/java/org/librecms/dispatcher/ItemResolver.java deleted file mode 100644 index 5903a59e7..000000000 --- a/ccm-cms/src/main/java/org/librecms/dispatcher/ItemResolver.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (C) 2017 LibreCCM Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package org.librecms.dispatcher; - -import com.arsdigita.bebop.PageState; -import com.arsdigita.cms.dispatcher.CMSPage; - -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentItemVersion; -import org.librecms.contentsection.ContentSection; - -import java.util.StringTokenizer; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; - -/** - * The {@code ItemResolver} is responsible for mapping a URL in a particular - * content section to a content item. - * - * - * As an example, here is the item resolution process for a request to - * {@code http://yourserver/cms/cheese}: - * - * The item resolver would be asked to map the URL stub {@code /cheese} in the - * content section mounted at {@code /cms} to a content item. To this end, the - * dispatcher calls the {@link #getItem} method, passing in the - * {@link ContentSection} and the URL stub for the item within - * the section, {@code /cheese} in our example. As a final argument, the - * dispatcher passes either {@link ContentItemVersion#DRAFT} or - * {@link ContentItemVersion#LIVE} to the {@code ItemResolver}, depending on - * whether the returned item should be the live version (for pages) or the draft - * version (for previewing). - * - * Originally these interface was located in the - * {@code org.arsdigita.cms.dispatcher} package but has been moved here when its - * implementations had been refactored to CDI beans. Also the default - * implementations of the {@link #getTemplateFromURL(java.lang.String)} and - * {@link #stripTemplateFromURL(java.lang.String)} from the old - * {@code AbstractItemResolver} class have been moved here which is now possible - * thanks to the default methods in interfaces introduced in Java 8. The - * class {@code AbstractItemResolver} has been removed completely. - * - * @author Michael Pih (pihman@arsdigita.com) - * @author Stanislav Freidin (sfreidin@arsdigita.com) - * @author Jens Pelzetter - * @version $Revision$ $DateTime: 2004/08/17 23:15:09 $ - * @version $Id$ - */ -public interface ItemResolver { - - public static final String TEMPLATE_CONTEXT_PREFIX = "tem_"; - - /** - * Return a content item based on section, url, and use context. - * - * @param section The current content section - * @param url The section-relative URL - * @param context The use context - * - * @return The content item, or null if no such item exists - */ - ContentItem getItem(ContentSection section, - String url, - String context); - - /** - * Fetches the current context based on the page state. - * - * @param state the current page state - * - * @return the context of the current URL, such as "live" or "admin" - */ - String getCurrentContext(PageState state); - - /** - * Generates a URL for a content item. - * - * @param state The page state - * @param itemId The item ID - * @param name The name of the content page - * @param section the content section to which the item belongs - * @param context the context of the URL, such as "live" or "admin" - * - * @return The URL of the item - * - * @see #getCurrentContext - */ - String generateItemURL(PageState state, - Long itemId, - String name, - ContentSection section, - String context); - - /** - * Generates a URL for a content item. - * - * @param itemId The item ID - * @param name The name of the content page - * @param state The page state - * @param section the content section to which the item belongs - * @param context the context of the URL, such as "live" or "admin" - * @param templateContext the context for the URL, such as "public" - * - * @return The URL of the item - * - * @see #getCurrentContext - */ - String generateItemURL(PageState state, - Long itemId, - String name, - ContentSection section, - String context, - String templateContext - ); - - /** - * Generates a URL for a content item. - * - * @param item The item - * @param state The page state - * @param section the content section to which the item belongs - * @param context the context of the URL, such as "live" or "admin" - * - * @return The URL of the item - * - * @see #getCurrentContext - */ - String generateItemURL(PageState state, - ContentItem item, - ContentSection section, - String context); - - /** - * Generates a URL for a content item. - * - * @param item The item - * @param state The page state - * @param section the content section to which the item belongs - * @param context the context of the URL, such as "live" or "admin" - * @param templateContext the context for the URL, such as "public" - * - * @return The URL of the item - * - * @see #getCurrentContext - */ - String generateItemURL(PageState state, - ContentItem item, - ContentSection section, - String context, - String templateContext); - - /** - * Return a master page based on page state (and content section). - * - * @param item The content item - * @param request The HTTP request - * - * @return The master page - * - * @throws javax.servlet.ServletException - */ - CMSPage getMasterPage(ContentItem item, HttpServletRequest request) - throws ServletException; - - - /* - * Having to stick the following methods, getTemplateFromURL, and - * stripTemplateFromURL in the ItemResolver interface is somewhat ugly. - * But, the relationship between ItemResolver and TemplateResolver needs - * to be cleaned up to fix this. As it is, ItemResolver parses URL's for - * template contexts, and TemplateResolver sets the actual template contexts - * in the request. - */ - /** - * Finds the template context from the URL and returns it, if it is there. - * Otherwise, returns null. - * - * @param inUrl the URL from which to get the template context - * - * @return the template context, or null if there is no template context - */ - default String getTemplateFromURL(final String inUrl) { - final String tempUrl; - if (inUrl.startsWith("/")) { - tempUrl = inUrl.substring(1); - } else { - tempUrl = inUrl; - } - - final StringTokenizer tokenizer = new StringTokenizer(tempUrl, "/"); - final String templateContext; - if (tokenizer.hasMoreTokens()) { - templateContext = tokenizer.nextToken(); - } else { - templateContext = null; - } - - if (templateContext != null && templateContext.startsWith( - TEMPLATE_CONTEXT_PREFIX)) { - return templateContext.substring(TEMPLATE_CONTEXT_PREFIX.length()); - } else { - return null; - } - } - - /** - * Removes the template context from the inUrl. - * - * @param inUrl URL, possibly including the template context. - * - * @return inUrl with the template context removed - */ - default String stripTemplateFromURL(final String inUrl) { - final String sTemplateContext = getTemplateFromURL(inUrl); - - if (sTemplateContext != null) { - //there is a template context, so strip it - final int iTemplateLength = TEMPLATE_CONTEXT_PREFIX.length() - + sTemplateContext.length() + 1; - return inUrl.substring(iTemplateLength, inUrl.length()); - } else { - return inUrl; - } - } - -} diff --git a/ccm-cms/src/main/java/org/librecms/dispatcher/MultilingualItemResolver.java b/ccm-cms/src/main/java/org/librecms/dispatcher/MultilingualItemResolver.java deleted file mode 100644 index 4f0c6f336..000000000 --- a/ccm-cms/src/main/java/org/librecms/dispatcher/MultilingualItemResolver.java +++ /dev/null @@ -1,805 +0,0 @@ -/* - * Copyright (C) 2017 LibreCCM Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package org.librecms.dispatcher; - -import com.arsdigita.bebop.PageState; -import com.arsdigita.cms.CMS; -import com.arsdigita.cms.dispatcher.CMSDispatcher; -import com.arsdigita.cms.dispatcher.CMSPage; -import com.arsdigita.cms.dispatcher.MasterPage; -import com.arsdigita.cms.ui.ContentItemPage; -import com.arsdigita.kernel.KernelConfig; -import com.arsdigita.util.Assert; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.libreccm.core.CcmObject; -import org.librecms.CmsConstants; -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentItemManager; -import org.librecms.contentsection.ContentItemRepository; -import org.librecms.contentsection.ContentItemVersion; -import org.librecms.contentsection.ContentSection; -import org.librecms.contentsection.Folder; -import org.librecms.contentsection.FolderManager; -import org.librecms.contentsection.FolderRepository; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.StringTokenizer; - -import javax.enterprise.context.RequestScoped; -import javax.inject.Inject; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.transaction.Transactional; - -/** - * Resolves items to URLs and URLs to items for multiple language variants. - * - * For version 7.0.0 this call has been moved from the - * {@code com.arsdigita.cms.dispatcher} package to the - * {@code org.librecms.dispatcher} package and refactored to an CDI bean. This - * was necessary to avoid several problems when accessing the entity beans for - * {@link Category} and {@link ContentItem}, primarily the infamous - * {@code LazyInitializationException}. Also several checks for null parameters - * were added to avoid {@code NullPointerExcpetions}. - * - * - * AS of version 7.0.0 this class not longer part of the public API. It is left - * here to keep the changes to the UI classes as minimal as possible. For new - * code other methods, for example from the {@link ContentItemManager} or the - * {@link ContentItemRepository} should be used. Because this class is no longer - * part of the public API the will might be removed or changed in future - * releases without prior warning. - * - * - * - * - * @author Michael Hanisch - * @author Jens Pelzetter - */ -@RequestScoped -public class MultilingualItemResolver implements ItemResolver { - - private static final Logger LOGGER = LogManager.getLogger( - MultilingualItemResolver.class); - - private static final String ADMIN_PREFIX = "admin"; - - /** - * The string identifying an item's ID in the query string of a URL. - */ - protected static final String ITEM_ID = "item_id"; - - /** - * The separator used in URL query strings; should be either "&" or ";". - */ - protected static final String SEPARATOR = "&"; - - @Inject - private FolderRepository folderRepo; - - @Inject - private FolderManager folderManager; - - @Inject - private ContentItemRepository itemRepo; - - @Inject - private ContentItemManager itemManager; - - /** - * Returns a content item based on section, url, and use context. - * - * @param section The current content section - * @param itemUrl The section-relative URL - * @param context The use context, e.g. ContentItem.LIVE, - * CMSDispatcher.PREVIEW or - * ContentItem.DRAFT. See {@link - * #getCurrentContext}. - * - * @return The content item, or null if no such item exists - */ - @Transactional(Transactional.TxType.REQUIRED) - @Override - public ContentItem getItem(final ContentSection section, - final String itemUrl, - final String context) { - if (section == null) { - throw new IllegalArgumentException( - "Can't get item from section null."); - } - if (itemUrl == null) { - throw new IllegalArgumentException("Can't get item for URL null."); - } - if (context == null) { - throw new IllegalArgumentException( - "Can't get item for context null."); - } - - LOGGER.debug("Resolving the item in content section \"{}\" at URL " - + "\"{}\" for context \"{}\"...", - section.getLabel(), - itemUrl, - context); - - final Folder rootFolder = section.getRootDocumentsFolder(); - String url = stripTemplateFromURL(itemUrl); - - if (rootFolder == null) { - // nothing to do, if root folder is null - LOGGER.debug("The root folder is null; returning no item"); - } else { - LOGGER.debug("Using root folder {}...", rootFolder.getName()); - - if (ContentItemVersion.LIVE.toString().equals(context)) { - LOGGER.debug("The use context is 'live'"); - - LOGGER.debug("The root folder has a live version; recursing"); - - final String prefix = String.join( - "", - section.getPrimaryUrl(), - folderManager.getFolderPath(rootFolder)); - - if (url.startsWith(prefix)) { - LOGGER. - debug("The starts with prefix \"{}\"; removing it...", - prefix); - - url = url.substring(prefix.length()); - } - - final ContentItem item = getItemFromLiveURL(url, rootFolder); - - LOGGER.debug("Resolved URL \"{}\" to item {}...", - url, - Objects.toString(item)); - - return item; - - } else if (ContentItemVersion.DRAFT.toString().equals(context)) { - LOGGER.debug("The use context is 'draft'"); - - // For 'draft' items, 'generateUrl()' method returns - // URL like this - // '/acs/wcms/admin/item.jsp?item_id=10201&set_tab=1' - // Check if URL contains any match of string - // 'item_id', then try to instanciate item_id value - // and return FIXME: Please hack this if there is - // more graceful solution. [aavetyan] - if (Assert.isEnabled()) { - Assert.isTrue(url.contains(ITEM_ID), - String.format("url must contain parameter %s", - ITEM_ID)); - } - - final ContentItem item = getItemFromDraftURL(url); - - LOGGER.debug("Resolved URL \"{}\" to item {}.", - url, - Objects.toString(item)); - - return item; - } else if (CMSDispatcher.PREVIEW.equals(context)) { - LOGGER.debug("The use context is 'preview'"); - - final String prefix = CMSDispatcher.PREVIEW + "/"; - - if (url.startsWith(prefix)) { - LOGGER.debug( - "The URL starts with prefix \"{}\"; removing it", - prefix); - - url = url.substring(prefix.length()); - } - - final ContentItem item = getItemFromLiveURL(url, rootFolder); - - LOGGER.debug("Resolved URL \"{}\" to item {}.", - url, - Objects.toString(item)); - - return item; - } else { - throw new IllegalArgumentException(String.format( - "Invalid item resolver context \"%s\".", context)); - } - } - - LOGGER.debug("No item resolved; returning null"); - - return null; - } - - /** - * Fetches the current context based on the page state. - * - * @param state the current page state - * - * @return the context of the current URL, such as - * ContentItem.LIVE or ContentItem.DRAFT - * - * @see ContentItem#LIVE - * @see ContentItem#DRAFT - * - * ToDo: Refactor to use the {@link ContentItemVersion} directly. - */ - @Transactional(Transactional.TxType.REQUIRED) - @Override - public String getCurrentContext(final PageState state) { - LOGGER.debug("Getting the current context"); - - // XXX need to use Web.getWebContext().getRequestURL() here. - String url = state.getRequest().getRequestURI(); - - final ContentSection section = CMS.getContext().getContentSection(); - - // If this page is associated with a content section, - // transform the URL so that it is relative to the content - // section site node. - if (section != null) { - final String sectionURL = section.getPrimaryUrl(); - - if (url.startsWith(sectionURL)) { - url = url.substring(sectionURL.length()); - } - } - - // Remove any template-specific URL components (will only work - // if they're first in the URL at this point; verify). XXX but - // we don't actually verify? - url = stripTemplateFromURL(url); - - // Determine if we are under the admin UI. - if (url.startsWith(ADMIN_PREFIX) - || url.startsWith(CmsConstants.CONTENT_CENTER_URL)) { - return ContentItemVersion.DRAFT.toString(); - } else { - return ContentItemVersion.LIVE.toString(); - } - } - - /** - * Generates a URL for a content item. - * - * @param itemId The item ID - * @param name The name of the content page - * @param state The page state - * @param section the content section to which the item belongs - * @param context the context of the URL, such as "live" or "admin" - * - * @return The URL of the item - * - * @see #getCurrentContext - */ - @Transactional(Transactional.TxType.REQUIRED) - @Override - public String generateItemURL(final PageState state, - final Long itemId, - final String name, - final ContentSection section, - final String context) { - return generateItemURL(state, itemId, name, section, context, null); - } - - /** - * Generates a URL for a content item. - * - * @param itemId The item ID - * @param name The name of the content page - * @param state The page state - * @param section the content section to which the item belongs - * @param context the context of the URL, such as "live" or "admin" - * @param templateContext the context for the URL, such as "public" - * - * @return The URL of the item - * - * @see #getCurrentContext - */ - @Transactional(Transactional.TxType.REQUIRED) - @Override - public String generateItemURL(final PageState state, - final Long itemId, - final String name, - final ContentSection section, - final String context, - final String templateContext) { - if (itemId == null) { - throw new IllegalArgumentException( - "Can't generate item URL for item id null."); - } - if (context == null) { - throw new IllegalArgumentException( - "Can't generate item URL for context null."); - } - if (section == null) { - throw new IllegalArgumentException( - "Can't generate item URL for section null."); - } - - LOGGER.debug("Generating an item URL for item id {}, section \"{}\" " - + "and context \"{}\" with name \"{}\"...", - itemId, - section.getLabel(), - context, - name); - - if (ContentItemVersion.DRAFT.toString().equals(context)) { - // No template context here. - return generateDraftURL(section, itemId); - } else if (CMSDispatcher.PREVIEW.equals(context)) { - final ContentItem item = itemRepo.findById(itemId).get(); - return generatePreviewURL(section, item, templateContext); - } else if (ContentItemVersion.LIVE.toString().equals(context)) { - final ContentItem item = itemRepo.findById(itemId).get(); - - return generateLiveURL(section, item, templateContext); - } else { - throw new IllegalArgumentException("Unknown context '" + context - + "'"); - } - } - - /** - * Generates a URL for a content item. - * - * @param item The item - * @param state The page state - * @param section the content section to which the item belongs - * @param context the context of the URL, such as "live" or "admin" - * - * @return The URL of the item - * - * @see #getCurrentContext - */ - @Transactional(Transactional.TxType.REQUIRED) - @Override - public String generateItemURL(final PageState state, - final ContentItem item, - final ContentSection section, - final String context) { - return generateItemURL(state, item, section, context, null); - } - - /** - * Generates a URL for a content item. - * - * @param item The item - * @param state The page state - * @param section the content section to which the item belongs - * @param context the context of the URL, such as "live" or "admin" - * @param templateContext the context for the URL, such as "public" - * - * @return The URL of the item - * - * @see #getCurrentContext - */ - @Transactional(Transactional.TxType.REQUIRED) - @Override - public String generateItemURL(final PageState state, - final ContentItem item, - final ContentSection section, - final String context, - final String templateContext) { - if (item == null) { - throw new IllegalArgumentException( - "Can't generate URL for item null."); - } - if (context == null) { - throw new IllegalArgumentException( - "Can't generate URL for context null."); - } - - final ContentSection contentSection; - if (section == null) { - contentSection = item.getContentType().getContentSection(); - } else { - contentSection = section; - } - - LOGGER.debug("Generating an item URL for item \"{}\", section \"{}\" " - + "and context \"{}\".", - item.getDisplayName(), - contentSection.getLabel(), - context); - - if (ContentItemVersion.DRAFT.toString().equals(context)) { - return generateDraftURL(section, item.getObjectId()); - } else if (CMSDispatcher.PREVIEW.equals(context)) { - return generatePreviewURL(section, item, templateContext); - } else if (ContentItemVersion.LIVE.toString().equals(context)) { - return generateLiveURL(contentSection, item, templateContext); - } else { - throw new IllegalArgumentException(String.format( - "Unknown context \"%s\".", context)); - } - } - - @Transactional(Transactional.TxType.REQUIRED) - @Override - public CMSPage getMasterPage(final ContentItem item, - final HttpServletRequest request) - throws ServletException { - - LOGGER.debug("Getting the master page for item {}", - item.getDisplayName()); - - final MasterPage masterPage = new MasterPage(); - masterPage.init(); - - return masterPage; - } - - /** - * Returns content item's draft version URL - * - * @param section The content section to which the item belongs - * @param itemId The content item's ID - * - * @return generated URL string - */ - @Transactional(Transactional.TxType.REQUIRED) - protected String generateDraftURL(final ContentSection section, - final Long itemId) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Generating draft URL for item ID " + itemId - + " and section " + section); - } - - if (Assert.isEnabled()) { - Assert.isTrue(section != null && itemId != null, - "get draft url: neither secion nor item " - + "can be null"); - } - - final String url = ContentItemPage.getItemURL( - String.format("%s/", section.getPrimaryUrl()), - itemId, - ContentItemPage.AUTHORING_TAB); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Generated draft URL " + url); - } - - return url; - } - - /** - * Generate a language-independent URL to the item in - * the given section.

- * When a client retrieves this URL, the URL is resolved to point to a - * specific language instance of the item referenced here, i.e. this URL - * will be resolved to a language-specific URL internally. - * - * @param section the ContentSection that contains this - * item - * @param item ContentItem for which a URL should be - * constructed. - * @param templateContext template context; will be ignored if - * null - * - * @return a language-independent URL to the item in - * the given section, which will be presented within - * the given templateContext - */ - @Transactional(Transactional.TxType.REQUIRED) - protected String generateLiveURL(final ContentSection section, - final ContentItem item, - final String templateContext) { - LOGGER.debug("Generating live URL for item {} in section {}", - Objects.toString(item), - Objects.toString(section)); - - /* - * URL = URL of section + templateContext + path to the ContentBundle - * which contains the item - */ - final StringBuffer url = new StringBuffer(400); - //url.append(section.getURL()); - url - .append(section.getPrimaryUrl()) - .append("/"); - - /* - * add template context, if one is given - */ - // This is breaking URL's...not sure why it's here. XXX - // this should work with the appropriate logic. trying again. - if (!(templateContext == null || templateContext.length() == 0)) { - url - .append(TEMPLATE_CONTEXT_PREFIX) - .append(templateContext) - .append("/"); - } - - url.append(itemManager.getItemPath(item)); - - return url.toString(); - } - - /** - * Generate a URL which can be used to preview the item, using - * the given templateContext.

- * Only a specific language instance can be previewed, meaning there - * no language negotiation is involved when a request is made to a - * URL that has been generated by this method. - * - * @param section The ContentSection which contains the - * item - * @param item The ContentItem for which a URL - * should be generated. - * @param templateContext the context that determines which template should - * render the item when it is previewed; ignored if - * the argument given here is null - * - * @return a URL which can be used to preview the given item - */ - @Transactional(Transactional.TxType.REQUIRED) - protected String generatePreviewURL(final ContentSection section, - final ContentItem item, - final String templateContext) { - Assert.exists(section, "ContentSection section"); - Assert.exists(item, "ContentItem item"); - - final StringBuffer url = new StringBuffer(100); - url - .append(section.getPrimaryUrl()) - .append("/") - .append(CMSDispatcher.PREVIEW) - .append("/"); - /* - * add template context, if one is given - */ - // This is breaking URL's...not sure why it's here. XXX - // this should work with the appropriate logic. trying again. - if (!(templateContext == null || templateContext.length() == 0)) { - url - .append(TEMPLATE_CONTEXT_PREFIX) - .append(templateContext) - .append("/"); - } - - url.append(itemManager.getItemPath(item)); - - return url.toString(); - } - - /** - * Retrieves ITEM_ID parameter from URL and instantiates item - * according to this ID. - * - * @param url URL that indicates which item should be retrieved; must - * contain the ITEM_ID parameter - * - * @return the ContentItem the given url points - * to, or null if no ID has been found in the - * url - */ - @Transactional(Transactional.TxType.REQUIRED) - protected ContentItem getItemFromDraftURL(final String url) { - LOGGER.debug("Looking up the item from draft URL ", url); - - int pos = url.indexOf(ITEM_ID); - - String item_id = url.substring(pos); // item_id == ITEM_ID=.... ? - - pos = item_id.indexOf("="); // should be exactly after the ITEM_ID string - - if (pos != ITEM_ID.length()) { - // item_id seems to be something like ITEM_IDFOO= - - LOGGER.debug("No suitable item_id parameter found; returning null"); - - return null; // no ID found - } - - pos++; // skip the "=" - - // ID is the string between the equal (at pos) and the next separator - int i = item_id.indexOf(SEPARATOR); - item_id = item_id.substring(pos, Math.min(i, item_id.length() - 1)); - - LOGGER.debug("Looking up item using item ID {}", item_id); - - final Optional item = itemRepo.findById(Long.parseLong( - item_id)); - - if (item.isPresent()) { - LOGGER.debug("Returning item {}", Objects.toString(item)); - return item.get(); - } else { - return null; - } - } - - /** - * Returns a content item based on URL relative to the root folder. - * - * @param url The content item url - * @param parentFolder The parent folder object, url must be relevant to it - * - * @return The Content Item instance, it can also be either Bundle or Folder - * objects, depending on URL and file language extension - */ - @Transactional(Transactional.TxType.REQUIRED) - protected ContentItem getItemFromLiveURL(final String url, - final Folder parentFolder) { - - if (parentFolder == null || url == null || url.equals("")) { - LOGGER.debug("The url is null or parent folder was null " - + "or something else is wrong, so just return " - + "null."); - - return null; - } - - LOGGER.debug("Resolving the item for live URL {}" - + " and parent folder {}...", - url, - parentFolder.getName()); - - int len = url.length(); - int index = url.indexOf('/'); - - if (index >= 0) { - LOGGER.debug("The URL starts with a slash; paring off the first " - + "URL element and recursing"); - - final String liveUrl = index + 1 < len ? url.substring(index + 1) - : ""; - - return getItemFromLiveURL(liveUrl, parentFolder); - } else { - LOGGER.debug("Found a file element in the URL"); - - final String[] nameAndLang = getNameAndLangFromURLFrag(url); - final String name = nameAndLang[0]; - - final Optional item = itemRepo.findByNameInFolder( - parentFolder, name); - - if (item.isPresent()) { - return item.get(); - } else { - return null; - } - } - } - - /** - * Returns an array containing the the item's name and lang based on the URL - * fragment. - * - * @param url - * - * @return a two-element string array, the first element containing the - * bundle name, and the second element containing the lang string - */ - @Transactional(Transactional.TxType.REQUIRED) - protected String[] getNameAndLangFromURLFrag(final String url) { - String name; - String lang = null; - - /* - * Try to find out if there's an extension with the language code - * 1 Get a list of all "extensions", i.e. parts of the url - * which are separated by colons - * 2 If one or more extensions have been found, compare them against - * the list of known language codes - * 2a if a match is found, this language is used to retrieve an instance - * from a bundle - * 2b if no match is found - */ - final List exts = new ArrayList<>(5); - final StringTokenizer tok = new StringTokenizer(url, "."); - - while (tok.hasMoreTokens()) { - exts.add(tok.nextToken()); - } - - if (exts.size() > 0) { - LOGGER.debug("Found some file extensions to look at; they " - + "are {}", - exts); - - /* - * We have found at least one extension, so we can - * proceed. Now try to find out if one of the - * extensions looks like a language code (we only - * support 2-letter language codes!). - * If so, use this as the language to look for. - */ - /* - * First element is the NAME of the item, not an extension! - */ - name = exts.get(0); - String ext; - final Collection supportedLangs = KernelConfig.getConfig() - .getSupportedLanguages(); - Iterator supportedLangIt; - - for (int i = 1; i < exts.size(); i++) { - ext = exts.get(i); - - LOGGER.debug("Examining extension {}", ext); - - /* - * Loop through all extensions, but discard the - * first one, which is the name of the item. - */ - if (ext != null && ext.length() == 2) { - /* Only check extensions consisting of 2 - * characters. - * - * Compare current extension with known - * languages; if it matches, we've found the - * language we should use! - */ - supportedLangIt = supportedLangs.iterator(); - while (supportedLangIt.hasNext()) { - if (ext.equals(supportedLangIt.next())) { - lang = ext; - LOGGER.debug("Found a match; using " - + "language {}", lang); - break; - } - } - } else { - LOGGER.debug("Discarding extension {}; it is too short", - ext); - } - } - } else { - LOGGER.debug("The file has no extensions; no language was encoded"); - name = url; // no extension, so we just have a name here - lang = null; // no extension, so we cannot guess the language - } - - LOGGER.debug("File name resolved to {}", name); - LOGGER.debug("File language resolved to {}", lang); - - final String[] returnArray = new String[2]; - returnArray[0] = name; - returnArray[1] = lang; - return returnArray; - } - - /** - * Finds a language instance of a content item given the bundle, name, and - * lang string. Note: Because there not ContentBundles anymore this method - * simply returns the provided item. - * - * @param lang The lang string from the URL - * @param item The content bundle - * - * @return The negotiated lang instance for the current request. - */ - @Transactional(Transactional.TxType.REQUIRED) - protected ContentItem getItemFromLangAndBundle(final String lang, - final ContentItem item) { - return item; - } - -} diff --git a/ccm-cms/src/main/java/org/librecms/dispatcher/SimpleItemResolver.java b/ccm-cms/src/main/java/org/librecms/dispatcher/SimpleItemResolver.java deleted file mode 100644 index 0aafe3998..000000000 --- a/ccm-cms/src/main/java/org/librecms/dispatcher/SimpleItemResolver.java +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (C) 2017 LibreCCM Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package org.librecms.dispatcher; - -import com.arsdigita.bebop.PageState; -import com.arsdigita.cms.CMS; -import com.arsdigita.cms.dispatcher.CMSDispatcher; -import com.arsdigita.cms.dispatcher.CMSPage; -import com.arsdigita.cms.dispatcher.MasterPage; -import com.arsdigita.cms.ui.ContentItemPage; -import com.arsdigita.dispatcher.DispatcherHelper; -import com.arsdigita.web.URL; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.libreccm.categorization.Category; -import org.libreccm.core.CcmObject; -import org.librecms.CmsConstants; -import org.librecms.contentsection.ContentItem; -import org.librecms.contentsection.ContentItemManager; -import org.librecms.contentsection.ContentItemRepository; -import org.librecms.contentsection.ContentItemVersion; -import org.librecms.contentsection.ContentSection; -import org.librecms.contentsection.Folder; - -import java.util.Optional; - -import javax.enterprise.context.RequestScoped; -import javax.inject.Inject; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.transaction.Transactional; - -/** - * This is the default implementation of - * {@link com.arsdigita.cms.dispatcher.ItemResolver}. - * - * The {@link #getItem(java.lang.String, org.librecms.contentsection.Folder) } - * method of the default implementation of null {@link ItemResolver}, - * {@link com.arsdigita.cms.dispatcher.SimpleItemResolver} runs a simple query - * using the passed in information to retrieve the content item with a name that - * matches the URL stub, in our example it looks for a content item with name - * {@code cheese}. If no such item exists, or if there is such an item, but - * without a live version, even though one has been requested, {@code getItem} - * returns {@code null}. - * - * After the CMS Dispatcher received the content item from the - * {@link ItemResolver}, it also asks it for the - * {@link com.arsdigita.cms.dispatcher.MasterPage} for that item in the current - * request. With the content item and the master page in hand, the dispatcher - * calls {@code service} on the page. - * - * For version 7.0.0 this call has been moved from the - * {@code com.arsdigita.cms.dispatcher} package to the - * {@code org.librecms.dispatcher} package and refactored to an CDI bean. This - * was necessary to avoid several problems when accessing the entity beans for - * {@link Category} and {@link ContentItem}, primarily the infamous - * {@code LazyInitializationException}. Also several checks for null parameters - * were added to avoid {@code NullPointerExcpetions}. - * - * - * AS of version 7.0.0 this class not longer part of the public API. It is left - * here to keep the changes to the UI classes as minimal as possible. For new - * code other methods, for example from the {@link ContentItemManager} or the - * {@link ContentItemRepository} should be used. Because this class is no longer - * part of the public API the will might be removed or changed in future - * releases without prior warning. - * - * - * @author Michael Pih (pihman@arsdigita.com) - * @author Jens Pelzetter - */ -@RequestScoped -public class SimpleItemResolver implements ItemResolver { - - private static final Logger LOGGER = LogManager.getLogger( - SimpleItemResolver.class); - - private static final String ADMIN_PREFIX = "admin"; - private static final String WORKSPACE_PREFIX - = CmsConstants.CONTENT_CENTER_URL; - - @Inject - private ContentItemRepository itemRepo; - @Inject - private ContentItemManager itemManager; - - @Transactional(Transactional.TxType.REQUIRED) - @Override - public ContentItem getItem(final ContentSection section, - final String url, - final String context) { - if (section == null) { - throw new IllegalArgumentException( - "Can't get an item for ContentSection null."); - } - if (url == null) { - throw new IllegalArgumentException("Can't get an item for URL null."); - } - if (context == null) { - throw new IllegalArgumentException( - "Can't get an item for context null."); - } - - LOGGER.debug( - "Trying to get {} item for url \"{}\" from content section \"{}\"...", - context, - url, - section.getLabel()); - - final String itemUrl = stripTemplateFromURL(url); - - // getItem fails if called from a JSP template, because the request URL - // gets replaced with the filesystem path to the JSP (when - // DispatcherHelper.forwardRequestByPath is called). To fix this, we check - // if the item had already been put into the request by the CMSDispatcher - // (which it usually has) and return it. - ContentItem reqItem = (ContentItem) DispatcherHelper.getRequest(). - getAttribute("com.arsdigita.cms.dispatcher.item"); - if (reqItem != null) { - LOGGER.info("Found item in the request, returning it."); - return reqItem; - } - - final Folder rootFolder = section.getRootDocumentsFolder(); - if (rootFolder == null) { - LOGGER.info("No root folder found, returning null."); - return null; - } - - return getItem(itemUrl, rootFolder); - } - - @Transactional(Transactional.TxType.REQUIRED) - @Override - public String getCurrentContext(final PageState state) { - - if (state == null) { - throw new IllegalArgumentException( - "Can't get current context from PageState null."); - } - - String url = state.getRequest().getRequestURI(); - - final ContentSection section = CMS.getContext().getContentSection(); - - // If this page is associated with a content section, transform - // the URL so that it is relative to the content section site node. - if (section != null) { - final String sectionURL = section.getPrimaryUrl(); - if (url.startsWith(sectionURL)) { - url = url.substring(sectionURL.length()); - } - } - - // remove any template-specific URL components - // (will only work if they're first in the URL at this point: verify - url = stripTemplateFromURL(url); - - // Determine if we are under the admin UI. - if (url.startsWith(ADMIN_PREFIX) || url.startsWith(WORKSPACE_PREFIX)) { - return ContentItemVersion.DRAFT.toString(); - } else { - return ContentItemVersion.LIVE.toString(); - } - } - - /** - * Return the content item at the specified path, or null if no such item - * exists. - * - * The path is interpreted as a series of folders; for example, - * {@code /foo/bar/baz} will look for an item named @code{baz} in a folder - * named * @code{bar} * in a folder named {@code foo} under the specified - * root folder. - * - * @param url the URL to the item - * @param rootFolder The root folder where the item search will start - * - * @return the item on success, null if no such item exists - */ - @Transactional(Transactional.TxType.REQUIRED) - public ContentItem getItem(final String url, final Folder rootFolder) { - - if (url == null) { - throw new IllegalArgumentException("Can't get item for URL null."); - } - if (rootFolder == null) { - throw new IllegalArgumentException( - "Can't get item from rootFolder null."); - } - - final String[] tokens = url.split("/"); - - Folder currentFolder = rootFolder; - int i; - for (i = 0; i < tokens.length; i++) { - final String token = tokens[i]; - final Optional folder = currentFolder.getSubFolders() - .stream() - .filter(subFolder -> subFolder.getDisplayName().equals(token)) - .findFirst(); - - if (folder.isPresent()) { - currentFolder = folder.get(); - } else { - break; - } - } - - if (i >= tokens.length - 1) { - // failure - LOGGER.debug("no more tokens found, returning null"); - return null; - } else { - //Get the content item which is the last token - final String name = tokens[tokens.length - 1]; - final Optional item = currentFolder.getObjects() - .stream() - .map(categorization -> categorization.getCategorizedObject()) - .filter(object -> object.getDisplayName().equals(name)) - .findFirst(); - if (item.isPresent() && item.get() instanceof ContentItem) { - return (ContentItem) item.get(); - } else { - return null; - } - } - } - - /** - * Generate the URL for an item in the DRAFT context - * - * @param itemId - * @param section - * - * @return - */ - private String generateDraftURL(final Long itemId, - final ContentSection section) { - if (itemId == null) { - throw new IllegalArgumentException( - "Can't generat draft URL for itemId null."); - } - if (itemId == null) { - throw new IllegalArgumentException( - "Can't generat draft URL for content section null."); - } - - return ContentItemPage.getItemURL( - String.format("%s%s/", - URL.getDispatcherPath(), - section.getPrimaryUrl()), - itemId, - ContentItemPage.AUTHORING_TAB); - } - - /** - * Generate the URL for an item in the LIVE context with a given template - * context - * - * @param item - * @param section - * @param templateContext - * - * @return - * - */ - private String generateLiveURL(final ContentItem item, - final ContentSection section, - final String templateContext) { - - if (item == null) { - throw new IllegalArgumentException( - "Can't generate live URL for item null."); - } - if (section == null) { - throw new IllegalArgumentException( - "Can't generate live URL for content section null."); - } - - final String templateUrlFrag; - if (templateContext == null || templateContext.isEmpty()) { - templateUrlFrag = ""; - } else { - templateUrlFrag = String.format(TEMPLATE_CONTEXT_PREFIX + "%s/", - templateContext); - } - - return String.format("%s/%s%s", - section.getPrimaryUrl(), - templateUrlFrag, - itemManager.getItemPath(item)); - } - - /** - * Generate the preview URL for an item in the DRAFT context. - * - * @param item - * @param section - * @param templateContext - * - * @return - */ - private String generatePreviewURL(final ContentItem item, - final ContentSection section, - final String templateContext) { - if (item == null) { - throw new IllegalArgumentException( - "Can't generate draft URL for item null."); - } - if (section == null) { - throw new IllegalArgumentException( - "Can't generate draft URL for content section null."); - } - - final String templateUrlFrag; - if (templateContext == null || templateContext.isEmpty()) { - templateUrlFrag = ""; - } else { - templateUrlFrag = String.format(TEMPLATE_CONTEXT_PREFIX + "%s/", - templateContext); - } - - final StringBuilder url = new StringBuilder(); - url - .append(section.getPrimaryUrl()) - .append("/") - .append(CMSDispatcher.PREVIEW) - .append("/") - .append(templateUrlFrag) - .append(itemManager.getItemPath(item)); - - return url.toString(); - } - - /** - * Generates a URL for a content item. - * - * @param itemId The item ID - * @param name The name of the content page - * @param state The page state - * @param section the content section to which the item belongs - * @param context the context of the URL, such as "LIVE" or "DRAFT" - * - * @return The URL of the item - */ - @Transactional(Transactional.TxType.REQUIRED) - @Override - public String generateItemURL(final PageState state, - final Long itemId, - final String name, - final ContentSection section, - final String context) { - return generateItemURL(state, itemId, name, section, context, null); - } - - /** - * Generates a URL for a content item. - * - * @param itemId The item ID - * @param name The name of the content page - * @param state The page state - * @param section the content section to which the item belongs - * @param context the context of the URL, such as "live" or "admin" - * @param templateContext the context for the URL, such as "public" - * - * @return The URL of the item - */ - @Transactional(Transactional.TxType.REQUIRED) - @Override - public String generateItemURL(final PageState state, - final Long itemId, - final String name, - final ContentSection section, - final String context, - final String templateContext) { - - if (ContentItemVersion.DRAFT.toString().equals(context)) { - return generateDraftURL(itemId, section); - } else if (ContentItemVersion.LIVE.toString().equals(context)) { - final ContentItem item = itemRepo.findById(itemId).get(); - return generateLiveURL(item, section, templateContext); - } else if (CMSDispatcher.PREVIEW.equals(context)) { - final ContentItem item = itemRepo.findById(itemId).get(); - return generatePreviewURL(item, section, templateContext); - } else { - throw new IllegalArgumentException(String.format( - "Unknown context \"%s\".", context)); - } - } - - /** - * Generates a URL for a content item. - * - * @param item The item - * @param state The page state - * @param section the content section to which the item belongs - * @param context the context of the URL, such as "LIVE" or "DRAFT" - * - * @return The URL of the item - * - * @see #getCurrentContext - */ - @Transactional(Transactional.TxType.REQUIRED) - @Override - public String generateItemURL(final PageState state, - final ContentItem item, - final ContentSection section, - final String context) { - return generateItemURL(state, item, section, context, null); - } - - /** - * Generates a URL for a content item. - * - * @param item The item - * @param state The page state - * @param section the content section to which the item belongs - * @param context the context of the URL, such as "live" or "admin" - * @param templateContext the context for the URL, such as "public" - * - * @return The URL of the item - * - * @see #getCurrentContext - */ - @Transactional(Transactional.TxType.REQUIRED) - @Override - public String generateItemURL(final PageState state, - final ContentItem item, - final ContentSection section, - final String context, - final String templateContext) { - - if (ContentItemVersion.LIVE.toString().equals(context)) { - return generateLiveURL(item, section, templateContext); - } else if (ContentItemVersion.DRAFT.toString().equals(context)) { - return generateDraftURL(item.getObjectId(), section); - } else if (CMSDispatcher.PREVIEW.equals(context)) { - return generatePreviewURL(item, section, templateContext); - } else { - throw new IllegalArgumentException(String.format( - "Unknown context \"%s\".", context)); - } - } - - @Transactional(Transactional.TxType.REQUIRED) - @Override - public CMSPage getMasterPage(final ContentItem item, - final HttpServletRequest request) - throws ServletException { - - final MasterPage masterPage = new MasterPage(); - masterPage.init(); - - return masterPage; - } - -}