/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.portal.processor; import java.util.Map; import org.apache.commons.lang.StringUtils; import com.google.common.base.Preconditions; import com.enonic.esl.servlet.http.HttpServletRequestWrapper; import com.enonic.cms.core.Path; import com.enonic.cms.core.content.ContentEntity; import com.enonic.cms.core.content.ContentLocationSpecification; import com.enonic.cms.core.content.ContentLocations; import com.enonic.cms.core.language.LanguageEntity; import com.enonic.cms.core.language.LanguageResolver; import com.enonic.cms.core.portal.ContentNameMismatchException; import com.enonic.cms.core.portal.ContentNotFoundException; import com.enonic.cms.core.portal.ContentPath; import com.enonic.cms.core.portal.PageRequestType; import com.enonic.cms.core.portal.PageTemplateNotFoundException; import com.enonic.cms.core.portal.PathToContentResolver; import com.enonic.cms.core.portal.rendering.PageTemplateResolver; import com.enonic.cms.core.preview.PreviewContext; import com.enonic.cms.core.structure.SiteKey; import com.enonic.cms.core.structure.SitePath; import com.enonic.cms.core.structure.SitePropertyNames; import com.enonic.cms.core.structure.menuitem.MenuItemEntity; import com.enonic.cms.core.structure.page.template.PageTemplateEntity; /** * Sep 28, 2009 */ public class ContentRequestProcessor extends AbstractPageRequestProcessor { public ContentRequestProcessor( final PageRequestProcessorContext context ) { super( context ); } public PageRequestProcessorResult process() { Preconditions.checkArgument( context.getPageRequestType() == PageRequestType.CONTENT ); Preconditions.checkNotNull( context.getContentPath() ); final PageRequestProcessorResult result = new PageRequestProcessorResult(); final SitePath sitePath = context.getSitePath(); // content from request final ContentEntity contentFromRequest = resolveContentFromRequest( context.getContentPath() ); result.setContentFromRequest( contentFromRequest ); final ContentPath contentPath = sitePath.getContentPath(); final boolean oldStyleContentPathToBeRedirected = contentPath.isOldStyleContentPath(); if ( oldStyleContentPathToBeRedirected ) { return setRedirectForOldStyleContentPaths( result, sitePath, contentFromRequest ); } final MenuItemEntity menuItemWithRequestedContent = contentFromRequest.getFirstDirectPlacementOnMenuItem( context.getSite().getKey() ); if ( menuItemWithRequestedContent != null ) { return resolveResultForRedirectToMenuItemWithRequestedContent( sitePath, menuItemWithRequestedContent ); } if ( !contentNamesMatch( contentFromRequest, contentPath ) ) { checkContentIsOnline( contentFromRequest ); portalAccessService.checkAccessToContent( sitePath, context.getRequester(), contentFromRequest, context.getMenuItem() ); throw new ContentNameMismatchException( contentPath.getContentKey(), contentPath.getContentName() ); } if ( contentPath.isPermaLink() ) { SiteKey siteKey = sitePath.getSiteKey(); if ( !sitePropertiesService.getSiteProperties( siteKey ).getPropertyAsBoolean( SitePropertyNames.ENABLE_UNPUBLISHED_CONTENT_PERMALINKS ) ) { ContentLocationSpecification contentLocationSpecification = new ContentLocationSpecification(); contentLocationSpecification.setSiteKey( siteKey ); ContentLocations contentLocations = contentFromRequest.getLocations( contentLocationSpecification ); if ( !contentLocations.hasLocations() ) { throw new ContentNotFoundException( contentFromRequest.getKey(), contentFromRequest.getMainVersion().getTitle() ); } } SitePath redirectSitePath = getRedirectSitePathForPermaLink( sitePath, contentFromRequest ); if ( redirectSitePath != null ) { PageRequestProcessorResult redirectResult = new PageRequestProcessorResult(); redirectResult.setRedirectToSitePath( redirectSitePath ); return redirectResult; } } checkContentIsOnline( contentFromRequest ); portalAccessService.checkAccessToContent( sitePath, context.getRequester(), contentFromRequest, context.getMenuItem() ); // page template PageTemplateEntity pageTemplate = resolvePageTemplate( contentFromRequest ); result.setPageTemplate( pageTemplate ); // language final LanguageEntity language = resolveLanguage( contentFromRequest ); result.setLanguage( language ); // site path sitePath.setParam( "key", contentFromRequest.getKey().toString() ); sitePath.addParam( "id", context.getMenuItem().getKey().toString() ); result.setSitePath( sitePath ); // http request HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper( context.getHttpRequest() ); // noinspection deprecation requestWrapper.setParamsMasked( false ); requestWrapper.setParameter( "key", contentFromRequest.getKey().toString() ); requestWrapper.setParameter( "id", context.getMenuItem().getKey().toString() ); result.setHttpRequest( requestWrapper ); // process common stuff processCommonRequest( result ); return result; } private boolean contentNamesMatch( ContentEntity contentFromRequest, ContentPath contentPath ) { return contentPath.getContentName().equalsIgnoreCase( contentFromRequest.getName() ); } private PageRequestProcessorResult setRedirectForOldStyleContentPaths( PageRequestProcessorResult result, SitePath sitePath, ContentEntity contentFromRequest ) { PathToContentResolver pathToContentResolver = new PathToContentResolver( sectionContentDao ); final Path newStyleContentLocalPath = pathToContentResolver.resolveContentUrlLocalPath( contentFromRequest, sitePath.getSiteKey() ); // We do not want any params persisted on the menu item in the redirect, therefore we fetch the original ones from the http request Map originalParameters = context.getHttpRequest().getParameterMap(); result.setRedirectToSitePath( new SitePath( sitePath.getSiteKey(), newStyleContentLocalPath, originalParameters ) ); return result; } private SitePath getRedirectSitePathForPermaLink( SitePath sitePath, ContentEntity contentFromRequest ) { PathToContentResolver pathToContentResolver = new PathToContentResolver( sectionContentDao ); Path newStyleContentLocalPath = pathToContentResolver.resolveContentUrlLocalPathForPermalink( contentFromRequest, sitePath ); final boolean noRedirectToBeDone = redirectPathIsEqualToRequestedPath( newStyleContentLocalPath.getPathAsString(), sitePath.getLocalPath().getPathAsString() ); //final boolean noRedirectToBeDone2 = new Path( newStyleContentLocalPath.getPathAsString(), true ).equals( // new Path( sitePath.getLocalPath().getPathAsString(), true ) ); if ( noRedirectToBeDone ) { return null; } // We do not want any params persisted on the menu item in the redirect, therefore we fetch the original ones from the http request Map originalParameters = context.getHttpRequest().getParameterMap(); return new SitePath( sitePath.getSiteKey(), newStyleContentLocalPath, originalParameters ); } private boolean redirectPathIsEqualToRequestedPath( String newLocalPath, String requestedPath ) { newLocalPath = StringUtils.removeStart( newLocalPath, "/" ); requestedPath = StringUtils.removeStart( requestedPath, "/" ); newLocalPath = StringUtils.removeEnd( newLocalPath, "/" ); requestedPath = StringUtils.removeEnd( requestedPath, "/" ); return newLocalPath.equalsIgnoreCase( requestedPath ); } private ContentEntity resolveContentFromRequest( final ContentPath contentPath ) { ContentEntity content = contentDao.findByKey( contentPath.getContentKey() ); if ( content == null ) { throw new ContentNotFoundException( contentPath.getContentKey() ); } final PreviewContext previewContext = context.getPreviewContext(); if ( previewContext.isPreviewingContent() && previewContext.getContentPreviewContext().isContentPreviewed( content ) ) { content = previewContext.getContentPreviewContext().getContentPreviewed(); } return content; } private void checkContentIsOnline( ContentEntity contentFromRequest ) { boolean skipOnlineCheck = false; final PreviewContext previewContext = context.getPreviewContext(); if ( previewContext.isPreviewingContent() ) { skipOnlineCheck = previewContext.getContentPreviewContext().isContentPreviewed( contentFromRequest ) || previewContext.getContentPreviewContext().treatContentAsAvailableEvenIfOffline( contentFromRequest.getKey() ); } // check access if not processing content request to the content in preview if ( !skipOnlineCheck ) { if ( !contentFromRequest.isOnline( context.getRequestTime() ) ) { throw new ContentNotFoundException( contentFromRequest.getKey(), contentFromRequest.getMainVersion().getTitle() ); } } } private PageTemplateEntity resolvePageTemplate( final ContentEntity contentFromRequest ) { PageTemplateResolver pageTemplateResolver = new PageTemplateResolver( pageTemplateDao ); final PageTemplateEntity pageTemplate = pageTemplateResolver.resolvePageTemplate( context.getSite(), contentFromRequest ); if ( pageTemplate == null ) { throw new PageTemplateNotFoundException( context.getSitePath() ); } return pageTemplate; } private LanguageEntity resolveLanguage( ContentEntity contentFromRequest ) { LanguageEntity language; if ( context.getOverridingLanguage() != null ) { language = context.getOverridingLanguage(); } else { language = LanguageResolver.resolve( contentFromRequest, context.getSite(), context.getMenuItem() ); } return language; } private PageRequestProcessorResult resolveResultForRedirectToMenuItemWithRequestedContent( SitePath sitePath, MenuItemEntity menuItemWithRequestedContent ) { Map originalParameters = context.getHttpRequest().getParameterMap(); SitePath sitePathToMenuItemWithRequestedContent = new SitePath( context.getSite().getKey(), menuItemWithRequestedContent.getPath(), originalParameters ); // sitePathToMenuItemWithRequestedContent.removeParam( "key" ); PageRequestProcessorResult redirectResult = new PageRequestProcessorResult(); redirectResult.setRedirectToSitePath( sitePathToMenuItemWithRequestedContent ); return redirectResult; } }