parent
f7721dd41b
commit
4cc48686d5
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@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<ComponentModelJsonConverter> 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<ComponentModel> 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<ComponentModelJsonConverter>
|
||||||
|
findJsonConverter(
|
||||||
|
final Class<? extends ComponentModel> componentModelClass
|
||||||
|
) {
|
||||||
|
|
||||||
|
final ConvertsComponentModelLiteral literal
|
||||||
|
= new ConvertsComponentModelLiteral(
|
||||||
|
componentModelClass
|
||||||
|
);
|
||||||
|
final Instance<ComponentModelJsonConverter> 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<ComponentModelJsonConverter> iterator = instance
|
||||||
|
.iterator();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final ComponentModelJsonConverter converter = iterator.next();
|
||||||
|
|
||||||
|
return Optional.of(converter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ConvertsComponentModelLiteral
|
||||||
|
extends AnnotationLiteral<ConvertsComponentModel>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.libreccm.pagemodel.rs;
|
package org.libreccm.api.pagemodels;
|
||||||
|
|
||||||
import org.libreccm.core.CoreConstants;
|
import org.libreccm.core.CoreConstants;
|
||||||
import org.libreccm.pagemodel.ContainerModel;
|
import org.libreccm.pagemodel.ContainerModel;
|
||||||
|
|
@ -27,6 +27,7 @@ import org.libreccm.security.AuthorizationRequired;
|
||||||
import org.libreccm.security.RequiresPrivilege;
|
import org.libreccm.security.RequiresPrivilege;
|
||||||
import org.libreccm.web.CcmApplication;
|
import org.libreccm.web.CcmApplication;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
|
@ -43,6 +44,8 @@ import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
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
|
* Provides RESTful endpoints for managing the {@link ContainerModel}s of a
|
||||||
|
|
@ -51,7 +54,7 @@ import javax.ws.rs.Produces;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
@Path("/")
|
@Path("/{appName}/{pageModelName}/containers")
|
||||||
public class Containers {
|
public class Containers {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
|
@ -66,7 +69,7 @@ public class Containers {
|
||||||
/**
|
/**
|
||||||
* Retrieves all {@link ContainerModel}s of a {@link PageModel}.
|
* 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.
|
* which the {@link PageModel} belongs.
|
||||||
* @param pageModelName The name of the {@link PageModel} of which the
|
* @param pageModelName The name of the {@link PageModel} of which the
|
||||||
* containers are retrieved.
|
* containers are retrieved.
|
||||||
|
|
@ -76,20 +79,22 @@ public class Containers {
|
||||||
* the {@link CcmApplication} with the primary URL {@code appPath}.
|
* the {@link CcmApplication} with the primary URL {@code appPath}.
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Path(PageModelsApp.CONTAINERS_PATH)
|
@Path("/")
|
||||||
@Produces("application/json; charset=utf-8")
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
public JsonArray getContainers(
|
public JsonArray getContainers(
|
||||||
@PathParam(PageModelsApp.APP_NAME) final String appPath,
|
@PathParam("appName") final String appName,
|
||||||
@PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName) {
|
@PathParam("pageModelName") final String pageModelName
|
||||||
|
) {
|
||||||
final CcmApplication app = controller.findCcmApplication(
|
final CcmApplication app = controller.findCcmApplication(
|
||||||
String.format("/%s/", appPath));
|
String.format("/%s/", appName)
|
||||||
|
);
|
||||||
|
|
||||||
final PageModel pageModel = controller.findPageModel(app,
|
final PageModel pageModel = controller.findPageModel(
|
||||||
pageModelName);
|
app, pageModelName
|
||||||
|
);
|
||||||
|
|
||||||
final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
|
final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
|
||||||
pageModel
|
pageModel
|
||||||
|
|
@ -104,7 +109,7 @@ public class Containers {
|
||||||
/**
|
/**
|
||||||
* Retrieve a specific {@link ContainerModel}.
|
* 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.
|
* which the {@link PageModel} belongs.
|
||||||
* @param pageModelName The name of the {@link PageModel} to which the
|
* @param pageModelName The name of the {@link PageModel} to which the
|
||||||
* {@link ContainerModel} belongs.
|
* {@link ContainerModel} belongs.
|
||||||
|
|
@ -114,25 +119,27 @@ public class Containers {
|
||||||
* @return A JSON object containing the data of the {@link PageModel}.
|
* @return A JSON object containing the data of the {@link PageModel}.
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Path(PageModelsApp.CONTAINER_PATH)
|
@Path("/{containerKey}")
|
||||||
@Produces("application/json; charset=utf-8")
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
public JsonObject getContainer(
|
public JsonObject getContainer(
|
||||||
@PathParam(PageModelsApp.APP_NAME) final String appPath,
|
@PathParam("appName") final String appName,
|
||||||
@PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
|
@PathParam("pageModelName") final String pageModelName,
|
||||||
@PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey) {
|
@PathParam("containerKey") final String containerKey
|
||||||
|
) {
|
||||||
final CcmApplication app = controller.findCcmApplication(
|
final CcmApplication app = controller.findCcmApplication(
|
||||||
String.format("/%s/", appPath));
|
String.format("/%s/", appName)
|
||||||
|
);
|
||||||
|
|
||||||
final PageModel pageModel = controller.findPageModel(app,
|
final PageModel pageModel = controller.findPageModel(
|
||||||
pageModelName);
|
app, pageModelName
|
||||||
|
);
|
||||||
|
|
||||||
final ContainerModel container = controller.findContainer(app,
|
final ContainerModel container = controller.findContainer(
|
||||||
pageModel,
|
app, pageModel, containerKey
|
||||||
containerKey);
|
);
|
||||||
|
|
||||||
return mapContainerModelToJson(container);
|
return mapContainerModelToJson(container);
|
||||||
}
|
}
|
||||||
|
|
@ -147,32 +154,36 @@ public class Containers {
|
||||||
* If there is no such {@link ContainerModel} a new {@link ContainerModel}
|
* If there is no such {@link ContainerModel} a new {@link ContainerModel}
|
||||||
* is created using the data provided by {@code containerModelData}.
|
* 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 pageModelName The name of the {@link PageModel}.
|
||||||
* @param containerKey The key identifying the {@link ContainerModel}.
|
* @param containerKey The key identifying the {@link ContainerModel}.
|
||||||
* @param containerModelData The data for updating or creating the
|
* @param containerModelData The data for updating or creating the
|
||||||
* {@link ContainerModel}.
|
* {@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
|
@PUT
|
||||||
@Path(PageModelsApp.CONTAINER_PATH)
|
@Path("/{containerKey}")
|
||||||
@Consumes("application/json; charset=utf-8")
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Produces("application/json; charset=utf-8")
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
public JsonObject putContainer(
|
public Response putContainer(
|
||||||
@PathParam(PageModelsApp.APP_NAME) final String appPath,
|
@PathParam("appName") final String appName,
|
||||||
@PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
|
@PathParam("pageModelName") final String pageModelName,
|
||||||
@PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
|
@PathParam("containerKey") final String containerKey,
|
||||||
final JsonObject containerModelData) {
|
final JsonObject containerModelData
|
||||||
|
) {
|
||||||
final CcmApplication app = controller.findCcmApplication(
|
final CcmApplication app = controller.findCcmApplication(
|
||||||
String.format("/%s/", appPath));
|
String.format("/%s/", appName)
|
||||||
|
);
|
||||||
final PageModel pageModel = controller.findPageModel(app,
|
final PageModel pageModel = controller.findPageModel(
|
||||||
pageModelName);
|
app, pageModelName
|
||||||
|
);
|
||||||
|
|
||||||
final Optional<ContainerModel> result = pageModel
|
final Optional<ContainerModel> result = pageModel
|
||||||
.getContainers()
|
.getContainers()
|
||||||
|
|
@ -181,52 +192,90 @@ public class Containers {
|
||||||
.findAny();
|
.findAny();
|
||||||
|
|
||||||
final ContainerModel containerModel;
|
final ContainerModel containerModel;
|
||||||
|
final boolean created;
|
||||||
if (result.isPresent()) {
|
if (result.isPresent()) {
|
||||||
|
|
||||||
containerModel = result.get();
|
containerModel = result.get();
|
||||||
|
|
||||||
result.get().setKey(containerKey);
|
containerModel.setKey(containerKey);
|
||||||
containerModelRepo.save(result.get());
|
containerModelRepo.save(containerModel);
|
||||||
|
created = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
containerModel = new ContainerModel();
|
containerModel = new ContainerModel();
|
||||||
containerModel.setKey(containerKey);
|
containerModel.setKey(containerKey);
|
||||||
|
|
||||||
pageModelManager.addContainerModel(pageModel, containerModel);
|
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.
|
* 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 pageModelName The name of the {@link PageModel}.
|
||||||
* @param containerKey The key identifying the {@link ContainerModel} to
|
* @param containerKey The key identifying the {@link ContainerModel} to
|
||||||
* delete.
|
* delete.
|
||||||
|
*
|
||||||
|
* @return A HTTP response with the status code {@code 200} if the container
|
||||||
|
* model was deleted successfully.
|
||||||
*/
|
*/
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path(PageModelsApp.CONTAINER_PATH)
|
@Path("/{containerKey}")
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
public void deleteContainer(
|
public Response deleteContainer(
|
||||||
@PathParam(PageModelsApp.APP_NAME) final String appPath,
|
@PathParam("appName") final String appName,
|
||||||
@PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
|
@PathParam("pageModelName") final String pageModelName,
|
||||||
@PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey) {
|
@PathParam("containerKey") final String containerKey
|
||||||
|
) {
|
||||||
|
|
||||||
final CcmApplication app = controller.findCcmApplication(
|
final CcmApplication app = controller.findCcmApplication(
|
||||||
String.format("/%s/", appPath));
|
String.format("/%s/", appName)
|
||||||
|
);
|
||||||
|
|
||||||
final PageModel pageModel = controller.findPageModel(app,
|
final PageModel pageModel = controller.findPageModel(
|
||||||
pageModelName);
|
app, pageModelName
|
||||||
|
);
|
||||||
|
|
||||||
final ContainerModel container = controller.findContainer(app,
|
final ContainerModel container = controller.findContainer(
|
||||||
pageModel,
|
app, pageModel, containerKey
|
||||||
containerKey);
|
);
|
||||||
|
|
||||||
pageModelManager.removeContainerModel(pageModel, container);
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -16,14 +16,13 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.libreccm.pagemodel.rs;
|
package org.libreccm.api.pagemodels;
|
||||||
|
|
||||||
import com.arsdigita.kernel.KernelConfig;
|
import com.arsdigita.kernel.KernelConfig;
|
||||||
|
|
||||||
import org.libreccm.configuration.ConfigurationManager;
|
import org.libreccm.configuration.ConfigurationManager;
|
||||||
import org.libreccm.core.CoreConstants;
|
import org.libreccm.core.CoreConstants;
|
||||||
import org.libreccm.l10n.GlobalizationHelper;
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
import org.libreccm.pagemodel.ComponentModel;
|
|
||||||
import org.libreccm.pagemodel.ContainerModel;
|
import org.libreccm.pagemodel.ContainerModel;
|
||||||
import org.libreccm.pagemodel.PageModel;
|
import org.libreccm.pagemodel.PageModel;
|
||||||
import org.libreccm.pagemodel.PageModelManager;
|
import org.libreccm.pagemodel.PageModelManager;
|
||||||
|
|
@ -32,6 +31,8 @@ import org.libreccm.security.AuthorizationRequired;
|
||||||
import org.libreccm.security.RequiresPrivilege;
|
import org.libreccm.security.RequiresPrivilege;
|
||||||
import org.libreccm.web.CcmApplication;
|
import org.libreccm.web.CcmApplication;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.json.Json;
|
import javax.json.Json;
|
||||||
|
|
@ -50,11 +51,11 @@ import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
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
|
* Provides RESTful endpoints for retrieving, creating, updating and deleting
|
||||||
|
|
@ -63,7 +64,7 @@ import java.util.stream.Collectors;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
@Path("/")
|
@Path("/{appName}")
|
||||||
public class PageModels {
|
public class PageModels {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
|
@ -85,29 +86,29 @@ public class PageModels {
|
||||||
* Retrieves all {@link PageModel}s available for an {@link
|
* Retrieves all {@link PageModel}s available for an {@link
|
||||||
* CcmApplication}.
|
* 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
|
* @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
|
* @throws NotFoundException If there is no {@link CcmApplication} with the
|
||||||
* primary URL {@code appPath} an {@link
|
* primary URL {@code appPath} an {@link
|
||||||
* NotFoundException} thrown resulting in 404
|
* NotFoundException} thrown resulting in 404 response.
|
||||||
* response.
|
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Path(PageModelsApp.PAGE_MODELS_PATH)
|
@Path("/")
|
||||||
@Produces("application/json; charset=utf-8")
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
public JsonArray getAllPageModels(
|
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/", appName)
|
||||||
final CcmApplication app = controller
|
);
|
||||||
.findCcmApplication(String.format("/%s/", appPath));
|
|
||||||
final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
|
final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
|
||||||
pageModelRepo
|
pageModelRepo
|
||||||
.findDraftByApplication(app)
|
.findDraftByApplication(app)
|
||||||
|
|
@ -121,65 +122,73 @@ public class PageModels {
|
||||||
/**
|
/**
|
||||||
* Retrieves a specific {@link PageModel}.
|
* 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
|
* {@link CcmApplication} to which the {@link
|
||||||
* PageModel} belongs (see
|
* PageModel} belongs (see {@link PageModel#application}).
|
||||||
* {@link PageModel#application}).
|
|
||||||
* @param pageModelName The name of the {@link PageModel} to retrieve (see
|
* @param pageModelName The name of the {@link PageModel} to retrieve (see
|
||||||
* {@link PageModel#name}).
|
* {@link PageModel#name}).
|
||||||
*
|
*
|
||||||
* @return A JSON object containing the data of the {@link PageModel}.
|
* @return A JSON object containing the data of the {@link PageModel}.
|
||||||
*
|
*
|
||||||
* @throws NotFoundException If there is not {@link CcmApplication} with the
|
* @throws NotFoundException If there is not {@link CcmApplication} with the
|
||||||
* primary URL {@code appPath} a {@link
|
* primary URL {@code appPath} a
|
||||||
* NotFoundException} is thrown resulting in a 404
|
* {@link NotFoundException} is thrown resulting
|
||||||
* response. A {@link NotFoundException} is also
|
* in a 404 response. A {@link NotFoundException}
|
||||||
* thrown if there no {@link PageModel} identified
|
* is also thrown if there no {@link PageModel}
|
||||||
* by {@code pageModelName} for the {@link
|
* identified by {@code pageModelName} for the
|
||||||
* CcmApplication} with the primary URL {@code
|
* {@link CcmApplication} with the primary URL
|
||||||
* appPath}.
|
* {@code appPath}.
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Path(PageModelsApp.PAGE_MODEL_PATH)
|
@Path("/{pageModelName}")
|
||||||
@Produces("application/json; charset=utf-8")
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
public JsonObject getPageModel(
|
public JsonObject getPageModel(
|
||||||
@PathParam(PageModelsApp.APP_NAME) final String appPath,
|
@PathParam("appName") final String appName,
|
||||||
@PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName) {
|
@PathParam("pageModelName") final String pageModelName
|
||||||
|
) {
|
||||||
Objects.requireNonNull(appPath);
|
Objects.requireNonNull(appName);
|
||||||
Objects.requireNonNull(pageModelName);
|
Objects.requireNonNull(pageModelName);
|
||||||
|
|
||||||
final CcmApplication app = controller
|
final CcmApplication app = controller.findCcmApplication(
|
||||||
.findCcmApplication(String.format("/%s/", appPath));
|
String.format("/%s/", appName)
|
||||||
final PageModel pageModel = controller.findPageModel(app,
|
);
|
||||||
pageModelName);
|
final PageModel pageModel = controller.findPageModel(
|
||||||
|
app, pageModelName
|
||||||
|
);
|
||||||
return mapPageModelToJson(pageModel);
|
return mapPageModelToJson(pageModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path(PageModelsApp.PAGE_MODEL_PATH)
|
@Path("/{pageModelName}")
|
||||||
@Produces("application/json; charset=utf-8")
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
public JsonObject publishPageModel(
|
public Response publishPageModel(
|
||||||
@PathParam(PageModelsApp.APP_NAME) final String appPath,
|
@PathParam("appName") final String appName,
|
||||||
@PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
|
@PathParam("pageModelName") final String pageModelName,
|
||||||
@FormParam("action") String action) {
|
@FormParam("action") String action
|
||||||
|
) {
|
||||||
if ("publish".equals(action)) {
|
if ("publish".equals(action)) {
|
||||||
|
final CcmApplication app = controller.findCcmApplication(
|
||||||
final CcmApplication app = controller
|
String.format("/%s/", appName)
|
||||||
.findCcmApplication(String.format("/%s/", appPath));
|
);
|
||||||
final PageModel pageModel = controller.findPageModel(app,
|
final PageModel pageModel = controller.findPageModel(
|
||||||
pageModelName);
|
app, pageModelName
|
||||||
|
);
|
||||||
pageModelManager.publish(pageModel);
|
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
|
* {@link PageModel} is created and associated with the {@link
|
||||||
* CcmApplication} identified by the primary URL {@code appPath}.
|
* 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.
|
* which the {@link PageModel} belongs.
|
||||||
* @param pageModelName The name of the {@link PageModel}.
|
* @param pageModelName The name of the {@link PageModel}.
|
||||||
* @param pageModelData The data for creating or updating the {@link
|
* @param pageModelData The data for creating or updating the {@link
|
||||||
* PageModel}.
|
* 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
|
@PUT
|
||||||
@Path(PageModelsApp.PAGE_MODEL_PATH)
|
@Path("/{pageModelName}")
|
||||||
@Consumes("application/json; charset=utf-8")
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Produces("application/json; charset=utf-8")
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
public JsonObject putPageModel(
|
public Response putPageModel(
|
||||||
@PathParam(PageModelsApp.APP_NAME) final String appPath,
|
@PathParam("appName") final String appName,
|
||||||
@PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
|
@PathParam("pageModelName") final String pageModelName,
|
||||||
final JsonObject pageModelData) {
|
final JsonObject pageModelData
|
||||||
|
) {
|
||||||
Objects.requireNonNull(appPath);
|
Objects.requireNonNull(appName);
|
||||||
Objects.requireNonNull(pageModelName);
|
Objects.requireNonNull(pageModelName);
|
||||||
|
|
||||||
final CcmApplication app = controller
|
final CcmApplication app = controller.findCcmApplication(
|
||||||
.findCcmApplication(String.format("/%s/", appPath));
|
String.format("/%s/", appName)
|
||||||
|
);
|
||||||
|
|
||||||
final KernelConfig kernelConfig = confManager
|
final KernelConfig kernelConfig = confManager
|
||||||
.findConfiguration(KernelConfig.class);
|
.findConfiguration(KernelConfig.class);
|
||||||
|
|
||||||
final PageModel pageModel;
|
final PageModel pageModel;
|
||||||
|
final boolean created;
|
||||||
if (controller.existsPageModel(app, pageModelName)) {
|
if (controller.existsPageModel(app, pageModelName)) {
|
||||||
pageModel = controller.findPageModel(app, pageModelName);
|
pageModel = controller.findPageModel(app, pageModelName);
|
||||||
|
created = false;
|
||||||
} else {
|
} else {
|
||||||
pageModel = pageModelManager.createPageModel(pageModelName, app);
|
pageModel = pageModelManager.createPageModel(pageModelName, app);
|
||||||
|
created = true;
|
||||||
}
|
}
|
||||||
if (pageModelData.containsKey("title")) {
|
if (pageModelData.containsKey("title")) {
|
||||||
pageModel.getTitle().addValue(kernelConfig.getDefaultLocale(),
|
pageModel.getTitle().addValue(
|
||||||
pageModelData.getString("title"));
|
kernelConfig.getDefaultLocale(),
|
||||||
|
pageModelData.getString("title")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (pageModelData.containsKey("description")) {
|
if (pageModelData.containsKey("description")) {
|
||||||
pageModel
|
pageModel
|
||||||
.getDescription()
|
.getDescription()
|
||||||
.addValue(kernelConfig.getDefaultLocale(),
|
.addValue(
|
||||||
pageModelData.getString("description"));
|
kernelConfig.getDefaultLocale(),
|
||||||
|
pageModelData.getString("description")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
controller.savePageModel(pageModel);
|
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}.
|
* 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.
|
* which the {@link PageModel} belongs.
|
||||||
* @param pageModelName The name of the {@link PageModel} to delete.
|
* @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
|
@DELETE
|
||||||
@Path(PageModelsApp.PAGE_MODEL_PATH)
|
@Path("/{appName}/{pageModelName}")
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
public void deletePageModel(
|
public Response deletePageModel(
|
||||||
@PathParam(PageModelsApp.APP_NAME) final String appPath,
|
@PathParam("appName") final String appName,
|
||||||
@PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName) {
|
@PathParam("pageModelName") final String pageModelName
|
||||||
|
) {
|
||||||
Objects.requireNonNull(appPath);
|
Objects.requireNonNull(appName);
|
||||||
Objects.requireNonNull(pageModelName);
|
Objects.requireNonNull(pageModelName);
|
||||||
|
|
||||||
final CcmApplication app = controller
|
final CcmApplication app = controller.findCcmApplication(
|
||||||
.findCcmApplication(String.format("/%s/", appPath));
|
String.format("/%s/", appName)
|
||||||
final PageModel pageModel = controller.findPageModel(app,
|
);
|
||||||
pageModelName);
|
final PageModel pageModel = controller.findPageModel(
|
||||||
|
app, pageModelName
|
||||||
|
);
|
||||||
pageModelRepo.delete(pageModel);
|
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);
|
Objects.requireNonNull(pageModel);
|
||||||
|
|
||||||
final long lastPublished;
|
final long lastPublished;
|
||||||
final Optional<PageModel> liveModel = pageModelManager
|
final Optional<PageModel> liveModel = pageModelManager.getLiveVersion(
|
||||||
.getLiveVersion(pageModel);
|
pageModel
|
||||||
|
);
|
||||||
if (liveModel.isPresent()
|
if (liveModel.isPresent()
|
||||||
&& liveModel.get().getLastModified() != null) {
|
&& liveModel.get().getLastModified() != null) {
|
||||||
lastPublished = liveModel.get().getLastModified().getTime();
|
lastPublished = liveModel.get().getLastModified().getTime();
|
||||||
} else {
|
} else {
|
||||||
lastPublished = 0;
|
lastPublished = 0;
|
||||||
|
|
@ -300,27 +351,33 @@ public class PageModels {
|
||||||
return Json
|
return Json
|
||||||
.createObjectBuilder()
|
.createObjectBuilder()
|
||||||
.add("containers", mapContainersToJson(pageModel))
|
.add("containers", mapContainersToJson(pageModel))
|
||||||
.add("description",
|
.add(
|
||||||
globalizationHelper
|
"description",
|
||||||
.getValueFromLocalizedString(pageModel.getDescription()))
|
globalizationHelper.getValueFromLocalizedString(
|
||||||
|
pageModel.getDescription()
|
||||||
|
)
|
||||||
|
)
|
||||||
.add("modelUuid", pageModel.getModelUuid())
|
.add("modelUuid", pageModel.getModelUuid())
|
||||||
.add("name", pageModel.getName())
|
.add("name", pageModel.getName())
|
||||||
.add("pageModelId", Long.toString(pageModel.getPageModelId()))
|
.add("pageModelId", Long.toString(pageModel.getPageModelId()))
|
||||||
.add("title",
|
.add(
|
||||||
globalizationHelper
|
"title",
|
||||||
.getValueFromLocalizedString(pageModel.getTitle()))
|
globalizationHelper.getValueFromLocalizedString(
|
||||||
|
pageModel.getTitle()
|
||||||
|
)
|
||||||
|
)
|
||||||
.add("type", pageModel.getType())
|
.add("type", pageModel.getType())
|
||||||
.add("uuid", pageModel.getUuid())
|
.add("uuid", pageModel.getUuid())
|
||||||
.add("version", pageModel.getVersion().toString())
|
.add("version", pageModel.getVersion().toString())
|
||||||
.add("publicationStatus",
|
.add("publicationStatus",
|
||||||
getPublicationStatus(pageModel).toString())
|
getPublicationStatus(pageModel).toString()
|
||||||
|
)
|
||||||
.add("lastModified", lastModified)
|
.add("lastModified", lastModified)
|
||||||
.add("lastPublished", lastPublished)
|
.add("lastPublished", lastPublished)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonArray mapContainersToJson(final PageModel pageModel) {
|
private JsonArray mapContainersToJson(final PageModel pageModel) {
|
||||||
|
|
||||||
final JsonArrayBuilder containers = Json.createArrayBuilder();
|
final JsonArrayBuilder containers = Json.createArrayBuilder();
|
||||||
|
|
||||||
pageModel
|
pageModel
|
||||||
|
|
@ -333,7 +390,6 @@ public class PageModels {
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonObject mapContainerToJson(final ContainerModel container) {
|
private JsonObject mapContainerToJson(final ContainerModel container) {
|
||||||
|
|
||||||
return Json
|
return Json
|
||||||
.createObjectBuilder()
|
.createObjectBuilder()
|
||||||
.add("containerUuid", container.getContainerUuid())
|
.add("containerUuid", container.getContainerUuid())
|
||||||
|
|
@ -350,7 +406,6 @@ public class PageModels {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private PublicationStatus getPublicationStatus(final PageModel pageModel) {
|
private PublicationStatus getPublicationStatus(final PageModel pageModel) {
|
||||||
|
|
||||||
final PageModel draftModel = pageModelManager
|
final PageModel draftModel = pageModelManager
|
||||||
.getDraftVersion(pageModel);
|
.getDraftVersion(pageModel);
|
||||||
final Optional<PageModel> liveModel = pageModelManager
|
final Optional<PageModel> liveModel = pageModelManager
|
||||||
|
|
@ -361,7 +416,7 @@ public class PageModels {
|
||||||
|
|
||||||
// Fallback if one the last modified dates is null
|
// Fallback if one the last modified dates is null
|
||||||
if (draftModel.getLastModified() == null
|
if (draftModel.getLastModified() == null
|
||||||
|| liveModel.get().getLastModified() == null) {
|
|| liveModel.get().getLastModified() == null) {
|
||||||
|
|
||||||
return PublicationStatus.NEEDS_UPDATE;
|
return PublicationStatus.NEEDS_UPDATE;
|
||||||
} else if (draftModel
|
} else if (draftModel
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.libreccm.pagemodel.rs;
|
package org.libreccm.api.pagemodels;
|
||||||
|
|
||||||
import org.libreccm.pagemodel.PageModel;
|
import org.libreccm.pagemodel.PageModel;
|
||||||
|
|
||||||
|
|
@ -42,34 +42,9 @@ import javax.ws.rs.core.Application;
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@ApplicationPath("/page-models")
|
@ApplicationPath("/api/page-models")
|
||||||
public class PageModelsApp extends Application {
|
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
|
@Override
|
||||||
public Set<Class<?>> getClasses() {
|
public Set<Class<?>> getClasses() {
|
||||||
|
|
||||||
|
|
@ -77,9 +52,6 @@ public class PageModelsApp extends Application {
|
||||||
classes.add(PageModels.class);
|
classes.add(PageModels.class);
|
||||||
classes.add(Containers.class);
|
classes.add(Containers.class);
|
||||||
classes.add(Components.class);
|
classes.add(Components.class);
|
||||||
classes.add(StylesRs.class);
|
|
||||||
classes.add(StylesMediaRule.class);
|
|
||||||
classes.add(StylesRule.class);
|
|
||||||
|
|
||||||
return classes;
|
return classes;
|
||||||
}
|
}
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.libreccm.pagemodel.rs;
|
package org.libreccm.api.pagemodels;
|
||||||
|
|
||||||
import org.libreccm.pagemodel.ComponentModel;
|
import org.libreccm.pagemodel.ComponentModel;
|
||||||
import org.libreccm.pagemodel.ComponentModelRepository;
|
import org.libreccm.pagemodel.ComponentModelRepository;
|
||||||
|
|
@ -67,9 +67,12 @@ class PageModelsController {
|
||||||
|
|
||||||
return appRepo
|
return appRepo
|
||||||
.retrieveApplicationForPath(Objects.requireNonNull(appPath))
|
.retrieveApplicationForPath(Objects.requireNonNull(appPath))
|
||||||
.orElseThrow(() -> new NotFoundException(String
|
.orElseThrow(() -> new NotFoundException(
|
||||||
.format("No application with path \"%s\" found.",
|
String.format(
|
||||||
appPath)));
|
"No application with path \"%s\" found.",
|
||||||
|
appPath)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -88,18 +91,23 @@ class PageModelsController {
|
||||||
final CcmApplication app,
|
final CcmApplication app,
|
||||||
final PageModel pageModel,
|
final PageModel pageModel,
|
||||||
final ContainerModel containerModel,
|
final ContainerModel containerModel,
|
||||||
final String componentKey) {
|
final String componentKey
|
||||||
|
) {
|
||||||
return componentModelRepo
|
return componentModelRepo
|
||||||
.findComponentByContainerAndKey(containerModel, componentKey)
|
.findComponentByContainerAndKey(containerModel, componentKey)
|
||||||
.orElseThrow(() -> new NotFoundException(String
|
.orElseThrow(
|
||||||
.format(
|
() -> new NotFoundException(
|
||||||
"The Container \"%s\" of the PageModel \"%s\" of application"
|
String.format(
|
||||||
+ "\"%s\" does not contain a component with the key \"%s\".",
|
"The Container \"%s\" of the PageModel \"%s\" of"
|
||||||
containerModel.getKey(),
|
+ " application \"%s\" does not contain a "
|
||||||
pageModel.getName(),
|
+ "component with the key \"%s\".",
|
||||||
app.getPrimaryUrl(),
|
containerModel.getKey(),
|
||||||
componentKey)));
|
pageModel.getName(),
|
||||||
|
app.getPrimaryUrl(),
|
||||||
|
componentKey
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -113,20 +121,26 @@ class PageModelsController {
|
||||||
* {@code containerKey}.
|
* {@code containerKey}.
|
||||||
*/
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
protected ContainerModel findContainer(final CcmApplication app,
|
protected ContainerModel findContainer(
|
||||||
final PageModel pageModel,
|
final CcmApplication app,
|
||||||
final String containerKey) {
|
final PageModel pageModel,
|
||||||
|
final String containerKey
|
||||||
|
) {
|
||||||
|
|
||||||
return containerRepo
|
return containerRepo
|
||||||
.findContainerByKeyAndPageModel(
|
.findContainerByKeyAndPageModel(
|
||||||
Objects.requireNonNull(containerKey),
|
Objects.requireNonNull(containerKey),
|
||||||
Objects.requireNonNull(pageModel))
|
Objects.requireNonNull(pageModel))
|
||||||
.orElseThrow(() -> new NotFoundException(String
|
.orElseThrow(
|
||||||
.format("The PageModel \"%s\" of application \"%s\" does not have "
|
() -> new NotFoundException(
|
||||||
+ "a container identified by the key \"%s\".",
|
String.format(
|
||||||
pageModel.getName(),
|
"The PageModel \"%s\" of application \"%s\" does not "
|
||||||
app.getPrimaryUrl(),
|
+ "have a container identified by the key \"%s\".",
|
||||||
containerKey)));
|
pageModel.getName(),
|
||||||
|
app.getPrimaryUrl(),
|
||||||
|
containerKey)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -142,8 +156,9 @@ class PageModelsController {
|
||||||
* {@link CcmApplication} {@code app}, {@code false} otherwise.
|
* {@link CcmApplication} {@code app}, {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
protected boolean existsPageModel(final CcmApplication app,
|
protected boolean existsPageModel(
|
||||||
final String pageModelName) {
|
final CcmApplication app, final String pageModelName
|
||||||
|
) {
|
||||||
return pageModelRepo
|
return pageModelRepo
|
||||||
.findDraftByApplicationAndName(app, pageModelName)
|
.findDraftByApplicationAndName(app, pageModelName)
|
||||||
.isPresent();
|
.isPresent();
|
||||||
|
|
@ -160,16 +175,22 @@ class PageModelsController {
|
||||||
* {@code pageModelName} for the {@link CcmApplication} {@code app}.
|
* {@code pageModelName} for the {@link CcmApplication} {@code app}.
|
||||||
*/
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
protected PageModel findPageModel(final CcmApplication app,
|
protected PageModel findPageModel(
|
||||||
final String pageModelName) {
|
final CcmApplication app, final String pageModelName
|
||||||
|
) {
|
||||||
return pageModelRepo
|
return pageModelRepo
|
||||||
.findDraftByApplicationAndName(
|
.findDraftByApplicationAndName(
|
||||||
Objects.requireNonNull(app),
|
Objects.requireNonNull(app),
|
||||||
Objects.requireNonNull(pageModelName))
|
Objects.requireNonNull(pageModelName)
|
||||||
.orElseThrow(() -> new NotFoundException(String.format(
|
)
|
||||||
"No PageModel with name \"%s\" for application \"%s\".",
|
.orElseThrow(
|
||||||
pageModelName, app.getPrimaryUrl())));
|
() -> new NotFoundException(
|
||||||
|
String.format(
|
||||||
|
"No PageModel with name \"%s\" for application \"%s\".",
|
||||||
|
pageModelName, app.getPrimaryUrl()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.libreccm.pagemodel.rs;
|
package org.libreccm.api.pagemodels;
|
||||||
|
|
||||||
public enum PublicationStatus {
|
public enum PublicationStatus {
|
||||||
|
|
||||||
|
|
@ -22,4 +22,4 @@
|
||||||
* editors.
|
* editors.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package org.libreccm.pagemodel.rs;
|
package org.libreccm.api.pagemodels;
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
|
||||||
*/
|
|
||||||
@RequestScoped
|
|
||||||
@Path("/")
|
|
||||||
public class Components {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private ComponentModelRepository componentRepo;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private ContainerModelManager containerManager;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private PageModelsController controller;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
@Any
|
|
||||||
private Instance<ComponentModelJsonConverter> 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<ComponentModel> 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<String> 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<String> 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<ComponentModelJsonConverter>
|
|
||||||
findJsonConverter(
|
|
||||||
final Class<? extends ComponentModel> componentModelClass) {
|
|
||||||
|
|
||||||
final ConvertsComponentModelLiteral literal
|
|
||||||
= new ConvertsComponentModelLiteral(
|
|
||||||
componentModelClass);
|
|
||||||
final Instance<ComponentModelJsonConverter> 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<ComponentModelJsonConverter> iterator = instance
|
|
||||||
.iterator();
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
final ComponentModelJsonConverter converter = iterator.next();
|
|
||||||
|
|
||||||
return Optional.of(converter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ConvertsComponentModelLiteral
|
|
||||||
extends AnnotationLiteral<ConvertsComponentModel>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
|
||||||
*/
|
|
||||||
@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<MediaRule> 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<Rule> 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<CssProperty> 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
|
||||||
*/
|
|
||||||
@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"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
|
||||||
*/
|
|
||||||
@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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
|
||||||
*/
|
|
||||||
@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"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue