From 3c6be1bf91f246f7098ad7fa22ab1c5f279ac86f Mon Sep 17 00:00:00 2001 From: jensp Date: Wed, 29 Mar 2017 08:27:11 +0000 Subject: [PATCH] CCM NG/ccm-cms: AssetTypesManager for retrieving information about available asset types. git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4649 8810af33-2d31-482b-a856-94f89814c4df --- .../arsdigita/cms/ui/assets/AssetForm.java | 27 +++ .../java/org/librecms/assets/AssetType.java | 95 ++++++++ .../org/librecms/assets/AssetTypeInfo.java | 185 ++++++++++++++++ .../java/org/librecms/assets/AssetTypes.java | 40 ++++ .../librecms/assets/AssetTypesManager.java | 203 ++++++++++++++++++ 5 files changed, 550 insertions(+) create mode 100644 ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetForm.java create mode 100644 ccm-cms/src/main/java/org/librecms/assets/AssetType.java create mode 100644 ccm-cms/src/main/java/org/librecms/assets/AssetTypeInfo.java create mode 100644 ccm-cms/src/main/java/org/librecms/assets/AssetTypes.java create mode 100644 ccm-cms/src/main/java/org/librecms/assets/AssetTypesManager.java diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetForm.java new file mode 100644 index 000000000..562b16594 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetForm.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 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 com.arsdigita.cms.ui.assets; + +/** + * + * @author Jens Pelzetter + */ +public class AssetForm { + +} diff --git a/ccm-cms/src/main/java/org/librecms/assets/AssetType.java b/ccm-cms/src/main/java/org/librecms/assets/AssetType.java new file mode 100644 index 000000000..4512e47a5 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/assets/AssetType.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2017 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.assets; + +import com.arsdigita.cms.ui.assets.AssetForm; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Used to describe an asset type. It provides the class name of edit/create + * form for the asset. Can also be used to customise the keys and bundles used + * to retrieve the label and the description of an asset type. + * + * The only required parameter is {@link #assetForm()} which provides the form + * for editing and creating assets of the annotated type. The other parameters + * can be left empty. If left empty a internal default value will be used. + * + * This annotation should only be used on subclasses of + * {@link org.librecms.contentsection.Asset}. + * + * @author Jens Pelzetter + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface AssetType { + + /** + * The form for editing and creating an asset of the annotated class. This + * parameter is required. + * + * @return The form for editing and creating assets of the annotated sub + * class {@link org.librecms.contentsection.Asset}. + */ + Class assetForm(); + + /** + * The key for the localised label of the asset type. If not set the default + * value {@code label} is used. + * + * @return The key for the localised label of the asset type. + */ + String labelKey() default ""; + + /** + * The bundle which provides the label of the asset type. If not set the + * default value is used. Default is the fully qualified class name of the + * annotated class with suffix {@code Bundle}. For example the default + * bundle for the asset type {@link org.librecms.assets.Image} is + * {@code org.librecms.assets.ImageBundle}. + * + * @return The fully qualified name of the bundle providing the label for + * the asset type. + */ + String labelBundle() default ""; + + /** + * The key for the description of the asset type in the description bundle. + * Default value is {@code descripion}. + * + * @return The key for the description of the asset type. + */ + String descriptionKey() default ""; + + /** + * The bundle which provides the description of the asset type. If not set + * the default value is used. Default is the fully qualified class name of + * the annotated class with the suffix {@code Bundle}. For example the + * default bundle for the asset type {@link org.librecms.assets.Image} is + * {@code org.librecms.assets.ImageBundle}. + * + * @return The fully qualified name of the bundle providing the description + * of the asset type. + */ + String descriptionBundle() default ""; + +} diff --git a/ccm-cms/src/main/java/org/librecms/assets/AssetTypeInfo.java b/ccm-cms/src/main/java/org/librecms/assets/AssetTypeInfo.java new file mode 100644 index 000000000..19c8a036b --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/assets/AssetTypeInfo.java @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2017 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.assets; + +import com.arsdigita.cms.ui.assets.AssetForm; + +import org.librecms.contentsection.Asset; + +import java.util.Objects; + +/** + * A easy to use encapsulation for the informations about an asset type. + * + * @author Jens Pelzetter + */ +public class AssetTypeInfo { + + /** + * The bundle which provides the localised label of the asset type. + */ + private String labelBundle; + + /** + * The key of the label in the {@link #labelBundle}. + */ + private String labelKey; + + /** + * The bundle which provides the localised description of the asset type. + */ + private String descriptionBundle; + + /** + * The key of the description in the {@link #descriptionBundle}. + */ + private String descriptionKey; + + /** + * The class of the asset type. + */ + private Class assetClass; + + /** + * The form for editing and creating asset of the type described. + */ + private Class assetForm; + + public String getLabelBundle() { + return labelBundle; + } + + public void setLabelBundle(final String labelBundle) { + this.labelBundle = labelBundle; + } + + public String getLabelKey() { + return labelKey; + } + + public void setLabelKey(final String labelKey) { + this.labelKey = labelKey; + } + + public String getDescriptionBundle() { + return descriptionBundle; + } + + public void setDescriptionBundle(final String descriptionBundle) { + this.descriptionBundle = descriptionBundle; + } + + public String getDescriptionKey() { + return descriptionKey; + } + + public void setDescriptionKey(final String descriptionKey) { + this.descriptionKey = descriptionKey; + } + + public Class getAssetClass() { + return assetClass; + } + + public void setAssetClass(final Class assetClass) { + this.assetClass = assetClass; + } + + public Class getAssetForm() { + return assetForm; + } + + public void setAssetForm(final Class assetForm) { + this.assetForm = assetForm; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 59 * hash + Objects.hashCode(labelBundle); + hash = 59 * hash + Objects.hashCode(labelKey); + hash = 59 * hash + Objects.hashCode(descriptionBundle); + hash = 59 * hash + Objects.hashCode(descriptionKey); + hash = 59 * hash + Objects.hashCode(assetClass); + hash = 59 * hash + Objects.hashCode(assetForm); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof AssetTypeInfo)) { + return false; + } + final AssetTypeInfo other = (AssetTypeInfo) obj; + if (!other.canEqual(this)) { + return false; + } + if (!Objects.equals(labelBundle, other.getLabelBundle())) { + return false; + } + if (!Objects.equals(labelKey, other.getLabelKey())) { + return false; + } + if (!Objects.equals(descriptionBundle, other.getDescriptionBundle())) { + return false; + } + if (!Objects.equals(descriptionKey, other.getDescriptionKey())) { + return false; + } + if (!Objects.equals(assetClass, other.getAssetClass())) { + return false; + } + return Objects.equals(assetForm, other.getAssetForm()); + } + + private boolean canEqual(final Object obj) { + return obj instanceof AssetTypeInfo; + } + + @Override + public final String toString() { + return toString(""); + } + + public String toString(final String data) { + return String.format("%s{ " + + "labelBundle = \"%s\", " + + "labelKey = \"%s\", " + + "descriptionBundle = \"%s\", " + + "descriptionKey = \"%s\", " + + "assetClass = \"%s\", " + + "assetForm = \"%s\"%s " + + " }", + super.toString(), + labelBundle, + labelKey, + descriptionBundle, + descriptionKey, + Objects.toString(assetClass), + Objects.toString(assetForm), + data); + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/assets/AssetTypes.java b/ccm-cms/src/main/java/org/librecms/assets/AssetTypes.java new file mode 100644 index 000000000..568ebebe8 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/assets/AssetTypes.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2017 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.assets; + +import org.librecms.contentsection.Asset; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Used on a module class like {@link org.librecms.Cms} to inform to system + * which asset types are provided by the module. + * + * @author Jens Pelzetter + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface AssetTypes { + + Class[] value(); + +} diff --git a/ccm-cms/src/main/java/org/librecms/assets/AssetTypesManager.java b/ccm-cms/src/main/java/org/librecms/assets/AssetTypesManager.java new file mode 100644 index 000000000..32a38ad12 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/assets/AssetTypesManager.java @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2017 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.assets; + +import org.libreccm.modules.CcmModule; +import org.librecms.contentsection.Asset; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.ServiceLoader; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.RequestScoped; + +/** + * Provides informations about the available asset types. + * + * @author Jens Pelzetter + */ +@RequestScoped +public class AssetTypesManager { + + private static final String DEFAULT_DESCRIPTION_KEY = "description"; + private static final String DEFAULT_LABEL_KEY = "label"; + + /** + * A list of all asset types available. + */ + private List availableAssetTypes; + + /** + * Initialises the class (is called by CDI). This method is called by the + * CDI container after an instance of this class has been created by the CDI + * container. This method creates the list {@link #availableAssetTypes}. + */ + @PostConstruct + protected void initialize() { + + final ServiceLoader modules = ServiceLoader + .load(CcmModule.class); + + final SortedSet> assetTypes = new TreeSet<>( + (type1, type2) -> type1.getName().compareTo(type2.getName())); + + for (final CcmModule module : modules) { + final AssetTypes annotation = module + .getClass() + .getAnnotation(AssetTypes.class); + + if (annotation == null) { + continue; + } + + assetTypes.addAll(Arrays.asList(annotation.value())); + } + + availableAssetTypes = assetTypes + .stream() + .filter(type -> type.getAnnotation(AssetType.class) != null) + .map(assetTypeClass -> createAssetTypeInfo(assetTypeClass)) + .collect(Collectors.toList()); + } + + /** + * Helper method for creating the info object for a asset type. + * + * @param assetTypeClass The class which provides the implementation of the + * asset type. + * + * @return A {@link AssetTypeInfo} object describing the asset type. + */ + private AssetTypeInfo createAssetTypeInfo( + final Class assetTypeClass) { + + Objects.requireNonNull(assetTypeClass); + + final AssetTypeInfo assetTypeInfo = new AssetTypeInfo(); + assetTypeInfo.setAssetClass(assetTypeClass); + + final String defaultBundleName = String.format("%sBundle", + assetTypeClass.getName()); + final AssetType assetType = assetTypeClass + .getAnnotation(AssetType.class); + + if (assetType == null) { + assetTypeInfo.setLabelBundle(defaultBundleName); + assetTypeInfo.setDescriptionBundle(defaultBundleName); + assetTypeInfo.setLabelKey(DEFAULT_LABEL_KEY); + assetTypeInfo.setDescriptionKey(DEFAULT_DESCRIPTION_KEY); + } else { + if (assetType.labelBundle().isEmpty()) { + assetTypeInfo.setLabelBundle(defaultBundleName); + } else { + assetTypeInfo.setLabelBundle(assetType.labelBundle()); + } + + if (assetType.labelKey().isEmpty()) { + assetTypeInfo.setLabelKey(DEFAULT_LABEL_KEY); + } else { + assetTypeInfo.setLabelKey(assetType.labelKey()); + } + + if (assetType.descriptionBundle().isEmpty()) { + assetTypeInfo.setDescriptionBundle(defaultBundleName); + } else { + assetTypeInfo.setDescriptionKey(assetType.descriptionBundle()); + } + + if (assetType.descriptionKey().isEmpty()) { + assetTypeInfo.setDescriptionKey(DEFAULT_DESCRIPTION_KEY); + } else { + assetTypeInfo.setDescriptionKey(assetType.descriptionKey()); + } + + assetTypeInfo.setAssetForm(assetType.assetForm()); + } + + return assetTypeInfo; + } + + /** + * Retrieves a list of all available asset types. + * + * @return A list all available asset types. + */ + public List getAvailableAssetTypes() { + return Collections.unmodifiableList(availableAssetTypes); + } + + /** + * Get the {@link AssetTypeInfo} for a specific type. + * + * @param assetTypeClass The class representing the asset type. + * + * @return A {@link AssetTypeInfo} object describing the asset type. + */ + public AssetTypeInfo getAssetTypeInfo( + final Class assetTypeClass) { + + Objects.requireNonNull(assetTypeClass); + + return createAssetTypeInfo(assetTypeClass); + } + + /** + * Convenient method for getting the {@link AssetTypeInfo} about a specific + * asset type. + * + * @param assetTypeClass The fully qualified name of the class representing + * the asset type. + * + * @return A {@link AssetTypeInfo} object describing the asset type. + * + * @throws IllegalArgumentException If no class with the provided name + * exists or the class is not a subclass of + * {@link Asset}. + */ + @SuppressWarnings("unchecked") + public AssetTypeInfo getAssetTypeInfo(final String assetTypeClass) { + + Objects.requireNonNull(assetTypeClass); + + final Class clazz; + try { + clazz = Class.forName(assetTypeClass); + } catch (ClassNotFoundException ex) { + throw new IllegalArgumentException(String.format( + "There is not class \"%s\".", assetTypeClass), + ex); + } + + if (!Asset.class.isAssignableFrom(clazz)) { + throw new IllegalArgumentException(String.format( + "Class \"%s\" is not a subclass of of \"%s\".", + assetTypeClass, + Asset.class.getName())); + } + + return getAssetTypeInfo((Class) clazz); + } + +}