CCM NG: RESTful backend for PageModel Editor
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5418 8810af33-2d31-482b-a856-94f89814c4df
parent
ca034a0177
commit
dfff31bd8a
|
|
@ -20,12 +20,23 @@ package org.libreccm.pagemodel.rs;
|
||||||
|
|
||||||
import org.libreccm.core.CoreConstants;
|
import org.libreccm.core.CoreConstants;
|
||||||
import org.libreccm.pagemodel.ComponentModel;
|
import org.libreccm.pagemodel.ComponentModel;
|
||||||
|
import org.libreccm.pagemodel.ComponentModelRepository;
|
||||||
import org.libreccm.pagemodel.ContainerModel;
|
import org.libreccm.pagemodel.ContainerModel;
|
||||||
|
import org.libreccm.pagemodel.ContainerModelManager;
|
||||||
import org.libreccm.pagemodel.PageModel;
|
import org.libreccm.pagemodel.PageModel;
|
||||||
import org.libreccm.security.AuthorizationRequired;
|
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.beans.BeanInfo;
|
||||||
|
import java.beans.IntrospectionException;
|
||||||
|
import java.beans.Introspector;
|
||||||
|
import java.beans.PropertyDescriptor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
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;
|
||||||
|
|
@ -34,10 +45,14 @@ import javax.json.JsonArrayBuilder;
|
||||||
import javax.json.JsonObject;
|
import javax.json.JsonObject;
|
||||||
import javax.json.JsonObjectBuilder;
|
import javax.json.JsonObjectBuilder;
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
|
import javax.ws.rs.BadRequestException;
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
|
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.WebApplicationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -47,6 +62,12 @@ import javax.ws.rs.Produces;
|
||||||
@Path("/")
|
@Path("/")
|
||||||
public class Components {
|
public class Components {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ComponentModelRepository componentRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContainerModelManager containerManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private PageModelsController controller;
|
private PageModelsController controller;
|
||||||
|
|
||||||
|
|
@ -104,6 +125,53 @@ public class Components {
|
||||||
return mapComponentModelToJson(component);
|
return mapComponentModelToJson(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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 componentModelJson) {
|
||||||
|
|
||||||
|
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(componentModelJson);
|
||||||
|
componentModel.setKey(componentKey);
|
||||||
|
containerManager.addComponentModel(container, componentModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
setComponentPropertiesFromJson(componentModelJson, componentModel);
|
||||||
|
|
||||||
|
componentRepo.save(componentModel);
|
||||||
|
|
||||||
|
return mapComponentModelToJson(componentModel);
|
||||||
|
}
|
||||||
|
|
||||||
private JsonObject mapComponentModelToJson(
|
private JsonObject mapComponentModelToJson(
|
||||||
final ComponentModel componentModel) {
|
final ComponentModel componentModel) {
|
||||||
|
|
||||||
|
|
@ -133,4 +201,98 @@ public class Components {
|
||||||
return objectBuilder.build();
|
return objectBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ComponentModel createComponentModel(final JsonObject 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Class<? extends ComponentModel> findComponentModelClass(
|
||||||
|
final String type) {
|
||||||
|
try {
|
||||||
|
final Class<?> clazz = Class.forName(type);
|
||||||
|
|
||||||
|
if (clazz.isAssignableFrom(ComponentModel.class)) {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setComponentPropertiesFromJson(
|
||||||
|
final JsonObject data,
|
||||||
|
final ComponentModel 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
if (writeMethod != null) {
|
||||||
|
try {
|
||||||
|
writeMethod.invoke(componentModel,
|
||||||
|
data.getString(propertyDesc.getName()));
|
||||||
|
} catch (IllegalAccessException
|
||||||
|
| InvocationTargetException ex) {
|
||||||
|
throw new WebApplicationException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,16 @@ package org.libreccm.pagemodel.rs;
|
||||||
|
|
||||||
import org.libreccm.core.CoreConstants;
|
import org.libreccm.core.CoreConstants;
|
||||||
import org.libreccm.pagemodel.ContainerModel;
|
import org.libreccm.pagemodel.ContainerModel;
|
||||||
|
import org.libreccm.pagemodel.ContainerModelRepository;
|
||||||
import org.libreccm.pagemodel.PageModel;
|
import org.libreccm.pagemodel.PageModel;
|
||||||
|
import org.libreccm.pagemodel.PageModelManager;
|
||||||
|
import org.libreccm.pagemodel.PageModelRepository;
|
||||||
import org.libreccm.security.AuthorizationRequired;
|
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.util.Optional;
|
||||||
|
|
||||||
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;
|
||||||
|
|
@ -32,7 +37,10 @@ import javax.json.JsonArray;
|
||||||
import javax.json.JsonArrayBuilder;
|
import javax.json.JsonArrayBuilder;
|
||||||
import javax.json.JsonObject;
|
import javax.json.JsonObject;
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
|
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;
|
||||||
|
|
@ -48,6 +56,15 @@ public class Containers {
|
||||||
@Inject
|
@Inject
|
||||||
private PageModelsController controller;
|
private PageModelsController controller;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContainerModelRepository containerModelRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PageModelManager pageModelManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PageModelRepository pageModelRepo;
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path(PageModelsApp.CONTAINERS_PATH)
|
@Path(PageModelsApp.CONTAINERS_PATH)
|
||||||
@Produces("application/json; charset=utf-8")
|
@Produces("application/json; charset=utf-8")
|
||||||
|
|
@ -98,6 +115,72 @@ public class Containers {
|
||||||
return mapContainerModelToJson(container);
|
return mapContainerModelToJson(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path(PageModelsApp.CONTAINER_PATH)
|
||||||
|
@Consumes("application/json; charset=utf-8")
|
||||||
|
@Produces("application/json; charset=utf-8")
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
@AuthorizationRequired
|
||||||
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
|
public JsonObject putContainer(
|
||||||
|
@PathParam(PageModelsApp.APP_NAME) final String appPath,
|
||||||
|
@PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
|
||||||
|
@PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey,
|
||||||
|
final JsonObject containerModelJson) {
|
||||||
|
|
||||||
|
final CcmApplication app = controller.findCcmApplication(
|
||||||
|
String.format("/%s/", appPath));
|
||||||
|
|
||||||
|
final PageModel pageModel = controller.findPageModel(app,
|
||||||
|
pageModelName);
|
||||||
|
|
||||||
|
final Optional<ContainerModel> result = pageModel
|
||||||
|
.getContainers()
|
||||||
|
.stream()
|
||||||
|
.filter(model -> model.getKey().equals(containerKey))
|
||||||
|
.findAny();
|
||||||
|
|
||||||
|
final ContainerModel containerModel;
|
||||||
|
if (result.isPresent()) {
|
||||||
|
|
||||||
|
containerModel = result.get();
|
||||||
|
|
||||||
|
result.get().setKey(containerKey);
|
||||||
|
containerModelRepo.save(result.get());
|
||||||
|
} else {
|
||||||
|
|
||||||
|
containerModel = new ContainerModel();
|
||||||
|
containerModel.setKey(containerKey);
|
||||||
|
|
||||||
|
pageModelManager.addContainerModel(pageModel, containerModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapContainerModelToJson(containerModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path(PageModelsApp.CONTAINER_PATH)
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
@AuthorizationRequired
|
||||||
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
|
public void deleteContainer(
|
||||||
|
@PathParam(PageModelsApp.APP_NAME) final String appPath,
|
||||||
|
@PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
|
||||||
|
@PathParam(PageModelsApp.CONTAINER_KEY) final String containerKey) {
|
||||||
|
|
||||||
|
final CcmApplication app = controller.findCcmApplication(
|
||||||
|
String.format("/%s/", appPath));
|
||||||
|
|
||||||
|
final PageModel pageModel = controller.findPageModel(app,
|
||||||
|
pageModelName);
|
||||||
|
|
||||||
|
final ContainerModel container = controller.findContainer(app,
|
||||||
|
pageModel,
|
||||||
|
containerKey);
|
||||||
|
|
||||||
|
pageModelManager.removeContainerModel(pageModel, container);
|
||||||
|
}
|
||||||
|
|
||||||
private JsonObject mapContainerModelToJson(
|
private JsonObject mapContainerModelToJson(
|
||||||
final ContainerModel containerModel) {
|
final ContainerModel containerModel) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ import javax.json.JsonArrayBuilder;
|
||||||
import javax.json.JsonObject;
|
import javax.json.JsonObject;
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.NotFoundException;
|
import javax.ws.rs.NotFoundException;
|
||||||
import javax.ws.rs.PUT;
|
import javax.ws.rs.PUT;
|
||||||
|
|
@ -151,6 +152,22 @@ public class PageModels {
|
||||||
return mapPageModelToJson(controller.findPageModel(app, pageModelName));
|
return mapPageModelToJson(controller.findPageModel(app, pageModelName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path(PageModelsApp.PAGE_MODEL_PATH)
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
@AuthorizationRequired
|
||||||
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
|
public void deletePageModel(
|
||||||
|
@PathParam(PageModelsApp.APP_NAME) final String appPath,
|
||||||
|
@PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName) {
|
||||||
|
|
||||||
|
final CcmApplication app = controller
|
||||||
|
.findCcmApplication(String.format("/%s/", appPath));
|
||||||
|
final PageModel pageModel = controller.findPageModel(app,
|
||||||
|
pageModelName);
|
||||||
|
pageModelRepo.delete(pageModel);
|
||||||
|
}
|
||||||
|
|
||||||
private JsonObject mapPageModelToJson(final PageModel pageModel) {
|
private JsonObject mapPageModelToJson(final PageModel pageModel) {
|
||||||
|
|
||||||
return Json
|
return Json
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,8 @@ class PageModelsController {
|
||||||
containerKey)));
|
containerKey)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
protected boolean existsPageModel(final CcmApplication app,
|
protected boolean existsPageModel(final CcmApplication app,
|
||||||
final String pageModelName) {
|
final String pageModelName) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue