CCM NG/ccm-cms: Ported forms for creating new items

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4691 8810af33-2d31-482b-a856-94f89814c4df

Former-commit-id: 8657ce76e3
pull/2/head
jensp 2017-04-26 17:35:02 +00:00
parent e8242ba661
commit bc4a31c492
7 changed files with 940 additions and 143 deletions

View File

@ -0,0 +1,282 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.authoring;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Container;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.FormSection;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.ParameterEvent;
import com.arsdigita.bebop.form.RadioGroup;
import com.arsdigita.bebop.parameters.LongParameter;
import com.arsdigita.bebop.parameters.NotNullValidationListener;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentSection;
import org.librecms.contentsection.ContentType;
import org.librecms.contentsection.Folder;
import com.arsdigita.cms.ui.workflow.WorkflowsOptionPrintListener;
import com.arsdigita.globalization.GlobalizedMessage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.security.PermissionChecker;
import org.libreccm.workflow.AssignableTask;
import org.libreccm.workflow.AssignableTaskManager;
import org.libreccm.workflow.Workflow;
import org.libreccm.workflow.WorkflowManager;
import org.libreccm.workflow.WorkflowTemplate;
import org.libreccm.workflow.WorkflowTemplateRepository;
import org.librecms.CmsConstants;
import org.librecms.contentsection.privileges.ItemPrivileges;
import java.util.List;
import java.util.TooManyListenersException;
/**
* A FormSection which will allow users with
* SecrityConstants.APPLY_ALTERNATE_WORFLOWS permission to choose a different
* workflow to apply to a new item.
*
* @author Stanislav Freidin (stas@arsdigita.com)
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ApplyWorkflowFormSection
extends FormSection
implements FormInitListener {
private static final Logger LOGGER = LogManager
.getLogger(ApplyWorkflowFormSection.class);
private RadioGroup radioGroup;
private CreationSelector creationSelector;
private ContentType contentType;
private ApplyWorkflowPrintListener printListener;
/**
* Construct a new ApplyWorkflowFormSection
*/
public ApplyWorkflowFormSection() {
this(null);
}
/**
* Construct a new ApplyWorkflowFormSection
*
* @param type
*/
public ApplyWorkflowFormSection(final ContentType type) {
this(type, new ColumnPanel(2, true));
}
/**
* Construct a new ApplyWorkflowFormSection
*
* @param type
* @param panel Container to use for this FormSection
*/
public ApplyWorkflowFormSection(final ContentType type,
final Container panel) {
super(panel);
radioGroup = new RadioGroup(new LongParameter("workflowSelect"));
radioGroup.setClassAttr("vertical");
contentType = type;
printListener = new ApplyWorkflowPrintListener();
try {
// should we filter on WorkflowDefinitions where this user
// is assigned to at least one initial task, or should we
// assume that users with "alternate workflow" permission
// are advanced enough to know what they're doing?
radioGroup.addPrintListener(printListener);
} catch (TooManyListenersException ex) {
LOGGER.error("Too many listeners", ex);
}
add(new Label(new GlobalizedMessage("cms.ui.authoring.workflow",
CmsConstants.CMS_BUNDLE)));
radioGroup.addValidationListener(new NotNullValidationListener() {
@Override
public void validate(final ParameterEvent event) {
final PageState state = event.getPageState();
if (!ApplyWorkflowFormSection.this.isVisible(state)) {
return;
}
super.validate(event);
}
});
add(radioGroup);
addInitListener(this);
}
/**
* Initialises the workflow selection widget to the default workflow for the
* content type.
*
* @param event
*
* @throws com.arsdigita.bebop.FormProcessException
*/
@Override
public void init(final FormSectionEvent event) throws FormProcessException {
final PageState state = event.getPageState();
final ContentSection section = creationSelector.getContentSection(
state);
final WorkflowTemplate template = contentType.getDefaultWorkflow();
if (template != null) {
radioGroup.setValue(state, template.getWorkflowId());
}
}
/**
* Sets the CreationSelector which should be the same as that of the
* creation component. This cannot be set in the constructor since for most
* creation components, addWidgets() is called via the superclass
* constructor, so this member will not yet be set.
*
* @param creationSelector CreationSelector to use for this FormSection
*/
public void setCreationSelector(final CreationSelector creationSelector) {
this.creationSelector = creationSelector;
}
/**
* Sets the ContentType for the creation component.
*
* @param contentType ContentType to use for this FormSection
*/
public void setContentType(final ContentType contentType) {
this.contentType = contentType;
}
/**
* Whether or not this component is visible. The additional visibility
* requirement is that the user must have the
* SecurityConstants.APPLY_ALTERNATE_WORKFLOWS privilege on the parent
* folder.
*
* @param state The PageState
*
* @return
*/
@Override
public boolean isVisible(final PageState state) {
boolean result = false;
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PermissionChecker permissionChecker = cdiUtil
.findBean(PermissionChecker.class);
;
if (super.isVisible(state)
&& permissionChecker
.isPermitted(ItemPrivileges.APPLY_ALTERNATE_WORKFLOW,
creationSelector.getFolder(state))) {
return !printListener.getCollection(state).isEmpty();
}
return result;
}
/**
* Apply the proper initial workflow to the item. If the user has
* SecurityConstants.APPLY_ALTERNATE_WORKFLOWS permission on the parent
* folder <em>and</em> a workflow has been chosen, use this workflow.
* Otherwise use the default workflow for the content type.
*
* @param state The PageState
* @param item The new ContentItem
*/
public void applyWorkflow(final PageState state, final ContentItem item) {
final Long flowId = (Long) radioGroup.getValue(state);
final ContentSection section = creationSelector.getContentSection(
state);
final Folder folder = creationSelector.getFolder(state);
final WorkflowTemplate template;
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PermissionChecker permissionChecker = cdiUtil
.findBean(PermissionChecker.class);
final WorkflowTemplateRepository templateRepo = cdiUtil
.findBean(WorkflowTemplateRepository.class);
if (flowId != null
&& permissionChecker.isPermitted(
ItemPrivileges.APPLY_ALTERNATE_WORKFLOW, folder)) {
template = templateRepo
.findById(flowId)
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No WorkflowTemplate with ID %d in database. "
+ "Where did that ID come from?")));
} else {
template = item.getContentType().getDefaultWorkflow();
}
if (template != null) {
final WorkflowManager workflowManager = cdiUtil
.findBean(WorkflowManager.class);
final Workflow workflow = workflowManager.createWorkflow(template,
item);
workflowManager.start(workflow);
if (!workflow.getTasks().isEmpty()) {
if (workflow.getTasks().get(0) instanceof AssignableTask) {
final AssignableTaskManager taskManager = cdiUtil
.findBean(AssignableTaskManager.class);
final AssignableTask task = (AssignableTask) workflow
.getTasks()
.get(0);
taskManager.lockTask(task);
}
}
}
}
private class ApplyWorkflowPrintListener
extends WorkflowsOptionPrintListener {
@Override
protected ContentSection getContentSection(final PageState state) {
return creationSelector.getContentSection(state);
}
@Override
protected List<WorkflowTemplate> getCollection(final PageState state) {
return super.getCollection(state);
}
}
}

