From 4f756133e9b68abd64972c33d7c781deeee5e12a Mon Sep 17 00:00:00 2001 From: jensp Date: Tue, 22 Jan 2019 15:29:15 +0000 Subject: [PATCH] More classes for the backport of Pages and Theming from 7.0 git-svn-id: https://svn.libreccm.org/ccm/trunk@5802 8810af33-2d31-482b-a856-94f89814c4df --- .../pagemodel/AbstractPageRenderer.java | 127 ++++++++++++++++++ .../libreccm/pagemodel/ComponentRenderer.java | 67 +++++++++ .../pagemodel/ComponentRendererManager.java | 68 ++++++++++ .../pagemodel/PageModelRepository.java | 56 ++++++++ .../org/libreccm/pagemodel/PageRenderer.java | 74 ++++++++++ 5 files changed, 392 insertions(+) create mode 100644 ccm-pages/src/org/libreccm/pagemodel/AbstractPageRenderer.java create mode 100644 ccm-pages/src/org/libreccm/pagemodel/ComponentRenderer.java create mode 100644 ccm-pages/src/org/libreccm/pagemodel/ComponentRendererManager.java create mode 100644 ccm-pages/src/org/libreccm/pagemodel/PageModelRepository.java create mode 100644 ccm-pages/src/org/libreccm/pagemodel/PageRenderer.java diff --git a/ccm-pages/src/org/libreccm/pagemodel/AbstractPageRenderer.java b/ccm-pages/src/org/libreccm/pagemodel/AbstractPageRenderer.java new file mode 100644 index 000000000..edc4d5369 --- /dev/null +++ b/ccm-pages/src/org/libreccm/pagemodel/AbstractPageRenderer.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2016 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.HashMap; +import java.util.Map; +import java.util.Optional; + +/** + * An abstract base class for implementations of the {@link PageRenderer} + * interface providing some functionality needed by all implementations of the + * {@link PageRenderer} interface. + * + * @author Jens Pelzetter + * + */ +public abstract class AbstractPageRenderer implements PageRenderer { + + private ComponentRendererManager componentRendererManager; + + /** + * Renders a {@code Page} based on a {@link PageModel}. This implementation + * first calls {@link #renderPage()} to create the page object. After that + * all {@link ComponentModel}s of the {@link PageModel} are processed and + * the component objects created by the {@link ComponentRenderer}s are added + * to the page. + * + * @param pageModel The {@link PageModel} to render. + * @param parameters Parameters provided by application which wants to + * render a {@link PageModel}. The parameters are passed + * the {@link ComponentRenderer}s. + * + * @return A map containing the results from rendering the components of the + * page model. + */ + @Override + public Map renderPage( + final PageModel pageModel, final Map parameters) { + + final Map page = renderPage(parameters); + + final ContainerModelCollection containers = pageModel + .getContainerModels(); + while(containers.next()) { + final ContainerModel containerModel = containers + .getContainerModel(); + + final Map container = renderContainer( + containerModel, parameters); + page.put(containerModel.getKey(), container); + } + + return page; + } + + protected Map renderContainer( + final ContainerModel containerModel, + final Map parameters) { + + final Map container = new HashMap<>(); + + container.put("key", containerModel.getKey()); + + final ComponentModelCollection components = containerModel + .getComponents(); + while (components.next()) { + final ComponentModel componentModel = components.getComponentModel(); + + renderComponent(componentModel, + componentModel.getClass(), + parameters) + .ifPresent(component -> container.put(componentModel.getKey(), + component)); + } + + return container; + } + + /** + * Helper method for rendering the components. + * + * @param Generics variable for the type of rendered + * component + * @param componentModel The {@link ComponentModel} to process. + * @param componentModelClass The class of the {@link ComponentModel}. + * @param parameters Parameters provided by application which wants + * to render a {@link PageModel}. The parameters + * are passed the {@link ComponentRenderer}s. + * + * @return A map containing the results from rendering the components of the + * page model. + */ + protected Optional renderComponent( + final ComponentModel componentModel, + final Class componentModelClass, + final Map parameters) { + + final Optional> renderer = componentRendererManager + .findComponentRenderer(componentModelClass); + + if (renderer.isPresent()) { + @SuppressWarnings("unchecked") + final M model = (M) componentModel; + return Optional + .of(renderer.get().renderComponent(model, parameters)); + } else { + return Optional.empty(); + } + } + +} diff --git a/ccm-pages/src/org/libreccm/pagemodel/ComponentRenderer.java b/ccm-pages/src/org/libreccm/pagemodel/ComponentRenderer.java new file mode 100644 index 000000000..45dfb55e1 --- /dev/null +++ b/ccm-pages/src/org/libreccm/pagemodel/ComponentRenderer.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2016 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.Map; + +/** + * A {@code ComponentRenderer} transforms a {@link ComponentModel} into a + * component. + * + * An implementation must be annotation with the {@link RendersComponent} + * qualifier annotation. + * + * @author Jens Pelzetter + * @param Type of the model the component renderer processes. + */ +public interface ComponentRenderer { + + /** + * Renders a {@link ComponentModel}. + * + * The result of the rendering process is a {@link Map} which uses strings + * as key. The values are either Java primitive types or Collections. More + * exactly the values are objects of one the following types: + * + *
    + *
  • {@link Double}
  • + *
  • {@link Float}
  • + *
  • {@link Integer}
  • + *
  • {@link Long}
  • + *
  • {@link Short}
  • + *
  • {@link String}
  • + *
  • {@link List}
  • + *
  • {@link Map}
  • + *
