CCM NG: Classes and annotations for describing and retrieving informations about a content type, including its authoring kit.
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4288 8810af33-2d31-482b-a856-94f89814c4dfpull/2/head
parent
eb33ac7dec
commit
36defa4cb7
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* 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 com.arsdigita.cms.ui.item;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class ItemCreateForm {
|
||||||
|
|
||||||
|
//Placeholder
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* 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.librecms.contenttypes;
|
||||||
|
|
||||||
|
import com.arsdigita.cms.ui.item.ItemCreateForm;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface AuthoringKit {
|
||||||
|
|
||||||
|
Class<? extends ItemCreateForm> createComponent();
|
||||||
|
|
||||||
|
AuthoringStep[] steps();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* 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.librecms.contenttypes;
|
||||||
|
|
||||||
|
import com.arsdigita.cms.ui.item.ItemCreateForm;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates the informations about an authoring kit.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class AuthoringKitInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The create component (the form used to collect the mandatory data for
|
||||||
|
* the content type).
|
||||||
|
*/
|
||||||
|
private Class<? extends ItemCreateForm> createComponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The authoring steps of the authoring kit.
|
||||||
|
*/
|
||||||
|
private List<AuthoringStepInfo> authoringSteps;
|
||||||
|
|
||||||
|
protected AuthoringKitInfo() {
|
||||||
|
authoringSteps = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<? extends ItemCreateForm> getCreateComponent() {
|
||||||
|
return createComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateComponent(
|
||||||
|
final Class<? extends ItemCreateForm> createComponent) {
|
||||||
|
|
||||||
|
this.createComponent = createComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AuthoringStepInfo> getAuthoringSteps() {
|
||||||
|
return Collections.unmodifiableList(authoringSteps);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setAuthoringSteps(
|
||||||
|
final List<AuthoringStepInfo> authoringSteps) {
|
||||||
|
this.authoringSteps = authoringSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addAuthoringStep(final AuthoringStepInfo authoringStep) {
|
||||||
|
authoringSteps.add(authoringStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void removeAuthoringStep(final AuthoringStepInfo authoringStep) {
|
||||||
|
authoringSteps.remove(authoringStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 3;
|
||||||
|
hash = 59 * hash + Objects.hashCode(createComponent);
|
||||||
|
hash = 59 * hash + Objects.hashCode(authoringSteps);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof AuthoringKitInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final AuthoringKitInfo other = (AuthoringKitInfo) obj;
|
||||||
|
if (!other.canEqual(this)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(this.createComponent, other.getCreateComponent())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Objects.equals(this.authoringSteps, other.getAuthoringSteps());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canEqual(final Object obj) {
|
||||||
|
return obj instanceof AuthoringKitInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String toString() {
|
||||||
|
return toString("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(final String data) {
|
||||||
|
return String.format("%s{ "
|
||||||
|
+ "createComponent = \"%s\", "
|
||||||
|
+ "authoringSteps = { %s }%s"
|
||||||
|
+ " }",
|
||||||
|
super.toString(),
|
||||||
|
Objects.toString(createComponent),
|
||||||
|
Objects.toString(authoringSteps),
|
||||||
|
data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* 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.librecms.contenttypes;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.Component;
|
||||||
|
import com.arsdigita.bebop.Form;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation used inside the {@link AuthoringKit} annotation to describe the
|
||||||
|
* authoring steps belonging to an authoring kit.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public @interface AuthoringStep {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key of the label in the {@link #labelBundle()}. If blank (default) the
|
||||||
|
* simple name of the annotated class with the suffix {@code .label} is
|
||||||
|
* used.
|
||||||
|
*
|
||||||
|
* @return The label key of the authoring step.
|
||||||
|
*/
|
||||||
|
String labelKey() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bundle providing the localised label for the authoring step. If omitted
|
||||||
|
* the default bundle for the content type will be used. The default bundle
|
||||||
|
* is the fully qualified name of the content type class with the suffix
|
||||||
|
* {@code Bundle}.
|
||||||
|
*
|
||||||
|
* @return The bundle providing the label for the authoring step.
|
||||||
|
*/
|
||||||
|
String labelBundle() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key of the description in the {@link #descriptionBundle()}. If blank
|
||||||
|
* (default) the simple name of the annotated class with the suffix
|
||||||
|
* {@code .description} is used.
|
||||||
|
*
|
||||||
|
* @return The description key of the authoring step.
|
||||||
|
*/
|
||||||
|
String descriptionKey() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bundle providing the localised description for the authoring step. If
|
||||||
|
* omitted the default bundle for the content type will be used. The default
|
||||||
|
* bundle is the fully qualified name of the content type class with the
|
||||||
|
* suffix {@code Bundle}.
|
||||||
|
*
|
||||||
|
* @return The bundle providing the description for the authoring step.
|
||||||
|
*/
|
||||||
|
String descriptionBundle() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The position of the authoring step.
|
||||||
|
*
|
||||||
|
* @return The position of the authoring step.
|
||||||
|
*/
|
||||||
|
int order();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The component (usually a {@link Form} providing the UI for the authoring
|
||||||
|
* step.
|
||||||
|
*
|
||||||
|
* @return The class providing the UI for the authoring step.
|
||||||
|
*/
|
||||||
|
Class<? extends Component> component();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,182 @@
|
||||||
|
/*
|
||||||
|
* 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.librecms.contenttypes;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.Component;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates the information about an authoring step.
|
||||||
|
*
|
||||||
|
* @see AuthoringStep
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class AuthoringStepInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bundle which provides the label for the authoring step.
|
||||||
|
*/
|
||||||
|
private String labelBundle;
|
||||||
|
/**
|
||||||
|
* The key of label for the authoring step in the {@link #labelBundle}
|
||||||
|
*/
|
||||||
|
private String labelKey;
|
||||||
|
/**
|
||||||
|
* The bundle which provides the description for the authoring step.
|
||||||
|
*/
|
||||||
|
private String descriptionBundle;
|
||||||
|
/**
|
||||||
|
* The key of the description for the authoring step in the
|
||||||
|
* {@link #descriptionBundle}.
|
||||||
|
*/
|
||||||
|
private String descriptionKey;
|
||||||
|
|
||||||
|
private int order;
|
||||||
|
private Class<? extends Component> component;
|
||||||
|
|
||||||
|
protected AuthoringStepInfo() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 int getOrder() {
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrder(final int order) {
|
||||||
|
this.order = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<? extends Component> getComponent() {
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setComponent(final Class<? extends Component> component) {
|
||||||
|
this.component = component;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 5;
|
||||||
|
hash = 53 * hash + Objects.hashCode(labelBundle);
|
||||||
|
hash = 53 * hash + Objects.hashCode(labelKey);
|
||||||
|
hash = 53 * hash + Objects.hashCode(descriptionBundle);
|
||||||
|
hash = 53 * hash + Objects.hashCode(descriptionKey);
|
||||||
|
hash = 53 * hash + Objects.hashCode(order);
|
||||||
|
hash = 53 * hash + Objects.hashCode(component);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof AuthoringStepInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final AuthoringStepInfo other = (AuthoringStepInfo) obj;
|
||||||
|
if (!other.canEqual(this)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(this.labelBundle, other.getLabelBundle())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(this.labelKey, other.getLabelKey())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(this.descriptionBundle,
|
||||||
|
other.getDescriptionBundle())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(this.descriptionKey, other.getDescriptionKey())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (order != other.getOrder()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Objects.equals(this.component, other.getComponent());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canEqual(final Object obj) {
|
||||||
|
return obj instanceof AuthoringStepInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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\","
|
||||||
|
+ "order = %d, "
|
||||||
|
+ "component = \"%s\"%s }",
|
||||||
|
super.toString(),
|
||||||
|
labelBundle,
|
||||||
|
labelKey,
|
||||||
|
descriptionKey,
|
||||||
|
descriptionBundle,
|
||||||
|
order,
|
||||||
|
Objects.toString(component),
|
||||||
|
data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* 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.librecms.contenttypes;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This annotation can be used to customise the keys and bundles used to
|
||||||
|
* retrieve the label and the description of a content type.
|
||||||
|
*
|
||||||
|
* If the annotation is not present or if one of the values in this annotation
|
||||||
|
* is omitted the default values are used.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface ContentTypeDescription {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The key of the label for the content type in the label bundle. Default
|
||||||
|
* value is {@code label}.
|
||||||
|
*
|
||||||
|
* @return The key for label of the content type.
|
||||||
|
*/
|
||||||
|
String labelKey() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bundle which provides the label for the content type. Default is the
|
||||||
|
* fully qualified class name of the annotated content item class with the
|
||||||
|
* suffix {@code Bundle}. For example the default bundle for the content
|
||||||
|
* type {@code org.librecms.contenttypes.Article} is
|
||||||
|
* {@code org.librecms.contenttypes.ArticleBundle}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return The fully qualified name of the bundle providing the label for
|
||||||
|
* the content type.
|
||||||
|
*/
|
||||||
|
String labelBundle() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The key of the description for the content type in the label bundle.
|
||||||
|
* Default value is {@code descripion}.
|
||||||
|
*
|
||||||
|
* @return The key for description of the content type.
|
||||||
|
*/
|
||||||
|
String descriptionKey() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bundle which provides the description for the content type. Default
|
||||||
|
* is the fully qualified class name of the annotated content item class
|
||||||
|
* with the suffix {@code Bundle}. For example the default bundle for the
|
||||||
|
* content type {@code org.librecms.contenttypes.Article} is
|
||||||
|
* {@code org.librecms.contenttypes.ArticleBundle}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return The fully qualified name of the bundle providing the label for
|
||||||
|
* the content type.
|
||||||
|
*/
|
||||||
|
String descriptionBundle() default "";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
* 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.librecms.contenttypes;
|
||||||
|
|
||||||
|
import org.librecms.contentsection.ContentItem;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class encapsulating all informations about a available Content Type.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class ContentTypeInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bundle which provides the localisable label for the content type.
|
||||||
|
*/
|
||||||
|
private String labelBundle;
|
||||||
|
/**
|
||||||
|
* The key of the label in the {@link #labelBundle}.
|
||||||
|
*/
|
||||||
|
private String labelKey;
|
||||||
|
/**
|
||||||
|
* The bundle which provides the description of the content type.
|
||||||
|
*/
|
||||||
|
private String descriptionBundle;
|
||||||
|
/**
|
||||||
|
* The key of the description of the content type in the
|
||||||
|
* {@link #descriptionBundle}.
|
||||||
|
*/
|
||||||
|
private String descriptionKey;
|
||||||
|
|
||||||
|
private Class<? extends ContentItem> contentItemClass;
|
||||||
|
private AuthoringKitInfo authoringKit;
|
||||||
|
|
||||||
|
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<? extends ContentItem> getContentItemClass() {
|
||||||
|
return contentItemClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentItemClass(
|
||||||
|
final Class<? extends ContentItem> contentItemClass) {
|
||||||
|
this.contentItemClass = contentItemClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthoringKitInfo getAuthoringKit() {
|
||||||
|
return authoringKit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthoringKit(final AuthoringKitInfo authoringKit) {
|
||||||
|
this.authoringKit = authoringKit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 3;
|
||||||
|
hash = 97 * hash + Objects.hashCode(labelBundle);
|
||||||
|
hash = 97 * hash + Objects.hashCode(labelKey);
|
||||||
|
hash = 97 * hash + Objects.hashCode(descriptionBundle);
|
||||||
|
hash = 97 * hash + Objects.hashCode(descriptionKey);
|
||||||
|
hash = 97 * hash + Objects.hashCode(contentItemClass);
|
||||||
|
hash = 97 * hash + Objects.hashCode(authoringKit);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof ContentTypeInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final ContentTypeInfo other = (ContentTypeInfo) 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(contentItemClass, other.getContentItemClass())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Objects.equals(authoringKit, other.getAuthoringKit());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canEqual(final Object obj) {
|
||||||
|
return obj instanceof ContentTypeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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\","
|
||||||
|
+ "contentItemClass = \"%s\", "
|
||||||
|
+ "authoringKit = { %s }%s"
|
||||||
|
+ " }",
|
||||||
|
super.toString(),
|
||||||
|
labelBundle,
|
||||||
|
labelKey,
|
||||||
|
descriptionBundle,
|
||||||
|
descriptionKey,
|
||||||
|
Objects.toString(contentItemClass),
|
||||||
|
Objects.toString(authoringKit),
|
||||||
|
data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,220 @@
|
||||||
|
/*
|
||||||
|
* 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.librecms.contenttypes;
|
||||||
|
|
||||||
|
import org.libreccm.modules.CcmModule;
|
||||||
|
import org.librecms.contentsection.ContentItem;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
public class ContentTypeManager {
|
||||||
|
|
||||||
|
private static final String DEFAULT_DESCRIPTION_KEY = "description";
|
||||||
|
private static final String DEFAULT_LABEL_KEY = "label";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of all content type currently available.
|
||||||
|
*/
|
||||||
|
private List<ContentTypeInfo> availableContentTypes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 fills the list {@link #availableContentTypes}.
|
||||||
|
*/
|
||||||
|
@PostConstruct
|
||||||
|
protected void initialize() {
|
||||||
|
final ServiceLoader<CcmModule> modules = ServiceLoader.load(
|
||||||
|
CcmModule.class);
|
||||||
|
|
||||||
|
final SortedSet<Class<? extends ContentItem>> types = new TreeSet<>(
|
||||||
|
(type1, type2) -> type1.getName().compareTo(type2.getName())
|
||||||
|
);
|
||||||
|
|
||||||
|
for (final CcmModule module : modules) {
|
||||||
|
final ContentTypes annotation = module.getClass().getAnnotation(
|
||||||
|
ContentTypes.class);
|
||||||
|
|
||||||
|
if (annotation == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<Class<? extends ContentItem>> moduleTypes = Arrays
|
||||||
|
.stream(annotation.value()).collect(Collectors.toList());
|
||||||
|
|
||||||
|
types.addAll(moduleTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
availableContentTypes = types.stream()
|
||||||
|
.filter(type -> type.getAnnotation(AuthoringKit.class) != null)
|
||||||
|
.map(contentTypeClass -> createContentTypeInfo(contentTypeClass))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for creating the info object for a content type.
|
||||||
|
*
|
||||||
|
* @param contentTypeClass The class which provides the implementation of
|
||||||
|
* the content type.
|
||||||
|
*
|
||||||
|
* @return A {@link ContentTypeInfo} object describing the content type.
|
||||||
|
*/
|
||||||
|
private ContentTypeInfo createContentTypeInfo(
|
||||||
|
final Class<? extends ContentItem> contentTypeClass) {
|
||||||
|
|
||||||
|
final ContentTypeInfo contentTypeInfo = new ContentTypeInfo();
|
||||||
|
contentTypeInfo.setContentItemClass(contentTypeClass);
|
||||||
|
|
||||||
|
final String defaultBundleName = String.join(
|
||||||
|
"",
|
||||||
|
contentTypeClass.getClass().getName(),
|
||||||
|
"Bundle");
|
||||||
|
final ContentTypeDescription typeDesc = contentTypeClass.getAnnotation(
|
||||||
|
ContentTypeDescription.class);
|
||||||
|
if (typeDesc == null) {
|
||||||
|
contentTypeInfo.setLabelBundle(defaultBundleName);
|
||||||
|
contentTypeInfo.setDescriptionBundle(defaultBundleName);
|
||||||
|
contentTypeInfo.setLabelKey(DEFAULT_LABEL_KEY);
|
||||||
|
contentTypeInfo.setDescriptionKey(DEFAULT_DESCRIPTION_KEY);
|
||||||
|
} else {
|
||||||
|
if (typeDesc.labelBundle().isEmpty()) {
|
||||||
|
contentTypeInfo.setLabelBundle(defaultBundleName);
|
||||||
|
} else {
|
||||||
|
contentTypeInfo.setLabelBundle(typeDesc.labelBundle());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeDesc.labelKey().isEmpty()) {
|
||||||
|
contentTypeInfo.setLabelKey(DEFAULT_LABEL_KEY);
|
||||||
|
} else {
|
||||||
|
contentTypeInfo.setLabelKey(typeDesc.labelKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeDesc.descriptionBundle().isEmpty()) {
|
||||||
|
contentTypeInfo.setDescriptionBundle(defaultBundleName);
|
||||||
|
} else {
|
||||||
|
contentTypeInfo.setDescriptionBundle(typeDesc
|
||||||
|
.descriptionBundle());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeDesc.descriptionKey().isEmpty()) {
|
||||||
|
contentTypeInfo.setDescriptionKey(DEFAULT_DESCRIPTION_KEY);
|
||||||
|
} else {
|
||||||
|
contentTypeInfo.setDescriptionKey(typeDesc.descriptionKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final AuthoringKit authoringKit = contentTypeClass.getAnnotation(
|
||||||
|
AuthoringKit.class);
|
||||||
|
final AuthoringKitInfo authoringKitInfo = new AuthoringKitInfo();
|
||||||
|
authoringKitInfo.setCreateComponent(authoringKit.createComponent());
|
||||||
|
|
||||||
|
final List<AuthoringStepInfo> steps = Arrays.stream(authoringKit
|
||||||
|
.steps())
|
||||||
|
.map(step -> createAuthoringStepInfo(contentTypeClass, step))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
authoringKitInfo.setAuthoringSteps(steps);
|
||||||
|
steps.sort((step1, step2) -> Integer.compare(step1.getOrder(),
|
||||||
|
step2.getOrder()));
|
||||||
|
|
||||||
|
return contentTypeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for creating an info object about an authoring step.
|
||||||
|
*
|
||||||
|
* @param contentTypeClass The class which provides the implementation of
|
||||||
|
* the content type.
|
||||||
|
* @param authoringStep The {@link AuthoringStep} annotation providing
|
||||||
|
* the information about the authoring step.
|
||||||
|
*
|
||||||
|
* @return An {@link AuthoringStepInfo} object describing the authoring
|
||||||
|
* step.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private AuthoringStepInfo createAuthoringStepInfo(
|
||||||
|
final Class<? extends ContentItem> contentTypeClass,
|
||||||
|
final AuthoringStep authoringStep) {
|
||||||
|
|
||||||
|
final AuthoringStepInfo stepInfo = new AuthoringStepInfo();
|
||||||
|
|
||||||
|
stepInfo.setComponent(authoringStep.component());
|
||||||
|
stepInfo.setOrder(authoringStep.order());
|
||||||
|
|
||||||
|
final String defaultBundleName = String.join(
|
||||||
|
"",
|
||||||
|
contentTypeClass.getClass().getName(),
|
||||||
|
"Bundle");
|
||||||
|
|
||||||
|
if (authoringStep.labelBundle().isEmpty()) {
|
||||||
|
stepInfo.setLabelBundle(defaultBundleName);
|
||||||
|
} else {
|
||||||
|
stepInfo.setLabelBundle(authoringStep.labelBundle());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authoringStep.labelKey().isEmpty()) {
|
||||||
|
stepInfo.setLabelKey(
|
||||||
|
String.join(".",
|
||||||
|
authoringStep.component().getSimpleName(),
|
||||||
|
DEFAULT_LABEL_KEY));
|
||||||
|
} else {
|
||||||
|
stepInfo.setLabelKey(authoringStep.labelKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authoringStep.descriptionBundle().isEmpty()) {
|
||||||
|
stepInfo.setDescriptionBundle(defaultBundleName);
|
||||||
|
} else {
|
||||||
|
stepInfo.setDescriptionBundle(authoringStep.descriptionBundle());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authoringStep.descriptionKey().isEmpty()) {
|
||||||
|
stepInfo.setDescriptionKey(
|
||||||
|
String.join(".",
|
||||||
|
authoringStep.component().getSimpleName(),
|
||||||
|
DEFAULT_DESCRIPTION_KEY));
|
||||||
|
} else {
|
||||||
|
stepInfo.setDescriptionKey(authoringStep.descriptionKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
return stepInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a list of all content types currently available on the system.
|
||||||
|
*
|
||||||
|
* @return A list of all available content types.
|
||||||
|
*/
|
||||||
|
public List<ContentTypeInfo> getAvailableContentTypes() {
|
||||||
|
return Collections.unmodifiableList(availableContentTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* 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.librecms.contenttypes;
|
||||||
|
|
||||||
|
import org.librecms.contentsection.ContentItem;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This annotation is used on module classes like {@link org.librecms.Cms} to
|
||||||
|
* inform the system which content types are provided by the module.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface ContentTypes {
|
||||||
|
|
||||||
|
Class<? extends ContentItem>[] value();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -34,9 +34,11 @@ import org.libreccm.security.AuthorizationRequired;
|
||||||
import org.libreccm.security.RequiresPrivilege;
|
import org.libreccm.security.RequiresPrivilege;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps between configuration classes and the settings stored in the database.
|
* Maps between configuration classes and the settings stored in the database.
|
||||||
|
|
@ -67,9 +69,8 @@ public class ConfigurationManager {
|
||||||
final ServiceLoader<CcmModule> modules = ServiceLoader.load(
|
final ServiceLoader<CcmModule> modules = ServiceLoader.load(
|
||||||
CcmModule.class);
|
CcmModule.class);
|
||||||
|
|
||||||
final SortedSet<Class<?>> configurations = new TreeSet<>((c1, c2) -> {
|
final SortedSet<Class<?>> configurations = new TreeSet<>(
|
||||||
return c1.getName().compareTo(c2.getName());
|
(conf1, conf2) -> conf1.getName().compareTo(conf2.getName()));
|
||||||
});
|
|
||||||
|
|
||||||
for (CcmModule module : modules) {
|
for (CcmModule module : modules) {
|
||||||
final Module annotation = module.getClass().getAnnotation(
|
final Module annotation = module.getClass().getAnnotation(
|
||||||
|
|
@ -79,9 +80,10 @@ public class ConfigurationManager {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Arrays.stream(annotation.configurations()).forEach(c -> {
|
final List<Class<?>> moduleConfs = Arrays.stream(
|
||||||
configurations.add(c);
|
annotation.configurations()).collect(Collectors.toList());
|
||||||
});
|
|
||||||
|
configurations.addAll(moduleConfs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return configurations;
|
return configurations;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue