diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/AbstractContentItemComponentJsonConverter.java b/ccm-cms/src/main/java/org/librecms/pagemodel/AbstractContentItemComponentJsonConverter.java new file mode 100644 index 000000000..efaf54cc8 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/AbstractContentItemComponentJsonConverter.java @@ -0,0 +1,59 @@ +/* + * 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.librecms.pagemodel; + +import org.libreccm.pagemodel.AbstractComponentModelJsonConverter; + +import java.util.Objects; + +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; + +/** + * + * @author Jens Pelzetter + */ +public abstract class AbstractContentItemComponentJsonConverter + extends AbstractComponentModelJsonConverter { + + private static final String MODE = "mode"; + + protected void convertContentItemComponentPropertiesToJson( + final ContentItemComponent component, + final JsonObjectBuilder objectBuilder) { + + Objects.requireNonNull(component); + Objects.requireNonNull(objectBuilder); + + objectBuilder.add(MODE, component.getMode()); + } + + protected void readContentItemComponentPropertiesFromJson( + final JsonObject jsonObject, final ContentItemComponent component) { + + Objects.requireNonNull(jsonObject); + Objects.requireNonNull(component); + + if (!jsonObject.isNull(MODE)) { + + component.setMode(jsonObject.getString(MODE)); + } + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/CategorizedItemComponentJsonBuilder.java b/ccm-cms/src/main/java/org/librecms/pagemodel/CategorizedItemComponentJsonBuilder.java new file mode 100644 index 000000000..cb0eec47b --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/CategorizedItemComponentJsonBuilder.java @@ -0,0 +1,74 @@ +/* + * 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.librecms.pagemodel; + +import org.libreccm.pagemodel.ComponentModel; +import org.libreccm.pagemodel.ConvertsComponentModel; + +import java.util.Objects; + +import javax.enterprise.context.RequestScoped; +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@ConvertsComponentModel(componentModel = CategorizedItemComponent.class) +public class CategorizedItemComponentJsonBuilder + extends AbstractContentItemComponentJsonConverter { + + @Override + public JsonObject toJson(final ComponentModel componentModel) { + + Objects.requireNonNull(componentModel); + + final JsonObjectBuilder objectBuilder = Json.createObjectBuilder(); + + if (!(componentModel instanceof CategorizedItemComponent)) { + throw new IllegalArgumentException( + "This converter only processes CategorizedItemComponents."); + } + + final CategorizedItemComponent component + = (CategorizedItemComponent) componentModel; + + convertBasePropertiesToJson(component, objectBuilder); + convertContentItemComponentPropertiesToJson(component, objectBuilder); + + return objectBuilder.build(); + } + + @Override + public ComponentModel fromJson(final JsonObject jsonObject) { + + Objects.requireNonNull(jsonObject); + + final CategorizedItemComponent component = new CategorizedItemComponent(); + + readBasePropertiesFromJson(jsonObject, component); + readContentItemComponentPropertiesFromJson(jsonObject, component); + + return component; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/CategoryTreeComponentJsonConverter.java b/ccm-cms/src/main/java/org/librecms/pagemodel/CategoryTreeComponentJsonConverter.java new file mode 100644 index 000000000..c90928bf4 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/CategoryTreeComponentJsonConverter.java @@ -0,0 +1,81 @@ +/* + * 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.librecms.pagemodel; + +import org.libreccm.pagemodel.AbstractComponentModelJsonConverter; +import org.libreccm.pagemodel.ComponentModel; +import org.libreccm.pagemodel.ConvertsComponentModel; + +import java.util.Objects; + +import javax.enterprise.context.RequestScoped; +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@ConvertsComponentModel(componentModel = CategoryTreeComponent.class) +public class CategoryTreeComponentJsonConverter + extends AbstractComponentModelJsonConverter { + + private static final String SHOW_FULL_TREE = "showFullTree"; + + @Override + public JsonObject toJson(final ComponentModel componentModel) { + + Objects.requireNonNull(componentModel); + + if (!(componentModel instanceof CategoryTreeComponent)) { + throw new IllegalArgumentException( + "This converter only processes CategoryTreeComponents."); + } + + final CategoryTreeComponent categoryTree + = (CategoryTreeComponent) componentModel; + + final JsonObjectBuilder builder = Json.createObjectBuilder(); + convertBasePropertiesToJson(categoryTree, builder); + + builder.add(SHOW_FULL_TREE, categoryTree.isShowFullTree()); + + return builder.build(); + } + + + @Override + public ComponentModel fromJson(final JsonObject jsonObject) { + + Objects.requireNonNull(jsonObject); + + final CategoryTreeComponent categoryTree = new CategoryTreeComponent(); + + readBasePropertiesFromJson(jsonObject, categoryTree); + + if (!jsonObject.isNull(SHOW_FULL_TREE)) { + categoryTree.setShowFullTree(jsonObject.getBoolean(SHOW_FULL_TREE)); + } + + return categoryTree; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/FixedContentItemComponentJsonConverter.java b/ccm-cms/src/main/java/org/librecms/pagemodel/FixedContentItemComponentJsonConverter.java new file mode 100644 index 000000000..d1796159e --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/FixedContentItemComponentJsonConverter.java @@ -0,0 +1,101 @@ +/* + * 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.librecms.pagemodel; + +import org.libreccm.core.UnexpectedErrorException; +import org.libreccm.pagemodel.ComponentModel; +import org.libreccm.pagemodel.ConvertsComponentModel; +import org.librecms.contentsection.ContentItemRepository; + +import java.util.Objects; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@ConvertsComponentModel(componentModel = FixedContentItemComponent.class) +public class FixedContentItemComponentJsonConverter + extends AbstractContentItemComponentJsonConverter { + + private static final String CONTENT_ITEM = "contentItem"; + + @Inject + private ContentItemRepository itemRepo; + + @Override + public JsonObject toJson(final ComponentModel componentModel) { + + Objects.requireNonNull(componentModel); + + if (!(componentModel instanceof FixedContentItemComponent)) { + throw new IllegalArgumentException( + "This converter only processes FixedContentItemComponents."); + } + + final FixedContentItemComponent component + = (FixedContentItemComponent) componentModel; + + final JsonObjectBuilder objectBuilder = Json.createObjectBuilder(); + + convertBasePropertiesToJson(component, objectBuilder); + convertContentItemComponentPropertiesToJson(component, objectBuilder); + + if (component.getContentItem() != null) { + objectBuilder.add(CONTENT_ITEM, + component.getContentItem().getUuid()); + } + + return objectBuilder.build(); + } + + @Override + public ComponentModel fromJson(final JsonObject jsonObject) { + + Objects.requireNonNull(jsonObject); + + final FixedContentItemComponent component + = new FixedContentItemComponent(); + + readBasePropertiesFromJson(jsonObject, component); + readContentItemComponentPropertiesFromJson(jsonObject, component); + + if (!jsonObject.isNull(CONTENT_ITEM)) { + + final String uuid = jsonObject.getString(CONTENT_ITEM); + + component + .setContentItem(itemRepo + .findByUuid(uuid) + .orElseThrow(() -> new UnexpectedErrorException( + String.format("No ContentItem with UUID \"%s\" exists.", + uuid)))); + + } + + return component; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemComponentJsonConverter.java b/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemComponentJsonConverter.java new file mode 100644 index 000000000..520c22e47 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemComponentJsonConverter.java @@ -0,0 +1,74 @@ +/* + * 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.librecms.pagemodel; + +import org.libreccm.pagemodel.ComponentModel; +import org.libreccm.pagemodel.ConvertsComponentModel; + +import java.util.Objects; + +import javax.enterprise.context.RequestScoped; +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@ConvertsComponentModel(componentModel = GreetingItemComponent.class) +public class GreetingItemComponentJsonConverter + extends AbstractContentItemComponentJsonConverter { + + @Override + public JsonObject toJson(final ComponentModel componentModel) { + + Objects.requireNonNull(componentModel); + + if (!(componentModel instanceof GreetingItemComponent)) { + throw new IllegalArgumentException( + "This converter only processes GreetingItemComponents."); + } + + final GreetingItemComponent component + = (GreetingItemComponent) componentModel; + + final JsonObjectBuilder objectBuilder = Json.createObjectBuilder(); + + convertBasePropertiesToJson(component, objectBuilder); + convertContentItemComponentPropertiesToJson(component, objectBuilder); + + return objectBuilder.build(); + } + + @Override + public ComponentModel fromJson(final JsonObject jsonObject) { + + Objects.requireNonNull(jsonObject); + + final GreetingItemComponent component = new GreetingItemComponent(); + + readBasePropertiesFromJson(jsonObject, component); + readContentItemComponentPropertiesFromJson(jsonObject, component); + + return component; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/ItemListComponentJsonConverter.java b/ccm-cms/src/main/java/org/librecms/pagemodel/ItemListComponentJsonConverter.java new file mode 100644 index 000000000..b96a1fece --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/ItemListComponentJsonConverter.java @@ -0,0 +1,114 @@ +/* + * 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.librecms.pagemodel; + +import org.libreccm.pagemodel.AbstractComponentModelJsonConverter; +import org.libreccm.pagemodel.ComponentModel; +import org.libreccm.pagemodel.ConvertsComponentModel; + +import java.util.Objects; +import java.util.stream.Collectors; + +import javax.enterprise.context.RequestScoped; +import javax.json.Json; +import javax.json.JsonArrayBuilder; +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@ConvertsComponentModel(componentModel = ItemListComponent.class) +public class ItemListComponentJsonConverter + extends AbstractComponentModelJsonConverter { + + private static final String LIST_ORDER = "listOrder"; + private static final String PAGE_SIZE = "pageSize"; + private static final String LIMIT_TO_TYPE = "limitToType"; + private static final String DESCENDING = "descending"; + + @Override + public JsonObject toJson(final ComponentModel componentModel) { + + Objects.requireNonNull(componentModel); + + if (!(componentModel instanceof ItemListComponent)) { + throw new IllegalArgumentException( + "This implementation does only handle ItemListComponents."); + } + + final ItemListComponent itemList = (ItemListComponent) componentModel; + final JsonObjectBuilder builder = Json.createObjectBuilder(); + + convertBasePropertiesToJson(itemList, builder); + + builder.add(DESCENDING, itemList.isDescending()); + builder.add(LIMIT_TO_TYPE, itemList.getLimitToType()); + builder.add(PAGE_SIZE, itemList.getPageSize()); + + final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder(); + if (itemList.getListOrder() != null) { + + itemList + .getListOrder() + .stream() + .forEach(value -> arrayBuilder.add(value)); + } + builder.add(LIST_ORDER, arrayBuilder.build()); + + return builder.build(); + } + + @Override + public ComponentModel fromJson(final JsonObject jsonObject) { + + Objects.requireNonNull(jsonObject); + + final ItemListComponent itemList = new ItemListComponent(); + readBasePropertiesFromJson(jsonObject, itemList); + + if (!jsonObject.isNull(DESCENDING)) { + itemList.setDescending(jsonObject.getBoolean(DESCENDING)); + } + + if (!jsonObject.isNull(LIMIT_TO_TYPE)) { + itemList.setLimitToType(jsonObject.getString(LIMIT_TO_TYPE)); + } + + if (!jsonObject.isNull(PAGE_SIZE)) { + itemList.setPageSize(jsonObject.getInt(PAGE_SIZE)); + } + + if (!jsonObject.isNull(LIST_ORDER)) { + + itemList.setListOrder( + jsonObject + .getJsonArray(LIST_ORDER) + .stream() + .map(value -> value.toString()) + .collect(Collectors.toList())); + + } + + return itemList; + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/AbstractComponentModelJsonConverter.java b/ccm-core/src/main/java/org/libreccm/pagemodel/AbstractComponentModelJsonConverter.java new file mode 100644 index 000000000..d9da153ac --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/AbstractComponentModelJsonConverter.java @@ -0,0 +1,107 @@ +/* + * 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; + +import java.util.Objects; + +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; + +/** + * Converter for the basic properties of a { + * + * @ComponentModel}. Can be used as base for implementations. + * + * @author Jens Pelzetter + */ +public abstract class AbstractComponentModelJsonConverter + implements ComponentModelJsonConverter { + + /** + * Converts the basic properties of a {@link ComponentModel} to JSON. + * + * @param componentModel The {@link ComponentModel}. + * @param objectBuilder The {@link JsonObjectBuilder} to use. + */ + protected void convertBasePropertiesToJson( + final ComponentModel componentModel, + final JsonObjectBuilder objectBuilder) { + + Objects.requireNonNull(componentModel); + Objects.requireNonNull(objectBuilder); + + objectBuilder + .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()); + } + } + + /** + * Read the basic properties of a {@link ComponentModel} from a + * {@link JsonObject}. + * + * @param jsonObject The {@link JsonObject}. + * @param componentModel The {@link ComponentModel}. + */ + protected void readBasePropertiesFromJson( + final JsonObject jsonObject, final ComponentModel componentModel) { + + Objects.requireNonNull(jsonObject); + Objects.requireNonNull(componentModel); + + componentModel.setComponentModelId( + jsonObject.getInt("componentModelId")); + componentModel.setUuid(jsonObject.getString("uuid")); + componentModel.setModelUuid(jsonObject.getString("modelUuid")); + componentModel.setKey(jsonObject.getString("key")); + + if (jsonObject.getString("idAttribute") != null) { + componentModel.setIdAttribute(jsonObject.getString("idAttribute")); + } + + if (jsonObject.getString("classAttribute") != null) { + componentModel + .setClassAttribute(jsonObject.getString("classAttribute")); + } + + if (jsonObject.getString("styleAttribute") != null) { + componentModel + .setStyleAttribute(jsonObject.getString("styleAttribute")); + } + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentModelJsonConverter.java b/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentModelJsonConverter.java new file mode 100644 index 000000000..78ad29ba3 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentModelJsonConverter.java @@ -0,0 +1,46 @@ +/* + * 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; + +import javax.json.JsonObject; + +/** + * Interface which the JSON converters for {@link ComponentModel}s. + * + * @author Jens Pelzetter + */ +public interface ComponentModelJsonConverter { + + /** + * Convert a {@link ComponentModel} to JSON. + * + * @param componentModel The {@link ComponentModel} to convert. + * @return The JSON representation of the provided {@link ComponentModel}. + */ + JsonObject toJson(ComponentModel componentModel); + + /** + * Read the values of a {@link ComponentModel} from a JSON object. + * + * @param jsonObject The JSON object with the values. + * @return The {@link ComponentModel}. + */ + ComponentModel fromJson(JsonObject jsonObject); + +} diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentRendererManager.java b/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentRendererManager.java index 2bb8a76b1..88607b08c 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentRendererManager.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentRendererManager.java @@ -71,7 +71,7 @@ public class ComponentRendererManager { + "and type \"{}\"...", componentModelClass.getName()); - final ComponentModelTypeLiteral literal = new ComponentModelTypeLiteral( + final RenderComponentLiteral literal = new RenderComponentLiteral( componentModelClass); final Instance> instance = componentRenderers @@ -99,7 +99,7 @@ public class ComponentRendererManager { /** * Annotation literal for the {@link RendersComponent} annotation. */ - private static class ComponentModelTypeLiteral + private static class RenderComponentLiteral extends AnnotationLiteral implements RendersComponent { @@ -107,7 +107,7 @@ public class ComponentRendererManager { private final Class componentModel; - public ComponentModelTypeLiteral( + public RenderComponentLiteral( final Class componentModel) { this.componentModel = componentModel; } diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/ConvertsComponentModel.java b/ccm-core/src/main/java/org/libreccm/pagemodel/ConvertsComponentModel.java new file mode 100644 index 000000000..be9966595 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/ConvertsComponentModel.java @@ -0,0 +1,42 @@ +/* + * 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; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + +/** + * + * @author Jens Pelzetter + */ +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, + ElementType.METHOD, + ElementType.PARAMETER, + ElementType.TYPE}) +public @interface ConvertsComponentModel { + + Class componentModel(); + +} diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/Components.java b/ccm-core/src/main/java/org/libreccm/pagemodel/rs/Components.java index 5c464c54c..38fd3fd42 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/rs/Components.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/rs/Components.java @@ -19,10 +19,13 @@ package org.libreccm.pagemodel.rs; import org.libreccm.core.CoreConstants; +import org.libreccm.core.UnexpectedErrorException; 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; @@ -34,14 +37,17 @@ import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; 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; @@ -79,6 +85,10 @@ public class Components { @Inject private PageModelsController controller; + @Inject + @Any + private Instance jsonConverters; + /** * Retrieve all {@link ComponentModel} of a {@link ContainerModel}. * @@ -285,63 +295,74 @@ public class Components { private JsonObject mapComponentModelToJson( final ComponentModel componentModel) { - Objects.requireNonNull(componentModel); + final Class clazz = Objects + .requireNonNull(componentModel.getClass()); - 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()); + final ComponentModelJsonConverter jsonConverter + = findJsonConverter(clazz) + .orElseThrow(() -> new WebApplicationException(String.format( + "No JSON converter available for component model \"%s\".", + clazz.getName()))); + + return jsonConverter.toJson(componentModel); - 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 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(); +// 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 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(); } /** @@ -373,9 +394,9 @@ public class Components { try { componentModel = clazz.getConstructor().newInstance(); } catch (IllegalAccessException - | InstantiationException - | InvocationTargetException - | NoSuchMethodException ex) { + | InstantiationException + | InvocationTargetException + | NoSuchMethodException ex) { throw new WebApplicationException(ex); } @@ -488,7 +509,7 @@ public class Components { } else if (propertyType == Double.TYPE) { writeMethod.invoke( componentModel, - Double.parseDouble(value.toString())); + Double.parseDouble(value.toString())); } else if (propertyType == Float.TYPE) { writeMethod.invoke(componentModel, Float.parseFloat(value.toString())); @@ -540,11 +561,57 @@ public class Components { } } catch (IllegalAccessException - | InvocationTargetException ex) { + | InvocationTargetException ex) { throw new WebApplicationException(ex); } } } } + private Optional + findJsonConverter( + final Class componentModelClass) { + + final ConvertsComponentModelLiteral literal + = new ConvertsComponentModelLiteral( + componentModelClass); + final Instance instance = jsonConverters + .select(literal); + if (instance.isUnsatisfied()) { + return Optional.empty(); + } else if (instance.isAmbiguous()) { + throw new IllegalStateException(String.format( + "Multiple JSONConverter for \"%s\".", + componentModelClass.getName())); + } else { + final Iterator iterator = instance + .iterator(); + @SuppressWarnings("unchecked") + final ComponentModelJsonConverter converter = iterator.next(); + + return Optional.of(converter); + } + } + + private static class ConvertsComponentModelLiteral + extends AnnotationLiteral + implements ConvertsComponentModel { + + private static final long serialVersionUID = 1L; + + private final Class componentModel; + + public ConvertsComponentModelLiteral( + final Class componentModel) { + + this.componentModel = componentModel; + } + + @Override + public Class componentModel() { + return componentModel; + } + + } + }