+ * + * Other subtypes {@link Collection} are might be supported but there is no + * guarantee for that. The values in a collection must be one of the types + * in the list above. Collections might contain multiple types from the list + * above. The keys for a map should always be strings. + * + * @param componentModel The component model to render. + * @param parameters Parameters provided by the calling + * {@link PageRenderer}. + * + * @return A map representing the rendered component. + */ + Map renderComponent(M componentModel, + Map parameters); + +} diff --git a/ccm-pages/src/org/libreccm/pagemodel/ComponentRendererManager.java b/ccm-pages/src/org/libreccm/pagemodel/ComponentRendererManager.java new file mode 100644 index 000000000..cc985a0c2 --- /dev/null +++ b/ccm-pages/src/org/libreccm/pagemodel/ComponentRendererManager.java @@ -0,0 +1,68 @@ +package org.libreccm.pagemodel; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +/** + * + * @author Jens Pelzetter + */ +public class ComponentRendererManager { + + private static final Logger LOGGER = LogManager + .getLogger(ComponentRendererManager.class); + + private static final ComponentRendererManager INSTANCE + = new ComponentRendererManager(); + + private final Map, ComponentRenderer> componentRenderers; + + public ComponentRendererManager() { + + componentRenderers = new HashMap<>(); + } + + public static ComponentRendererManager getInstance() { + return INSTANCE; + } + + /** + * Find an implementation of the {@link ComponentRenderer} interface for a + * specific {@link ComponentModel}. + * + * @param Generic variable for the subtype of + * {@link ComponentModel} which is produced by + * the {@link ComponentRenderer} implementation. + * @param componentModelClass The sub class of the {@link ComponentModel} + * for which is processed by the + * {@link ComponentRenderer}. + * + * @return An {@link Optional} containing the implementation of the + * {@link ComponentRenderer} interface for the specified parameters. + * If there is no implementation for the specified parameters an + * empty {@link Optional} is returned. + */ + @SuppressWarnings({"unchecked"}) + public Optional> findComponentRenderer( + final Class componentModelClass) { + + if (componentRenderers.containsKey(componentModelClass)) { + return Optional.of((ComponentRenderer) componentRenderers + .get(componentModelClass)); + } else { + return Optional.empty(); + } + } + + public void registerComponentRenderer( + final Class componentClass, + final ComponentRenderer componentRenderer) { + + componentRenderers.put(componentClass, componentRenderer); + } + +} diff --git a/ccm-pages/src/org/libreccm/pagemodel/PageModelRepository.java b/ccm-pages/src/org/libreccm/pagemodel/PageModelRepository.java new file mode 100644 index 000000000..0524f8b6e --- /dev/null +++ b/ccm-pages/src/org/libreccm/pagemodel/PageModelRepository.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 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.Date; +import java.util.Objects; +import java.util.UUID; + +/** + * + * @author Jens Pelzetter + */ +public class PageModelRepository { + + private static final PageModelRepository INSTANCE = new PageModelRepository(); + + private PageModelRepository() { + + } + + public static final PageModelRepository getInstance() { + return INSTANCE; + } + + public void save(final PageModel pageModel) { + + Objects.requireNonNull(pageModel); + + pageModel.setLastModified(new Date()); + + if (pageModel.getUuid() == null) { + pageModel.setUuid(UUID.randomUUID().toString()); + } + + if (pageModel.getModelUuid() == null) { + pageModel.setModelUuid(pageModel.getUuid()); + } + } + +} diff --git a/ccm-pages/src/org/libreccm/pagemodel/PageRenderer.java b/ccm-pages/src/org/libreccm/pagemodel/PageRenderer.java new file mode 100644 index 000000000..7d9c539a5 --- /dev/null +++ b/ccm-pages/src/org/libreccm/pagemodel/PageRenderer.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 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.Map; + +/** + * Interface for page renderers. A page renderer is invoked to render a page of + * specific type. An implementation should be a CDI bean which is annotated with + * the qualifier {@link RendersPageModelType}. + * + * An implementation should add all default components which have to be present + * in page. The {@link PageModel} should only specify + * additional components. + * + * + * @author Jens Pelzetter + */ +public interface PageRenderer { + + /** + * Render a page with the default components for a application. An + * implementation of {@link #renderPage(org.libreccm.pagemodel.PageModel)} + * should use this method for creating the default page. + * + * The result of the rendering process is a map with the values of the + * {@link ComponentModel#key} property as key and the result of rendering + * the component as value. + * + * @param parameters Parameters provided by application which wants to + * render a {@link PageModel}. The parameters are passed + * the {@link ComponentRenderer}s. + * + * @return A page with the default components. + */ + Map renderPage(Map parameters); + + /** + * Render a page using the provided {@link PageModel}. Implementations + * should call the implementation of {@link #renderPage()} for creating the + * basic page with the default components. + * + * The result of the rendering process is a map with the values of the + * {@link ComponentModel#key} property as key and the result of rendering + * the component as value. + * + * + * @param pageModel The {@link PageModel} from which the page is generated. + * @param parameters Parameters provided by application which wants to + * render a {@link PageModel}. The parameters are passed + * the {@link ComponentRenderer}s. + * + * @return The page generated from the provided {@link PageModel}. + */ + Map renderPage(PageModel pageModel, + Map parameters); + +}