View File

@ -20,6 +20,7 @@ package com.arsdigita.cms.ui.authoring;
import com.arsdigita.bebop.ColumnPanel; import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Component; import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException; import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.FormSection; import com.arsdigita.bebop.FormSection;
import com.arsdigita.bebop.Label; import com.arsdigita.bebop.Label;
@ -39,7 +40,12 @@ import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.web.Web; import com.arsdigita.web.Web;
import com.arsdigita.xml.Element; import com.arsdigita.xml.Element;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.CmsConstants; import org.librecms.CmsConstants;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemRepository;
/** /**
* A form for editing subclasses of ContentItem. This is just a convenience * A form for editing subclasses of ContentItem. This is just a convenience
@ -222,7 +228,7 @@ public abstract class BasicItemForm extends FormSection
} }
/** /**
* Perform form initialization. Children should override this this method to * Perform form initialisation. Children should override this this method to
* pre-fill the widgets with data, instantiate the content item, etc. * pre-fill the widgets with data, instantiate the content item, etc.
* *
* @param e * @param e
@ -343,140 +349,64 @@ public abstract class BasicItemForm extends FormSection
* @param event the {@link FormSectionEvent} which was passed to the * @param event the {@link FormSectionEvent} which was passed to the
* validation listener * validation listener
*/ */
// public void validateNameUniqueness(Category parent, FormSectionEvent event) { public void validateNameUniqueness(final Category parent,
// final FormSectionEvent event) {
// FormData data = event.getFormData();
// String newName = (String) data.get(NAME); final FormData data = event.getFormData();
// final String newName = (String) data.get(NAME);
// validateNameUniqueness(parent, event, newName);
// } validateNameUniqueness(parent, event, newName);
}
/** /**
* *
* @param parent * @param parent
* @param event * @param event
* @param newName * @param newName
*/ */
// public void validateNameUniqueness(Category parent, public void validateNameUniqueness(final Category parent,
// FormSectionEvent event, final FormSectionEvent event,
// String newName) { final String newName) {
//
// final String ERR_MSG = "cms.ui.authoring.an_item_with_this_name_exists"; final String ERR_MSG = "cms.ui.authoring.an_item_with_this_name_exists";
//
// if (newName != null) { if (newName != null) {
// final String query = "com.arsdigita.cms.validateUniqueItemName"; final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
// DataQuery dq = SessionManager.getSession().retrieveQuery(query); final CategoryRepository categoryRepo = cdiUtil
// dq.setParameter("parentId", parent.getID()); .findBean(CategoryRepository.class);
// dq.setParameter("name", newName.toUpperCase()); final ContentItemRepository itemRepo = cdiUtil
// FormData data = event.getFormData(); .findBean(ContentItemRepository.class);
// ParameterData name = data.getParameter(NAME);
// final long result = itemRepo.countByNameInFolder(parent, newName);
// if (dq.size() > 0) {
// // Try to get a currently selected content item if (result > 0) {
// ContentItem item = null; // Try to get a currently selected content item
// if (getItemSelectionModel() != null) { final ContentItem item;
// item = (ContentItem) getItemSelectionModel() if (getItemSelectionModel() == null) {
// .getSelectedObject(event.getPageState()); item = null;
// } } else {
// if (item == null) { // The content item being null item = getItemSelectionModel()
// // means it is a creation form. .getSelectedObject(event.getPageState());
// // Therefore finding any item of the same name is a fault. }
// data.addError(globalize(ERR_MSG)); if (item == null) { // The content item being null
// return; // means it is a creation form.
// } else { // Therefore finding any item of the same name is a fault.
// // means we are in a edit form. event.getFormData()
// // We need to add all of the items that are different .addError(new GlobalizedMessage(ERR_MSG,
// // versions of this item to the list so that we do not mark CmsConstants.CMS_BUNDLE));
// // an error if those are the only problems. } else {
// BigDecimal itemID = null; // means we are in a edit form.
// Collection list = getAllVersionIDs(item); // We need to add all of the items that are different
// while (dq.next()) { // versions of this item to the list so that we do not mark
// itemID = (BigDecimal) dq.get("itemID"); // an error if those are the only problems.
// if (!list.contains(itemID)) { event.getFormData()
// String[] itemObj = new String[1]; .addError(new GlobalizedMessage(
// itemObj[0] = itemID.toString(); ERR_MSG,
// dq.close(); CmsConstants.CMS_BUNDLE,
// data.addError(globalize(ERR_MSG, itemObj)); new Object[]{item.getUuid()}));
// return; }
// } }
// } }
// } }
// }
// }
// }
/**
* NOT USED ANYMORE.
*
* Ensure that the name of an item is unique within a category. This should
* only be called from the validation listener of an "edit" form.
*
* @param event the {@link FormSectionEvent} which was passed to the
* validation listener
* @param id The id of the item that is being checked. This must no be
* null.
*
* @return
*
* @throws FormProcessException if the folder already contains an item with
* the name the user provided on the input
* form. / public void
* validateNameUniquenessWithinCategory(FormSectionEvent
* event, BigDecimal id) throws
* FormProcessException { if (id == null) {
* s_log.warn("Trying to validation the name
* uniqueness without " + " a valid item is
* invalid. This method should only " + " be
* called in \"edit\" forms. The passed in id "
* + " was null."); return; } // now we check
* to make sure that the new name is valid //
* within every category that the item is
* mapped to // this is only necessary for
* category browsing FormData data =
* event.getFormData(); String url = (String)
* data.get(NAME); if (url == null) { return; }
* DataQuery query =
* SessionManager.getSession().retrieveQuery(
* "com.arsdigita.categorization.getAllItemURLsForCategoryFromItem");
* query.setParameter("itemID", id);
* query.addEqualsFilter("lower(url)",
* url.toLowerCase()); if (query.size() > 0) {
* // we need to make sure that the conflicting
* item is not a // pending or live version of
* the same item BigDecimal itemID = null;
*
* ContentItem item = (ContentItem)getItemSelectionModel()
* .getSelectedObject(event.getPageState()); Collection list =
* getAllVersionIDs(item); try { while (query.next()) { itemID =
* (BigDecimal) query.get("itemID"); if (!list.contains(itemID)) { //
* StringBuffer buffer = new StringBuffer((String) GlobalizationUtil //
* .globalize("cms.ui.authoring.error_conflicts_with_this_url") //
* .localize()); // buffer.append(url); String[] urlObj=new String[1];
* urlObj[0]=url; throw new FormProcessException( "Error: Conflict with url:
* "+url, globalize( "cms.ui.authoring.error_conflicts_with_this_url",
* urlObj) ); } }
*
* } finally { query.close(); } } }
*/
/**
* Helper Method for name uniqueness validation.
*
* @param item
*
* @return
*/
// public static Collection getAllVersionIDs(ContentItem item) {
// // we need to add all of the items that are different versions
// // of this item to the list so that we do not throw an error
// // if those are the only problems
// ArrayList list = new ArrayList();
// list.add(item.getID());
// ContentItem live = item.getLiveVersion();
// if (live != null) {
// list.add(live.getID());
// }
// ItemCollection collection = item.getPendingVersions();
// while (collection.next()) {
// list.add(collection.getID());
// }
// return list;
// }
} }

