diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/AbstractPageBuilder.java b/ccm-core/src/main/java/org/libreccm/pagemodel/AbstractPageBuilder.java index f4d62c5a6..b62db70a7 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/AbstractPageBuilder.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/AbstractPageBuilder.java @@ -22,8 +22,12 @@ import java.util.Optional; import javax.inject.Inject; /** + * An abstract base class for implementations of the {@link PageBuilder} + * interface providing some functionality needed by all implementations of the + * {@link PageBuilder} interface. * - * @param

Page class + * @param

Generics variable for the class which represents the page created + * by the {@link PageBuilder}. * * @author Jens Pelzetter * @@ -33,13 +37,24 @@ public abstract class AbstractPageBuilder

implements PageBuilder

{ @Inject private ComponentBuilderManager componentBuilderManager; + /** + * Build a {@code Page} based on a {@link PageModel}. This implementation + * first calls {@link #buildPage()} 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 ComponentBuilder}s are added + * to the page. + * + * @param pageModel The {@link PageModel\ to process. + * + * @return A page containing all components from the {@link PageModel}. + */ @Override public P buildPage(final PageModel pageModel) { final P page = buildPage(); for (final ComponentModel componentModel : pageModel.getComponents()) { final Optional component = buildComponent( - componentModel, componentModel.getClass()); + componentModel, componentModel.getClass()); if (component.isPresent()) { addComponent(page, component); } @@ -48,15 +63,25 @@ public abstract class AbstractPageBuilder

implements PageBuilder

{ return page; } + /** + * Helper method for building the components. + * + * @param Generics variable for the type the component + * created. + * @param componentModel The {@link ComponentModel} to process. + * @param componentModelClass The class of the {@link ComponentModel}. + * + * @return The components described by the {@code componentModel}. + */ protected Optional buildComponent( - final ComponentModel componentModel, - final Class componentModelClass) { + final ComponentModel componentModel, + final Class componentModelClass) { componentBuilderManager.findComponentBuilder(componentModel.getClass(), getType()); final Optional> builder = componentBuilderManager - .findComponentBuilder(componentModelClass, getType()); + .findComponentBuilder(componentModelClass, getType()); if (builder.isPresent()) { return Optional.of(builder.get().buildComponent((M) componentModel)); @@ -65,7 +90,22 @@ public abstract class AbstractPageBuilder

implements PageBuilder

{ } } + /** + * Abstract method returning the type (view technology) for which the + * {@link PageBuilder} processes {@link PageModel}s. + * + * @return + */ protected abstract String getType(); + /** + * A helper method for adding components to the page. How this is done + * depends on the view technology, therefore this method must be implemented + * by the implementations of this abstract class. + * + * @param page The page to which the component is added. + * @param component The component to add to the page. + */ protected abstract void addComponent(P page, Object component); + } diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentBuilderManager.java b/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentBuilderManager.java index 1fbb9c0bc..1eebcaf64 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentBuilderManager.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentBuilderManager.java @@ -28,6 +28,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** + * Provides access to all available implementations of the + * {@link ComponentBuilder} interface. * * @author Jens Pelzetter */ @@ -35,38 +37,58 @@ import org.apache.logging.log4j.Logger; public class ComponentBuilderManager { private static final Logger LOGGER = LogManager.getLogger( - ComponentBuilderManager.class); + ComponentBuilderManager.class); @Inject private Instance> componentBuilders; + /** + * Find an implementation of the {@link ComponentBuilder} interface for a + * specific {@link ComponentModel} and type. + * + * @param Generic variable for the subtype of + * {@link ComponentModel} which is produced by + * the {@link ComponentBuilder} implementation. + * @param componentModelClass The sub class of the {@link ComponentModel} + * for which is processed by the + * {@link ComponentBuilder}. + * @param type The type for which the + * {@link ComponentBuilder} produces the + * component(s). + * + * @return An {@link Optional} containing the implementation of the + * {@link ComponentBuilder} interface for the specified parameters. + * If there is no implementation of the specified parameters an + * empty {@link Optional} is returned. + */ + @SuppressWarnings("unchecked") public Optional> findComponentBuilder( - final Class componentModelClass, - final String type) { + final Class componentModelClass, + final String type) { LOGGER.debug("Trying to find ComponentBuilder for ComponentModel\"{}\"" - + "and type \"{}\"...", + + "and type \"{}\"...", componentModelClass.getName(), type); final ComponentModelTypeLiteral literal = new ComponentModelTypeLiteral( - componentModelClass, type); + componentModelClass, type); final Instance> instance = componentBuilders - .select(literal); + .select(literal); if (instance.isUnsatisfied()) { LOGGER.warn("No ComponentBuilder for component model \"%s\" " - + "and type \"%s\". Ignoring component model."); + + "and type \"%s\". Ignoring component model."); return Optional.empty(); } else if (instance.isAmbiguous()) { throw new IllegalStateException(String.format( - "Multiple ComponentBuilders for component model \"%s\" and " - + "type \"%s\" available. Something is wrong", - componentModelClass.getName(), - type)); + "Multiple ComponentBuilders for component model \"%s\" and " + + "type \"%s\" available. Something is wrong", + componentModelClass.getName(), + type)); } else { final Iterator> iterator = instance. - iterator(); + iterator(); final ComponentBuilder componentBuilder = iterator.next(); return Optional.of((ComponentBuilder) componentBuilder); @@ -75,8 +97,8 @@ public class ComponentBuilderManager { } private class ComponentModelTypeLiteral - extends AnnotationLiteral - implements ComponentModelType { + extends AnnotationLiteral + implements ComponentModelType { private static final long serialVersionUID = -2601632434295178600L; @@ -84,8 +106,8 @@ public class ComponentBuilderManager { private final String type; public ComponentModelTypeLiteral( - final Class componentModel, - final String type) { + final Class componentModel, + final String type) { this.componentModel = componentModel; this.type = type; } diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentModelRepository.java b/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentModelRepository.java index 5f14b8a73..aa2dda986 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentModelRepository.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/ComponentModelRepository.java @@ -19,12 +19,17 @@ package org.libreccm.pagemodel; import org.libreccm.core.AbstractEntityRepository; +import org.libreccm.core.CoreConstants; +import org.libreccm.security.AuthorizationRequired; +import org.libreccm.security.RequiresPrivilege; import java.util.UUID; import javax.enterprise.context.RequestScoped; +import javax.transaction.Transactional; /** + * Repository class for managing {@link ComponentModel} entities. * * @author Jens Pelzetter */ @@ -41,15 +46,29 @@ public class ComponentModelRepository extends AbstractEntityRepositoryJens Pelzetter */ @RequestScoped public class PageBuilderManager { + private static final Logger LOGGER = LogManager.getLogger( + PageBuilderManager.class); + @Inject private Instance> pageBuilders; - public PageBuilder findPageBuilder( + /** + * Find a {@link PageBuilder} for a specific type and application type. + * + * @param type The type of the {@link PageBuilder}. + * @param applicationType The application type for which the + * {@link PageBuilder} builds pages. + * + * @return An {@link Optional} containing the {@link PageBuilder} + * implementation for the specified {@code type} and + * {@code applicationType}. If there is no {@code PageBuilder} for + * the specified parameters an empty {@link Optional} is returned. + */ + public Optional> findPageBuilder( final String type, final Class applicationType) { + LOGGER.debug("Trying to find PageBuilder for type \"{}\" and " + + "application type \"{}\"...", + type, + applicationType); + final PageModelTypeLiteral literal = new PageModelTypeLiteral( type, applicationType); final Instance> instance = pageBuilders.select(literal); if (instance.isUnsatisfied()) { - throw new IllegalArgumentException(String.format( - "No PageBuilder for type \"%s\" and application type \"%s\" " - + "available.", - type, - applicationType)); + LOGGER.warn("No PageBuilder for type \"{}\" and application type " + + "\"{}\" available.", + type, + applicationType); + return Optional.empty(); } else if (instance.isAmbiguous()) { throw new IllegalArgumentException(String.format( "Multiple PageBuilders for type \"%s\" and " @@ -58,10 +82,14 @@ public class PageBuilderManager { type, applicationType)); } else { + LOGGER.debug("Found PageBuilder for type \"{}\" and application " + + "type \"{}\"...", + type, + applicationType); final Iterator> iterator = instance.iterator(); final PageBuilder pageBuilder = iterator.next(); - return pageBuilder; + return Optional.of(pageBuilder); } } diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModel.java b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModel.java index 8920b522b..df3c560ba 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModel.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModel.java @@ -36,6 +36,8 @@ import javax.persistence.Enumerated; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToOne; @@ -56,6 +58,7 @@ import javax.validation.constraints.NotNull; * @see PageBuilder */ @Entity +@Inheritance(strategy = InheritanceType.JOINED) @Table(name = "PAGE_MODELS", schema = CoreConstants.DB_SCHEMA) @NamedQueries({ @NamedQuery( diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/bebop/AbstractBebopPageBuilder.java b/ccm-core/src/main/java/org/libreccm/pagemodel/bebop/AbstractBebopPageBuilder.java index ce62afd14..6aa7faa80 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/bebop/AbstractBebopPageBuilder.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/bebop/AbstractBebopPageBuilder.java @@ -25,6 +25,10 @@ import com.arsdigita.web.Web; import org.libreccm.pagemodel.AbstractPageBuilder; /** + * Basic implementation of a {@link PageBuilder} for Bebop {@link Page}s. + * Applications must provided an implementation of the {@link PageBuilder}. + * These implementations must override the + * {@link #addDefaultComponents(com.arsdigita.bebop.Page)} method. * * @author Jens Pelzetter */ @@ -48,7 +52,7 @@ public abstract class AbstractBebopPageBuilder extends AbstractPageBuilder public Page buildPage() { final String application = Web.getWebContext().getApplication(). - getPrimaryUrl(); + getPrimaryUrl(); final Page page = PageFactory.buildPage(application, ""); addDefaultComponents(page); @@ -56,5 +60,11 @@ public abstract class AbstractBebopPageBuilder extends AbstractPageBuilder return page; } + /** + * Add the default components which are present on every page. + * + * @param page The page to which the components are added. + */ public abstract void addDefaultComponents(final Page page); + }