/* * 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; } } }