View File

@ -0,0 +1,310 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.authoring;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.FormSection;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.ParameterEvent;
import com.arsdigita.bebop.event.ParameterListener;
import com.arsdigita.bebop.parameters.DateParameter;
import com.arsdigita.bebop.parameters.ParameterData;
import com.arsdigita.bebop.parameters.ParameterModel;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentSection;
import org.librecms.contentsection.Folder;
import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.KernelConfig;
import com.arsdigita.util.Assert;
import org.arsdigita.cms.CMSConfig;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.CmsConstants;
import org.librecms.contentsection.ContentItemManager;
import org.librecms.contentsection.ContentType;
import org.librecms.contentsection.FolderManager;
import javax.servlet.ServletException;
import java.util.Date;
import java.util.Locale;
import java.util.Optional;
/**
* A form for editing basic properties of documents (that is subclasses of class
* ContentPage).
*
* Document specific classes inherit from this class which provides the basic
* widgets for title, name launch date to use by those classes.
*
* This is just a convenience class. It uses parent class to construct the form
* including basic widgets (i.e. title and name/URL as well as save/cancel
* buttons) and adds optional launch date.
*
* Note: It is for editing existing content (specifically due to its validation
* method).
*
* @author Stanislav Freidin (stas@arsdigita.com)
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public abstract class BasicPageForm extends BasicItemForm {
private static final String LAUNCH_DATE = "launch_date";
private FormSection widgetSection;
/**
* Construct a new BasicPageForm
*
* @param formName the name of this form
* @param itemModel The {@link ItemSelectionModel} which will be responsible
* for loading the current item
*/
public BasicPageForm(final String formName,
final ItemSelectionModel itemModel) {
super(formName, itemModel);
}
/**
* Construct a new BasicPageForm with nothing on it
*
* @param formName the name of this form
* @param columnPanel the column panel of the form
* @param itemModel The {@link ItemSelectionModel} which will be
* responsible for loading the current item
*/
public BasicPageForm(final String formName,
final ColumnPanel columnPanel,
final ItemSelectionModel itemModel) {
super(formName, columnPanel, itemModel);
}
/**
* Add various widgets to the form. Child classes should override this
* method to perform all their widget-adding needs
*/
@Override
protected void addWidgets() {
/* Add basic widgets title/name which are part of any content item */
super.addWidgets();
final CMSConfig cmsConfig = CMSConfig.getConfig();
/* Optionally add Lunchdate */
if (!cmsConfig.isHideLaunchDate()) {
add(new Label(new GlobalizedMessage(
"cms.ui.authoring.page_launch_date",
CmsConstants.CMS_BUNDLE)));
final ParameterModel launchDateParam
= new DateParameter(LAUNCH_DATE);
com.arsdigita.bebop.form.Date launchDate
= new com.arsdigita.bebop.form.Date(
launchDateParam);
if (CMSConfig.getConfig().isRequireLaunchDate()) {
launchDate.addValidationListener(
new LaunchDateValidationListener());
// if launch date is required, help user by suggesting today's date
launchDateParam.setDefaultValue(new Date());
}
add(launchDate);
}
}
/**
* Utility method to initialise the name/title widgets. Child classes may
* call this method from the init listener
*
* @param event the {@link FormSectionEvent} which was passed to the init
* listener
*
* @return the ContentPage instance which was extracted from the
* ItemSelectionModel
*/
public ContentItem initBasicWidgets(final FormSectionEvent event) {
Assert.exists(getItemSelectionModel());
final FormData data = event.getFormData();
final PageState state = event.getPageState();
final ContentItem item = getItemSelectionModel()
.getSelectedObject(state);
if (item != null) {
// Preset fields
data.put(CONTENT_ITEM_ID, Long.toString(item.getObjectId()));
data.put(NAME, item.getName());
data.put(TITLE, item.getTitle());
final CMSConfig cmsConfig = CMSConfig.getConfig();
if (!cmsConfig.isHideLaunchDate()) {
data.put(LAUNCH_DATE, item.getLaunchDate());
// if launch date is required, help user by suggesting today's date
if (cmsConfig.isRequireLaunchDate()
&& item.getLaunchDate() == null) {
data.put(LAUNCH_DATE, new Date());
}
}
}
return item;
}
/**
* Class specific implementation of FormValidationListener interface
* (inherited from BasicItemForm).
*
* @param fse
*
* @throws FormProcessException
*/
@Override
public void validate(final FormSectionEvent fse) throws FormProcessException {
super.validate(fse); //noop, BasicItemForm#validate does nothing
final ContentItem item = getItemSelectionModel()
.getSelectedItem(fse.getPageState());
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final ContentItemManager itemManager = cdiUtil
.findBean(ContentItemManager.class);
final Optional<Folder> folder = itemManager.getItemFolder(item);
if (folder.isPresent()) {
final FormData data = fse.getFormData();
final String name = fse.getFormData().getString(NAME);
if (!item.getName()
.getValue(KernelConfig.getConfig().getDefaultLocale())
.equals(name)) {
validateNameUniqueness(folder.get(), fse);
}
}
}
/**
* Utility method to process the name/title widgets. Child classes may call
* this method from the process listener.
*
* @param event the {@link FormSectionEvent} which was passed to the process
* listener
*
* @return
*/
public ContentItem processBasicWidgets(final FormSectionEvent event) {
Assert.exists(getItemSelectionModel());
final FormData data = event.getFormData();
final PageState state = event.getPageState();
final ContentItem item = getItemSelectionModel()
.getSelectedObject(state);
if (item != null) {
// Update attributes
final KernelConfig kernelConfig = KernelConfig.getConfig();
final Locale defaultLocale = kernelConfig.getDefaultLocale();
item.getName().addValue(defaultLocale, (String) data.get(NAME));
item.getTitle().addValue(defaultLocale, (String) data.get(TITLE));
if (!CMSConfig.getConfig().isHideLaunchDate()) {
item.setLaunchDate((Date) data.get(LAUNCH_DATE));
}
}
return item;
}
/**
* A utility method that will create a new item and tell the selection model
* to select the new item.
*
* Creation components may call this method in the process listener of their
* form. See {@link PageCreate} for an example.
*
* @param state
* @param name
* @param section
* @param folder
*
* @return the new content item (or a proper subclass thereof)
*
* @throws com.arsdigita.bebop.FormProcessException
*/
public ContentItem createContentPage(final PageState state,
final String name,
final ContentSection section,
final Folder folder)
throws FormProcessException {
final ItemSelectionModel selectionModel = getItemSelectionModel();
final ContentType contentType = selectionModel.getContentType();
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final ContentItemManager itemManager = cdiUtil
.findBean(ContentItemManager.class);
// Create new item
final ContentItem item;
try {
@SuppressWarnings("unchecked")
final Class<? extends ContentItem> clazz
= (Class<? extends ContentItem>) Class
.forName(contentType.getContentItemClass());
item = itemManager.createContentItem(name, section, folder, clazz);
} catch (ClassNotFoundException ex) {
throw new FormProcessException(
"Couldn't create contentpage",
new GlobalizedMessage(
"cms.ui.authoring.couldnt_create_contentpage",
CmsConstants.CMS_BUNDLE),
ex);
}
// Create new item
// Make sure the item will be remembered across requests
selectionModel.setSelectedKey(state, item.getObjectId());
return item;
}
/**
* Constructs a new <code>LaunchDateValidationListener</code>.
*/
private class LaunchDateValidationListener implements ParameterListener {
@Override
public void validate(final ParameterEvent event) {
final ParameterData data = event.getParameterData();
final Object value = data.getValue();
if (value == null) {
data.addError("launch date is required");
}
}
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.authoring;
import com.arsdigita.bebop.Container;
import com.arsdigita.bebop.SaveCancelSection;
import com.arsdigita.bebop.event.FormProcessListener;
/**
* Interface which item creation components should implement. It's
* currently an optional interface, but user defined content types
* will not work unless they inherit from a type whose creation
* component implements this. This interface currently only defines
* methods which are essential to the operation of UDCT creation
* components.
*
* @author Scott Seago (sseago@redhat.com)
*/
public interface CreationComponent extends Container, FormProcessListener {
/**
* Instantiate and add the save/cancel section for this CreationComponent.
*/
void addSaveCancelSection();
/**
* Return the save/cancel section for this CreationComponent.
*
* @return the save/cancel section for this CreationComponent.
*/
SaveCancelSection getSaveCancelSection();
/**
* Removes the specified process listener from the
* list of process listeners (if it had previously been added).
*
* @param listener the process listener to remove
*/
void removeProcessListener(FormProcessListener listener);
/**
* Return the ApplyWorkflowFormSection associated with this CreationComponent.
*
* @return the ApplyWorkflowFormSection associated with this CreationComponent.
*/
ApplyWorkflowFormSection getWorkflowSection();
}

View File

@ -26,7 +26,6 @@ import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SingleSelectionModel; import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.form.FormErrorDisplay; import com.arsdigita.bebop.form.FormErrorDisplay;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.bebop.parameters.LongParameter; import com.arsdigita.bebop.parameters.LongParameter;
import com.arsdigita.cms.ItemSelectionModel; import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.cms.ui.ContentItemPage; import com.arsdigita.cms.ui.ContentItemPage;
@ -45,14 +44,12 @@ import org.librecms.contentsection.ContentType;
import org.librecms.contentsection.ContentTypeManager; import org.librecms.contentsection.ContentTypeManager;
import org.librecms.contentsection.ContentTypeRepository; import org.librecms.contentsection.ContentTypeRepository;
import org.librecms.contentsection.Folder; import org.librecms.contentsection.Folder;
import org.librecms.contenttypes.AuthoringKit;
import org.librecms.contenttypes.AuthoringKitInfo; import org.librecms.contenttypes.AuthoringKitInfo;
import org.librecms.contenttypes.ContentTypeInfo; import org.librecms.contenttypes.ContentTypeInfo;
import org.librecms.contenttypes.ContentTypesManager; import org.librecms.contenttypes.ContentTypesManager;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.Optional; import java.util.Optional;
/** /**

View File

@ -22,36 +22,28 @@ import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Form; import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.Label; import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Text;
import com.arsdigita.bebop.event.PrintEvent; import com.arsdigita.bebop.event.PrintEvent;
import com.arsdigita.bebop.event.PrintListener; import com.arsdigita.bebop.event.PrintListener;
import com.arsdigita.bebop.form.Option; import com.arsdigita.bebop.form.Option;
import com.arsdigita.bebop.form.OptionGroup; import com.arsdigita.bebop.form.OptionGroup;
import com.arsdigita.bebop.form.SingleSelect; import com.arsdigita.bebop.form.SingleSelect;
import com.arsdigita.bebop.form.Submit; import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.bebop.parameters.LongParameter; import com.arsdigita.bebop.parameters.LongParameter;
import com.arsdigita.cms.ui.ItemSearch; import com.arsdigita.cms.ui.ItemSearch;
import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.util.UncheckedWrapperException; import com.arsdigita.util.UncheckedWrapperException;
import com.arsdigita.xml.Element; import com.arsdigita.xml.Element;
import java.math.BigDecimal;
import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.security.PermissionChecker; import org.libreccm.security.PermissionChecker;
import org.librecms.CmsConstants; import org.librecms.CmsConstants;
import org.librecms.contentsection.ContentSection; import org.librecms.contentsection.ContentSection;
import org.librecms.contentsection.ContentType; import org.librecms.contentsection.ContentType;
import org.librecms.contentsection.ContentTypeRepository; import org.librecms.contentsection.ContentTypeRepository;
import org.librecms.contentsection.privileges.TypePrivileges;
import java.util.List; import java.util.List;
import java.util.TooManyListenersException; import java.util.TooManyListenersException;
import java.util.stream.Collectors;
import org.libreccm.l10n.GlobalizationHelper;
import org.librecms.contentsection.ContentTypeManager;
import org.librecms.contenttypes.ContentTypeInfo; import org.librecms.contenttypes.ContentTypeInfo;
import org.librecms.contenttypes.ContentTypesManager; import org.librecms.contenttypes.ContentTypesManager;
@ -107,7 +99,7 @@ public abstract class NewItemForm extends Form {
createLabel.setIdAttr("create_label"); createLabel.setIdAttr("create_label");
panel.add(createLabel); panel.add(createLabel);
typeSelect = new SingleSelect(new BigDecimalParameter(TYPE_ID), typeSelect = new SingleSelect(new LongParameter(TYPE_ID),
OptionGroup.SortMode.ALPHABETICAL_ASCENDING); OptionGroup.SortMode.ALPHABETICAL_ASCENDING);
try { try {
typeSelect.addPrintListener(new PrintListener() { typeSelect.addPrintListener(new PrintListener() {

View File

@ -0,0 +1,222 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.authoring;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormSubmissionListener;
import org.librecms.contentsection.ContentSection;
import org.librecms.contentsection.ContentType;
import org.librecms.contentsection.Folder;
import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.KernelConfig;
import com.arsdigita.util.Assert;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.arsdigita.cms.CMSConfig;
import org.librecms.CmsConstants;
import org.librecms.contentsection.ContentItem;
import java.util.Date;
import java.util.Locale;
/**
* A form which will create a new document (that is subclasses of class
* ContentPage).
*
* Used to create a new document / content item. Creates widgets to select the
* workflow, and language. It displays the type of document as well. Super class
* adds additional widgets (title and name/URL) to complete the form.
*
* It's a pane which is part of a more complex page, additionally containing
* folder structure, content items in the folder, permissions, etc.
*
* @author Stanislav Freidin (stas@arsdigita.com)
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class PageCreate
extends BasicPageForm
implements FormSubmissionListener, CreationComponent {
private final CreationSelector creationSelector;
private final ApplyWorkflowFormSection workflowSection;
/**
* The state parameter which specifies the content section
*/
public static final String SECTION_ID = "sid";
/**
* Construct a new PageCreationForm
*
* @param itemModel The {@link ItemSelectionModel} which will be
* responsible for loading the current item
* @param creationSelector The {@link CreationSelector} parent. This class
* should call either the {@link
* CreationSelector#redirectBack(PageState)} or {@link
* CreationSelector#editItem(PageState, ContentItem)} methods on the parent
* eventually
*/
public PageCreate(final ItemSelectionModel itemModel,
final CreationSelector creationSelector) {
super("PageCreate", itemModel);
this.creationSelector = creationSelector;
/* Retrieve Content Type */
final ContentType type = getItemSelectionModel().getContentType();
/* Add workflow selection based on configured Content Type */
workflowSection = new ApplyWorkflowFormSection(type);
workflowSection.setCreationSelector(creationSelector);
addSubmissionListener(this);
getSaveCancelSection().getSaveButton()
.setButtonLabel(new GlobalizedMessage("cms.ui.create",
CmsConstants.CMS_BUNDLE));
}
/**
* Add various widgets to the form. Child classes should override this
* method to perform all their widget-adding needs.
*/
@Override
protected void addWidgets() {
add(workflowSection, ColumnPanel.INSERT);
/* content type */
add(new Label(new GlobalizedMessage("cms.ui.authoring.content_type",
CmsConstants.CMS_BUNDLE)));
/* Retrieve Content Type */
final ContentType type = getItemSelectionModel().getContentType();
add(new Label(type.getLabel().getValue(KernelConfig
.getConfig()
.getDefaultLocale())));
/* language selection */
add(new Label(new GlobalizedMessage("cms.ui.language.field",
CmsConstants.CMS_BUNDLE)));
add(new LanguageWidget(LANGUAGE));
/* Additional widgets from super type: title and name (url) */
super.addWidgets();
}
/**
* Return the ApplyWorkflowFormSection associated with this
* CreationComponent.
*
* @return the ApplyWorkflowFormSection associated with this
* CreationComponent.
*/
@Override
public ApplyWorkflowFormSection getWorkflowSection() {
return workflowSection;
}
/**
* Create a new item id.
*
* @throws com.arsdigita.bebop.FormProcessException
*/
@Override
public void init(final FormSectionEvent event) throws FormProcessException {
// this is currently a no-op
}
/**
* If the Cancel button was pressed, hide self and show the display
* component.
*
* @throws com.arsdigita.bebop.FormProcessException
*/
@Override
public void submitted(final FormSectionEvent event)
throws FormProcessException {
final PageState state = event.getPageState();
if (getSaveCancelSection().getCancelButton().isSelected(state)) {
creationSelector.redirectBack(state);
throw new FormProcessException(
new GlobalizedMessage("cms.ui.authoring.submission_cancelled",
CmsConstants.CMS_BUNDLE));
}
}
/**
* Validate inputs to ensure name uniqueness. Note: We can't call
* {@code super.validate(FormSectionEvent)} here because the super method
* {@link BasicPageForm#validate(com.arsdigita.bebop.event.FormSectionEvent)}
* tries to access things which on existing yet.
*
* @param event
*
* @throws com.arsdigita.bebop.FormProcessException
*/
@Override
public void validate(final FormSectionEvent event)
throws FormProcessException {
final Folder folder = creationSelector.getFolder(event.getPageState());
validateNameUniqueness(folder, event);
}
/**
* Class specific implementation if FormProcessListener (as inherited from
* BasicItemForm), saves fields to the database.
*
* @param event
*
* @throws FormProcessException
*/
@Override
public void process(final FormSectionEvent event)
throws FormProcessException {
final FormData data = event.getFormData();
final PageState state = event.getPageState();
final ContentSection section = creationSelector.getContentSection(state);
final Folder folder = creationSelector.getFolder(state);
Assert.exists(section, ContentSection.class);
final ContentItem item = createContentPage(state,
(String) data.get(NAME),
section,
folder);
final Locale locale = new Locale((String) data.get(LANGUAGE));
item.getName().addValue(locale, (String) data.get(NAME));
item.getTitle().addValue(locale, (String) data.get(TITLE));
workflowSection.applyWorkflow(state, item);
creationSelector.editItem(state, item);
}
}