/* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.riotfamily.pages.mapping; import javax.servlet.http.HttpServletRequest; import org.riotfamily.common.util.FormatUtils; import org.riotfamily.common.web.support.ServletUtils; import org.riotfamily.components.support.EditModeUtils; import org.riotfamily.pages.config.RootPageType; import org.riotfamily.pages.config.SystemPageType; import org.riotfamily.pages.model.ContentPage; import org.riotfamily.pages.model.Page; import org.riotfamily.pages.model.Site; /** * @author Carsten Woelk [cwoelk at neteye dot de] * @author Felix Gnass [fgnass at neteye dot de] * @since 7.0 */ public final class PageResolver { public static final String SITE_ATTRIBUTE = PageResolver.class.getName() + ".site"; public static final String PAGE_ATTRIBUTE = PageResolver.class.getName() + ".page"; private static final Object NOT_FOUND = new Object(); private PageResolver() { } /** * Returns the first Site that matches the given request. The PathCompleter * is used to strip the servlet mapping from the request URI. * @return The first matching Site, or <code>null</code> if no match is found */ public static Site getSite(HttpServletRequest request) { Object site = request.getAttribute(SITE_ATTRIBUTE); if (site == null) { site = resolveSite(request); exposeSite((Site) site, request); } if (site == null || site == NOT_FOUND) { return null; } Site result = (Site) site; result.refreshIfDetached(); return result; } protected static void exposeSite(Site site, HttpServletRequest request) { expose(site, request, SITE_ATTRIBUTE); } /** * Returns the Page for the given request. */ public static Page getPage(HttpServletRequest request) { Object page = request.getAttribute(PAGE_ATTRIBUTE); if (page == null) { page = resolvePage(request); exposePage((Page) page, request); } if (page == null || page == NOT_FOUND) { return null; } return (Page) page; } public static Page resolvePage(Site site, String type, Object object) { return site.getSchema().getPageType(type).getPage(site, object); } protected static void exposePage(Page page, HttpServletRequest request) { expose(page, request, PAGE_ATTRIBUTE); } private static Site resolveSite(HttpServletRequest request) { String hostName = request.getServerName(); return Site.loadByHostName(hostName); } private static Page resolvePage(HttpServletRequest request) { Site site = getSite(request); if (site == null) { return null; } String lookupPath = getLookupPath(request); Page page = ContentPage.loadBySiteAndPath(site, lookupPath); if (page == null) { page = resolveVirtualChildPage(site, lookupPath); } if (page == null || ((!site.isEnabled() || !page.getContentContainer().isPublished()) && !EditModeUtils.isPreview(request, null))) { return null; } return page; } private static Page resolveVirtualChildPage(Site site, String lookupPath) { for (ContentPage parent : ContentPage.findByTypesAndSite(site.getSchema().getVirtualParents(), site)) { String parentPath = parent.getPath(); if (lookupPath.startsWith(parentPath)) { String tail = lookupPath.substring(parent.getPath().length()); if (tail.startsWith("/") || RootPageType.class.equals(parent.getPageType().getClass())) { SystemPageType parentType = (SystemPageType) parent.getPageType(); return parentType.getVirtualChildType().resolve(parent, tail); } } } return null; } public static String getLookupPath(HttpServletRequest request) { String s = FormatUtils.stripExtension(FormatUtils.stripTrailingSlash( ServletUtils.getPathWithinApplication(request))); return s.length() > 0 ? s : "/"; } private static void expose(Object object, HttpServletRequest request, String attributeName) { if (object == null) { object = NOT_FOUND; } request.setAttribute(attributeName, object); } /** * Resets all internally used attributes. * @param request */ public static void resetAttributes(HttpServletRequest request) { request.removeAttribute(SITE_ATTRIBUTE); request.removeAttribute(PAGE_ATTRIBUTE); } }