diff --git a/modules/server/server-rest/src/main/java/com/enonic/xp/impl/server/rest/WebappResource.java b/modules/server/server-rest/src/main/java/com/enonic/xp/impl/server/rest/WebappResource.java new file mode 100644 index 00000000000..bdd09a593b5 --- /dev/null +++ b/modules/server/server-rest/src/main/java/com/enonic/xp/impl/server/rest/WebappResource.java @@ -0,0 +1,58 @@ +package com.enonic.xp.impl.server.rest; + +import java.util.List; +import java.util.stream.Collectors; + +import javax.annotation.security.RolesAllowed; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +import com.enonic.xp.app.Application; +import com.enonic.xp.app.ApplicationService; +import com.enonic.xp.impl.server.rest.model.WebappJson; +import com.enonic.xp.jaxrs.JaxRsComponent; +import com.enonic.xp.resource.Resource; +import com.enonic.xp.resource.ResourceKey; +import com.enonic.xp.resource.ResourceService; +import com.enonic.xp.security.RoleKeys; + +@Path("/content/projects") +@Produces(MediaType.APPLICATION_JSON) +@RolesAllowed(RoleKeys.ADMIN_ID) +@Component(immediate = true, property = "group=api") +public final class WebappResource + implements JaxRsComponent +{ + private final ApplicationService applicationService; + + private final ResourceService resourceService; + + @Activate + public WebappResource( @Reference final ApplicationService applicationService, @Reference final ResourceService resourceService ) + { + this.applicationService = applicationService; + this.resourceService = resourceService; + } + + @GET + @Path("list") + public List list() + { + return applicationService.getInstalledApplications() + .stream() + .map( Application::getKey ) + .map( key -> ResourceKey.from( key, "/webapp/webapp.js" ) ) + .map( resourceService::getResource ) + .filter( Resource::exists ) + .map( Resource::getKey ) + .map( ResourceKey::getApplicationKey ) + .map( WebappJson::from ) + .collect( Collectors.toList() ); + } +} diff --git a/modules/server/server-rest/src/main/java/com/enonic/xp/impl/server/rest/model/WebappJson.java b/modules/server/server-rest/src/main/java/com/enonic/xp/impl/server/rest/model/WebappJson.java new file mode 100644 index 00000000000..c330422f897 --- /dev/null +++ b/modules/server/server-rest/src/main/java/com/enonic/xp/impl/server/rest/model/WebappJson.java @@ -0,0 +1,44 @@ +package com.enonic.xp.impl.server.rest.model; + +import com.enonic.xp.app.ApplicationKey; + +public final class WebappJson +{ + private final String name; + + private WebappJson( Builder builder ) + { + this.name = builder.name; + } + + public static Builder create() + { + return new Builder(); + } + + public static WebappJson from( final ApplicationKey key ) + { + return create().name( key.toString() ).build(); + } + + public String getName() + { + return name; + } + + public static class Builder + { + private String name; + + public Builder name( final String name ) + { + this.name = name; + return this; + } + + public WebappJson build() + { + return new WebappJson( this ); + } + } +} diff --git a/modules/server/server-rest/src/test/java/com/enonic/xp/impl/server/rest/WebappResourceTest.java b/modules/server/server-rest/src/test/java/com/enonic/xp/impl/server/rest/WebappResourceTest.java new file mode 100644 index 00000000000..31abda73071 --- /dev/null +++ b/modules/server/server-rest/src/test/java/com/enonic/xp/impl/server/rest/WebappResourceTest.java @@ -0,0 +1,87 @@ +package com.enonic.xp.impl.server.rest; + +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.enonic.xp.app.Application; +import com.enonic.xp.app.ApplicationKey; +import com.enonic.xp.app.ApplicationService; +import com.enonic.xp.app.Applications; +import com.enonic.xp.impl.server.rest.model.WebappJson; +import com.enonic.xp.resource.Resource; +import com.enonic.xp.resource.ResourceKey; +import com.enonic.xp.resource.ResourceService; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class WebappResourceTest +{ + private WebappResource resource; + + @Mock + private ApplicationService applicationService; + + @Mock + private ResourceService resourceService; + + @BeforeEach + public void setUp() + { + resource = new WebappResource( applicationService, resourceService ); + } + + @Test + void testList() + { + final List keys = + List.of( ApplicationKey.from( "app1" ), ApplicationKey.from( "app2" ), ApplicationKey.from( "app3" ) ); + + final List applications = keys.stream().map( key -> { + final Application app = mock( Application.class ); + when( app.getKey() ).thenReturn( key ); + + return app; + } ).collect( Collectors.toList() ); + + final Applications from = Applications.from( applications ); + when( applicationService.getInstalledApplications() ).thenReturn( from ); + + final Resource resource1 = mock( Resource.class ); + when( resource1.getKey() ).thenReturn( ResourceKey.from( keys.get( 0 ), "/webapp/webapp.js" ) ); + when( resource1.exists() ).thenReturn( true ); + + final Resource resource2 = mock( Resource.class ); + when( resource2.getKey() ).thenReturn( ResourceKey.from( keys.get( 1 ), "/webapp/webapp.js" ) ); + when( resource2.exists() ).thenReturn( false ); + + final Resource resource3 = mock( Resource.class ); + when( resource3.getKey() ).thenReturn( ResourceKey.from( keys.get( 2 ), "/webapp/webapp.js" ) ); + when( resource3.exists() ).thenReturn( true ); + + final List resources = List.of( resource1, resource2, resource3 ); + + when( resourceService.getResource( resources.get( 0 ).getKey() ) ).thenReturn( resources.get( 0 ) ); + when( resourceService.getResource( resources.get( 1 ).getKey() ) ).thenReturn( resources.get( 1 ) ); + when( resourceService.getResource( resources.get( 2 ).getKey() ) ).thenReturn( resources.get( 2 ) ); + + assertThat( resource.list() ).usingRecursiveComparison() + .isEqualTo( List.of( WebappJson.from( keys.get( 0 ) ), WebappJson.from( keys.get( 2 ) ) ) ); + } + + @Test + void testEmptyList() + { + when( applicationService.getInstalledApplications() ).thenReturn( Applications.empty() ); + assertThat( resource.list() ).isEmpty(); + } + +}