From 23d015664ec2595e89e2b4ef8cbbb9d13baf8c5b Mon Sep 17 00:00:00 2001 From: jensp Date: Tue, 6 Dec 2016 14:07:44 +0000 Subject: [PATCH] CCM NG: More JavaDoc for PageModel git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4466 8810af33-2d31-482b-a856-94f89814c4df --- .../org/libreccm/pagemodel/PageModel.java | 132 ++++++++---- .../pagemodel/PageModelComponentModel.java | 45 +++- .../libreccm/pagemodel/PageModelManager.java | 202 ++++++++++-------- 3 files changed, 241 insertions(+), 138 deletions(-) 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 8ba0809cb..8920b522b 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModel.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModel.java @@ -50,103 +50,147 @@ import javax.validation.constraints.NotNull; * a page. The {@code PageModel} specifics which components are used on a page. * * @author Jens Pelzetter + * + * @see PageModelRepository + * @see PageModelManager + * @see PageBuilder */ @Entity @Table(name = "PAGE_MODELS", schema = CoreConstants.DB_SCHEMA) @NamedQueries({ @NamedQuery( - name = "PageModel.findDraftVersion", - query = "SELECT p FROM PageModel p " - + "WHERE p.modelUuid = :uuid " - + "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT") + name = "PageModel.findDraftVersion", + query = "SELECT p FROM PageModel p " + + "WHERE p.modelUuid = :uuid " + + "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT") , @NamedQuery( - name = "PageModel.hasLiveVersion", - query = "SELECT (CASE WHEN COUNT(p) > 0 THEN true ELSE False END) " - + "FROM PageModel p " - + "WHERE p.modelUuid = :uuid " - + "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE" + name = "PageModel.hasLiveVersion", + query = "SELECT (CASE WHEN COUNT(p) > 0 THEN true ELSE False END) " + + "FROM PageModel p " + + "WHERE p.modelUuid = :uuid " + + "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE" ) , @NamedQuery( - name = "PageModel.findLiveVersion", - query = "SELECT p FROM PageModel p " - + "WHERE p.modelUuid = :uuid " - + "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE") + name = "PageModel.findLiveVersion", + query = "SELECT p FROM PageModel p " + + "WHERE p.modelUuid = :uuid " + + "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE") , @NamedQuery( - name = "PageModel.findByApplication", - query = "SELECT p FROM PageModel p WHERE p.application = :application") + name = "PageModel.findByApplication", + query = "SELECT p FROM PageModel p " + + "WHERE p.application = :application " + + "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE") , @NamedQuery( - name = "PageModel.countByApplication", - query = "SELECT COUNT(p) FROM PageModel p " - + "WHERE p.application = :application") + name = "PageModel.countByApplication", + query = "SELECT COUNT(p) FROM PageModel p " + + "WHERE p.application = :application " + + "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE") , @NamedQuery( - name = "PageModel.findByApplicationAndName", - query = "SELECT p FROM PageModel p " - + "WHERE p.name = :name AND p.application = :application" + name = "PageModel.findByApplicationAndName", + query = "SELECT p FROM PageModel p " + + "WHERE p.name = :name " + + "AND p.application = :application " + + "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE" ) , @NamedQuery( - name = "PageModel.countByApplicationAndName", - query = "SELECT COUNT(p) FROM PageModel p " - + "WHERE p.name = :name AND p.application = :application" + name = "PageModel.countByApplicationAndName", + query = "SELECT COUNT(p) FROM PageModel p " + + "WHERE p.name = :name " + + "AND p.application = :application " + + "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE" ) }) public class PageModel implements Serializable { private static final long serialVersionUID = 7252512839926020978L; + /** + * The ID of the entity in the database. + */ @Id @Column(name = "PAGE_MODEL_ID") @GeneratedValue(strategy = GenerationType.AUTO) private long pageModelId; + /** + * The UUID of this {@code PageModel}. Please note that this UUID identifies + * the dataset not the model. Therefore the draft and the live version have + * different values for this field. + */ @Column(name = "UUID", length = 255, nullable = false) @NotNull private String uuid; + /** + * The UUID of the model. Same for draft and live version. + */ @Column(name = "MODEL_UUID", length = 255, nullable = false) @NotNull private String modelUuid; + /** + * The name of this {@code PageModel}. Not localised, for use in URLs. + */ @Column(name = "NAME", length = 255) private String name; + /** + * The version of this {@code PageModel}. + */ @Column(name = "VERSION", length = 255, nullable = false) @Enumerated(EnumType.STRING) private PageModelVersion version; + /** + * The localised title of this {@code PageModel} (shown in the + * administration UI), + */ @Embedded @AssociationOverride( - name = "values", - joinTable = @JoinTable(name = "PAGE_MODEL_TITLES", - schema = CoreConstants.DB_SCHEMA, - joinColumns = { - @JoinColumn(name = "PAGE_MODEL_ID") - })) + name = "values", + joinTable = @JoinTable(name = "PAGE_MODEL_TITLES", + schema = CoreConstants.DB_SCHEMA, + joinColumns = { + @JoinColumn(name = "PAGE_MODEL_ID") + })) private LocalizedString title; + /** + * A description of this {@code PageModel} describing its purpose. + */ @Embedded @AssociationOverride( - name = "values", - joinTable = @JoinTable(name = "PAGE_MODEL_DESCRIPTIONS", - schema = CoreConstants.DB_SCHEMA, - joinColumns = { - @JoinColumn(name = "PAGE_MODEL_ID") - })) + name = "values", + joinTable = @JoinTable(name = "PAGE_MODEL_DESCRIPTIONS", + schema = CoreConstants.DB_SCHEMA, + joinColumns = { + @JoinColumn(name = "PAGE_MODEL_ID") + })) private LocalizedString description; + /** + * The application with which this {@code PageModel} is associated. + */ @ManyToOne @JoinColumn(name = "APPLICATION_ID") private CcmApplication application; + /** + * The type of this {@code PageModel}. + */ @Column(name = "TYPE", length = 255, nullable = false) @NotNull private String type; + /** + * The components of the page described by this {@code PageModel}. + */ @OneToMany(mappedBy = "pageModel") private List components; @@ -246,7 +290,7 @@ public class PageModel implements Serializable { protected void clearComponents() { components.clear(); } - + @Override public int hashCode() { int hash = 7; @@ -303,13 +347,13 @@ public class PageModel implements Serializable { public String toString(final String data) { return String.format("%s{ " - + "pageModelId = %d, " - + "uuid = %s, " - + "name = \"%s\", " - + "title = %s, " - + "description = %s, " - + "type = \"%s\"" - + " }", + + "pageModelId = %d, " + + "uuid = %s, " + + "name = \"%s\", " + + "title = %s, " + + "description = %s, " + + "type = \"%s\"" + + " }", super.toString(), pageModelId, uuid, diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelComponentModel.java b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelComponentModel.java index 53914cf80..7c2ba1b83 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelComponentModel.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelComponentModel.java @@ -24,23 +24,56 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.util.ResourceBundle; /** + * Used in the description of {@link CcmModule} to specify which + * {@link ComponentModel}s are provided by an module. * * @author Jens Pelzetter */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface PageModelComponentModel { - + + /** + * Fully qualified name of a resource bundle providing the title and + * description of the {@link ComponentModel}. + * + * @return The fully qualified name of the {@link ResourceBundle} which + * provides the title and description of the {@link ComponentModel}. + */ String descBundle() default ""; - + + /** + * Key for the title of the {@link ComponentModel} in the + * {@link ResourceBundle} specified by {@link #descBundle()}. + * + * @return The key for the title of the {@link ComponentModel}. + */ String titleKey() default "component_model_title"; - + + /** + * Key for the description of the {@link ComponentModel} in the + * {@link ResourceBundle} specified by {@link #descBundle()}. + * + * @return The key for the description of the {@link ComponentModel}. + */ String descKey() default "component_model_desc"; - + + /** + * The class which provides the {@link ComponentModel}. + * + * @return The class which provides the {@link ComponentModel}. + */ Class modelClass(); - + + /** + * A (Bebop) form for editing the properties of an instance of the + * {@link ComponentModel}. + * + * @return A (Bebop) form for editing the {@code ComponentModel}. + */ Class editor(); - + } diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelManager.java b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelManager.java index 33124dca4..91031d75b 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelManager.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/PageModelManager.java @@ -41,8 +41,6 @@ import java.util.Map; import java.util.Optional; import java.util.ServiceLoader; import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.annotation.PostConstruct; import javax.enterprise.context.RequestScoped; @@ -52,6 +50,7 @@ import javax.persistence.TypedQuery; import javax.transaction.Transactional; /** + * Provides several methods for managing {@link PageModel}s. * * @author Jens Pelzetter */ @@ -68,19 +67,24 @@ public class PageModelManager { private ComponentModelRepository componentModelRepo; private final Map components - = new HashMap<>(); + = new HashMap<>(); + /** + * Called by CDI after an instance of this class is created. Initialises the + * {@link #components} by retrieving the data about all available + * {@link ComponentModel}s. + */ @PostConstruct private void init() { final ServiceLoader modules = ServiceLoader.load( - CcmModule.class); + CcmModule.class); for (CcmModule module : modules) { final Module moduleData = module.getClass().getAnnotation( - Module.class); + Module.class); final PageModelComponentModel[] models = moduleData - .pageModelComponentModels(); + .pageModelComponentModels(); for (PageModelComponentModel model : models) { components.put(model.modelClass().getName(), @@ -90,13 +94,17 @@ public class PageModelManager { } /** - * Creates a new {@link PageModel} for the provided application. + * Creates a new {@link PageModel} for the provided application. The tries + * to retrieve the appropriate page model by using + * {@link PageModelRepository#findByApplicationAndName(org.libreccm.web.CcmApplication, java.lang.String)}. + * Please note that this method will always return the live + * version of the page model. * - * @param name The name of the new page model. Must be unique for the - * application. + * @param name The name of the new page model. Must be unique for the + * application. * @param application The application for which the {@link PageModel} is - * created. - * @param type Type of the page model (view technology). + * created. + * @param type Type of the page model (view technology). * * @return The new {@link PageModel}. */ @@ -109,12 +117,12 @@ public class PageModelManager { if (application == null) { throw new IllegalArgumentException( - "Can't create a page model for application null"); + "Can't create a page model for application null"); } if (name == null || name.trim().isEmpty()) { throw new IllegalArgumentException( - "The name of a page model can't be null or empty."); + "The name of a page model can't be null or empty."); } final long count = pageModelRepo.countByApplicationAndName(application, @@ -122,10 +130,10 @@ public class PageModelManager { if (count > 0) { throw new IllegalArgumentException(String.format( - "A page model with the name \"%s\" for the application \"%s\" " + "A page model with the name \"%s\" for the application \"%s\" " + "already exists.", - name, - application.getPrimaryUrl())); + name, + application.getPrimaryUrl())); } final PageModel pageModel = new PageModel(); @@ -138,42 +146,61 @@ public class PageModelManager { return pageModel; } + /** + * Retrieves the draft version of a {@link PageModel}. To invoke this method + * the current user needs a permission granting the + * {@link CoreConstants#PRIVILEGE_ADMIN} privilege. + * + * @param pageModel The {@link PageModel} for which the draft version is + * retrieved. + * @return The draft version of the provided {@link PageModel}. + */ @AuthorizationRequired @Transactional(Transactional.TxType.REQUIRED) public PageModel getDraftVersion( - @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) - final PageModel pageModel) { + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + final PageModel pageModel) { if (pageModel == null) { throw new IllegalArgumentException( - "Can't get draft version for page model null."); + "Can't get draft version for page model null."); } final TypedQuery query = entityManager.createNamedQuery( - "PageModel.findDraftVersion", PageModel.class); + "PageModel.findDraftVersion", PageModel.class); query.setParameter("uuid", pageModel.getModelUuid()); return query.getSingleResult(); } + /** + * Checks if a {@link PageModel} has a live version. + * + * @param pageModel The {@link PageModel} to check for a live version. + * @return {@code true} if there is a live version for the provided + * {@link PageModel}, {@code false} otherwise. + */ @Transactional(Transactional.TxType.REQUIRED) public boolean isLive(final PageModel pageModel) { final TypedQuery query = entityManager.createNamedQuery( - "PageModel.hasLiveVersion", Boolean.class); + "PageModel.hasLiveVersion", Boolean.class); query.setParameter("uuid", pageModel.getModelUuid()); return query.getSingleResult(); } - @AuthorizationRequired + /** + * + * @param pageModel + * @return + */ @Transactional(Transactional.TxType.REQUIRED) - public Optional getLiveVersion( - @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) PageModel pageModel) { + public Optional getLiveVersion(final PageModel pageModel) { if (isLive(pageModel)) { final TypedQuery query = entityManager.createNamedQuery( - "PageModel.findLiveVersion", - PageModel.class); + "PageModel.findLiveVersion", + PageModel.class); query.setParameter("uuid", pageModel.getModelUuid()); return Optional.of(query.getSingleResult()); } else { @@ -195,159 +222,159 @@ public class PageModelManager { liveModel.setModelUuid(draftModel.getModelUuid()); for (Map.Entry entry : draftModel.getTitle().getValues() - .entrySet()) { + .entrySet()) { liveModel.getTitle().addValue(entry.getKey(), entry.getValue()); } for (Map.Entry entry : liveModel.getDescription() - .getValues().entrySet()) { - liveModel.getDescription().addValue(entry.getKey(), + .getValues().entrySet()) { + liveModel.getDescription().addValue(entry.getKey(), entry.getValue()); } liveModel.setApplication(draftModel.getApplication()); liveModel.setType(draftModel.getType()); - - + liveModel.clearComponents(); - for(final ComponentModel draft : draftModel.getComponents()) { + for (final ComponentModel draft : draftModel.getComponents()) { final ComponentModel live = publishComponentModel(draft); addComponentModel(liveModel, live); } - + return liveModel; } - + @SuppressWarnings("unchecked") private ComponentModel publishComponentModel(final ComponentModel draftModel) { - + final Class clazz = draftModel.getClass(); - + final ComponentModel liveModel; try { liveModel = clazz.newInstance(); } catch (InstantiationException | IllegalAccessException ex) { throw new UncheckedWrapperException(ex); } - + liveModel.setModelUuid(draftModel.getModelUuid()); - + final BeanInfo beanInfo; try { beanInfo = Introspector.getBeanInfo(clazz); - } catch(IntrospectionException ex) { + } catch (IntrospectionException ex) { throw new UncheckedWrapperException(ex); } - - for(final PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) { + + for (final PropertyDescriptor propertyDescriptor : beanInfo. + getPropertyDescriptors()) { final Class propType = propertyDescriptor.getPropertyType(); final Method readMethod = propertyDescriptor.getReadMethod(); final Method writeMethod = propertyDescriptor.getWriteMethod(); - + if (propertyIsExcluded(propertyDescriptor.getName())) { continue; } - + if (writeMethod == null) { continue; } - + if (propType != null - && propType.isAssignableFrom(List.class)) { - + && propType.isAssignableFrom(List.class)) { + final List source; final List target; try { source = (List) readMethod.invoke(draftModel); target = (List) readMethod.invoke(liveModel); - } catch(IllegalAccessException - | IllegalArgumentException - | InvocationTargetException ex) { + } catch (IllegalAccessException + | IllegalArgumentException + | InvocationTargetException ex) { throw new UncheckedWrapperException(ex); } - + target.addAll(source); - } else if(propType != null - && propType.isAssignableFrom(Map.class)) { - + } else if (propType != null + && propType.isAssignableFrom(Map.class)) { + final Map source; final Map target; - + try { source = (Map) readMethod.invoke(draftModel); target = (Map) readMethod.invoke(liveModel); - } catch(IllegalAccessException - | IllegalArgumentException - | InvocationTargetException ex) { + } catch (IllegalAccessException + | IllegalArgumentException + | InvocationTargetException ex) { throw new UncheckedWrapperException(ex); } - + source.forEach((key, value) -> target.put(key, value)); - - } else if(propType != null - && propType.isAssignableFrom(Set.class)) { - + + } else if (propType != null + && propType.isAssignableFrom(Set.class)) { + final Set source; final Set target; - + try { source = (Set) readMethod.invoke(draftModel); target = (Set) readMethod.invoke(liveModel); - }catch(IllegalAccessException - | IllegalArgumentException - | InvocationTargetException ex) { + } catch (IllegalAccessException + | IllegalArgumentException + | InvocationTargetException ex) { throw new UncheckedWrapperException(ex); } - + target.addAll(source); } else { final Object value; try { value = readMethod.invoke(draftModel); writeMethod.invoke(liveModel, value); - } catch(IllegalAccessException - | IllegalArgumentException - | InvocationTargetException ex) { + } catch (IllegalAccessException + | IllegalArgumentException + | InvocationTargetException ex) { throw new UncheckedWrapperException(ex); } } } - + componentModelRepo.save(liveModel); - + return liveModel; } - + private boolean propertyIsExcluded(final String name) { final String[] excluded = new String[]{ "uuid", "modelUuid" }; - + boolean result = false; - for(final String current : excluded) { + for (final String current : excluded) { if (current.equals(name)) { result = true; break; } } - + return result; } public List findAvailableComponents() { final List list = new ArrayList<>(components - .values()); + .values()); list.sort((component1, component2) -> { return component1.modelClass().getName().compareTo( - component2.modelClass().getName()); + component2.modelClass().getName()); }); return list; } public Optional findComponentModel( - final String className) { + final String className) { if (components.containsKey(className)) { return Optional.of(components.get(className)); @@ -359,8 +386,7 @@ public class PageModelManager { /** * Add a {@link ComponentModel} to a {@link PageModel}. * - * @param pageModel The {@link PageModel} to which component model is - * added. + * @param pageModel The {@link PageModel} to which component model is added. * @param componentModel The {@link ComponentModel} to add. */ public void addComponentModel(final PageModel pageModel, @@ -368,12 +394,12 @@ public class PageModelManager { if (pageModel == null) { throw new IllegalArgumentException( - "Can't add a component model to page model null."); + "Can't add a component model to page model null."); } if (componentModel == null) { throw new IllegalArgumentException( - "Can't add component model null to a page model."); + "Can't add component model null to a page model."); } pageModel.addComponent(componentModel); @@ -386,22 +412,22 @@ public class PageModelManager { /** * Removes a {@link ComponentModel} from a {@link PageModel}. * - * @param pageModel The {@link PageModel} from which the - * {@link ComponentModel} is removed. + * @param pageModel The {@link PageModel} from which the + * {@link ComponentModel} is removed. * @param componentModel The {@link ComponentModel} to remove. The component - * model is also removed from the database. + * model is also removed from the database. */ public void removeComponentModel(final PageModel pageModel, final ComponentModel componentModel) { if (pageModel == null) { throw new IllegalArgumentException( - "Can't remove a component model from page model null."); + "Can't remove a component model from page model null."); } if (componentModel == null) { throw new IllegalArgumentException( - "Can't remove component model null from a page model."); + "Can't remove component model null from a page model."); } pageModel.removeComponent(componentModel);