/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.client; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.jdom.CDATA; import org.jdom.Document; import org.jdom.Element; import org.joda.time.DateTime; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.enonic.cms.framework.client.ClientHttpServletRequest; import com.enonic.cms.api.client.model.RenderContentParams; import com.enonic.cms.api.client.model.RenderPageParams; import com.enonic.cms.api.client.model.RenderParams; import com.enonic.cms.core.Attribute; import com.enonic.cms.core.Path; import com.enonic.cms.core.content.ContentEntity; import com.enonic.cms.core.content.ContentKey; import com.enonic.cms.core.language.LanguageEntity; import com.enonic.cms.core.language.LanguageKey; import com.enonic.cms.core.portal.PathToContentResolver; import com.enonic.cms.core.portal.PortalRequest; import com.enonic.cms.core.portal.PortalRequestService; import com.enonic.cms.core.portal.PortalResponse; import com.enonic.cms.core.portal.VerticalSession; import com.enonic.cms.core.portal.ticket.TicketGenerator; import com.enonic.cms.core.security.SecurityService; import com.enonic.cms.core.security.user.User; import com.enonic.cms.core.servlet.ServletRequestAccessor; import com.enonic.cms.core.structure.SiteEntity; import com.enonic.cms.core.structure.SiteKey; import com.enonic.cms.core.structure.SitePath; import com.enonic.cms.core.structure.menuitem.MenuItemEntity; import com.enonic.cms.store.dao.ContentDao; import com.enonic.cms.store.dao.LanguageDao; import com.enonic.cms.store.dao.MenuItemDao; import com.enonic.cms.store.dao.SectionContentDao; import com.enonic.cms.store.dao.SiteDao; @Component public class InternalClientRenderService { @Autowired private PortalRequestService portalRequestService; @Autowired private SecurityService securityService; @Autowired private MenuItemDao menuItemDao; @Autowired private SiteDao siteDao; @Autowired private LanguageDao languageDao; @Autowired private ContentDao contentDao; @Autowired private SectionContentDao sectionContentDao; public Document renderPage( final RenderPageParams params ) { checkCommonRenderParams( params ); if ( params.menuItemKey < 0 ) { throw new IllegalArgumentException( "Illegal value for required parameter 'menuItemKey' : " + params.menuItemKey ); } final MenuItemEntity menuItem = menuItemDao.findByKey( params.menuItemKey ); if ( menuItem == null ) { throw new IllegalArgumentException( "Unknown menu item for key : " + params.menuItemKey ); } SitePath sitePath = setupSitePath( params, menuItem.getSite().getKey(), menuItem.getPath() ); setupHttpRequestForRenderCall( params, sitePath ); // setupPortalRequest PortalRequest portalRequest = setupPortalRequestForRenderCall( params, sitePath ); if ( params.languageCode != null ) { LanguageEntity language = languageDao.findByCode( params.languageCode ); LanguageKey languageKey = language.getKey(); portalRequest.setOverridingLanguage( languageKey != null ? languageKey.toInt() : -1 ); } return processRequest( portalRequest ); } private SitePath setupSitePath( final RenderParams params, final SiteKey siteKey, Path path ) { SitePath sitePath = new SitePath( siteKey, path ); Map<String, Object> requestParameters = compileRequestParameters( params.parameters ); for ( String key : requestParameters.keySet() ) { sitePath.addParam( key, (String) requestParameters.get( key ) ); } return sitePath; } private void setupHttpRequestForRenderCall( final RenderParams params, SitePath sitePath ) { String uriAsString = "/site/" + sitePath.getSiteKey() + sitePath.getLocalPath().getPathAsString(); ClientHttpServletRequest httpRequest = new ClientHttpServletRequest( params.serverName, params.portNumber, uriAsString, params.basePath ); if ( !params.basePath.startsWith( "/" ) ) { params.basePath = "/" + params.basePath; } if ( !params.basePath.endsWith( "/" ) ) { params.basePath = params.basePath + "/"; } httpRequest.setAttribute( Attribute.BASEPATH_OVERRIDE_ATTRIBUTE_NAME, params.basePath ); httpRequest.setParameters( compileRequestParameters( params.parameters ) ); ServletRequestAccessor.setRequest( httpRequest ); } private void checkCommonRenderParams( final RenderParams params ) { if ( params.serverName == null || params.serverName.equals( "" ) ) { throw new IllegalArgumentException( "Illegal value for required parameter 'serverName' : " + params.serverName ); } if ( params.basePath == null || params.basePath.equals( "" ) || params.basePath.contains( "://" ) ) { throw new IllegalArgumentException( "Illegal value for required parameter 'basePath' : " + params.basePath ); } } private Document processRequest( final PortalRequest portalRequest ) { PortalResponse portalResponse = portalRequestService.processRequest( portalRequest ); Element markup = new Element( "markup" ); markup.addContent( new CDATA( portalResponse.getContent() ) ); return new Document( markup ); } public Document renderContent( final RenderContentParams params ) { checkCommonRenderParams( params ); if ( params.siteKey < 0 ) { throw new IllegalArgumentException( "Illegal value for required parameter 'siteKey' : " + params.siteKey ); } if ( params.contentKey < 0 ) { throw new IllegalArgumentException( "Illegal value for required parameter 'contentKey' : " + params.contentKey ); } final SiteEntity siteEntity = siteDao.findByKey( params.siteKey ); if ( siteEntity == null ) { throw new IllegalArgumentException( "Unknown site for key : " + params.siteKey ); } Path localPath = resolveContentUrlLocalPath( new ContentKey( params.contentKey ), siteEntity.getKey() ); SitePath sitePath = setupSitePath( params, siteEntity.getKey(), localPath ); setupHttpRequestForRenderCall( params, sitePath ); PortalRequest portalRequest = setupPortalRequestForRenderCall( params, sitePath ); return processRequest( portalRequest ); } private PortalRequest setupPortalRequestForRenderCall( final RenderParams params, SitePath sitePath ) { HttpServletRequest httpRequest = ServletRequestAccessor.getRequest(); final User loggedInPortalUser = securityService.getImpersonatedPortalUser(); // setupPortalRequest PortalRequest portalRequest = new PortalRequest(); if ( params.profile != null ) { portalRequest.setProfile( params.profile ); } portalRequest.setRequestParams( compileRequestParameters( params.parameters ) ); portalRequest.setEncodeURIs( params.encodeURIs ); portalRequest.setOriginalSitePath( sitePath ); portalRequest.setSitePath( sitePath ); portalRequest.setRequester( loggedInPortalUser.getKey() ); portalRequest.setTicketId( TicketGenerator.getOrGenerate( httpRequest ) ); portalRequest.setRequestTime( new DateTime() ); portalRequest.setOriginalUrl( httpRequest.getRequestURL().toString() ); portalRequest.setVerticalSession( getAndEnsureVerticalSessionOnHttpSession( httpRequest.getSession() ) ); return portalRequest; } // FIXME duplicate code private VerticalSession getAndEnsureVerticalSessionOnHttpSession( HttpSession httpSession ) { VerticalSession vsession = (VerticalSession) httpSession.getAttribute( VerticalSession.VERTICAL_SESSION_OBJECT ); if ( vsession == null ) { vsession = new VerticalSession(); httpSession.setAttribute( VerticalSession.VERTICAL_SESSION_OBJECT, vsession ); } return vsession; } private HashMap<String, Object> compileRequestParameters( String[] params ) { HashMap<String, Object> parameters = new HashMap<String, Object>(); if ( params == null ) { return parameters; } for ( String param : params ) { if ( !param.contains( "=" ) ) { throw new IllegalArgumentException( "Param on wrong format, should be <key>=<value>: " + param ); } String[] nameAndValue = param.split( "=" ); parameters.put( nameAndValue[0], nameAndValue[1] ); } return parameters; } private Path resolveContentUrlLocalPath( final ContentKey contentKey, final SiteKey siteKey ) { ContentEntity content = contentDao.findByKey( contentKey ); if ( content == null || content.isDeleted() ) { return new Path( contentKey + ".cms" ); } PathToContentResolver pathToContentResolver = new PathToContentResolver( sectionContentDao ); return pathToContentResolver.resolveContentUrlLocalPath( content, siteKey ); } }