From 14f084eef7054ce49496be3f505ebac0fecbb1f1 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Thu, 2 Jul 2020 09:41:59 +0200 Subject: [PATCH] RESTful endpoint for creating applications --- .../libreccm/api/admin/sites/SitesApi.java | 1 - .../api/admin/web/CcmApplicationsApi.java | 91 ++++++++++++++++++- .../api/admin/web/dto/CcmApplicationDto.java | 11 +++ 3 files changed, 101 insertions(+), 2 deletions(-) diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/sites/SitesApi.java b/ccm-core/src/main/java/org/libreccm/api/admin/sites/SitesApi.java index fc02bc243..009f44b2e 100644 --- a/ccm-core/src/main/java/org/libreccm/api/admin/sites/SitesApi.java +++ b/ccm-core/src/main/java/org/libreccm/api/admin/sites/SitesApi.java @@ -33,7 +33,6 @@ import org.libreccm.sites.SiteRepository; import org.libreccm.web.ApplicationRepository; import org.libreccm.web.CcmApplication; -import java.util.List; import java.util.stream.Collectors; import javax.enterprise.context.RequestScoped; diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/web/CcmApplicationsApi.java b/ccm-core/src/main/java/org/libreccm/api/admin/web/CcmApplicationsApi.java index b8100accc..798c2a275 100644 --- a/ccm-core/src/main/java/org/libreccm/api/admin/web/CcmApplicationsApi.java +++ b/ccm-core/src/main/java/org/libreccm/api/admin/web/CcmApplicationsApi.java @@ -24,21 +24,28 @@ import org.libreccm.api.admin.categorization.dto.DomainOwnershipData; import org.libreccm.api.admin.web.dto.CcmApplicationDto; import org.libreccm.api.dto.ListView; import org.libreccm.core.CoreConstants; +import org.libreccm.l10n.LocalizedString; import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.RequiresPrivilege; import org.libreccm.sites.SiteAwareApplicationRepository; +import org.libreccm.web.ApplicationCreateException; +import org.libreccm.web.ApplicationManager; import org.libreccm.web.ApplicationRepository; +import org.libreccm.web.ApplicationType; import org.libreccm.web.CcmApplication; +import java.util.Map; import java.util.stream.Collectors; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.transaction.Transactional; +import javax.ws.rs.BadRequestException; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; +import javax.ws.rs.InternalServerErrorException; import javax.ws.rs.NotFoundException; import javax.ws.rs.POST; import javax.ws.rs.PUT; @@ -46,8 +53,10 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; /** * @@ -57,6 +66,12 @@ import javax.ws.rs.core.Response; @Path("/applications/") public class CcmApplicationsApi { + @Context + private UriInfo uriInfo; + + @Inject + private ApplicationManager applicationManager; + @Inject private ApplicationRepository applicationRepository; @@ -121,8 +136,82 @@ public class CcmApplicationsApi { @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) + public Response createApplication(final CcmApplicationDto applicationData) { - throw new UnsupportedOperationException(); + + final String applicationClassName = applicationData + .getApplicationClassName(); + final String path = applicationData.getPrimaryUrl(); + + final LocalizedString title = applicationData.getTitle(); + final LocalizedString description = applicationData.getDescription(); + + final Class clazz; + try { + clazz = Class.forName(applicationClassName); + + } catch (ClassNotFoundException ex) { + throw new BadRequestException( + String.format( + "No class for applicationClassName \"%s\" found.", + applicationClassName + ) + ); + } + if (!CcmApplication.class.isAssignableFrom(clazz)) { + throw new BadRequestException( + String.format( + "The provided class \"%s\" is not an subclass of \"%s\".)", + clazz.getName(), + CcmApplication.class.getName() + ) + ); + } + @SuppressWarnings("unchecked") + final Class applicationClass + = (Class) clazz; + + final Map applicationTypes = applicationManager + .getApplicationTypes(); + + if (!applicationTypes.containsKey(applicationClass.getName())) { + throw new NotFoundException( + String.format( + "No application type for class \"%s\" available.", + applicationClass.getName() + ) + ); + } + + final ApplicationType applicationType = applicationTypes.get( + applicationClass.getName() + ); + + final CcmApplication application; + try { + application = applicationManager.createInstance( + applicationType, path, applicationClass + ); + } catch (ApplicationCreateException ex) { + throw new InternalServerErrorException( + String.format( + "Failed to created new application of type \"%s\".", + applicationClass.getName() + ) + ); + } + + application.setTitle(title); + application.setDescription(description); + + return Response + .created( + uriInfo + .getBaseUriBuilder() + .path(path) + .build() + ).build(); + } @PUT diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/web/dto/CcmApplicationDto.java b/ccm-core/src/main/java/org/libreccm/api/admin/web/dto/CcmApplicationDto.java index 52c6089d0..ecb844604 100644 --- a/ccm-core/src/main/java/org/libreccm/api/admin/web/dto/CcmApplicationDto.java +++ b/ccm-core/src/main/java/org/libreccm/api/admin/web/dto/CcmApplicationDto.java @@ -45,6 +45,8 @@ public class CcmApplicationDto { private LocalizedString description; private String created; + + private String applicationClassName; private String applicationType; @@ -74,6 +76,7 @@ public class CcmApplicationDto { created = DateTimeFormatter.ISO_DATE_TIME.format( application.getCreated().toInstant() ); + applicationClassName = application.getClass().getName(); applicationType = application.getApplicationType(); primaryUrl = application.getPrimaryUrl(); domains = application @@ -129,6 +132,14 @@ public class CcmApplicationDto { public void setCreated(final String created) { this.created = created; } + + public String getApplicationClassName() { + return applicationClassName; + } + + protected void setApplicationClassName(final String applicationClassName) { + this.applicationClassName = applicationClassName; + } public String getApplicationType() { return applicationType;