From f71fde875a14eeafa1b24d01e73cbbd1d72d8d7b Mon Sep 17 00:00:00 2001 From: ashklianko Date: Mon, 16 Dec 2024 10:58:53 +0100 Subject: [PATCH] lib-portal.getContent doesn't resolve page templates #10800 --- .../ComponentServiceMappingHandler.java | 12 ++++- .../impl/handler/mapping/MappingHandler.java | 12 ++++- .../handler/mapping/MappingHandlerHelper.java | 51 +++++++++++++------ .../ComponentServiceMappingHandlerTest.java | 15 +++++- .../handler/mapping/MappingHandlerTest.java | 42 +++++++++++++-- 5 files changed, 107 insertions(+), 25 deletions(-) diff --git a/modules/portal/portal-impl/src/main/java/com/enonic/xp/portal/impl/handler/mapping/ComponentServiceMappingHandler.java b/modules/portal/portal-impl/src/main/java/com/enonic/xp/portal/impl/handler/mapping/ComponentServiceMappingHandler.java index 141e907ef03..e299c4dc5a0 100644 --- a/modules/portal/portal-impl/src/main/java/com/enonic/xp/portal/impl/handler/mapping/ComponentServiceMappingHandler.java +++ b/modules/portal/portal-impl/src/main/java/com/enonic/xp/portal/impl/handler/mapping/ComponentServiceMappingHandler.java @@ -5,12 +5,16 @@ import org.osgi.service.component.annotations.Reference; import com.enonic.xp.content.ContentService; +import com.enonic.xp.page.PageDescriptorService; +import com.enonic.xp.page.PageTemplateService; import com.enonic.xp.portal.controller.ControllerScriptFactory; import com.enonic.xp.portal.filter.FilterScriptFactory; import com.enonic.xp.portal.handler.EndpointHandler; import com.enonic.xp.portal.impl.ContentResolver; +import com.enonic.xp.portal.impl.handler.render.PageResolver; import com.enonic.xp.portal.impl.rendering.RendererDelegate; import com.enonic.xp.project.ProjectService; +import com.enonic.xp.region.LayoutDescriptorService; import com.enonic.xp.resource.ResourceService; import com.enonic.xp.site.SiteService; import com.enonic.xp.web.HttpMethod; @@ -30,13 +34,17 @@ public ComponentServiceMappingHandler( @Reference final ProjectService projectSe @Reference final ControllerScriptFactory controllerScriptFactory, @Reference final FilterScriptFactory filterScriptFactory, @Reference final RendererDelegate rendererDelegate, @Reference final SiteService siteService, - @Reference final ContentService contentService ) + @Reference final ContentService contentService, + @Reference final PageTemplateService pageTemplateService, + @Reference final PageDescriptorService pageDescriptorService, + @Reference final LayoutDescriptorService layoutDescriptorService ) { super( HttpMethod.standard(), "component" ); this.mappingHandlerHelper = new MappingHandlerHelper( projectService, resourceService, controllerScriptFactory, filterScriptFactory, rendererDelegate, - new ControllerMappingsResolver( siteService ), new ContentResolver( contentService ) ); + new ControllerMappingsResolver( siteService ), new ContentResolver( contentService ), + new PageResolver( pageTemplateService, pageDescriptorService, layoutDescriptorService )); } @Override diff --git a/modules/portal/portal-impl/src/main/java/com/enonic/xp/portal/impl/handler/mapping/MappingHandler.java b/modules/portal/portal-impl/src/main/java/com/enonic/xp/portal/impl/handler/mapping/MappingHandler.java index e5d31bebedc..b58d77916d6 100644 --- a/modules/portal/portal-impl/src/main/java/com/enonic/xp/portal/impl/handler/mapping/MappingHandler.java +++ b/modules/portal/portal-impl/src/main/java/com/enonic/xp/portal/impl/handler/mapping/MappingHandler.java @@ -5,11 +5,15 @@ import org.osgi.service.component.annotations.Reference; import com.enonic.xp.content.ContentService; +import com.enonic.xp.page.PageDescriptorService; +import com.enonic.xp.page.PageTemplateService; import com.enonic.xp.portal.controller.ControllerScriptFactory; import com.enonic.xp.portal.filter.FilterScriptFactory; import com.enonic.xp.portal.impl.ContentResolver; +import com.enonic.xp.portal.impl.handler.render.PageResolver; import com.enonic.xp.portal.impl.rendering.RendererDelegate; import com.enonic.xp.project.ProjectService; +import com.enonic.xp.region.LayoutDescriptorService; import com.enonic.xp.resource.ResourceService; import com.enonic.xp.site.SiteService; import com.enonic.xp.web.WebRequest; @@ -28,11 +32,15 @@ public MappingHandler( @Reference final SiteService siteService, @Reference fina @Reference final ResourceService resourceService, @Reference final ControllerScriptFactory controllerScriptFactory, @Reference final FilterScriptFactory filterScriptFactory, @Reference final RendererDelegate rendererDelegate, - @Reference final ProjectService projectService ) + @Reference final ProjectService projectService, @Reference final PageTemplateService pageTemplateService, + @Reference final PageDescriptorService pageDescriptorService, + @Reference final LayoutDescriptorService layoutDescriptorService + ) { this.mappingHandlerHelper = new MappingHandlerHelper( projectService, resourceService, controllerScriptFactory, filterScriptFactory, rendererDelegate, - new ControllerMappingsResolver( siteService ), new ContentResolver( contentService ) ); + new ControllerMappingsResolver( siteService ), new ContentResolver( contentService ), + new PageResolver( pageTemplateService, pageDescriptorService, layoutDescriptorService ) ); } @Override diff --git a/modules/portal/portal-impl/src/main/java/com/enonic/xp/portal/impl/handler/mapping/MappingHandlerHelper.java b/modules/portal/portal-impl/src/main/java/com/enonic/xp/portal/impl/handler/mapping/MappingHandlerHelper.java index 19c7e836d30..77b340fdffb 100644 --- a/modules/portal/portal-impl/src/main/java/com/enonic/xp/portal/impl/handler/mapping/MappingHandlerHelper.java +++ b/modules/portal/portal-impl/src/main/java/com/enonic/xp/portal/impl/handler/mapping/MappingHandlerHelper.java @@ -20,6 +20,8 @@ import com.enonic.xp.portal.handler.WebHandlerHelper; import com.enonic.xp.portal.impl.ContentResolver; import com.enonic.xp.portal.impl.ContentResolverResult; +import com.enonic.xp.portal.impl.handler.render.PageResolver; +import com.enonic.xp.portal.impl.handler.render.PageResolverResult; import com.enonic.xp.portal.impl.rendering.RendererDelegate; import com.enonic.xp.project.Project; import com.enonic.xp.project.ProjectName; @@ -58,10 +60,21 @@ class MappingHandlerHelper private final ContentResolver contentResolver; + private final PageResolver pageResolver; + MappingHandlerHelper( final ProjectService projectService, final ResourceService resourceService, final ControllerScriptFactory controllerScriptFactory, final FilterScriptFactory filterScriptFactory, final RendererDelegate rendererDelegate, final ControllerMappingsResolver controllerMappingsResolver, final ContentResolver contentResolver ) + { + this( projectService, resourceService, controllerScriptFactory, filterScriptFactory, rendererDelegate, controllerMappingsResolver, + contentResolver, null ); + } + + MappingHandlerHelper( final ProjectService projectService, final ResourceService resourceService, + final ControllerScriptFactory controllerScriptFactory, final FilterScriptFactory filterScriptFactory, + final RendererDelegate rendererDelegate, final ControllerMappingsResolver controllerMappingsResolver, + final ContentResolver contentResolver, final PageResolver pageResolver ) { this.projectService = projectService; this.resourceService = resourceService; @@ -70,6 +83,7 @@ class MappingHandlerHelper this.rendererDelegate = rendererDelegate; this.controllerMappingsResolver = controllerMappingsResolver; this.contentResolver = contentResolver; + this.pageResolver = pageResolver; } public WebResponse handle( final WebRequest webRequest, final WebResponse webResponse, final WebHandlerChain webHandlerChain ) @@ -100,8 +114,6 @@ public WebResponse handle( final WebRequest webRequest, final WebResponse webRes final Site site = resolvedContent.getNearestSite(); - final Content content = resolvedContent.getContent(); - final SiteConfigs siteConfigs; if ( site != null ) @@ -119,15 +131,29 @@ public WebResponse handle( final WebRequest webRequest, final WebResponse webRes return webHandlerChain.handle( webRequest, webResponse ); } - final Optional resolve = + final Content content = resolvedContent.getContent(); + + final Optional optionalControllerMapping = controllerMappingsResolver.resolve( resolvedContent.getSiteRelativePath(), request.getParams(), content, siteConfigs, getServiceType( request ) ); - if ( resolve.isPresent() ) + if ( optionalControllerMapping.isPresent() ) { - final ControllerMappingDescriptor mapping = resolve.get(); + final ControllerMappingDescriptor mapping = optionalControllerMapping.get(); + + if ( content == null || pageResolver == null ) + { + request.setContent( content ); + } + else + { + final PageResolverResult resolvedPage = pageResolver.resolve( request.getMode(), content, site ); + final Content effectiveContent = Content.create( content ).page( resolvedPage.getEffectivePage() ).build(); + request.setContent( effectiveContent ); + request.setApplicationKey( resolvedPage.getApplicationKey() ); + request.setPageDescriptor( resolvedPage.getPageDescriptor() ); + } - request.setContent( content ); request.setSite( site ); request.setContextPath( request.getBaseUri() + "/" + RepositoryUtils.getContentRepoName( request.getRepositoryId() ) + "/" + request.getBranch() + @@ -138,17 +164,12 @@ public WebResponse handle( final WebRequest webRequest, final WebResponse webRes { return handleController( request, mapping ); } - else - { - return handleFilter( request, webResponse, webHandlerChain, mapping ); - } - } - else - { - return webHandlerChain.handle( request, webResponse ); + + return handleFilter( request, webResponse, webHandlerChain, mapping ); } - } + return webHandlerChain.handle( request, webResponse ); + } private PortalResponse handleController( final PortalRequest portalRequest, final ControllerMappingDescriptor mapping ) throws Exception diff --git a/modules/portal/portal-impl/src/test/java/com/enonic/xp/portal/impl/handler/mapping/ComponentServiceMappingHandlerTest.java b/modules/portal/portal-impl/src/test/java/com/enonic/xp/portal/impl/handler/mapping/ComponentServiceMappingHandlerTest.java index 5a971a98b72..ea8da877588 100644 --- a/modules/portal/portal-impl/src/test/java/com/enonic/xp/portal/impl/handler/mapping/ComponentServiceMappingHandlerTest.java +++ b/modules/portal/portal-impl/src/test/java/com/enonic/xp/portal/impl/handler/mapping/ComponentServiceMappingHandlerTest.java @@ -11,6 +11,8 @@ import com.enonic.xp.content.ContentPath; import com.enonic.xp.content.ContentService; import com.enonic.xp.data.PropertyTree; +import com.enonic.xp.page.PageDescriptorService; +import com.enonic.xp.page.PageTemplateService; import com.enonic.xp.portal.PortalRequest; import com.enonic.xp.portal.PortalResponse; import com.enonic.xp.portal.controller.ControllerScript; @@ -19,6 +21,7 @@ import com.enonic.xp.portal.filter.FilterScriptFactory; import com.enonic.xp.portal.impl.rendering.RendererDelegate; import com.enonic.xp.project.ProjectService; +import com.enonic.xp.region.LayoutDescriptorService; import com.enonic.xp.resource.Resource; import com.enonic.xp.resource.ResourceKey; import com.enonic.xp.resource.ResourceService; @@ -62,6 +65,12 @@ class ComponentServiceMappingHandlerTest private FilterScript filterScript; + private PageTemplateService pageTemplateService; + + private PageDescriptorService pageDescriptorService; + + private LayoutDescriptorService layoutDescriptorService; + @BeforeEach final void setup() { @@ -72,6 +81,9 @@ final void setup() RendererDelegate rendererDelegate = mock( RendererDelegate.class ); this.siteService = mock( SiteService.class ); this.webHandlerChain = mock( WebHandlerChain.class ); + this.pageTemplateService = mock( PageTemplateService.class ); + this.pageDescriptorService = mock( PageDescriptorService.class ); + this.layoutDescriptorService = mock( LayoutDescriptorService.class ); final ControllerScriptFactory controllerScriptFactory = mock( ControllerScriptFactory.class ); ControllerScript controllerScript = mock( ControllerScript.class ); @@ -85,7 +97,8 @@ final void setup() when( filterScript.execute( Mockito.any(), Mockito.any(), Mockito.any() ) ).thenReturn( portalResponse ); this.handler = new ComponentServiceMappingHandler( projectService, resourceService, controllerScriptFactory, filterScriptFactory, - rendererDelegate, siteService, contentService ); + rendererDelegate, siteService, contentService, pageTemplateService, + pageDescriptorService, layoutDescriptorService ); this.request.setMethod( HttpMethod.GET ); this.request.setBranch( ContentConstants.BRANCH_MASTER ); diff --git a/modules/portal/portal-impl/src/test/java/com/enonic/xp/portal/impl/handler/mapping/MappingHandlerTest.java b/modules/portal/portal-impl/src/test/java/com/enonic/xp/portal/impl/handler/mapping/MappingHandlerTest.java index 57206273835..72255708d2a 100644 --- a/modules/portal/portal-impl/src/test/java/com/enonic/xp/portal/impl/handler/mapping/MappingHandlerTest.java +++ b/modules/portal/portal-impl/src/test/java/com/enonic/xp/portal/impl/handler/mapping/MappingHandlerTest.java @@ -14,9 +14,13 @@ import com.enonic.xp.content.ContentService; import com.enonic.xp.context.ContextAccessor; import com.enonic.xp.data.PropertyTree; +import com.enonic.xp.page.DescriptorKey; import com.enonic.xp.page.Page; +import com.enonic.xp.page.PageDescriptorService; import com.enonic.xp.page.PageRegions; +import com.enonic.xp.page.PageTemplate; import com.enonic.xp.page.PageTemplateKey; +import com.enonic.xp.page.PageTemplateService; import com.enonic.xp.portal.PortalRequest; import com.enonic.xp.portal.PortalResponse; import com.enonic.xp.portal.controller.ControllerScript; @@ -27,6 +31,7 @@ import com.enonic.xp.project.Project; import com.enonic.xp.project.ProjectName; import com.enonic.xp.project.ProjectService; +import com.enonic.xp.region.LayoutDescriptorService; import com.enonic.xp.region.PartComponent; import com.enonic.xp.region.Region; import com.enonic.xp.resource.Resource; @@ -80,6 +85,12 @@ public class MappingHandlerTest private ProjectService projectService; + private PageTemplateService pageTemplateService; + + private PageDescriptorService pageDescriptorService; + + private LayoutDescriptorService layoutDescriptorService; + @BeforeEach public final void setup() throws Exception @@ -107,9 +118,13 @@ public final void setup() this.rendererDelegate = mock( RendererDelegate.class ); this.siteService = mock( SiteService.class ); this.projectService = mock( ProjectService.class ); + this.pageTemplateService = mock( PageTemplateService.class ); + this.pageDescriptorService = mock( PageDescriptorService.class ); + this.layoutDescriptorService = mock( LayoutDescriptorService.class ); this.handler = new MappingHandler( siteService, contentService, resourceService, controllerScriptFactory, filterScriptFactory, - rendererDelegate, projectService ); + rendererDelegate, projectService, pageTemplateService, pageDescriptorService, + layoutDescriptorService ); this.request.setMethod( HttpMethod.GET ); } @@ -230,6 +245,8 @@ public void executeScriptFromProjectApp() when( rendererDelegate.render( eq( projectMapping ), same( request ) ) ).thenReturn( PortalResponse.create().body( "Project body" ).build() ); + final Site site = createSite( "id", "mysite", "myapplication:contenttypename", "project-app1" ); + when( this.contentService.findNearestSiteByPath( any( ContentPath.class) ) ).thenReturn( site ); final WebResponse response = this.handler.handle( this.request, PortalResponse.create().build(), null ); assertEquals( HttpStatus.OK, response.getStatus() ); @@ -302,7 +319,7 @@ public void executeFilter() private void setupContentAndSite( final ControllerMappingDescriptor mapping ) { final Content content = createPage( "id", "site/somesite/content", "myapplication:ctype", true ); - final Site site = createSite( "id", "site", "myapplication:contenttypename" ); + final Site site = createSite( "id", "site", "myapplication:contenttypename", "myapplication" ); final ContentPath path = ContentPath.from( "site/somesite/content" ).asAbsolute(); when( this.contentService.getByPath( path ) ).thenReturn( content ); @@ -311,6 +328,8 @@ private void setupContentAndSite( final ControllerMappingDescriptor mapping ) when( this.contentService.getById( content.getId() ) ).thenReturn( content ); + when( this.pageTemplateService.getByKey( any( PageTemplateKey.class ) ) ).thenReturn( createPageTemplate() ); + final ControllerMappingDescriptors mappings = ControllerMappingDescriptors.from( mapping ); final SiteDescriptor siteDescriptor = SiteDescriptor.create().mappingDescriptors( mappings ).build(); when( this.siteService.getDescriptor( any( ApplicationKey.class ) ) ).thenReturn( siteDescriptor ); @@ -336,10 +355,11 @@ private void setupContentAndSiteAndProject( final ControllerMappingDescriptor pr when( this.contentService.getByPath( path ) ).thenReturn( content ); when( this.contentService.getById( content.getId() ) ).thenReturn( content ); + when( this.pageTemplateService.getByKey( any( PageTemplateKey.class ) ) ).thenReturn( createPageTemplate() ); if ( siteMapping != null ) { - final Site site = createSite( "id", "mysite", "myapplication:contenttypename" ); + final Site site = createSite( "id", "mysite", "myapplication:contenttypename", "myapplication" ); when( this.contentService.findNearestSiteByPath( eq( path ) ) ).thenReturn( site ); final ControllerMappingDescriptors siteMappings = ControllerMappingDescriptors.from( siteMapping ); @@ -383,7 +403,7 @@ private Content createPage( final String id, final String path, final String con return content.build(); } - private Site createSite( final String id, final String path, final String contentTypeName ) + private Site createSite( final String id, final String path, final String contentTypeName, final String appKey ) { PropertyTree rootDataSet = new PropertyTree(); rootDataSet.addString( "property1", "value1" ); @@ -391,7 +411,7 @@ private Site createSite( final String id, final String path, final String conten Page page = Page.create().template( PageTemplateKey.from( "my-page" ) ).config( rootDataSet ).build(); final SiteConfig siteConfig = - SiteConfig.create().application( ApplicationKey.from( "myapplication" ) ).config( new PropertyTree() ).build(); + SiteConfig.create().application( ApplicationKey.from( appKey ) ).config( new PropertyTree() ).build(); return Site.create() .siteConfigs( SiteConfigs.from( siteConfig ) ) .id( ContentId.from( id ) ) @@ -415,4 +435,16 @@ private Project createProject( final String name, final ApplicationKeys applicat return project.build(); } + + private PageTemplate createPageTemplate() + { + final PageTemplate.Builder pageTemplate = PageTemplate.newPageTemplate() + .key( PageTemplateKey.from( "my-page-tempalte" ) ) + .controller( DescriptorKey.from( "my-template-controller" ) ) + .id( ContentId.from( "pageTemplateId" ) ) + .path( ContentPath.from( "site/somesite/template" ) ) + .type( ContentTypeName.pageTemplate() ); + + return pageTemplate.build(); + } }