diff --git a/ccm-core/src/main/java/org/libreccm/api/pagemodels/Components.java b/ccm-core/src/main/java/org/libreccm/api/pagemodels/Components.java
new file mode 100644
index 000000000..629b3d2a6
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/pagemodels/Components.java
@@ -0,0 +1,531 @@
+/*
+ * Copyright (C) 2018 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.api.pagemodels;
+
+import org.libreccm.core.CoreConstants;
+import org.libreccm.pagemodel.ComponentModel;
+import org.libreccm.pagemodel.ComponentModelJsonConverter;
+import org.libreccm.pagemodel.ComponentModelRepository;
+import org.libreccm.pagemodel.ContainerModel;
+import org.libreccm.pagemodel.ContainerModelManager;
+import org.libreccm.pagemodel.ConvertsComponentModel;
+import org.libreccm.pagemodel.PageModel;
+import org.libreccm.security.AuthorizationRequired;
+import org.libreccm.security.RequiresPrivilege;
+import org.libreccm.web.CcmApplication;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+import java.util.Iterator;
+import java.util.Objects;
+import java.util.Optional;
+
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.inject.Inject;
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.transaction.Transactional;
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+/**
+ * Provides RESTful endpoints for retrieving, creating, updating and deleting
+ * {@link ComponentModel}s of a {@link ContainerModel}.
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+@Path("/{appName}/{pageModelName}/containers/{containerKey}/components")
+public class Components {
+
+ @Inject
+ private ComponentModelRepository componentRepo;
+
+ @Inject
+ private ContainerModelManager containerManager;
+
+ @Inject
+ private PageModelsController controller;
+
+ @Inject
+ @Any
+ private Instance jsonConverters;
+
+ /**
+ * Retrieve all {@link ComponentModel} of a {@link ContainerModel}.
+ *
+ * @param Name The primary URL of the {@link CcmApplication}.
+ * @param pageModelName The name of the {@link PageModel}.
+ * @param containerKey The key of the {@link ContainerModel}.
+ *
+ * @return A JSON array containing the data of all {@link ComponentModel} of
+ * the {@link ContainerModel}.
+ */
+ @GET
+ @Path("/")
+ @Produces(MediaType.APPLICATION_JSON)
+ @Transactional(Transactional.TxType.REQUIRED)
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ public JsonArray getComponents(
+ @PathParam("appName") final String Name,
+ @PathParam("pageModelName") final String pageModelName,
+ @PathParam("containerKey") final String containerKey
+ ) {
+ Objects.requireNonNull(Name);
+ Objects.requireNonNull(pageModelName);
+ Objects.requireNonNull(containerKey);
+
+ final CcmApplication app = controller.findCcmApplication(
+ String.format("/%s/", Name)
+ );
+ final PageModel pageModel = controller.findPageModel(
+ app, pageModelName
+ );
+ final ContainerModel container = controller.findContainer(
+ app, pageModel, containerKey
+ );
+
+ final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+ container
+ .getComponents()
+ .stream()
+ .map(component -> mapComponentModelToJson(component))
+ .forEach(arrayBuilder::add);
+
+ return arrayBuilder.build();
+ }
+
+ /**
+ * Retrieves a specific {@link ComponentModel}.
+ *
+ * @param appName The primary URL of the {@link CcmApplication}.
+ * @param pageModelName The name of the {@link PageModel}.
+ * @param containerKey The key of the {@link ContainerModel}.
+ * @param componentKey The key of the {@link ComponentModel}.
+ *
+ * @return A JSON object containing the data of the {@link ComponentModel}.
+ */
+ @GET
+ @Path("/{componentKey}")
+ @Produces(MediaType.APPLICATION_JSON)
+ @Transactional(Transactional.TxType.REQUIRED)
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ public JsonObject getComponent(
+ @PathParam("appName") final String appName,
+ @PathParam("pageModelName") final String pageModelName,
+ @PathParam("containerKey") final String containerKey,
+ @PathParam("componentKey") final String componentKey
+ ) {
+ Objects.requireNonNull(appName);
+ Objects.requireNonNull(pageModelName);
+ Objects.requireNonNull(containerKey);
+ Objects.requireNonNull(componentKey);
+
+ final CcmApplication app = controller.findCcmApplication(
+ String.format("/%s/", appName)
+ );
+ final PageModel pageModel = controller.findPageModel(
+ app, pageModelName
+ );
+ final ContainerModel container = controller.findContainer(
+ app, pageModel, containerKey
+ );
+ final ComponentModel component = controller.findComponentModel(
+ app, pageModel, container, componentKey
+ );
+
+ return mapComponentModelToJson(component);
+ }
+
+ /**
+ * Creates or updates a {@link ComponentModel}.If a {@link ComponentModel}
+ * with provided {@code componentKey} already exists in the container
+ * identified by {@code appName}, {@code pageModelName} and
+ * {@code containerKey} the {@link ComponentModel} is updated with the data
+ * from {@code componentModelData}.
+ *
+ * Otherwise a new {@link ComponentModel} is created using the data from
+ * {@code componentModelData}.
+ *
+ * @param appName The primary URL of the {@link CcmApplication}.
+ * @param pageModelName The name of the {@link PageModel}.
+ * @param containerKey The key of the {@link ContainerModel}.
+ * @param componentKey The key of the {@link ComponentModel} to create
+ * or update.
+ * @param componentModelData The data for creating or updating the
+ * {@link ComponentModel}.
+ *
+ * @return A HTTP response with the status code {@code 200} if the component
+ * model was updated or {@code 201} if the component model was
+ * created. If the component model was created the response also
+ * contains the URI of the new component model.
+ *
+ *
+ */
+ @PUT
+ @Path("/{componentKey}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Transactional(Transactional.TxType.REQUIRED)
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ public Response putComponent(
+ @PathParam("appName") final String appName,
+ @PathParam("pageModelName") final String pageModelName,
+ @PathParam("containerKey") final String containerKey,
+ @PathParam("componentKey") final String componentKey,
+ final JsonObject componentModelData
+ ) {
+ Objects.requireNonNull(appName);
+ Objects.requireNonNull(pageModelName);
+ Objects.requireNonNull(containerKey);
+ Objects.requireNonNull(componentKey);
+ Objects.requireNonNull(componentModelData);
+
+ final CcmApplication app = controller.findCcmApplication(
+ String.format("/%s/", appName)
+ );
+ final PageModel pageModel = controller.findPageModel(
+ app, pageModelName
+ );
+ final ContainerModel container = controller.findContainer(
+ app, pageModel, containerKey
+ );
+
+ final Optional result = container
+ .getComponents()
+ .stream()
+ .filter(c -> c.getKey().equals(componentKey))
+ .findAny();
+
+ final ComponentModel componentModel;
+ final boolean created;
+ if (result.isPresent()) {
+ componentModel = result.get();
+ created = false;
+ } else {
+ componentModel = createComponentModel(componentModelData);
+ componentModel.setKey(componentKey);
+ containerManager.addComponentModel(container, componentModel);
+ created = true;
+ }
+
+ setComponentPropertiesFromJson(componentModelData, componentModel);
+ componentRepo.save(componentModel);
+
+ if (created) {
+ return Response.created(
+ URI.create(
+ String.format(
+ "/page-models/%s/%s/%s/%s",
+ appName,
+ pageModelName,
+ containerKey,
+ componentKey
+ )
+ )
+ ).build();
+ } else {
+ return Response.ok(
+ String.format(
+ "Component %s of container %s of page model %s of "
+ + "application %s updated successfully.",
+ componentKey,
+ containerKey,
+ pageModelName,
+ appName
+ )
+ ).build();
+ }
+ }
+
+ /**
+ * Deletes a {@link ComponentModel}.
+ *
+ * @param appName The primary URL of the {@link CcmApplication}.
+ * @param pageModelName The name of the {@link PageModel}.
+ * @param containerKey The key of the {@link ContainerModel}.
+ * @param componentKey The key of the {@link ComponentModel} to delete.
+ *
+ * @return HTTP response for successful delete.
+ *
+ */
+ @DELETE
+ @Path("/{componentKey}")
+ @Transactional(Transactional.TxType.REQUIRED)
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ public Response deleteComponent(
+ @PathParam("appName") final String appName,
+ @PathParam("pageModelName") final String pageModelName,
+ @PathParam("containerKey") final String containerKey,
+ @PathParam("componentKey") final String componentKey
+ ) {
+ Objects.requireNonNull(appName);
+ Objects.requireNonNull(pageModelName);
+ Objects.requireNonNull(containerKey);
+ Objects.requireNonNull(componentKey);
+
+ final CcmApplication app = controller.findCcmApplication(
+ String.format("/%s/", appName)
+ );
+ final PageModel pageModel = controller.findPageModel(
+ app, pageModelName
+ );
+ final ContainerModel container = controller.findContainer(
+ app, pageModel, containerKey
+ );
+ final ComponentModel component = controller.findComponentModel(
+ app, pageModel, container, componentKey
+ );
+
+ containerManager.removeComponentModel(container, component);
+
+ return Response.ok(
+ String.format(
+ "Component %s successfully deleted from container %s "
+ + "of page model %s of application %s.",
+ componentKey,
+ containerKey,
+ pageModelName,
+ appName
+ )
+ ).build();
+ }
+
+ /**
+ * Helper method for mapping a {@link ComponentModel} to JSON.
+ *
+ * @param componentModel The {@link ComponentModel} to map.
+ *
+ * @return The JSON representation of the
+ * {@link ComponentModel} {@code componentModel}.
+ */
+ private JsonObject mapComponentModelToJson(
+ final ComponentModel componentModel) {
+
+ final Class extends ComponentModel> clazz = Objects
+ .requireNonNull(componentModel)
+ .getClass();
+
+ final ComponentModelJsonConverter jsonConverter
+ = findJsonConverter(clazz)
+ .orElseThrow(
+ () -> new WebApplicationException(
+ String.format(
+ "No JSON converter available for component "
+ + "model \"%s\".",
+ clazz.getName()
+ ),
+ Response.Status.INTERNAL_SERVER_ERROR
+ )
+ );
+
+ return jsonConverter.toJson(componentModel);
+ }
+
+ /**
+ * Creates a new {@link ComponentModel} instance.
+ *
+ * Uses reflection and the value of {@code type} property from the JSON
+ * {@code data} to determine the correct class.
+ *
+ * @param data The data from which the new {@link ComponentModel} is
+ * created.
+ *
+ * @return The new {@link ComponentModel}.
+ */
+ private ComponentModel createComponentModel(final JsonObject data) {
+
+ Objects.requireNonNull(data);
+
+ if (!data.containsKey("type")) {
+ throw new WebApplicationException(
+ "The JSON data for creating the "
+ + "component has no value for the type of the component to "
+ + "create.",
+ Response.Status.BAD_REQUEST
+ );
+ }
+
+ final String type = data.getString("type");
+ final Class extends ComponentModel> clazz = findComponentModelClass(
+ type
+ );
+
+ final ComponentModel componentModel;
+ try {
+ componentModel = clazz.getConstructor().newInstance();
+ } catch (IllegalAccessException
+ | InstantiationException
+ | InvocationTargetException
+ | NoSuchMethodException ex) {
+ throw new WebApplicationException(ex);
+ }
+
+ return componentModel;
+ }
+
+ /**
+ * Helper method for finding the correct subclass of {@link ComponentModel}
+ * using the fully qualified name the class.
+ *
+ * @param type The fully qualified name of the subclass of
+ * {@link ComponentModel}.
+ *
+ * @return The subclass of {@link ComponentModel}.
+ *
+ * @throws BadRequestException If there is no subclass of
+ * {@link ComponentModel} with the fully
+ * qualified name provided by the {@code type}
+ * parameter.
+ */
+ @SuppressWarnings("unchecked")
+ private Class extends ComponentModel> findComponentModelClass(
+ final String type
+ ) {
+ Objects.requireNonNull(type);
+
+ try {
+ final Class> clazz = Class.forName(type);
+
+ if (ComponentModel.class.isAssignableFrom(clazz)) {
+ return (Class extends ComponentModel>) clazz;
+ } else {
+ throw new WebApplicationException(
+ String.format(
+ "The type \"%s\" is not a subclass of \"%s\".",
+ type,
+ ComponentModel.class.getName()
+ ),
+ Response.Status.BAD_REQUEST
+ );
+ }
+ } catch (ClassNotFoundException ex) {
+ throw new WebApplicationException(
+ String.format(
+ "The component model type \"%s\" "
+ + "does not exist.",
+ type
+ ),
+ Response.Status.BAD_REQUEST
+ );
+ }
+ }
+
+ /**
+ * Helper method for setting the properties of a {@link ComponentModel} from
+ * the JSON data.
+ *
+ * @param data The JSON data.
+ * @param componentModel The {@link ComponentModel}.
+ */
+ private void setComponentPropertiesFromJson(
+ final JsonObject data,
+ final ComponentModel componentModel
+ ) {
+ final Class extends ComponentModel> clazz = Objects
+ .requireNonNull(componentModel)
+ .getClass();
+
+ final ComponentModelJsonConverter jsonConverter
+ = findJsonConverter(clazz)
+ .orElseThrow(
+ () -> new WebApplicationException(
+ String.format(
+ "No JSON converter available for component "
+ + "model \"%s\".",
+ clazz.getName()
+ ),
+ Response.Status.INTERNAL_SERVER_ERROR
+ )
+ );
+
+ jsonConverter.fromJson(data, componentModel);
+ }
+
+ private Optional
+ findJsonConverter(
+ final Class extends ComponentModel> componentModelClass
+ ) {
+
+ final ConvertsComponentModelLiteral literal
+ = new ConvertsComponentModelLiteral(
+ componentModelClass
+ );
+ final Instance instance = jsonConverters
+ .select(literal);
+ if (instance.isUnsatisfied()) {
+ return Optional.empty();
+ } else if (instance.isAmbiguous()) {
+ throw new WebApplicationException(
+ String.format(
+ "Multiple JSONConverter for \"%s\".",
+ componentModelClass.getName()
+ ),
+ Response.Status.INTERNAL_SERVER_ERROR
+ );
+ } else {
+ final Iterator iterator = instance
+ .iterator();
+ @SuppressWarnings("unchecked")
+ final ComponentModelJsonConverter converter = iterator.next();
+
+ return Optional.of(converter);
+ }
+ }
+
+ private static class ConvertsComponentModelLiteral
+ extends AnnotationLiteral
+ implements ConvertsComponentModel {
+
+ private static final long serialVersionUID = 1L;
+
+ private final Class extends ComponentModel> componentModel;
+
+ public ConvertsComponentModelLiteral(
+ final Class extends ComponentModel> componentModel
+ ) {
+ this.componentModel = componentModel;
+ }
+
+ @Override
+ public Class extends ComponentModel> componentModel() {
+ return componentModel;
+ }
+
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/Containers.java b/ccm-core/src/main/java/org/libreccm/api/pagemodels/Containers.java
similarity index 64%
rename from ccm-core/src/main/java/org/libreccm/pagemodel/rs/Containers.java
rename to ccm-core/src/main/java/org/libreccm/api/pagemodels/Containers.java
index 437f44b04..169e2d249 100644
--- a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/Containers.java
+++ b/ccm-core/src/main/java/org/libreccm/api/pagemodels/Containers.java
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.pagemodel.rs;
+package org.libreccm.api.pagemodels;
import org.libreccm.core.CoreConstants;
import org.libreccm.pagemodel.ContainerModel;
@@ -27,6 +27,7 @@ import org.libreccm.security.AuthorizationRequired;
import org.libreccm.security.RequiresPrivilege;
import org.libreccm.web.CcmApplication;
+import java.net.URI;
import java.util.Optional;
import javax.enterprise.context.RequestScoped;
@@ -43,6 +44,8 @@ import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
/**
* Provides RESTful endpoints for managing the {@link ContainerModel}s of a
@@ -51,7 +54,7 @@ import javax.ws.rs.Produces;
* @author Jens Pelzetter
*/
@RequestScoped
-@Path("/")
+@Path("/{appName}/{pageModelName}/containers")
public class Containers {
@Inject
@@ -66,7 +69,7 @@ public class Containers {
/**
* Retrieves all {@link ContainerModel}s of a {@link PageModel}.
*
- * @param appPath The primary URL of the {@link CcmApplication} to
+ * @param appName The primary URL of the {@link CcmApplication} to
* which the {@link PageModel} belongs.
* @param pageModelName The name of the {@link PageModel} of which the
* containers are retrieved.
@@ -76,20 +79,22 @@ public class Containers {
* the {@link CcmApplication} with the primary URL {@code appPath}.
*/
@GET
- @Path(PageModelsApp.CONTAINERS_PATH)
- @Produces("application/json; charset=utf-8")
+ @Path("/")
+ @Produces(MediaType.APPLICATION_JSON)
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
public JsonArray getContainers(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName) {
-
+ @PathParam("appName") final String appName,
+ @PathParam("pageModelName") final String pageModelName
+ ) {
final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
+ String.format("/%s/", appName)
+ );
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
+ final PageModel pageModel = controller.findPageModel(
+ app, pageModelName
+ );
final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
pageModel
@@ -104,7 +109,7 @@ public class Containers {
/**
* Retrieve a specific {@link ContainerModel}.
*
- * @param appPath The primary URL of the {@link CcmApplication} to
+ * @param appName The primary URL of the {@link CcmApplication} to
* which the {@link PageModel} belongs.
* @param pageModelName The name of the {@link PageModel} to which the
* {@link ContainerModel} belongs.
@@ -114,25 +119,27 @@ public class Containers {
* @return A JSON object containing the data of the {@link PageModel}.
*/
@GET
- @Path(PageModelsApp.CONTAINER_PATH)
- @Produces("application/json; charset=utf-8")
+ @Path("/{containerKey}")
+ @Produces(MediaType.APPLICATION_JSON)
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
public JsonObject getContainer(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey) {
-
+ @PathParam("appName") final String appName,
+ @PathParam("pageModelName") final String pageModelName,
+ @PathParam("containerKey") final String containerKey
+ ) {
final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
+ String.format("/%s/", appName)
+ );
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
+ final PageModel pageModel = controller.findPageModel(
+ app, pageModelName
+ );
- final ContainerModel container = controller.findContainer(app,
- pageModel,
- containerKey);
+ final ContainerModel container = controller.findContainer(
+ app, pageModel, containerKey
+ );
return mapContainerModelToJson(container);
}
@@ -147,32 +154,36 @@ public class Containers {
* If there is no such {@link ContainerModel} a new {@link ContainerModel}
* is created using the data provided by {@code containerModelData}.
*
- * @param appPath The path of the {@link CcmApplication}.
+ * @param appName The path of the {@link CcmApplication}.
* @param pageModelName The name of the {@link PageModel}.
* @param containerKey The key identifying the {@link ContainerModel}.
* @param containerModelData The data for updating or creating the
* {@link ContainerModel}.
*
- * @return The new or updated {@link ContainerModel}.
+ * @return A HTTP response with the status code {@code 200} if the container
+ * model was updated or {@code 201} if the container model was
+ * created. If the container model was created the response also
+ * contains the URI of the new container model.
*/
@PUT
- @Path(PageModelsApp.CONTAINER_PATH)
- @Consumes("application/json; charset=utf-8")
- @Produces("application/json; charset=utf-8")
+ @Path("/{containerKey}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject putContainer(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- final JsonObject containerModelData) {
-
+ public Response putContainer(
+ @PathParam("appName") final String appName,
+ @PathParam("pageModelName") final String pageModelName,
+ @PathParam("containerKey") final String containerKey,
+ final JsonObject containerModelData
+ ) {
final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
-
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
+ String.format("/%s/", appName)
+ );
+ final PageModel pageModel = controller.findPageModel(
+ app, pageModelName
+ );
final Optional result = pageModel
.getContainers()
@@ -181,52 +192,90 @@ public class Containers {
.findAny();
final ContainerModel containerModel;
+ final boolean created;
if (result.isPresent()) {
-
containerModel = result.get();
- result.get().setKey(containerKey);
- containerModelRepo.save(result.get());
+ containerModel.setKey(containerKey);
+ containerModelRepo.save(containerModel);
+ created = false;
} else {
-
containerModel = new ContainerModel();
containerModel.setKey(containerKey);
pageModelManager.addContainerModel(pageModel, containerModel);
+ created = true;
}
- return mapContainerModelToJson(containerModel);
+ if (created) {
+ return Response.created(
+ URI.create(
+ String.format(
+ "/page-models/%s/%s/containers/%s",
+ appName,
+ pageModelName,
+ containerKey
+ )
+ )
+ ).build();
+ } else {
+ return Response.ok(
+ String.format(
+ "Container model %s of page model %s of application %s "
+ + "updated successfully.",
+ containerKey,
+ pageModelName,
+ appName
+ )
+ ).build();
+ }
}
/**
* Deletes the {@link ContainerModel} identified by the provided parameters.
*
- * @param appPath The path of the {@link CcmApplication}.
+ * @param appName The path of the {@link CcmApplication}.
* @param pageModelName The name of the {@link PageModel}.
* @param containerKey The key identifying the {@link ContainerModel} to
* delete.
+ *
+ * @return A HTTP response with the status code {@code 200} if the container
+ * model was deleted successfully.
*/
@DELETE
- @Path(PageModelsApp.CONTAINER_PATH)
+ @Path("/{containerKey}")
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public void deleteContainer(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey) {
+ public Response deleteContainer(
+ @PathParam("appName") final String appName,
+ @PathParam("pageModelName") final String pageModelName,
+ @PathParam("containerKey") final String containerKey
+ ) {
final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
+ String.format("/%s/", appName)
+ );
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
+ final PageModel pageModel = controller.findPageModel(
+ app, pageModelName
+ );
- final ContainerModel container = controller.findContainer(app,
- pageModel,
- containerKey);
+ final ContainerModel container = controller.findContainer(
+ app, pageModel, containerKey
+ );
pageModelManager.removeContainerModel(pageModel, container);
+
+ return Response.ok(
+ String.format(
+ "Container model %s of page model %s of application %s deleted"
+ + "successfully.",
+ containerKey,
+ pageModelName,
+ appName
+ )
+ ).build();
}
/**
diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/PageModels.java b/ccm-core/src/main/java/org/libreccm/api/pagemodels/PageModels.java
similarity index 62%
rename from ccm-core/src/main/java/org/libreccm/pagemodel/rs/PageModels.java
rename to ccm-core/src/main/java/org/libreccm/api/pagemodels/PageModels.java
index d242ee713..7a7540542 100644
--- a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/PageModels.java
+++ b/ccm-core/src/main/java/org/libreccm/api/pagemodels/PageModels.java
@@ -16,14 +16,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.pagemodel.rs;
+package org.libreccm.api.pagemodels;
import com.arsdigita.kernel.KernelConfig;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.core.CoreConstants;
import org.libreccm.l10n.GlobalizationHelper;
-import org.libreccm.pagemodel.ComponentModel;
import org.libreccm.pagemodel.ContainerModel;
import org.libreccm.pagemodel.PageModel;
import org.libreccm.pagemodel.PageModelManager;
@@ -32,6 +31,8 @@ import org.libreccm.security.AuthorizationRequired;
import org.libreccm.security.RequiresPrivilege;
import org.libreccm.web.CcmApplication;
+import java.net.URI;
+
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.json.Json;
@@ -50,11 +51,11 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
-import java.util.Date;
-import java.util.List;
import java.util.Objects;
import java.util.Optional;
-import java.util.stream.Collectors;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
/**
* Provides RESTful endpoints for retrieving, creating, updating and deleting
@@ -63,7 +64,7 @@ import java.util.stream.Collectors;
* @author Jens Pelzetter
*/
@RequestScoped
-@Path("/")
+@Path("/{appName}")
public class PageModels {
@Inject
@@ -85,29 +86,29 @@ public class PageModels {
* Retrieves all {@link PageModel}s available for an {@link
* CcmApplication}.
*
- * @param appPath The path of the {@code app}.
+ * @param appName The path of the {@code app}.
*
* @return A JSON array with the data of all {@link PageModel}s of the
- * {@link CcmApplication} {@code app}.
+ * {@link CcmApplication} {@code app}.
*
* @throws NotFoundException If there is no {@link CcmApplication} with the
* primary URL {@code appPath} an {@link
- * NotFoundException} thrown resulting in 404
- * response.
+ * NotFoundException} thrown resulting in 404 response.
*/
@GET
- @Path(PageModelsApp.PAGE_MODELS_PATH)
- @Produces("application/json; charset=utf-8")
+ @Path("/")
+ @Produces(MediaType.APPLICATION_JSON)
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
public JsonArray getAllPageModels(
- @PathParam(PageModelsApp.APP_NAME) String appPath) {
+ @PathParam("appName") String appName
+ ) {
+ Objects.requireNonNull(appName);
- Objects.requireNonNull(appPath);
-
- final CcmApplication app = controller
- .findCcmApplication(String.format("/%s/", appPath));
+ final CcmApplication app = controller.findCcmApplication(
+ String.format("/%s/", appName)
+ );
final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
pageModelRepo
.findDraftByApplication(app)
@@ -121,65 +122,73 @@ public class PageModels {
/**
* Retrieves a specific {@link PageModel}.
*
- * @param appPath The path ({@link CcmApplication#primaryUrl} of the
+ * @param appName The path ({@link CcmApplication#primaryUrl} of the
* {@link CcmApplication} to which the {@link
- * PageModel} belongs (see
- * {@link PageModel#application}).
+ * PageModel} belongs (see {@link PageModel#application}).
* @param pageModelName The name of the {@link PageModel} to retrieve (see
* {@link PageModel#name}).
*
* @return A JSON object containing the data of the {@link PageModel}.
*
* @throws NotFoundException If there is not {@link CcmApplication} with the
- * primary URL {@code appPath} a {@link
- * NotFoundException} is thrown resulting in a 404
- * response. A {@link NotFoundException} is also
- * thrown if there no {@link PageModel} identified
- * by {@code pageModelName} for the {@link
- * CcmApplication} with the primary URL {@code
- * appPath}.
+ * primary URL {@code appPath} a
+ * {@link NotFoundException} is thrown resulting
+ * in a 404 response. A {@link NotFoundException}
+ * is also thrown if there no {@link PageModel}
+ * identified by {@code pageModelName} for the
+ * {@link CcmApplication} with the primary URL
+ * {@code appPath}.
*/
@GET
- @Path(PageModelsApp.PAGE_MODEL_PATH)
- @Produces("application/json; charset=utf-8")
+ @Path("/{pageModelName}")
+ @Produces(MediaType.APPLICATION_JSON)
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
public JsonObject getPageModel(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName) {
-
- Objects.requireNonNull(appPath);
+ @PathParam("appName") final String appName,
+ @PathParam("pageModelName") final String pageModelName
+ ) {
+ Objects.requireNonNull(appName);
Objects.requireNonNull(pageModelName);
- final CcmApplication app = controller
- .findCcmApplication(String.format("/%s/", appPath));
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
+ final CcmApplication app = controller.findCcmApplication(
+ String.format("/%s/", appName)
+ );
+ final PageModel pageModel = controller.findPageModel(
+ app, pageModelName
+ );
return mapPageModelToJson(pageModel);
}
@POST
- @Path(PageModelsApp.PAGE_MODEL_PATH)
- @Produces("application/json; charset=utf-8")
+ @Path("/{pageModelName}")
+ @Produces(MediaType.APPLICATION_JSON)
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject publishPageModel(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @FormParam("action") String action) {
-
+ public Response publishPageModel(
+ @PathParam("appName") final String appName,
+ @PathParam("pageModelName") final String pageModelName,
+ @FormParam("action") String action
+ ) {
if ("publish".equals(action)) {
-
- final CcmApplication app = controller
- .findCcmApplication(String.format("/%s/", appPath));
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
+ final CcmApplication app = controller.findCcmApplication(
+ String.format("/%s/", appName)
+ );
+ final PageModel pageModel = controller.findPageModel(
+ app, pageModelName
+ );
pageModelManager.publish(pageModel);
}
- return getPageModel(appPath, pageModelName);
+ return Response.ok(
+ String.format(
+ "Page model %s of application %s successfully published.",
+ pageModelName,
+ appName
+ )
+ ).build();
}
/**
@@ -191,82 +200,123 @@ public class PageModels {
* {@link PageModel} is created and associated with the {@link
* CcmApplication} identified by the primary URL {@code appPath}.
*
- * @param appPath The primary URL of the {@link CcmApplication} to
+ * @param appName The primary URL of the {@link CcmApplication} to
* which the {@link PageModel} belongs.
* @param pageModelName The name of the {@link PageModel}.
* @param pageModelData The data for creating or updating the {@link
* PageModel}.
*
- * @return The new or updated {@link PageModel}.
+ * @return A HTTP response with status code {@code 200} if the page model
+ * was updated successfully or with status code {@code 201} if the
+ * page model was successfully created. If the page model was
+ * created the response also contains the URI of the new page model.
*/
@PUT
- @Path(PageModelsApp.PAGE_MODEL_PATH)
- @Consumes("application/json; charset=utf-8")
- @Produces("application/json; charset=utf-8")
+ @Path("/{pageModelName}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject putPageModel(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- final JsonObject pageModelData) {
-
- Objects.requireNonNull(appPath);
+ public Response putPageModel(
+ @PathParam("appName") final String appName,
+ @PathParam("pageModelName") final String pageModelName,
+ final JsonObject pageModelData
+ ) {
+ Objects.requireNonNull(appName);
Objects.requireNonNull(pageModelName);
- final CcmApplication app = controller
- .findCcmApplication(String.format("/%s/", appPath));
+ final CcmApplication app = controller.findCcmApplication(
+ String.format("/%s/", appName)
+ );
final KernelConfig kernelConfig = confManager
.findConfiguration(KernelConfig.class);
final PageModel pageModel;
+ final boolean created;
if (controller.existsPageModel(app, pageModelName)) {
pageModel = controller.findPageModel(app, pageModelName);
-
+ created = false;
} else {
pageModel = pageModelManager.createPageModel(pageModelName, app);
+ created = true;
}
if (pageModelData.containsKey("title")) {
- pageModel.getTitle().addValue(kernelConfig.getDefaultLocale(),
- pageModelData.getString("title"));
+ pageModel.getTitle().addValue(
+ kernelConfig.getDefaultLocale(),
+ pageModelData.getString("title")
+ );
}
if (pageModelData.containsKey("description")) {
pageModel
.getDescription()
- .addValue(kernelConfig.getDefaultLocale(),
- pageModelData.getString("description"));
+ .addValue(
+ kernelConfig.getDefaultLocale(),
+ pageModelData.getString("description")
+ );
}
controller.savePageModel(pageModel);
- return mapPageModelToJson(pageModel);
+ if (created) {
+ return Response.created(
+ URI.create(
+ String.format(
+ "/page-models/%s/%s",
+ appName,
+ pageModelName
+ )
+ )
+ ).build();
+ } else {
+ return Response.ok(
+ String.format(
+ "Page model %s of application %s updated successfully",
+ pageModelName,
+ appName
+ )
+ ).build();
+ }
}
/**
* Deletes a {@link PageModel}.
*
- * @param appPath The primary URL of the {@link CcmApplication} to
+ * @param appName The primary URL of the {@link CcmApplication} to
* which the {@link PageModel} belongs.
* @param pageModelName The name of the {@link PageModel} to delete.
+ *
+ * @return A HTTP response with status code {@code 200} if the page model
+ * was deleted sucessfully.
*/
@DELETE
- @Path(PageModelsApp.PAGE_MODEL_PATH)
+ @Path("/{appName}/{pageModelName}")
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public void deletePageModel(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName) {
-
- Objects.requireNonNull(appPath);
+ public Response deletePageModel(
+ @PathParam("appName") final String appName,
+ @PathParam("pageModelName") final String pageModelName
+ ) {
+ Objects.requireNonNull(appName);
Objects.requireNonNull(pageModelName);
- final CcmApplication app = controller
- .findCcmApplication(String.format("/%s/", appPath));
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
+ final CcmApplication app = controller.findCcmApplication(
+ String.format("/%s/", appName)
+ );
+ final PageModel pageModel = controller.findPageModel(
+ app, pageModelName
+ );
pageModelRepo.delete(pageModel);
+
+ return Response.ok(
+ String.format(
+ "Page model %s of application %s deleted successfully.",
+ pageModelName,
+ appName
+ )
+ ).build();
}
/**
@@ -282,10 +332,11 @@ public class PageModels {
Objects.requireNonNull(pageModel);
final long lastPublished;
- final Optional liveModel = pageModelManager
- .getLiveVersion(pageModel);
+ final Optional liveModel = pageModelManager.getLiveVersion(
+ pageModel
+ );
if (liveModel.isPresent()
- && liveModel.get().getLastModified() != null) {
+ && liveModel.get().getLastModified() != null) {
lastPublished = liveModel.get().getLastModified().getTime();
} else {
lastPublished = 0;
@@ -300,27 +351,33 @@ public class PageModels {
return Json
.createObjectBuilder()
.add("containers", mapContainersToJson(pageModel))
- .add("description",
- globalizationHelper
- .getValueFromLocalizedString(pageModel.getDescription()))
+ .add(
+ "description",
+ globalizationHelper.getValueFromLocalizedString(
+ pageModel.getDescription()
+ )
+ )
.add("modelUuid", pageModel.getModelUuid())
.add("name", pageModel.getName())
.add("pageModelId", Long.toString(pageModel.getPageModelId()))
- .add("title",
- globalizationHelper
- .getValueFromLocalizedString(pageModel.getTitle()))
+ .add(
+ "title",
+ globalizationHelper.getValueFromLocalizedString(
+ pageModel.getTitle()
+ )
+ )
.add("type", pageModel.getType())
.add("uuid", pageModel.getUuid())
.add("version", pageModel.getVersion().toString())
.add("publicationStatus",
- getPublicationStatus(pageModel).toString())
+ getPublicationStatus(pageModel).toString()
+ )
.add("lastModified", lastModified)
.add("lastPublished", lastPublished)
.build();
}
private JsonArray mapContainersToJson(final PageModel pageModel) {
-
final JsonArrayBuilder containers = Json.createArrayBuilder();
pageModel
@@ -333,7 +390,6 @@ public class PageModels {
}
private JsonObject mapContainerToJson(final ContainerModel container) {
-
return Json
.createObjectBuilder()
.add("containerUuid", container.getContainerUuid())
@@ -341,7 +397,7 @@ public class PageModels {
.add("uuid", container.getUuid())
.build();
}
-
+
/**
* Check if the {@link PublicationStatus} of the provided PageModel.
*
@@ -350,7 +406,6 @@ public class PageModels {
* @return
*/
private PublicationStatus getPublicationStatus(final PageModel pageModel) {
-
final PageModel draftModel = pageModelManager
.getDraftVersion(pageModel);
final Optional liveModel = pageModelManager
@@ -361,7 +416,7 @@ public class PageModels {
// Fallback if one the last modified dates is null
if (draftModel.getLastModified() == null
- || liveModel.get().getLastModified() == null) {
+ || liveModel.get().getLastModified() == null) {
return PublicationStatus.NEEDS_UPDATE;
} else if (draftModel
diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/PageModelsApp.java b/ccm-core/src/main/java/org/libreccm/api/pagemodels/PageModelsApp.java
similarity index 53%
rename from ccm-core/src/main/java/org/libreccm/pagemodel/rs/PageModelsApp.java
rename to ccm-core/src/main/java/org/libreccm/api/pagemodels/PageModelsApp.java
index 82e4e0e72..e1c431a77 100644
--- a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/PageModelsApp.java
+++ b/ccm-core/src/main/java/org/libreccm/api/pagemodels/PageModelsApp.java
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.pagemodel.rs;
+package org.libreccm.api.pagemodels;
import org.libreccm.pagemodel.PageModel;
@@ -42,34 +42,9 @@ import javax.ws.rs.core.Application;
*
* @author Jens Pelzetter
*/
-@ApplicationPath("/page-models")
+@ApplicationPath("/api/page-models")
public class PageModelsApp extends Application {
- protected static final String APP_NAME = "appName";
- protected static final String PAGE_MODEL_NAME = "pageModelName";
- protected static final String CONTAINER_KEY = "containerKey";
- protected static final String COMPONENT_KEY = "componentKey";
-
- protected static final String PAGE_MODELS_PATH = "/{" + APP_NAME + "}";
- protected static final String PAGE_MODEL_PATH = PAGE_MODELS_PATH
- + "/{"
- + PAGE_MODEL_NAME
- + "}";
- protected static final String CONTAINERS_PATH = PAGE_MODEL_PATH
- + "/containers";
- protected static final String CONTAINER_PATH = CONTAINERS_PATH
- + "/{"
- + CONTAINER_KEY
- + "}";
- protected static final String COMPONENTS_PATH = CONTAINER_PATH
- + "/components";
- protected static final String COMPONENT_PATH = COMPONENTS_PATH
- + "/{"
- + COMPONENT_KEY
- + "}";
-
- protected static final String STYLES_PATH = CONTAINER_PATH + "/styles";
-
@Override
public Set> getClasses() {
@@ -77,9 +52,6 @@ public class PageModelsApp extends Application {
classes.add(PageModels.class);
classes.add(Containers.class);
classes.add(Components.class);
- classes.add(StylesRs.class);
- classes.add(StylesMediaRule.class);
- classes.add(StylesRule.class);
return classes;
}
diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/PageModelsController.java b/ccm-core/src/main/java/org/libreccm/api/pagemodels/PageModelsController.java
similarity index 72%
rename from ccm-core/src/main/java/org/libreccm/pagemodel/rs/PageModelsController.java
rename to ccm-core/src/main/java/org/libreccm/api/pagemodels/PageModelsController.java
index eb35d69ed..7728a7ba7 100644
--- a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/PageModelsController.java
+++ b/ccm-core/src/main/java/org/libreccm/api/pagemodels/PageModelsController.java
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.pagemodel.rs;
+package org.libreccm.api.pagemodels;
import org.libreccm.pagemodel.ComponentModel;
import org.libreccm.pagemodel.ComponentModelRepository;
@@ -67,9 +67,12 @@ class PageModelsController {
return appRepo
.retrieveApplicationForPath(Objects.requireNonNull(appPath))
- .orElseThrow(() -> new NotFoundException(String
- .format("No application with path \"%s\" found.",
- appPath)));
+ .orElseThrow(() -> new NotFoundException(
+ String.format(
+ "No application with path \"%s\" found.",
+ appPath)
+ )
+ );
}
/**
@@ -88,18 +91,23 @@ class PageModelsController {
final CcmApplication app,
final PageModel pageModel,
final ContainerModel containerModel,
- final String componentKey) {
-
+ final String componentKey
+ ) {
return componentModelRepo
.findComponentByContainerAndKey(containerModel, componentKey)
- .orElseThrow(() -> new NotFoundException(String
- .format(
- "The Container \"%s\" of the PageModel \"%s\" of application"
- + "\"%s\" does not contain a component with the key \"%s\".",
- containerModel.getKey(),
- pageModel.getName(),
- app.getPrimaryUrl(),
- componentKey)));
+ .orElseThrow(
+ () -> new NotFoundException(
+ String.format(
+ "The Container \"%s\" of the PageModel \"%s\" of"
+ + " application \"%s\" does not contain a "
+ + "component with the key \"%s\".",
+ containerModel.getKey(),
+ pageModel.getName(),
+ app.getPrimaryUrl(),
+ componentKey
+ )
+ )
+ );
}
/**
@@ -113,20 +121,26 @@ class PageModelsController {
* {@code containerKey}.
*/
@Transactional(Transactional.TxType.REQUIRED)
- protected ContainerModel findContainer(final CcmApplication app,
- final PageModel pageModel,
- final String containerKey) {
+ protected ContainerModel findContainer(
+ final CcmApplication app,
+ final PageModel pageModel,
+ final String containerKey
+ ) {
return containerRepo
.findContainerByKeyAndPageModel(
Objects.requireNonNull(containerKey),
Objects.requireNonNull(pageModel))
- .orElseThrow(() -> new NotFoundException(String
- .format("The PageModel \"%s\" of application \"%s\" does not have "
- + "a container identified by the key \"%s\".",
- pageModel.getName(),
- app.getPrimaryUrl(),
- containerKey)));
+ .orElseThrow(
+ () -> new NotFoundException(
+ String.format(
+ "The PageModel \"%s\" of application \"%s\" does not "
+ + "have a container identified by the key \"%s\".",
+ pageModel.getName(),
+ app.getPrimaryUrl(),
+ containerKey)
+ )
+ );
}
/**
@@ -142,8 +156,9 @@ class PageModelsController {
* {@link CcmApplication} {@code app}, {@code false} otherwise.
*/
@Transactional(Transactional.TxType.REQUIRED)
- protected boolean existsPageModel(final CcmApplication app,
- final String pageModelName) {
+ protected boolean existsPageModel(
+ final CcmApplication app, final String pageModelName
+ ) {
return pageModelRepo
.findDraftByApplicationAndName(app, pageModelName)
.isPresent();
@@ -160,16 +175,22 @@ class PageModelsController {
* {@code pageModelName} for the {@link CcmApplication} {@code app}.
*/
@Transactional(Transactional.TxType.REQUIRED)
- protected PageModel findPageModel(final CcmApplication app,
- final String pageModelName) {
-
+ protected PageModel findPageModel(
+ final CcmApplication app, final String pageModelName
+ ) {
return pageModelRepo
.findDraftByApplicationAndName(
Objects.requireNonNull(app),
- Objects.requireNonNull(pageModelName))
- .orElseThrow(() -> new NotFoundException(String.format(
- "No PageModel with name \"%s\" for application \"%s\".",
- pageModelName, app.getPrimaryUrl())));
+ Objects.requireNonNull(pageModelName)
+ )
+ .orElseThrow(
+ () -> new NotFoundException(
+ String.format(
+ "No PageModel with name \"%s\" for application \"%s\".",
+ pageModelName, app.getPrimaryUrl()
+ )
+ )
+ );
}
@Transactional(Transactional.TxType.REQUIRED)
diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/PublicationStatus.java b/ccm-core/src/main/java/org/libreccm/api/pagemodels/PublicationStatus.java
similarity index 70%
rename from ccm-core/src/main/java/org/libreccm/pagemodel/rs/PublicationStatus.java
rename to ccm-core/src/main/java/org/libreccm/api/pagemodels/PublicationStatus.java
index ce1b19b15..9f79997ea 100644
--- a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/PublicationStatus.java
+++ b/ccm-core/src/main/java/org/libreccm/api/pagemodels/PublicationStatus.java
@@ -1,4 +1,4 @@
-package org.libreccm.pagemodel.rs;
+package org.libreccm.api.pagemodels;
public enum PublicationStatus {
diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/package-info.java b/ccm-core/src/main/java/org/libreccm/api/pagemodels/package-info.java
similarity index 96%
rename from ccm-core/src/main/java/org/libreccm/pagemodel/rs/package-info.java
rename to ccm-core/src/main/java/org/libreccm/api/pagemodels/package-info.java
index a18589a62..b64ebcd66 100644
--- a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/package-info.java
+++ b/ccm-core/src/main/java/org/libreccm/api/pagemodels/package-info.java
@@ -22,4 +22,4 @@
* editors.
*
*/
-package org.libreccm.pagemodel.rs;
+package org.libreccm.api.pagemodels;
diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/Components.java b/ccm-core/src/main/java/org/libreccm/pagemodel/rs/Components.java
deleted file mode 100644
index e8a1a5d84..000000000
--- a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/Components.java
+++ /dev/null
@@ -1,627 +0,0 @@
-/*
- * Copyright (C) 2018 LibreCCM Foundation.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-package org.libreccm.pagemodel.rs;
-
-import org.libreccm.core.CoreConstants;
-import org.libreccm.pagemodel.ComponentModel;
-import org.libreccm.pagemodel.ComponentModelJsonConverter;
-import org.libreccm.pagemodel.ComponentModelRepository;
-import org.libreccm.pagemodel.ContainerModel;
-import org.libreccm.pagemodel.ContainerModelManager;
-import org.libreccm.pagemodel.ConvertsComponentModel;
-import org.libreccm.pagemodel.PageModel;
-import org.libreccm.security.AuthorizationRequired;
-import org.libreccm.security.RequiresPrivilege;
-import org.libreccm.web.CcmApplication;
-
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
-import javax.enterprise.context.RequestScoped;
-import javax.enterprise.inject.Any;
-import javax.enterprise.inject.Instance;
-import javax.enterprise.util.AnnotationLiteral;
-import javax.inject.Inject;
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObject;
-import javax.json.JsonValue;
-import javax.transaction.Transactional;
-import javax.ws.rs.BadRequestException;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-
-/**
- * Provides RESTful endpoints for retrieving, creating, updating and deleting
- * {@link ComponentModel}s of a {@link ContainerModel}.
- *
- * @author Jens Pelzetter
- */
-@RequestScoped
-@Path("/")
-public class Components {
-
- @Inject
- private ComponentModelRepository componentRepo;
-
- @Inject
- private ContainerModelManager containerManager;
-
- @Inject
- private PageModelsController controller;
-
- @Inject
- @Any
- private Instance jsonConverters;
-
- /**
- * Retrieve all {@link ComponentModel} of a {@link ContainerModel}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- *
- * @return A JSON array containing the data of all {@link ComponentModel} of
- * the {@link ContainerModel}.
- */
- @GET
- @Path(PageModelsApp.COMPONENTS_PATH)
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonArray getComponents(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
-
- final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
- final ContainerModel container = controller.findContainer(app,
- pageModel,
- containerKey);
-
- final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
- container
- .getComponents()
- .stream()
- .map(component -> mapComponentModelToJson(component))
- .forEach(arrayBuilder::add);
-
- return arrayBuilder.build();
- }
-
- /**
- * Retrieves a specific {@link ComponentModel}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- * @param componentKey The key of the {@link ComponentModel}.
- *
- * @return A JSON object containing the data of the {@link ComponentModel}.
- */
- @GET
- @Path(PageModelsApp.COMPONENT_PATH)
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject getComponent(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(PageModelsApp.COMPONENT_KEY) final String componentKey) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(componentKey);
-
- final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
- final ContainerModel container = controller.findContainer(app,
- pageModel,
- containerKey);
- final ComponentModel component = controller
- .findComponentModel(app, pageModel, container, componentKey);
-
- return mapComponentModelToJson(component);
- }
-
- /**
- * Creates or updates a {@link ComponentModel}.
- *
- * If a {@link ComponentModel} with provided {@code componentKey} already
- * exists in the container identified by {@code appPath},
- * {@code pageModelName} and {@code containerKey} the {@link ComponentModel}
- * is updated with the data from {@code componentModelData}.
- *
- * Otherwise a new {@link ComponentModel} is created using the data from
- * {@code componentModelData}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- * @param componentKey The key of the {@link ComponentModel} to create
- * or update.
- * @param componentModelData The data for creating or updating the
- * {@link ComponentModel}.
- *
- * @return The new or updated {@link ComponentModel}.
- */
- @PUT
- @Path(PageModelsApp.COMPONENT_PATH)
- @Consumes("application/json; charset=utf-8")
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject putComponent(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(PageModelsApp.COMPONENT_KEY) final String componentKey,
- final JsonObject componentModelData) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(componentKey);
- Objects.requireNonNull(componentModelData);
-
- final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
- final ContainerModel container = controller.findContainer(app,
- pageModel,
- containerKey);
-
- final Optional result = container
- .getComponents()
- .stream()
- .filter(c -> c.getKey().equals(componentKey))
- .findAny();
-
- final ComponentModel componentModel;
- if (result.isPresent()) {
-
- componentModel = result.get();
-
- } else {
-
- componentModel = createComponentModel(componentModelData);
- componentModel.setKey(componentKey);
- containerManager.addComponentModel(container, componentModel);
- }
-
- setComponentPropertiesFromJson(componentModelData, componentModel);
-
- componentRepo.save(componentModel);
-
- final ComponentModel saved = controller
- .findComponentModel(app, pageModel, container, componentKey);
- return mapComponentModelToJson(saved);
- }
-
- /**
- * Deletes a {@link ComponentModel}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- * @param componentKey The key of the {@link ComponentModel} to delete.
- *
- */
- @DELETE
- @Path(PageModelsApp.COMPONENT_PATH)
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public void deleteComponent(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(PageModelsApp.COMPONENT_KEY) final String componentKey) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(componentKey);
-
- final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
- final ContainerModel container = controller.findContainer(app,
- pageModel,
- containerKey);
- final ComponentModel component = controller
- .findComponentModel(app, pageModel, container, componentKey);
-
- containerManager.removeComponentModel(container, component);
- }
-
- /**
- * Helper method for mapping a {@link ComponentModel} to JSON.
- *
- * @param componentModel The {@link ComponentModel} to map.
- *
- * @return The JSON representation of the
- * {@link ComponentModel} {@code componentModel}.
- */
- private JsonObject mapComponentModelToJson(
- final ComponentModel componentModel) {
-
- final Class extends ComponentModel> clazz = Objects
- .requireNonNull(componentModel)
- .getClass();
-
- final ComponentModelJsonConverter jsonConverter
- = findJsonConverter(clazz)
- .orElseThrow(() -> new WebApplicationException(String.format(
- "No JSON converter available for component model \"%s\".",
- clazz.getName())));
-
- return jsonConverter.toJson(componentModel);
-
-// Objects.requireNonNull(componentModel);
-//
-// final JsonObjectBuilder objectBuilder = Json
-// .createObjectBuilder()
-// .add("componentModelId",
-// Long.toString(componentModel.getComponentModelId()))
-// .add("uuid", componentModel.getUuid())
-// .add("modelUuid", componentModel.getModelUuid())
-// .add("key", componentModel.getKey())
-// .add("type", componentModel.getClass().getName());
-//
-// if (componentModel.getIdAttribute() != null) {
-// objectBuilder.add("idAttribute", componentModel.getIdAttribute());
-// }
-//
-// if (componentModel.getClassAttribute() != null) {
-// objectBuilder.add("classAttribute",
-// componentModel.getClassAttribute());
-// }
-//
-// if (componentModel.getStyleAttribute() != null) {
-// objectBuilder.add("styleAttribute",
-// componentModel.getStyleAttribute());
-// }
-//
-// final Class extends ComponentModel> clazz = componentModel.getClass();
-// final BeanInfo beanInfo;
-// try {
-// beanInfo = Introspector.getBeanInfo(clazz);
-// } catch (IntrospectionException ex) {
-// throw new WebApplicationException(ex);
-// }
-//
-// for (final PropertyDescriptor propertyDescriptor
-// : beanInfo.getPropertyDescriptors()) {
-//
-// final Method readMethod = propertyDescriptor.getReadMethod();
-// final Object value;
-// try {
-// value = readMethod.invoke(componentModel);
-// } catch (IllegalAccessException
-// | InvocationTargetException ex) {
-// throw new WebApplicationException(ex);
-// }
-//
-// final String valueStr;
-// if (value == null) {
-// valueStr = "";
-// } else {
-// valueStr = value.toString();
-// }
-//
-// objectBuilder.add(propertyDescriptor.getName(), valueStr);
-//
-// }
-//
-// return objectBuilder.build();
- }
-
- /**
- * Creates a new {@link ComponentModel} instance.
- *
- * Uses reflection and the value of {@code type} property from the JSON
- * {@code data} to determine the correct class.
- *
- * @param data The data from which the new {@link ComponentModel} is
- * created.
- *
- * @return The new {@link ComponentModel}.
- */
- private ComponentModel createComponentModel(final JsonObject data) {
-
- Objects.requireNonNull(data);
-
- if (!data.containsKey("type")) {
- throw new BadRequestException("The JSON data for creating the "
- + "component has no value for the type of the component to "
- + "create.");
- }
-
- final String type = data.getString("type");
- final Class extends ComponentModel> clazz = findComponentModelClass(
- type);
-
- final ComponentModel componentModel;
- try {
- componentModel = clazz.getConstructor().newInstance();
- } catch (IllegalAccessException
- | InstantiationException
- | InvocationTargetException
- | NoSuchMethodException ex) {
- throw new WebApplicationException(ex);
- }
-
- return componentModel;
- }
-
- /**
- * Helper method for finding the correct subclass of {@link ComponentModel}
- * using the fully qualified name the class.
- *
- * @param type The fully qualified name of the subclass of
- * {@link ComponentModel}.
- *
- * @return The subclass of {@link ComponentModel}.
- *
- * @throws BadRequestException If there is no subclass of
- * {@link ComponentModel} with the fully
- * qualified name provided by the {@code type}
- * parameter.
- */
- @SuppressWarnings("unchecked")
- private Class extends ComponentModel> findComponentModelClass(
- final String type) {
-
- Objects.requireNonNull(type);;
-
- try {
- final Class> clazz = Class.forName(type);
-
- if (ComponentModel.class.isAssignableFrom(clazz)) {
- return (Class extends ComponentModel>) clazz;
- } else {
- throw new BadRequestException(String.format(
- "The type \"%s\" is not a subclass of \"%s\".",
- type,
- ComponentModel.class.getName()));
- }
- } catch (ClassNotFoundException ex) {
- throw new BadRequestException(String.format(
- "The component model type \"%s\" "
- + "does not exist.",
- type));
- }
- }
-
- /**
- * Helper method for setting the properties of a {@link ComponentModel} from
- * the JSON data.
- *
- * @param data The JSON data.
- * @param componentModel The {@link ComponentModel}.
- */
- private void setComponentPropertiesFromJson(
- final JsonObject data,
- final ComponentModel componentModel) {
-
- final Class extends ComponentModel> clazz = Objects
- .requireNonNull(componentModel)
- .getClass();
-
- final ComponentModelJsonConverter jsonConverter
- = findJsonConverter(clazz)
- .orElseThrow(() -> new WebApplicationException(String.format(
- "No JSON converter available for component model \"%s\".",
- clazz.getName())));
-
- jsonConverter.fromJson(data, componentModel);
-
-// final BeanInfo beanInfo;
-// try {
-// beanInfo = Introspector.getBeanInfo(componentModel.getClass());
-// } catch (IntrospectionException ex) {
-// throw new WebApplicationException(ex);
-// }
-//
-// Arrays
-// .stream(beanInfo.getPropertyDescriptors())
-// .forEach(
-// propertyDesc -> setComponentPropertyFromJson(componentModel,
-// propertyDesc,
-// data));
- }
-
- /**
- * Helper emthod for setting a property of a {@link ComponentModel} using a
- * value from JSON data.
- *
- * @param componentModel The {@link ComponentModel}
- * @param propertyDesc The {@link PropertyDescriptor} for the property to
- * set.
- * @param data The JSON data containing the new value of the
- * property.
- */
- private void setComponentPropertyFromJson(
- final ComponentModel componentModel,
- final PropertyDescriptor propertyDesc,
- final JsonObject data) {
-
- // Ignore key and type (handled by other methods).
- if ("key".equals(propertyDesc.getName())
- || "type".equals(propertyDesc.getName())) {
-
- return;
- }
-
- if (data.containsKey(propertyDesc.getName())) {
-
- final Method writeMethod = propertyDesc.getWriteMethod();
- final Class> propertyType = propertyDesc.getPropertyType();
-
- if (writeMethod != null) {
- try {
-
-// final String value = data.getString(propertyDesc.getName());
- final JsonValue value = data.get(propertyDesc.getName());
-// final JsonValue.ValueType valueType = value.getValueType();
-
- if (propertyType == Boolean.TYPE) {
- writeMethod.invoke(
- componentModel,
- Boolean.parseBoolean(value.toString()));
- } else if (propertyType == Double.TYPE) {
- writeMethod.invoke(
- componentModel,
- Double.parseDouble(value.toString()));
- } else if (propertyType == Float.TYPE) {
- writeMethod.invoke(componentModel,
- Float.parseFloat(value.toString()));
- } else if (propertyType == Integer.TYPE) {
- writeMethod.invoke(componentModel,
- Integer.parseInt(value.toString()));
- } else if (propertyType == Long.TYPE) {
- writeMethod.invoke(componentModel,
- Long.parseLong(value.toString()));
- } else if (propertyType == String.class) {
- writeMethod.invoke(componentModel, value.toString());
- } else if (propertyType == List.class) {
-
- final JsonValue valueObj = data
- .get(propertyDesc.getName());
- if (valueObj.getValueType()
- == JsonValue.ValueType.ARRAY) {
-
- final JsonArray dataArray = data
- .getJsonArray(propertyDesc.getName());
- final List values = dataArray
- .stream()
- .map(jsonValue -> jsonValue.toString())
- .collect(Collectors.toList());
- writeMethod.invoke(componentModel, values);
- } else {
-
- String valueStr = value.toString();
- if (valueStr.startsWith("[")) {
- valueStr = valueStr.substring(1);
- }
-
- if (valueStr.endsWith("]")) {
- valueStr = valueStr
- .substring(valueStr.length() - 1);
- }
-
- final String[] tokens = valueStr.split(",");
-
- final List values = Arrays
- .stream(tokens)
- .map(token -> token.trim())
- .collect(Collectors.toList());
- writeMethod.invoke(componentModel, values);
- }
- } else {
- throw new IllegalArgumentException(
- "Unsupported property type.");
- }
-
- } catch (IllegalAccessException
- | InvocationTargetException ex) {
- throw new WebApplicationException(ex);
- }
- }
- }
- }
-
- private Optional
- findJsonConverter(
- final Class extends ComponentModel> componentModelClass) {
-
- final ConvertsComponentModelLiteral literal
- = new ConvertsComponentModelLiteral(
- componentModelClass);
- final Instance instance = jsonConverters
- .select(literal);
- if (instance.isUnsatisfied()) {
- return Optional.empty();
- } else if (instance.isAmbiguous()) {
- throw new IllegalStateException(String.format(
- "Multiple JSONConverter for \"%s\".",
- componentModelClass.getName()));
- } else {
- final Iterator iterator = instance
- .iterator();
- @SuppressWarnings("unchecked")
- final ComponentModelJsonConverter converter = iterator.next();
-
- return Optional.of(converter);
- }
- }
-
- private static class ConvertsComponentModelLiteral
- extends AnnotationLiteral
- implements ConvertsComponentModel {
-
- private static final long serialVersionUID = 1L;
-
- private final Class extends ComponentModel> componentModel;
-
- public ConvertsComponentModelLiteral(
- final Class extends ComponentModel> componentModel) {
-
- this.componentModel = componentModel;
- }
-
- @Override
- public Class extends ComponentModel> componentModel() {
- return componentModel;
- }
-
- }
-
-}
diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/StylesJsonMapper.java b/ccm-core/src/main/java/org/libreccm/pagemodel/rs/StylesJsonMapper.java
deleted file mode 100644
index fbc351de0..000000000
--- a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/StylesJsonMapper.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2018 LibreCCM Foundation.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-package org.libreccm.pagemodel.rs;
-
-import org.libreccm.pagemodel.styles.CssProperty;
-import org.libreccm.pagemodel.styles.Dimension;
-import org.libreccm.pagemodel.styles.MediaQuery;
-import org.libreccm.pagemodel.styles.MediaRule;
-import org.libreccm.pagemodel.styles.Rule;
-
-import java.util.List;
-import java.util.Objects;
-
-import javax.enterprise.context.RequestScoped;
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObject;
-
-/**
- * Utility class for mapping the entities from the
- * {@link org.libreccm.pagemodel.styles} package to JSON.
- *
- * @author Jens Pelzetter
- */
-@RequestScoped
-class StylesJsonMapper {
-
- /**
- * Map a {@link Dimension} object to JSON.
- *
- * @param dimension The {@link Dimension} object to map.
- *
- * @return A JSON object representing the provided {@link Dimension} object.
- */
- protected JsonObject mapDimensionToJson(final Dimension dimension) {
-
- Objects.requireNonNull(dimension);
-
- return Json
- .createObjectBuilder()
- .add("value", dimension.getValue())
- .add("unit", dimension.getUnit().toString())
- .build();
- }
-
- /**
- * Maps a List of {@link MediaRule} objects to JSON.
- *
- * @param mediaRules The {@link MediaRule}s to map.
- *
- * @return An JSON array with the data from the {@link MediaRule} objects in
- * the list.
- */
- protected JsonArray mapMediaRulesToJson(final List mediaRules) {
-
- final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
- Objects
- .requireNonNull(mediaRules)
- .stream()
- .map(this::mapMediaRuleToJson)
- .forEach(arrayBuilder::add);
-
- return arrayBuilder.build();
- }
-
- /**
- * Maps a {@link MediaRule} object to JSON.
- *
- * @param mediaRule The {@link MediaRule} object to map.
- *
- * @return The JSON representation of the provided {@link MediaRule} object.
- */
- protected JsonObject mapMediaRuleToJson(final MediaRule mediaRule) {
-
- Objects.requireNonNull(mediaRule);
-
- return Json
- .createObjectBuilder()
- .add("mediaRuleId", mediaRule.getMediaRuleId())
- .add("mediaQuery", mapMediaQueryToJson(mediaRule.getMediaQuery()))
- .add("rules", mapRulesToJson(mediaRule.getRules()))
- .build();
- }
-
- /**
- * Maps a {@link MediaQuery} object to JSON.
- *
- * @param mediaQuery The {@link MediaQuery} object to map.
- *
- * @return The JSON representation of the provided {@link MediaQuery}
- * object.
- */
- protected JsonObject mapMediaQueryToJson(final MediaQuery mediaQuery) {
-
- Objects.requireNonNull(mediaQuery);
-
- return Json
- .createObjectBuilder()
- .add("mediaQueryId", mediaQuery.getMediaQueryId())
- .add("mediaType", mediaQuery.getMediaType().toString())
- .add("minWidth", mapDimensionToJson(mediaQuery.getMinWidth()))
- .add("maxWidth", mapDimensionToJson(mediaQuery.getMaxWidth()))
- .build();
- }
-
- /**
- * Maps a list of {@link Rule} objects to JSON.
- *
- * @param rules The list of {@link Rule} objects to map.
- *
- * @return A JSON array with the JSON representations of the {@link Rule}
- * objects in the list.
- */
- protected JsonArray mapRulesToJson(final List rules) {
-
- final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
- Objects
- .requireNonNull(rules)
- .stream()
- .map(this::mapRuleToJson)
- .forEach(arrayBuilder::add);
-
- return arrayBuilder.build();
- }
-
- /**
- * Maps a {@link Rule} object to JSON.
- *
- * @param rule The {@link Rule} object to map.
- *
- * @return The JSON representation of the provided {@link RuleObject}.
- */
- protected JsonObject mapRuleToJson(final Rule rule) {
-
- Objects.requireNonNull(rule);
-
- return Json
- .createObjectBuilder()
- .add("ruleId", rule.getRuleId())
- .add("selector", rule.getSelector())
- .add("properties", mapPropertiesToJson(rule.getProperties()))
- .build();
- }
-
- /**
- * Maps a list of {@link CssProperty} objects to JSON.
- *
- * @param properties The list of {@link CssProperty} objects to map.
- *
- * @return A JSON array containing the JSON representations of the
- * {@link CssProperty} objects in the list.
- */
- protected JsonArray mapPropertiesToJson(final List properties) {
-
- final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
- Objects
- .requireNonNull(properties)
- .stream()
- .map(this::mapCssPropertyToJson)
- .forEach(arrayBuilder::add);
-
- return arrayBuilder.build();
- }
-
- /**
- * Maps a {@link CssProperty} object to JSON.
- *
- * @param property The {@link CssProperty} to map.
- * @return The JSON representation of the provided {@link CssProperty}.
- */
- protected JsonObject mapCssPropertyToJson(final CssProperty property) {
-
- Objects.requireNonNull(property);
-
- return Json
- .createObjectBuilder()
- .add("propertyId", property.getPropertyId())
- .add("name", property.getName())
- .add("value", property.getValue())
- .build();
- }
-
-}
diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/StylesMediaRule.java b/ccm-core/src/main/java/org/libreccm/pagemodel/rs/StylesMediaRule.java
deleted file mode 100644
index 99c1eb7da..000000000
--- a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/StylesMediaRule.java
+++ /dev/null
@@ -1,622 +0,0 @@
-/*
- * Copyright (C) 2018 LibreCCM Foundation.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-package org.libreccm.pagemodel.rs;
-
-import org.libreccm.core.CoreConstants;
-import org.libreccm.pagemodel.ContainerModel;
-import org.libreccm.pagemodel.styles.CssProperty;
-import org.libreccm.pagemodel.styles.MediaRule;
-import org.libreccm.pagemodel.styles.Rule;
-import org.libreccm.pagemodel.styles.StylesManager;
-import org.libreccm.pagemodel.styles.StylesRepository;
-import org.libreccm.security.AuthorizationRequired;
-import org.libreccm.security.RequiresPrivilege;
-import org.libreccm.web.CcmApplication;
-
-import java.io.Serializable;
-import java.util.Objects;
-
-import javax.enterprise.context.RequestScoped;
-import javax.inject.Inject;
-import javax.json.JsonArray;
-import javax.json.JsonObject;
-import javax.transaction.Transactional;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.NotFoundException;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-
-/**
- * Provides RESTful endpoints for retrieving, creating, updating and deleting
- * {@link MediaRule}s.
- *
- * @author Jens Pelzetter
- */
-@RequestScoped
-@Path(StylesRs.MEDIA_RULE_PATH)
-public class StylesMediaRule implements Serializable {
-
- private static final long serialVersionUID = 3257114872624583807L;
-
- protected final static String PROPERTY_ID = "propertyId";
- protected final static String RULE_ID = "ruleId";
-
- protected final static String RULES_PATH = "/rules";
- protected final static String RULE_PATH = RULES_PATH
- + "/{"
- + RULE_ID
- + "}";
- protected final static String PROPERTIES_PATH = RULE_PATH + "/properties";
- protected final static String PROPERTY_PATH = PROPERTIES_PATH
- + "/{"
- + PROPERTY_ID
- + "}";
-
- @Inject
- private StylesJsonMapper stylesJsonMapper;
-
- @Inject
- private StylesManager stylesManager;
-
- @Inject
- private StylesRepository stylesRepo;
-
- @Inject
- private StylesRs stylesRs;
-
- /**
- * Retrieves all {@link Rule}s of a {@link MediaRule}.
- *
- * @param appPath The path of the {@link CcmApplication} to which
- * the {@link PageModel} belongs.
- * @param pageModelName The name of the {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param containerKey The key of the {@link ContainerModel} to which
- * the {@link MediaRule} belongs.
- * @param mediaRuleIdParam The ID of the {@link MediaRule}.
- *
- * @return A JSON array with the JSON representations of all {@link Rule}s
- * belonging the {@link MediaRule} identified by the provided path.
- */
- @GET
- @Path(RULES_PATH)
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonArray getRules(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.MEDIA_RULE_ID) final String mediaRuleIdParam) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(mediaRuleIdParam);
-
- final MediaRule mediaRule = stylesRs.findMediaRule(appPath,
- pageModelName,
- containerKey,
- mediaRuleIdParam);
- return stylesJsonMapper.mapRulesToJson(mediaRule.getRules());
- }
-
- /**
- * Retrieves a specific {@link Rule} from a {@link MediaRule}.
- *
- * @param appPath The path of the {@link CcmApplication} to which
- * the {@link PageModel} belongs.
- * @param pageModelName The name of the {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param containerKey The key of the {@link ContainerModel} to which
- * the {@link MediaRule} belongs.
- * @param mediaRuleIdParam The ID of the {@link MediaRule}.
- * @param ruleIdParam The ID of the {@link Rule} to retrieve.
- *
- * @return The JSON representation of the {@link Rule} identified by the
- * provided path.
- */
- @GET
- @Path(RULE_PATH)
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject getRule(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.MEDIA_RULE_ID) final String mediaRuleIdParam,
- @PathParam(RULE_ID) String ruleIdParam) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(mediaRuleIdParam);
- Objects.requireNonNull(ruleIdParam);
-
- final MediaRule mediaRule = stylesRs.findMediaRule(appPath,
- pageModelName,
- containerKey,
- mediaRuleIdParam);
-
- return stylesJsonMapper.mapRuleToJson(findRule(mediaRule,
- ruleIdParam));
- }
-
- /**
- * Creates a new {@link Rule} for a {@link MediaRule}.
- *
- * @param appPath The path of the {@link CcmApplication} to which
- * the {@link PageModel} belongs.
- * @param pageModelName The name of the {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param containerKey The key of the {@link ContainerModel} to which
- * the {@link MediaRule} belongs.
- * @param mediaRuleIdParam The ID of the {@link MediaRule}.
- * @param ruleData The data from which the new {@link Rule} is
- * created.
- *
- * @return The JSON representation of the new {@link Rule}.
- */
- @POST
- @Path(RULES_PATH)
- @Consumes("application/json; charset=utf-8")
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject createRule(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.MEDIA_RULE_ID) final String mediaRuleIdParam,
- final JsonObject ruleData) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(mediaRuleIdParam);
- Objects.requireNonNull(ruleData);
-
- final MediaRule mediaRule = stylesRs.findMediaRule(appPath,
- pageModelName,
- containerKey,
- mediaRuleIdParam);
-
- final Rule rule = new Rule();
- rule.setSelector(ruleData.getString("selector"));
- stylesManager.addRuleToMediaRule(rule, mediaRule);
-
- return stylesJsonMapper.mapRuleToJson(rule);
- }
-
- /**
- * Updates an existing {@link Rule}
- *
- * @param appPath The path of the {@link CcmApplication} to which
- * the {@link PageModel} belongs.
- * @param pageModelName The name of the {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param containerKey The key of the {@link ContainerModel} to which
- * the {@link MediaRule} belongs.
- * @param mediaRuleIdParam The ID of the {@link MediaRule}.
- * @param ruleIdParam The ID of the {@link Rule} to update.
- * @param ruleData The data from which used to update the
- * {@link Rule}.
- *
- * @return The JSON representation of the updated {@link Rule}.
- */
- @PUT
- @Path(RULE_PATH)
- @Consumes("application/json; charset=utf-8")
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject updateRule(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.MEDIA_RULE_ID) final String mediaRuleIdParam,
- @PathParam(RULE_ID) String ruleIdParam,
- final JsonObject ruleData) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(mediaRuleIdParam);
- Objects.requireNonNull(ruleIdParam);
- Objects.requireNonNull(ruleData);
-
- final MediaRule mediaRule = stylesRs.findMediaRule(appPath,
- pageModelName,
- containerKey,
- mediaRuleIdParam);
-
- final Rule rule = findRule(mediaRule, ruleIdParam);
- rule.setSelector(ruleData.getString("selector"));
- stylesManager.addRuleToMediaRule(rule, mediaRule);
-
- return stylesJsonMapper.mapRuleToJson(rule);
- }
-
- @DELETE
- @Path(RULE_PATH)
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public void deleteRule(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.MEDIA_RULE_ID) final String mediaRuleIdParam,
- @PathParam(RULE_ID) String ruleIdParam) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(mediaRuleIdParam);
- Objects.requireNonNull(ruleIdParam);
-
- final MediaRule mediaRule = stylesRs.findMediaRule(appPath,
- pageModelName,
- containerKey,
- mediaRuleIdParam);
-
- final Rule rule = findRule(mediaRule, ruleIdParam);
-
- stylesManager.removeRuleFromMediaRule(rule, mediaRule);
- stylesRepo.deleteRule(rule);
- }
-
- /**
- * Retrieves all {@link CssProperty} objects assigned to {@link Rule} which
- * is assigned to {@link MediaRule}.
- *
- * @param appPath The path of the {@link CcmApplication} to which
- * the {@link PageModel} belongs.
- * @param pageModelName The name of the {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param containerKey The key of the {@link ContainerModel} to which
- * the {@link MediaRule} belongs.
- * @param mediaRuleIdParam The ID of the {@link MediaRule}.
- * @param ruleIdParam The ID of the {@link Rule} from which the
- * {@link CssProperty} objects are retrieved.
- *
- * @return A JSON array with the JSON representations of the
- * {@link CssProperty} objects.
- */
- @GET
- @Path(PROPERTIES_PATH)
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonArray getProperties(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.MEDIA_RULE_ID) final String mediaRuleIdParam,
- @PathParam(RULE_ID) String ruleIdParam) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(mediaRuleIdParam);
- Objects.requireNonNull(ruleIdParam);
-
- final MediaRule mediaRule = stylesRs.findMediaRule(appPath,
- pageModelName,
- containerKey,
- mediaRuleIdParam);
-
- final Rule rule = findRule(mediaRule, ruleIdParam);
-
- return stylesJsonMapper.mapPropertiesToJson(rule.getProperties());
- }
-
- /**
- * Retrieve a {@link CssProperty} assigned to {@link Rule} which is assigned
- * to {@link MediaRule}.
- *
- * @param appPath The path of the {@link CcmApplication} to which
- * the {@link PageModel} belongs.
- * @param pageModelName The name of the {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param containerKey The key of the {@link ContainerModel} to which
- * the {@link MediaRule} belongs.
- * @param mediaRuleIdParam The ID of the {@link MediaRule}.
- * @param ruleIdParam The ID of the {@link Rule} from which the
- * {@link CssProperty} is retrieved.
- * @param propertyIdParam The ID of the {@link CssProperty} to retrieve.
- *
- * @return The JSON representation of the {@link CssProperty} identified by
- * the provided path.
- */
- @GET
- @Path(PROPERTY_PATH)
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject getProperty(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.MEDIA_RULE_ID) final String mediaRuleIdParam,
- @PathParam(RULE_ID) final String ruleIdParam,
- @PathParam(PROPERTY_ID) final String propertyIdParam) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(mediaRuleIdParam);
- Objects.requireNonNull(ruleIdParam);
- Objects.requireNonNull(propertyIdParam);
-
- final MediaRule mediaRule = stylesRs.findMediaRule(appPath,
- pageModelName,
- containerKey,
- mediaRuleIdParam);
-
- final Rule rule = findRule(mediaRule, ruleIdParam);
- final CssProperty property = findProperty(rule, propertyIdParam);
-
- return stylesJsonMapper.mapCssPropertyToJson(property);
- }
-
- /**
- * Creates a new {@link CssProperty} for a {@link Rule} of a
- * {@link MediaRule}.
- *
- * @param appPath The path of the {@link CcmApplication} to which
- * the {@link PageModel} belongs.
- * @param pageModelName The name of the {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param containerKey The key of the {@link ContainerModel} to which
- * the {@link MediaRule} belongs.
- * @param mediaRuleIdParam The ID of the {@link MediaRule}.
- * @param ruleIdParam The ID of the {@link Rule} for which the new
- * {@link CssProperty} is created.
- * @param propertyData The data from which the new {@link CssProperty}
- * is created.
- *
- * @return The JSON representation of the new {@link CssProperty}.
- */
- @POST
- @Path(PROPERTIES_PATH)
- @Consumes("application/json; charset=utf-8")
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject createProperty(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.MEDIA_RULE_ID) final String mediaRuleIdParam,
- @PathParam(RULE_ID) String ruleIdParam,
- final JsonObject propertyData) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(mediaRuleIdParam);
- Objects.requireNonNull(ruleIdParam);
- Objects.requireNonNull(propertyData);
-
- final MediaRule mediaRule = stylesRs.findMediaRule(appPath,
- pageModelName,
- containerKey,
- mediaRuleIdParam);
-
- final Rule rule = findRule(mediaRule, ruleIdParam);
-
- final CssProperty property = new CssProperty();
- setCssPropertyData(property, propertyData);
- stylesManager.addCssPropertyToRule(property, rule);
-
- return stylesJsonMapper.mapCssPropertyToJson(property);
- }
-
- /**
- * Updates an existing {@link CssProperty} of {@link Rule} of a
- * {@link MediaRule}.
- *
- * @param appPath The path of the {@link CcmApplication} to which
- * the {@link PageModel} belongs.
- * @param pageModelName The name of the {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param containerKey The key of the {@link ContainerModel} to which
- * the {@link MediaRule} belongs.
- * @param mediaRuleIdParam The ID of the {@link MediaRule}.
- * @param ruleIdParam The ID of the {@link Rule} to which the
- * {@link CssProperty} belongs.
- * @param propertyIdParam The ID of the {@link CssProperty} to update.
- * @param propertyData The data which is used to update the
- * {@link CssProperty}.
- *
- * @return The JSON representation of the updated {@link CssProperty}.
- */
- @PUT
- @Path(PROPERTY_PATH)
- @Consumes("application/json; charset=utf-8")
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject updateProperty(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.MEDIA_RULE_ID) final String mediaRuleIdParam,
- @PathParam(RULE_ID) String ruleIdParam,
- @PathParam(PROPERTY_ID) final String propertyIdParam,
- final JsonObject propertyData) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(mediaRuleIdParam);
- Objects.requireNonNull(ruleIdParam);
- Objects.requireNonNull(propertyIdParam);
- Objects.requireNonNull(propertyData);
-
- final MediaRule mediaRule = stylesRs.findMediaRule(appPath,
- pageModelName,
- containerKey,
- mediaRuleIdParam);
-
- final Rule rule = findRule(mediaRule, ruleIdParam);
-
- final CssProperty property = findProperty(rule, propertyIdParam);
- setCssPropertyData(property, propertyData);
- stylesRepo.saveCssProperty(property);
-
- return stylesJsonMapper.mapCssPropertyToJson(property);
- }
-
- /**
- * Deletes a {@link CssProperty} of a {@link Rule} assigned to a
- * {@link MediaRule}.
- *
- * @param appPath The path of the {@link CcmApplication} to which
- * the {@link PageModel} belongs.
- * @param pageModelName The name of the {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param containerKey The key of the {@link ContainerModel} to which
- * the {@link MediaRule} belongs.
- * @param mediaRuleIdParam The ID of the {@link MediaRule}.
- * @param ruleIdParam The ID of the {@link Rule} to which the
- * {@link CssProperty} belongs.
- * @param propertyIdParam The ID of the {@link CssProperty} to delete.
- */
- @DELETE
- @Path(PROPERTY_PATH)
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public void deleteProperty(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.MEDIA_RULE_ID) final String mediaRuleIdParam,
- @PathParam(RULE_ID) String ruleIdParam,
- @PathParam(PROPERTY_ID) final String propertyIdParam) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(mediaRuleIdParam);
- Objects.requireNonNull(ruleIdParam);
- Objects.requireNonNull(propertyIdParam);
-
- final MediaRule mediaRule = stylesRs.findMediaRule(appPath,
- pageModelName,
- containerKey,
- mediaRuleIdParam);
-
- final Rule rule = findRule(mediaRule, ruleIdParam);
-
- final CssProperty property = findProperty(rule, propertyIdParam);
- stylesManager.removeCssPropertyFromRule(property, rule);
- stylesRepo.deleteCssProperty(property);
- }
-
- /**
- * Helper method for finding a {@link CssProperty}.
- *
- * @param rule The {@link Rule} to which the {@link CssProperty}
- * belongs.
- * @param propertyIdParam The ID of the {@link CssProperty} to find.
- *
- * @return The {@link CssProperty}.
- */
- private CssProperty findProperty(final Rule rule,
- final String propertyIdParam) {
-
- final long propertyId;
- try {
- propertyId = Long.parseLong(propertyIdParam);
- } catch (NumberFormatException ex) {
- throw new WebApplicationException(ex);
- }
-
- return rule
- .getProperties()
- .stream()
- .filter(property -> propertyId == property.getPropertyId())
- .findAny()
- .orElseThrow(() -> new NotFoundException());
- }
-
- /**
- * Helper method for finding a {@link Rule} assigned to {@link MediaRule}.
- *
- * @param mediaRule The {@link MediaRule}.
- * @param ruleIdParam The ID of {@link Rule} to find.
- *
- * @return The {@link Rule}.
- */
- private Rule findRule(final MediaRule mediaRule,
- final String ruleIdParam) {
-
- final long ruleId;
- try {
- ruleId = Long.parseLong(ruleIdParam);
- } catch (NumberFormatException ex) {
- throw new WebApplicationException(ex);
- }
-
- Objects.requireNonNull(mediaRule);
-
- return mediaRule
- .getRules()
- .stream()
- .filter(rule -> ruleId == rule.getRuleId())
- .findAny()
- .orElseThrow(() -> new NotFoundException());
- }
-
- /**
- * Helper method for updating the values of the properties of
- * {@link CssProperty} object from its JSON representation.
- *
- * @param property The {@link CssProperty}.
- * @param propertyData The {@link JsonObject} containing the data.
- */
- private void setCssPropertyData(final CssProperty property,
- final JsonObject propertyData) {
-
- Objects.requireNonNull(property);
- Objects.requireNonNull(propertyData);
-
- property.setName(propertyData.getString("name"));
- property.setValue(propertyData.getString("value"));
- }
-
-}
diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/StylesRs.java b/ccm-core/src/main/java/org/libreccm/pagemodel/rs/StylesRs.java
deleted file mode 100644
index 255789262..000000000
--- a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/StylesRs.java
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
- * Copyright (C) 2018 LibreCCM Foundation.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-package org.libreccm.pagemodel.rs;
-
-import org.libreccm.core.CoreConstants;
-import org.libreccm.pagemodel.ContainerModel;
-import org.libreccm.pagemodel.PageModel;
-import org.libreccm.pagemodel.styles.Dimension;
-import org.libreccm.pagemodel.styles.MediaRule;
-import org.libreccm.pagemodel.styles.MediaType;
-import org.libreccm.pagemodel.styles.Rule;
-import org.libreccm.pagemodel.styles.Styles;
-import org.libreccm.pagemodel.styles.StylesManager;
-import org.libreccm.pagemodel.styles.StylesRepository;
-import org.libreccm.pagemodel.styles.Unit;
-import org.libreccm.security.AuthorizationRequired;
-import org.libreccm.security.RequiresPrivilege;
-import org.libreccm.web.CcmApplication;
-
-import java.util.Objects;
-
-import javax.enterprise.context.RequestScoped;
-import javax.inject.Inject;
-import javax.json.JsonArray;
-import javax.json.JsonObject;
-import javax.transaction.Transactional;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.NotFoundException;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-
-/**
- * Provides RESTful endpoints for managing the (CSS) styles of a
- * {@link ContainerModel}.
- *
- * @author Jens Pelzetter
- */
-@RequestScoped
-@Path(PageModelsApp.STYLES_PATH)
-public class StylesRs {
-
- protected static final String MEDIA_RULE_ID = "mediaRuleId";
- protected static final String RULE_ID = "ruleId";
-
- protected static final String MEDIA_RULES_PATH = "/media-rules";
- protected static final String MEDIA_RULE_PATH = MEDIA_RULES_PATH
- + "/{"
- + MEDIA_RULE_ID
- + "}";
- protected static final String RULES_PATH = "/rules";
- protected static final String RULE_PATH = RULES_PATH
- + "/{"
- + RULE_ID
- + "}";
-
- @Inject
- private PageModelsController controller;
-
- @Inject
- private StylesJsonMapper stylesJsonMapper;
-
- @Inject
- private StylesManager stylesManager;
-
- @Inject
- private StylesRepository stylesRepo;
-
- /**
- * Retrieves all {@link MediaRule}s from the {@link Styles} entity of a
- * {@link ContainerModel}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- *
- * @return The JSON Array with the JSON representations of all
- * {@link MediaRule}s of the {@link ContainerModel} identified by
- * the provided path.
- */
- @GET
- @Path(MEDIA_RULES_PATH)
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonArray getMediaRules(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
-
- final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
-
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
-
- final ContainerModel container = controller.findContainer(app,
- pageModel,
- containerKey);
-
- final Styles styles = container.getStyles();
-
- return stylesJsonMapper.mapMediaRulesToJson(styles.getMediaRules());
-
- }
-
- /**
- * Retrieves a specific {@link MediaRule} from the {@link Styles} entity of
- * a {@link ContainerModel}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- * @param mediaRuleIdParam The ID of the {@link MediaRule} to retrieve.
- *
- * @return The JSON representation of the {@link MediaRule}.
- */
- @GET
- @Path(MEDIA_RULE_PATH)
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject getMediaRule(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(MEDIA_RULE_ID) final String mediaRuleIdParam) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(mediaRuleIdParam);
-
- return stylesJsonMapper
- .mapMediaRuleToJson(findMediaRule(appPath,
- pageModelName,
- containerKey,
- mediaRuleIdParam));
- }
-
- /**
- * Creates a new {@link MediaRule}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- * @param mediaRuleData The data for the new {@link MediaRule}.
- *
- * @return The JSON representation of the new {@link MediaRule}.
- */
- @POST
- @Path(MEDIA_RULES_PATH)
- @Consumes("application/json; charset=utf-8")
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject createMediaRule(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- final JsonObject mediaRuleData) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(mediaRuleData);
-
- final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
-
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
-
- final ContainerModel container = controller.findContainer(app,
- pageModel,
- containerKey);
- final Styles styles = container.getStyles();
-
- final MediaRule mediaRule = new MediaRule();
- setMediaRuleProperties(mediaRuleData, mediaRule);
- stylesManager.addMediaRuleToStyles(mediaRule, styles);
-
- return stylesJsonMapper.mapMediaRuleToJson(mediaRule);
- }
-
- /**
- * Update a {@link MediaRule}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- * @param mediaRuleIdParam The ID of the {@link MediaRule} to update.
- * @param mediaRuleData The data for updating the {@link MediaRule}.
- *
- * @return The JSON representation of the updated {@link MediaRule}.
- */
- @PUT
- @Path(MEDIA_RULE_PATH)
- @Consumes("application/json; charset=utf-8")
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject updateMediaRule(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(MEDIA_RULE_ID) final String mediaRuleIdParam,
- final JsonObject mediaRuleData) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(mediaRuleIdParam);
- Objects.requireNonNull(mediaRuleData);
-
- final MediaRule mediaRule = findMediaRule(appPath,
- pageModelName,
- containerKey,
- mediaRuleIdParam);
- setMediaRuleProperties(mediaRuleData, mediaRule);
- stylesRepo.saveMediaRule(mediaRule);
-
- return stylesJsonMapper.mapMediaRuleToJson(mediaRule);
- }
-
- /**
- * Deletes a {@link MediaRule}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- * @param mediaRuleIdParam The ID of the {@link MediaRule} to delete.
- */
- @DELETE
- @Path(MEDIA_RULE_PATH)
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public void deleteMediaRule(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(MEDIA_RULE_ID) final String mediaRuleIdParam) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(mediaRuleIdParam);
-
- final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
-
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
-
- final ContainerModel container = controller.findContainer(app,
- pageModel,
- containerKey);
-
- final Styles styles = container.getStyles();
-
- final MediaRule mediaRule = findMediaRule(pageModel,
- container,
- mediaRuleIdParam);
- stylesManager.removeMediaRuleFromStyles(mediaRule, styles);
- }
-
- /**
- * Retrieves all {@link Rule}s from the {@link Styles} entity of a
- * {@link ContainerModel}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- *
- * @return A JSON array with the JSON representation of all {@link Rule}s of
- * the {@link ContainerModel}.
- */
- @GET
- @Path(RULES_PATH)
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonArray getRules(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
-
- final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
-
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
-
- final ContainerModel container = controller.findContainer(app,
- pageModel,
- containerKey);
-
- final Styles styles = container.getStyles();
-
- return stylesJsonMapper.mapRulesToJson(styles.getRules());
- }
-
- /**
- * Retrieves a specific {@link Rule} from the {@link Styles} entity of a
- * {@link ContainerModel}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- * @param ruleIdParam The ID of the {@link Rule} to retrieve.
- *
- * @return The JSON representation of the {@link Rule}.
- */
- @GET
- @Path(RULE_PATH)
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject getRule(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(RULE_ID) final String ruleIdParam) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(ruleIdParam);
-
- return stylesJsonMapper
- .mapRuleToJson(findRule(appPath,
- pageModelName,
- containerKey,
- ruleIdParam));
- }
-
- /**
- * Creates a new {@link Rule}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- * @param ruleData The data for the new {@link Rule}.
- *
- * @return The JSON representation of the new {@link Rule}.
- */
- @POST
- @Path(RULES_PATH)
- @Consumes("application/json; charset=utf-8")
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject createRule(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- final JsonObject ruleData) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(ruleData);
-
- final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
-
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
-
- final ContainerModel container = controller.findContainer(app,
- pageModel,
- containerKey);
- final Styles styles = container.getStyles();
-
- final Rule rule = new Rule();
- rule.setSelector(ruleData.getString("selector"));
- stylesManager.addRuleToStyles(rule, styles);
-
- return stylesJsonMapper.mapRuleToJson(rule);
- }
-
- /**
- * Updates an existing {@link Rule}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- * @param ruleIdParam The ID of the {@link Rule} to update.
- * @param ruleData The data for updating the {@link Rule}.
- *
- * @return The JSON representation of the updated {@link Rule}.
- */
- @PUT
- @Path(RULE_PATH)
- @Consumes("application/json; charset=utf-8")
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject updateRule(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(RULE_ID) final String ruleIdParam,
- final JsonObject ruleData) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(ruleIdParam);
- Objects.requireNonNull(ruleData);
-
- final Rule rule = findRule(appPath,
- pageModelName,
- containerKey,
- ruleIdParam);
- rule.setSelector(ruleData.getString("selector"));
- stylesRepo.saveRule(rule);
- return stylesJsonMapper.mapRuleToJson(rule);
- }
-
- /**
- * Deletes a {@link Rule}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- * @param ruleIdParam The ID of the {@link Rule} to delete.
- */
- @DELETE
- @Path(RULE_PATH)
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public void deleteRule(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(RULE_ID) final String ruleIdParam) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(ruleIdParam);
-
- final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
-
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
-
- final ContainerModel container = controller.findContainer(app,
- pageModel,
- containerKey);
-
- final Styles styles = container.getStyles();
-
- final Rule rule = findRule(pageModel, container, ruleIdParam);
- stylesManager.removeRuleFromStyles(rule, styles);
- }
-
- /**
- * An utility method for finding a {@link MediaRule}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- * @param mediaRuleIdParam The ID of the {@link MediaRule} to find.
- *
- * @return The {@link MediaRule} with the provided {@code mediaRuleId}.
- */
- protected MediaRule findMediaRule(final String appPath,
- final String pageModelName,
- final String containerKey,
- final String mediaRuleIdParam) {
-
- final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
-
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
-
- final ContainerModel container = controller.findContainer(app,
- pageModel,
- containerKey);
-
- return findMediaRule(pageModel, container, mediaRuleIdParam);
- }
-
- /**
- * An utility method for finding a {@link MediaRule}.
- *
- * @param pageModel The {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param container The {@link ContainerModel} to which the
- * {@link MediaRule} belongs.
- * @param mediaRuleIdParam The ID of the {@link MediaRule} to find.
- *
- * @return The {@link MediaRule} with the ID {@code mediaRuleIdParam}.
- */
- private MediaRule findMediaRule(final PageModel pageModel,
- final ContainerModel container,
- final String mediaRuleIdParam) {
-
- final Styles styles = container.getStyles();
-
- final long mediaRuleId;
- try {
- mediaRuleId = Long.parseLong(mediaRuleIdParam);
- } catch (NumberFormatException ex) {
- throw new WebApplicationException(String.format(
- "The provided mediaRuleId \"%s\" numeric.", mediaRuleIdParam));
- }
-
- return styles
- .getMediaRules()
- .stream()
- .filter(mediaRule -> mediaRuleId == mediaRule.getMediaRuleId())
- .findAny()
- .orElseThrow(() -> new NotFoundException(String.format(
- "No MediaRule with ID %d available in the Styles for "
- + "Container \"%s\" of PageModel \"%s\".",
- mediaRuleId,
- container.getKey(),
- pageModel.getName())));
- }
-
- /**
- * Utility method for finding a {@link Rule}.
- *
- * @param appPath The primary URL of the {@link CcmApplication}.
- * @param pageModelName The name of the {@link PageModel}.
- * @param containerKey The key of the {@link ContainerModel}.
- * @param ruleIdParam The ID of the {@link Rule} to find.
- *
- * @return The {@link Rule} identified by {@code ruleIdParam}.
- */
- protected Rule findRule(final String appPath,
- final String pageModelName,
- final String containerKey,
- final String ruleIdParam) {
-
- final CcmApplication app = controller.findCcmApplication(
- String.format("/%s/", appPath));
-
- final PageModel pageModel = controller.findPageModel(app,
- pageModelName);
-
- final ContainerModel container = controller.findContainer(app,
- pageModel,
- containerKey);
-
- return findRule(pageModel, container, ruleIdParam);
- }
-
- /**
- * An utility method for finding a {@link Rule}.
- *
- * @param pageModel The {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param container The {@link ContainerModel} to which the {@link Rule}
- * belongs.
- * @param ruleIdParam The ID of the {@link Rule} to find.
- *
- * @return The {@link Rule} with the ID {@code ruleIdParam}.
- */
- private Rule findRule(final PageModel pageModel,
- final ContainerModel container,
- final String ruleIdParam) {
-
- final Styles styles = container.getStyles();
-
- final long ruleId;
- try {
- ruleId = Long.parseLong(ruleIdParam);
- } catch (NumberFormatException ex) {
- throw new WebApplicationException(String.format(
- "The provided mediaRuleId \"%s\" numeric.", ruleIdParam));
- }
-
- return styles
- .getRules()
- .stream()
- .filter(rule -> ruleId == rule.getRuleId())
- .findAny()
- .orElseThrow(() -> new NotFoundException(String.format(
- "No Rule with ID %d available in the Styles for "
- + "Container \"%s\" of PageModel \"%s\".",
- ruleId,
- container.getKey(),
- pageModel.getName())));
- }
-
- /**
- * Helper method for setting the values of the properties of a
- * {@link MediaRule} using the data from a JSON object.
- *
- * @param mediaRuleData The JSON object providing the data.
- * @param mediaRule The {@link MediaRule}.
- */
- private void setMediaRuleProperties(final JsonObject mediaRuleData,
- final MediaRule mediaRule) {
-
- Objects.requireNonNull(mediaRuleData);
- Objects.requireNonNull(mediaRule);
-
- final JsonObject mediaQueryData = mediaRuleData
- .getJsonObject("mediaQuery");
- final JsonObject maxWidthData = mediaQueryData
- .getJsonObject("maxWidth");
- final JsonObject minWidthData = mediaQueryData
- .getJsonObject("minWidth");
-
- final Dimension maxWidth = new Dimension();
- maxWidth.setUnit(Unit.valueOf(maxWidthData.getString("unit")));
- maxWidth.setValue(maxWidthData.getJsonNumber("value").doubleValue());
- final MediaType mediaType = MediaType.valueOf(mediaQueryData
- .getString("mediaType"));
-
- final Dimension minWidth = new Dimension();
- minWidth.setUnit(Unit.valueOf(minWidthData.getString("unit")));
- minWidth.setValue(minWidthData.getJsonNumber("minWidth").doubleValue());
-
- mediaRule.getMediaQuery().setMaxWidth(maxWidth);
- mediaRule.getMediaQuery().setMediaType(mediaType);
- mediaRule.getMediaQuery().setMinWidth(minWidth);
- }
-
-}
diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/StylesRule.java b/ccm-core/src/main/java/org/libreccm/pagemodel/rs/StylesRule.java
deleted file mode 100644
index c396f0437..000000000
--- a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/StylesRule.java
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2018 LibreCCM Foundation.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-package org.libreccm.pagemodel.rs;
-
-import org.libreccm.core.CoreConstants;
-import org.libreccm.pagemodel.ContainerModel;
-import org.libreccm.pagemodel.styles.CssProperty;
-import org.libreccm.pagemodel.styles.Rule;
-import org.libreccm.pagemodel.styles.StylesManager;
-import org.libreccm.pagemodel.styles.StylesRepository;
-import org.libreccm.security.AuthorizationRequired;
-import org.libreccm.security.RequiresPrivilege;
-import org.libreccm.web.CcmApplication;
-
-import java.io.Serializable;
-import java.util.Objects;
-
-import javax.enterprise.context.RequestScoped;
-import javax.inject.Inject;
-import javax.json.JsonArray;
-import javax.json.JsonObject;
-import javax.transaction.Transactional;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.NotFoundException;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-
-/**
- * Provides RESTful endpoints for retrieving, creating, updating and deleting
- * {@link Rule} objects.
- *
- * @author Jens Pelzetter
- */
-@RequestScoped
-@Path(StylesRs.RULE_PATH)
-public class StylesRule implements Serializable {
-
- private static final long serialVersionUID = -8447970787677773230L;
-
- protected final static String PROPERTY_ID = "propertyId";
-
- protected final static String PROPERTIES_PATH = "/properties";
- protected final static String PROPERTY_PATH = PROPERTIES_PATH
- + "/{"
- + PROPERTY_ID
- + "}";
-
- @Inject
- private StylesJsonMapper stylesJsonMapper;
-
- @Inject
- private StylesManager stylesManager;
-
- @Inject
- private StylesRepository stylesRepo;
-
- @Inject
- private StylesRs stylesRs;
-
- /**
- * Retrieves all {@link CssProperty} objects of a {@link Rule} assigned to
- * the {@link Styles} entity of a {@link ContainerModel}.
- *
- * @param appPath The primary URL of the {@link CcmApplication} to
- * which the {@link PageModel} belongs.
- * @param pageModelName The name of the {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param containerKey The key of the {@link ContainerModel} to which the
- * {@link Rule} belongs.
- * @param ruleIdParam The ID of the {@link Rule} from which the
- * {@link CssProperty} objects are retrieved.
- *
- * @return A JSON array with the JSON representation of the
- * {@link CssProperty} objects of the {@link Rule} identified by the
- * provided path.
- */
- @GET
- @Path(PROPERTIES_PATH)
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonArray getProperties(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.RULE_ID) final String ruleIdParam) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(ruleIdParam);
-
- final Rule rule = stylesRs.findRule(appPath,
- pageModelName,
- containerKey,
- ruleIdParam);
- return stylesJsonMapper.mapPropertiesToJson(rule.getProperties());
- }
-
- /**
- * Retrieves a specific {@link CssProperty} from a {@link Rule} assigned to
- * the {@link Styles} entity of a {@link ContainerModel}.
- *
- * @param appPath The primary URL of the {@link CcmApplication} to
- * which the {@link PageModel} belongs.
- * @param pageModelName The name of the {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param containerKey The key of the {@link ContainerModel} to which the
- * {@link Rule} belongs.
- * @param ruleIdParam The ID of the {@link Rule} to which the
- * {@link CssProperty} is assigned.
- * @param propertyIdParam The ID of the {@link CssProperty} to retrieve.
- *
- * @return The JSON representation of the {@link CssProperty}.
- */
- @GET
- @Path(PROPERTY_PATH)
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject getProperty(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.RULE_ID) final String ruleIdParam,
- @PathParam(PROPERTY_ID) final String propertyIdParam) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(ruleIdParam);
- Objects.requireNonNull(propertyIdParam);
-
- final Rule rule = stylesRs.findRule(appPath,
- pageModelName,
- containerKey,
- ruleIdParam);
-
- return stylesJsonMapper
- .mapCssPropertyToJson(findProperty(rule,
- propertyIdParam));
- }
-
- /**
- * Creates a new {@link CssProperty} for a {@link Rule} assigned to the
- * {@link Styles} entity of a {@link ContainerModel}.
- *
- * @param appPath The primary URL of the {@link CcmApplication} to
- * which the {@link PageModel} belongs.
- * @param pageModelName The name of the {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param containerKey The key of the {@link ContainerModel} to which the
- * {@link Rule} belongs.
- * @param ruleIdParam The ID of the {@link Rule} to which the
- * {@link CssProperty} is assigned.
- * @param propertyData The data used to create the new {@link CssProperty}.
- *
- * @return The JSON representation of the new {@link CssProperty}.
- */
- @POST
- @Path(PROPERTIES_PATH)
- @Consumes("application/json; charset=utf-8")
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject createProperty(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.RULE_ID) final String ruleIdParam,
- final JsonObject propertyData) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(ruleIdParam);
- Objects.requireNonNull(propertyData);
-
- final Rule rule = stylesRs.findRule(appPath,
- pageModelName,
- containerKey,
- ruleIdParam);
-
- final CssProperty property = new CssProperty();
- setCssPropertyData(property, propertyData);
- stylesManager.addCssPropertyToRule(property, rule);
-
- return stylesJsonMapper.mapCssPropertyToJson(property);
- }
-
- /**
- * Updates an existing {@link CssProperty} for a {@link Rule} assigned to
- * the {@link Styles} entity of a {@link ContainerModel}.
- *
- * @param appPath The primary URL of the {@link CcmApplication} to
- * which the {@link PageModel} belongs.
- * @param pageModelName The name of the {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param containerKey The key of the {@link ContainerModel} to which the
- * {@link Rule} belongs.
- * @param ruleIdParam The ID of the {@link Rule} to which the
- * {@link CssProperty} is assigned.
- * @param propertyIdParam The ID of the {@link CssProperty} to update.
- * @param propertyData The data used to update the {@link CssProperty}.
- *
- * @return The JSON representation of the updated {@link CssProperty}.
- */
- @PUT
- @Path(PROPERTY_PATH)
- @Consumes("application/json; charset=utf-8")
- @Produces("application/json; charset=utf-8")
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public JsonObject updateProperty(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.RULE_ID) final String ruleIdParam,
- @PathParam(PROPERTY_ID) final String propertyIdParam,
- final JsonObject propertyData) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(ruleIdParam);
- Objects.requireNonNull(propertyIdParam);
- Objects.requireNonNull(propertyData);
-
- final Rule rule = stylesRs.findRule(appPath,
- pageModelName,
- containerKey,
- ruleIdParam);
-
- final CssProperty property = findProperty(rule, propertyIdParam);
- setCssPropertyData(property, propertyData);
- stylesRepo.saveCssProperty(property);
-
- return stylesJsonMapper.mapCssPropertyToJson(property);
- }
-
- /**
- * Deletes{@link CssProperty} for a {@link Rule} assigned to the
- * {@link Styles} entity of a {@link ContainerModel}.
- *
- * @param appPath The primary URL of the {@link CcmApplication} to
- * which the {@link PageModel} belongs.
- * @param pageModelName The name of the {@link PageModel} to which the
- * {@link ContainerModel} belongs.
- * @param containerKey The key of the {@link ContainerModel} to which the
- * {@link Rule} belongs.
- * @param ruleIdParam The ID of the {@link Rule} to which the
- * {@link CssProperty} is assigned.
- * @param propertyIdParam The ID of the {@link CssProperty} to delete.
- */
- @DELETE
- @Path(PROPERTY_PATH)
- @Transactional(Transactional.TxType.REQUIRED)
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- public void deleteProperty(
- @PathParam(PageModelsApp.APP_NAME) final String appPath,
- @PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
- @PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
- @PathParam(StylesRs.RULE_ID) final String ruleIdParam,
- @PathParam(PROPERTY_ID) final String propertyIdParam) {
-
- Objects.requireNonNull(appPath);
- Objects.requireNonNull(pageModelName);
- Objects.requireNonNull(containerKey);
- Objects.requireNonNull(ruleIdParam);
- Objects.requireNonNull(propertyIdParam);
-
- final Rule rule = stylesRs.findRule(appPath,
- pageModelName,
- containerKey,
- ruleIdParam);
-
- final CssProperty property = findProperty(rule, propertyIdParam);
- stylesManager.removeCssPropertyFromRule(property, rule);
- stylesRepo.deleteCssProperty(property);
- }
-
- /**
- * Helper method for finding a {@link CssProperty} assigned to {@link Rule}.
- *
- * @param rule The {@link Rule}.
- * @param propertyIdParam The ID of the {@link CssProperty} to find.
- *
- * @return The {@link CssProperty} identified by {@code propertyIdParam}.
- */
- private CssProperty findProperty(final Rule rule,
- final String propertyIdParam) {
-
- Objects.requireNonNull(rule);
- Objects.requireNonNull(propertyIdParam);
-
- final long propertyId;
- try {
- propertyId = Long.parseLong(propertyIdParam);
- } catch (NumberFormatException ex) {
- throw new WebApplicationException(ex);
- }
-
- return rule
- .getProperties()
- .stream()
- .filter(property -> propertyId == property.getPropertyId())
- .findAny()
- .orElseThrow(() -> new NotFoundException());
- }
-
- /**
- * Helper method for updating a {@link CssProperty} object with data from
- * its JSON representation.
- *
- * @param property The {@link CssProperty}.
- * @param propertyData The data.
- */
- private void setCssPropertyData(final CssProperty property,
- final JsonObject propertyData) {
-
- Objects.requireNonNull(property);
- Objects.requireNonNull(propertyData);
-
- property.setName(propertyData.getString("name"));
- property.setValue(propertyData.getString("value"));
- }
-
-}
diff --git a/ccm-core/src/site/resources/ccm-core-api.json b/ccm-core/src/site/resources/ccm-core-api.json
index 2e85e1652..3d041bcdf 100644
--- a/ccm-core/src/site/resources/ccm-core-api.json
+++ b/ccm-core/src/site/resources/ccm-core-api.json
@@ -67,6 +67,99 @@
}
}
},
+ "/api/admin/categories/{domainIdentifier}/{path}" : {
+ "get" : {
+ "operationId" : "getCategory_2",
+ "parameters" : [ {
+ "name" : "domainIdentifier",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ }, {
+ "name" : "path",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "default response",
+ "content" : {
+ "application/json" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/CategoryData"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put" : {
+ "operationId" : "updateCategory_2",
+ "parameters" : [ {
+ "name" : "domainIdentifier",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ }, {
+ "name" : "path",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "requestBody" : {
+ "content" : {
+ "application/json" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/CategoryData"
+ }
+ }
+ }
+ },
+ "responses" : {
+ "default" : {
+ "description" : "default response",
+ "content" : {
+ "*/*" : { }
+ }
+ }
+ }
+ },
+ "delete" : {
+ "operationId" : "deleteCategory_1",
+ "parameters" : [ {
+ "name" : "domainIdentifier",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ }, {
+ "name" : "path",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "default response",
+ "content" : {
+ "*/*" : { }
+ }
+ }
+ }
+ }
+ },
"/api/admin/categories/ID-{categoryId}" : {
"get" : {
"operationId" : "getCategory_1",
@@ -122,7 +215,7 @@
}
},
"delete" : {
- "operationId" : "deleteCategory_1",
+ "operationId" : "deleteCategory_2",
"parameters" : [ {
"name" : "categoryId",
"in" : "path",
@@ -142,102 +235,9 @@
}
}
},
- "/api/admin/categories/{domainIdentifier}/{path}" : {
- "get" : {
- "operationId" : "getCategory",
- "parameters" : [ {
- "name" : "domainIdentifier",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- }, {
- "name" : "path",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- } ],
- "responses" : {
- "default" : {
- "description" : "default response",
- "content" : {
- "application/json" : {
- "schema" : {
- "$ref" : "#/components/schemas/CategoryData"
- }
- }
- }
- }
- }
- },
- "put" : {
- "operationId" : "updateCategory_2",
- "parameters" : [ {
- "name" : "domainIdentifier",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- }, {
- "name" : "path",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- } ],
- "requestBody" : {
- "content" : {
- "application/json" : {
- "schema" : {
- "$ref" : "#/components/schemas/CategoryData"
- }
- }
- }
- },
- "responses" : {
- "default" : {
- "description" : "default response",
- "content" : {
- "*/*" : { }
- }
- }
- }
- },
- "delete" : {
- "operationId" : "deleteCategory_2",
- "parameters" : [ {
- "name" : "domainIdentifier",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- }, {
- "name" : "path",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- } ],
- "responses" : {
- "default" : {
- "description" : "default response",
- "content" : {
- "*/*" : { }
- }
- }
- }
- }
- },
"/api/admin/categories/{domainIdentifier}/{path}/subcategories" : {
"get" : {
- "operationId" : "getSubCategories",
+ "operationId" : "getSubCategories_2",
"parameters" : [ {
"name" : "domainIdentifier",
"in" : "path",
@@ -318,48 +318,9 @@
}
}
},
- "/api/admin/categories/UUID-{uuid}/objects" : {
- "get" : {
- "operationId" : "getObjectsInCategory",
- "parameters" : [ {
- "name" : "uuid",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- }, {
- "name" : "limit",
- "in" : "query",
- "schema" : {
- "type" : "integer",
- "format" : "int32"
- }
- }, {
- "name" : "offset",
- "in" : "query",
- "schema" : {
- "type" : "integer",
- "format" : "int32"
- }
- } ],
- "responses" : {
- "default" : {
- "description" : "default response",
- "content" : {
- "application/json" : {
- "schema" : {
- "$ref" : "#/components/schemas/ListViewCategorizationData"
- }
- }
- }
- }
- }
- }
- },
"/api/admin/categories/{domainIdentifier}/{path}/objects" : {
"get" : {
- "operationId" : "getObjectsInCategory_1",
+ "operationId" : "getObjectsInCategory",
"parameters" : [ {
"name" : "domainIdentifier",
"in" : "path",
@@ -438,6 +399,45 @@
}
}
},
+ "/api/admin/categories/UUID-{uuid}/objects" : {
+ "get" : {
+ "operationId" : "getObjectsInCategory_1",
+ "parameters" : [ {
+ "name" : "uuid",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ }, {
+ "name" : "limit",
+ "in" : "query",
+ "schema" : {
+ "type" : "integer",
+ "format" : "int32"
+ }
+ }, {
+ "name" : "offset",
+ "in" : "query",
+ "schema" : {
+ "type" : "integer",
+ "format" : "int32"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "default response",
+ "content" : {
+ "application/json" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/ListViewCategorizationData"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/api/admin/categories/ID-{categoryId}/objects" : {
"get" : {
"operationId" : "getCategoryObjectsInCategory",
@@ -509,7 +509,7 @@
}
},
"delete" : {
- "operationId" : "removeObjectFromCategory_1",
+ "operationId" : "removeObjectFromCategory",
"parameters" : [ {
"name" : "categoryId",
"in" : "path",
@@ -568,7 +568,7 @@
},
"/api/admin/categories/{domainIdentifier}/{path}/objects/{objectIdentifier}" : {
"delete" : {
- "operationId" : "removeObjectFromCategory",
+ "operationId" : "removeObjectFromCategory_1",
"parameters" : [ {
"name" : "domainIdentifier",
"in" : "path",
@@ -629,32 +629,15 @@
}
}
},
- "/api/admin/categories/ID-{categoryId}/subcategories" : {
+ "/api/admin/categories/UUID-{categoryId}" : {
"get" : {
- "operationId" : "getSubCategories_1",
+ "operationId" : "getCategory",
"parameters" : [ {
"name" : "categoryId",
"in" : "path",
"required" : true,
"schema" : {
- "type" : "integer",
- "format" : "int64"
- }
- }, {
- "name" : "limit",
- "in" : "query",
- "schema" : {
- "type" : "integer",
- "format" : "int32",
- "default" : 20
- }
- }, {
- "name" : "offset",
- "in" : "query",
- "schema" : {
- "type" : "integer",
- "format" : "int32",
- "default" : 20
+ "type" : "string"
}
} ],
"responses" : {
@@ -663,7 +646,7 @@
"content" : {
"application/json" : {
"schema" : {
- "$ref" : "#/components/schemas/ListViewCategoryData"
+ "$ref" : "#/components/schemas/CategoryData"
}
}
}
@@ -673,7 +656,7 @@
},
"/api/admin/categories/UUID-{categoryUid}/subcategories" : {
"get" : {
- "operationId" : "getSubCategories_2",
+ "operationId" : "getSubCategories",
"parameters" : [ {
"name" : "categoryUuid",
"in" : "path",
@@ -712,15 +695,32 @@
}
}
},
- "/api/admin/categories/UUID-{categoryId}" : {
+ "/api/admin/categories/ID-{categoryId}/subcategories" : {
"get" : {
- "operationId" : "getCategory_2",
+ "operationId" : "getSubCategories_1",
"parameters" : [ {
"name" : "categoryId",
"in" : "path",
"required" : true,
"schema" : {
- "type" : "string"
+ "type" : "integer",
+ "format" : "int64"
+ }
+ }, {
+ "name" : "limit",
+ "in" : "query",
+ "schema" : {
+ "type" : "integer",
+ "format" : "int32",
+ "default" : 20
+ }
+ }, {
+ "name" : "offset",
+ "in" : "query",
+ "schema" : {
+ "type" : "integer",
+ "format" : "int32",
+ "default" : 20
}
} ],
"responses" : {
@@ -729,7 +729,7 @@
"content" : {
"application/json" : {
"schema" : {
- "$ref" : "#/components/schemas/CategoryData"
+ "$ref" : "#/components/schemas/ListViewCategoryData"
}
}
}
@@ -1119,6 +1119,60 @@
}
}
},
+ "/api/admin/groups/{groupIdentifier}/members/{userIdentifier}" : {
+ "put" : {
+ "operationId" : "addMember",
+ "parameters" : [ {
+ "name" : "groupIdentifier",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ }, {
+ "name" : "userIdentifier",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "default response",
+ "content" : {
+ "*/*" : { }
+ }
+ }
+ }
+ },
+ "delete" : {
+ "operationId" : "removeMember",
+ "parameters" : [ {
+ "name" : "groupIdentifier",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ }, {
+ "name" : "userIdentifier",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "default response",
+ "content" : {
+ "*/*" : { }
+ }
+ }
+ }
+ }
+ },
"/api/admin/groups/{groupIdentifier}" : {
"get" : {
"operationId" : "getGroup",
@@ -1245,6 +1299,47 @@
}
}
},
+ "/api/admin/groups/{groupIdentifier}/members" : {
+ "get" : {
+ "operationId" : "getMembers",
+ "parameters" : [ {
+ "name" : "groupIdentifier",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ }, {
+ "name" : "limit",
+ "in" : "query",
+ "schema" : {
+ "type" : "integer",
+ "format" : "int32",
+ "default" : 20
+ }
+ }, {
+ "name" : "offset",
+ "in" : "query",
+ "schema" : {
+ "type" : "integer",
+ "format" : "int32",
+ "default" : 0
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "default response",
+ "content" : {
+ "application/json" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/ListViewGroupUserMembership"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/api/admin/groups/{groupIdentifier}/roles" : {
"get" : {
"operationId" : "getRoleMemberships",
@@ -1327,101 +1422,6 @@
}
}
},
- "/api/admin/groups/{groupIdentifier}/members/{userIdentifier}" : {
- "put" : {
- "operationId" : "addMember",
- "parameters" : [ {
- "name" : "groupIdentifier",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- }, {
- "name" : "userIdentifier",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- } ],
- "responses" : {
- "default" : {
- "description" : "default response",
- "content" : {
- "*/*" : { }
- }
- }
- }
- },
- "delete" : {
- "operationId" : "removeMember",
- "parameters" : [ {
- "name" : "groupIdentifier",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- }, {
- "name" : "userIdentifier",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- } ],
- "responses" : {
- "default" : {
- "description" : "default response",
- "content" : {
- "*/*" : { }
- }
- }
- }
- }
- },
- "/api/admin/groups/{groupIdentifier}/members" : {
- "get" : {
- "operationId" : "getMembers",
- "parameters" : [ {
- "name" : "groupIdentifier",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- }, {
- "name" : "limit",
- "in" : "query",
- "schema" : {
- "type" : "integer",
- "format" : "int32",
- "default" : 20
- }
- }, {
- "name" : "offset",
- "in" : "query",
- "schema" : {
- "type" : "integer",
- "format" : "int32",
- "default" : 0
- }
- } ],
- "responses" : {
- "default" : {
- "description" : "default response",
- "content" : {
- "application/json" : {
- "schema" : {
- "$ref" : "#/components/schemas/ListViewGroupUserMembership"
- }
- }
- }
- }
- }
- }
- },
"/api/admin/roles/{roleIdentifier}" : {
"get" : {
"operationId" : "getRole",
@@ -1494,9 +1494,9 @@
}
}
},
- "/api/admin/roles/{roleIdentifier}/permissions/{permissionIdentifier}" : {
- "delete" : {
- "operationId" : "removePermission",
+ "/api/admin/roles/{roleIdentifier}/members/{partyIdentifier}" : {
+ "put" : {
+ "operationId" : "addMember_1",
"parameters" : [ {
"name" : "roleIdentifier",
"in" : "path",
@@ -1505,7 +1505,7 @@
"type" : "string"
}
}, {
- "name" : "permissionIdentifier",
+ "name" : "partyIdentifier",
"in" : "path",
"required" : true,
"schema" : {
@@ -1520,52 +1520,24 @@
}
}
}
- }
- },
- "/api/admin/roles" : {
- "get" : {
- "operationId" : "getRoles",
+ },
+ "delete" : {
+ "operationId" : "removeMember_1",
"parameters" : [ {
- "name" : "limit",
- "in" : "query",
+ "name" : "roleIdentifier",
+ "in" : "path",
+ "required" : true,
"schema" : {
- "type" : "integer",
- "format" : "int32",
- "default" : 20
+ "type" : "string"
}
}, {
- "name" : "offset",
- "in" : "query",
+ "name" : "partyIdentifier",
+ "in" : "path",
+ "required" : true,
"schema" : {
- "type" : "integer",
- "format" : "int32",
- "default" : 0
+ "type" : "string"
}
} ],
- "responses" : {
- "default" : {
- "description" : "default response",
- "content" : {
- "application/json" : {
- "schema" : {
- "$ref" : "#/components/schemas/ListViewRoleData"
- }
- }
- }
- }
- }
- },
- "post" : {
- "operationId" : "addRole",
- "requestBody" : {
- "content" : {
- "application/json" : {
- "schema" : {
- "$ref" : "#/components/schemas/RoleData"
- }
- }
- }
- },
"responses" : {
"default" : {
"description" : "default response",
@@ -1645,60 +1617,6 @@
}
}
},
- "/api/admin/roles/{roleIdentifier}/members/{partyIdentifier}" : {
- "put" : {
- "operationId" : "addMember_1",
- "parameters" : [ {
- "name" : "roleIdentifier",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- }, {
- "name" : "partyIdentifier",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- } ],
- "responses" : {
- "default" : {
- "description" : "default response",
- "content" : {
- "*/*" : { }
- }
- }
- }
- },
- "delete" : {
- "operationId" : "removeMember_1",
- "parameters" : [ {
- "name" : "roleIdentifier",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- }, {
- "name" : "partyIdentifier",
- "in" : "path",
- "required" : true,
- "schema" : {
- "type" : "string"
- }
- } ],
- "responses" : {
- "default" : {
- "description" : "default response",
- "content" : {
- "*/*" : { }
- }
- }
- }
- }
- },
"/api/admin/roles/{roleIdentifier}/members" : {
"get" : {
"operationId" : "getMembers_1",
@@ -1740,6 +1658,142 @@
}
}
},
+ "/api/admin/roles" : {
+ "get" : {
+ "operationId" : "getRoles",
+ "parameters" : [ {
+ "name" : "limit",
+ "in" : "query",
+ "schema" : {
+ "type" : "integer",
+ "format" : "int32",
+ "default" : 20
+ }
+ }, {
+ "name" : "offset",
+ "in" : "query",
+ "schema" : {
+ "type" : "integer",
+ "format" : "int32",
+ "default" : 0
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "default response",
+ "content" : {
+ "application/json" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/ListViewRoleData"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post" : {
+ "operationId" : "addRole",
+ "requestBody" : {
+ "content" : {
+ "application/json" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/RoleData"
+ }
+ }
+ }
+ },
+ "responses" : {
+ "default" : {
+ "description" : "default response",
+ "content" : {
+ "*/*" : { }
+ }
+ }
+ }
+ }
+ },
+ "/api/admin/roles/{roleIdentifier}/permissions/{permissionIdentifier}" : {
+ "delete" : {
+ "operationId" : "removePermission",
+ "parameters" : [ {
+ "name" : "roleIdentifier",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ }, {
+ "name" : "permissionIdentifier",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "default response",
+ "content" : {
+ "*/*" : { }
+ }
+ }
+ }
+ }
+ },
+ "/api/admin/users" : {
+ "get" : {
+ "operationId" : "getUsers",
+ "parameters" : [ {
+ "name" : "limit",
+ "in" : "query",
+ "schema" : {
+ "type" : "integer",
+ "format" : "int32",
+ "default" : 20
+ }
+ }, {
+ "name" : "offset",
+ "in" : "query",
+ "schema" : {
+ "type" : "integer",
+ "format" : "int32",
+ "default" : 0
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "default response",
+ "content" : {
+ "application/json" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/ListViewUserData"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post" : {
+ "operationId" : "addUser",
+ "requestBody" : {
+ "content" : {
+ "application/json" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/User"
+ }
+ }
+ }
+ },
+ "responses" : {
+ "default" : {
+ "description" : "default response",
+ "content" : {
+ "*/*" : { }
+ }
+ }
+ }
+ }
+ },
"/api/admin/users/{userIdentifier}" : {
"get" : {
"operationId" : "getUser",
@@ -1812,60 +1866,6 @@
}
}
},
- "/api/admin/users" : {
- "get" : {
- "operationId" : "getUsers",
- "parameters" : [ {
- "name" : "limit",
- "in" : "query",
- "schema" : {
- "type" : "integer",
- "format" : "int32",
- "default" : 20
- }
- }, {
- "name" : "offset",
- "in" : "query",
- "schema" : {
- "type" : "integer",
- "format" : "int32",
- "default" : 0
- }
- } ],
- "responses" : {
- "default" : {
- "description" : "default response",
- "content" : {
- "application/json" : {
- "schema" : {
- "$ref" : "#/components/schemas/ListViewUserData"
- }
- }
- }
- }
- }
- },
- "post" : {
- "operationId" : "addUser",
- "requestBody" : {
- "content" : {
- "application/json" : {
- "schema" : {
- "$ref" : "#/components/schemas/User"
- }
- }
- }
- },
- "responses" : {
- "default" : {
- "description" : "default response",
- "content" : {
- "*/*" : { }
- }
- }
- }
- }
- },
"/api/admin/users/{userIdentifier}/roles" : {
"get" : {
"operationId" : "getRoleMemberships_1",
@@ -2521,13 +2521,13 @@
}
}
},
- "ListViewGroupData" : {
+ "ListViewGroupUserMembership" : {
"type" : "object",
"properties" : {
"list" : {
"type" : "array",
"items" : {
- "$ref" : "#/components/schemas/GroupData"
+ "$ref" : "#/components/schemas/GroupUserMembership"
}
},
"count" : {
@@ -2544,13 +2544,13 @@
}
}
},
- "ListViewGroupUserMembership" : {
+ "ListViewGroupData" : {
"type" : "object",
"properties" : {
"list" : {
"type" : "array",
"items" : {
- "$ref" : "#/components/schemas/GroupUserMembership"
+ "$ref" : "#/components/schemas/GroupData"
}
},
"count" : {
@@ -2625,29 +2625,6 @@
}
}
},
- "ListViewRoleData" : {
- "type" : "object",
- "properties" : {
- "list" : {
- "type" : "array",
- "items" : {
- "$ref" : "#/components/schemas/RoleData"
- }
- },
- "count" : {
- "type" : "integer",
- "format" : "int64"
- },
- "limit" : {
- "type" : "integer",
- "format" : "int64"
- },
- "offset" : {
- "type" : "integer",
- "format" : "int64"
- }
- }
- },
"ListViewRolePermission" : {
"type" : "object",
"properties" : {
@@ -2709,90 +2686,13 @@
}
}
},
- "EmailAddressData" : {
- "type" : "object",
- "properties" : {
- "address" : {
- "type" : "string"
- },
- "bouncing" : {
- "type" : "boolean"
- },
- "verified" : {
- "type" : "boolean"
- }
- }
- },
- "UserData" : {
- "type" : "object",
- "properties" : {
- "partyId" : {
- "type" : "integer",
- "format" : "int64"
- },
- "uuid" : {
- "type" : "string"
- },
- "name" : {
- "type" : "string"
- },
- "givenName" : {
- "type" : "string"
- },
- "familyName" : {
- "type" : "string"
- },
- "primaryEmailAddress" : {
- "$ref" : "#/components/schemas/EmailAddressData"
- },
- "emailAddresses" : {
- "type" : "array",
- "items" : {
- "$ref" : "#/components/schemas/EmailAddressData"
- }
- },
- "banned" : {
- "type" : "boolean"
- },
- "passwordResetRequired" : {
- "type" : "boolean"
- },
- "groupMemberships" : {
- "type" : "array",
- "items" : {
- "$ref" : "#/components/schemas/UserGroupMembership"
- }
- },
- "roleMemberships" : {
- "type" : "array",
- "items" : {
- "$ref" : "#/components/schemas/PartyRoleMembership"
- }
- }
- }
- },
- "UserGroupMembership" : {
- "type" : "object",
- "properties" : {
- "membershipId" : {
- "type" : "integer",
- "format" : "int64"
- },
- "uuid" : {
- "type" : "string"
- },
- "group" : {
- "$ref" : "#/components/schemas/PartyId"
- }
- }
- },
- "ListViewUserData" : {
+ "ListViewRoleData" : {
"type" : "object",
"properties" : {
"list" : {
"type" : "array",
"items" : {
- "$ref" : "#/components/schemas/UserData"
+ "$ref" : "#/components/schemas/RoleData"
}
},
"count" : {
@@ -2905,6 +2805,106 @@
"name" : "user",
"namespace" : "http://core.libreccm.org"
}
+ },
+ "EmailAddressData" : {
+ "type" : "object",
+ "properties" : {
+ "address" : {
+ "type" : "string"
+ },
+ "bouncing" : {
+ "type" : "boolean"
+ },
+ "verified" : {
+ "type" : "boolean"
+ }
+ }
+ },
+ "ListViewUserData" : {
+ "type" : "object",
+ "properties" : {
+ "list" : {
+ "type" : "array",
+ "items" : {
+ "$ref" : "#/components/schemas/UserData"
+ }
+ },
+ "count" : {
+ "type" : "integer",
+ "format" : "int64"
+ },
+ "limit" : {
+ "type" : "integer",
+ "format" : "int64"
+ },
+ "offset" : {
+ "type" : "integer",
+ "format" : "int64"
+ }
+ }
+ },
+ "UserData" : {
+ "type" : "object",
+ "properties" : {
+ "partyId" : {
+ "type" : "integer",
+ "format" : "int64"
+ },
+ "uuid" : {
+ "type" : "string"
+ },
+ "name" : {
+ "type" : "string"
+ },
+ "givenName" : {
+ "type" : "string"
+ },
+ "familyName" : {
+ "type" : "string"
+ },
+ "primaryEmailAddress" : {
+ "$ref" : "#/components/schemas/EmailAddressData"
+ },
+ "emailAddresses" : {
+ "type" : "array",
+ "items" : {
+ "$ref" : "#/components/schemas/EmailAddressData"
+ }
+ },
+ "banned" : {
+ "type" : "boolean"
+ },
+ "passwordResetRequired" : {
+ "type" : "boolean"
+ },
+ "groupMemberships" : {
+ "type" : "array",
+ "items" : {
+ "$ref" : "#/components/schemas/UserGroupMembership"
+ }
+ },
+ "roleMemberships" : {
+ "type" : "array",
+ "items" : {
+ "$ref" : "#/components/schemas/PartyRoleMembership"
+ }
+ }
+ }
+ },
+ "UserGroupMembership" : {
+ "type" : "object",
+ "properties" : {
+ "membershipId" : {
+ "type" : "integer",
+ "format" : "int64"
+ },
+ "uuid" : {
+ "type" : "string"
+ },
+ "group" : {
+ "$ref" : "#/components/schemas/PartyId"
+ }
+ }
}
}
}