CCM NG/ccm-cms: ItemCategoryStep migrated to CCM NG
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4752 8810af33-2d31-482b-a856-94f89814c4dfpull/2/head
parent
37bc61b2c1
commit
13faa6f4c6
|
|
@ -0,0 +1,220 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 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.form.Widget;
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.parameters.ArrayParameter;
|
||||||
|
import com.arsdigita.bebop.parameters.StringParameter;
|
||||||
|
import com.arsdigita.bebop.parameters.BigDecimalParameter;
|
||||||
|
import com.arsdigita.bebop.parameters.LongParameter;
|
||||||
|
import com.arsdigita.xml.Element;
|
||||||
|
import com.arsdigita.xml.XML;
|
||||||
|
|
||||||
|
import org.libreccm.categorization.Category;
|
||||||
|
|
||||||
|
import com.arsdigita.cms.CMS;
|
||||||
|
import com.arsdigita.kernel.KernelConfig;
|
||||||
|
|
||||||
|
import org.arsdigita.cms.CMSConfig;
|
||||||
|
import org.libreccm.categorization.CategoryRepository;
|
||||||
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
|
import org.librecms.contentsection.ContentSection;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import static javax.naming.ldap.SortControl.*;
|
||||||
|
|
||||||
|
public class CategoryWidget extends Widget {
|
||||||
|
|
||||||
|
private LongParameter rootParameter;
|
||||||
|
private StringParameter modeParameter;
|
||||||
|
|
||||||
|
public CategoryWidget(final String name,
|
||||||
|
final LongParameter rootParameter,
|
||||||
|
final StringParameter modeParameter) {
|
||||||
|
|
||||||
|
super(new ArrayParameter(new BigDecimalParameter(name)));
|
||||||
|
|
||||||
|
this.rootParameter = rootParameter;
|
||||||
|
this.modeParameter = modeParameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getType() {
|
||||||
|
return "category";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCompound() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void generateWidget(final PageState state,
|
||||||
|
final Element parent) {
|
||||||
|
|
||||||
|
Element widget = parent.newChildElement("cms:categoryWidget",
|
||||||
|
CMS.CMS_XML_NS);
|
||||||
|
exportAttributes(widget);
|
||||||
|
|
||||||
|
widget.addAttribute("mode", (String) state.getValue(modeParameter));
|
||||||
|
widget.addAttribute("name", getName());
|
||||||
|
|
||||||
|
final Set<Long> selectedCategories = new HashSet<>();
|
||||||
|
|
||||||
|
final Long[] values = (Long[]) getValue(state);
|
||||||
|
if (values != null) {
|
||||||
|
selectedCategories.addAll(Arrays.asList(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
final CategoryRepository categoryRepo = cdiUtil
|
||||||
|
.findBean(CategoryRepository.class);
|
||||||
|
final Category rootCategory = categoryRepo
|
||||||
|
.findById((Long) state.getValue(rootParameter))
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(
|
||||||
|
String.format(
|
||||||
|
"No Category with ID %d in the database. "
|
||||||
|
+ "Where did that ID come from?",
|
||||||
|
state.getValue(rootParameter))));
|
||||||
|
|
||||||
|
final List<Category> categories = rootCategory.getSubCategories();
|
||||||
|
|
||||||
|
final Map children = new HashMap();
|
||||||
|
// ToDo, I don't understand was is done here...
|
||||||
|
// while (categories.next()) {
|
||||||
|
// final Category cat = categories.getCategory();
|
||||||
|
// final BigDecimal parentID = (BigDecimal) categories
|
||||||
|
// .get("parents.id");
|
||||||
|
//
|
||||||
|
// List childList = (List) children.get(parentID);
|
||||||
|
// if (childList == null) {
|
||||||
|
// childList = new ArrayList();
|
||||||
|
// children.put(parentID, childList);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// childList.add(
|
||||||
|
// new CategorySortKeyPair(cat, (BigDecimal) categories.get(
|
||||||
|
// "parents.link.sortKey")));
|
||||||
|
// }
|
||||||
|
|
||||||
|
generateCategory(widget, null, rootCategory, null, selectedCategories,
|
||||||
|
children);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateCategory(final Element parent,
|
||||||
|
final String path,
|
||||||
|
final Category category,
|
||||||
|
final Long sortKey,
|
||||||
|
final Set selected,
|
||||||
|
final Map children) {
|
||||||
|
|
||||||
|
final Element element = new Element("cms:category",
|
||||||
|
CMS.CMS_XML_NS);
|
||||||
|
|
||||||
|
element.addAttribute("id", XML.format(category.getObjectId()));
|
||||||
|
element.addAttribute("name", category.getName());
|
||||||
|
element.addAttribute("description",
|
||||||
|
category
|
||||||
|
.getDescription()
|
||||||
|
.getValue(KernelConfig
|
||||||
|
.getConfig()
|
||||||
|
.getDefaultLocale()));
|
||||||
|
if (selected.contains(category.getObjectId())) {
|
||||||
|
element.addAttribute("isSelected", "1");
|
||||||
|
} else {
|
||||||
|
element.addAttribute("isSelected", "0");
|
||||||
|
}
|
||||||
|
if (category.isAbstractCategory()) {
|
||||||
|
element.addAttribute("isAbstract", "1");
|
||||||
|
} else {
|
||||||
|
element.addAttribute("isAbstract", "0");
|
||||||
|
}
|
||||||
|
if (category.isEnabled()) {
|
||||||
|
element.addAttribute("isEnabled", "1");
|
||||||
|
} else {
|
||||||
|
element.addAttribute("isEnabled", "0");
|
||||||
|
}
|
||||||
|
if (sortKey != null) {
|
||||||
|
element.addAttribute("sortKey", sortKey.toString());
|
||||||
|
}
|
||||||
|
// sort order attribute added to every node in order that same xsl may
|
||||||
|
// be used to transform xml fragments returned by ajax in the Aplaws
|
||||||
|
// extension
|
||||||
|
// element.addAttribute("order",
|
||||||
|
// CMSConfig.getConfig().getCategoryTreeOrder());
|
||||||
|
|
||||||
|
String fullname = path == null ? "/" : path + " > " + category.getName();
|
||||||
|
element.addAttribute("fullname", fullname);
|
||||||
|
StringBuilder nodeID = new StringBuilder(parent.getAttribute("node-id"));
|
||||||
|
if (nodeID.length() > 0) {
|
||||||
|
nodeID.append("-");
|
||||||
|
}
|
||||||
|
nodeID.append(category.getObjectId());
|
||||||
|
element.addAttribute("node-id", nodeID.toString());
|
||||||
|
parent.addContent(element);
|
||||||
|
|
||||||
|
List c = (List) children.get(category.getObjectId());
|
||||||
|
if (c != null) {
|
||||||
|
Iterator i = c.iterator();
|
||||||
|
while (i.hasNext()) {
|
||||||
|
CategorySortKeyPair pair = (CategorySortKeyPair) i.next();
|
||||||
|
Category child = pair.getCategory();
|
||||||
|
Long childSortKey = pair.getSortKey();
|
||||||
|
generateCategory(element,
|
||||||
|
fullname,
|
||||||
|
child,
|
||||||
|
childSortKey,
|
||||||
|
selected,
|
||||||
|
children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CategorySortKeyPair {
|
||||||
|
|
||||||
|
private Category category;
|
||||||
|
private Long sortKey;
|
||||||
|
|
||||||
|
public CategorySortKeyPair(final Category category,
|
||||||
|
final Long sortKey) {
|
||||||
|
this.category = category;
|
||||||
|
this.sortKey = sortKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Category getCategory() {
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getSortKey() {
|
||||||
|
return sortKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 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 org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.form.Widget;
|
||||||
|
import com.arsdigita.bebop.parameters.LongParameter;
|
||||||
|
import com.arsdigita.bebop.parameters.StringParameter;
|
||||||
|
import com.arsdigita.categorization.ui.ACSObjectCategoryForm;
|
||||||
|
import com.arsdigita.cms.CMS;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (No description available yet).
|
||||||
|
*
|
||||||
|
* Usage of this class is configured in parameter
|
||||||
|
* c.ad.cms.category_authoring_add_form
|
||||||
|
*/
|
||||||
|
public class ItemCategoryForm extends ACSObjectCategoryForm {
|
||||||
|
|
||||||
|
private static Logger LOGGER = LogManager.getLogger(ItemCategoryForm.class);
|
||||||
|
|
||||||
|
public ItemCategoryForm(final LongParameter rootParameter,
|
||||||
|
final StringParameter modeParameter,
|
||||||
|
final Widget widget) {
|
||||||
|
|
||||||
|
super(rootParameter, modeParameter, widget);
|
||||||
|
LOGGER.debug("creating new ItemTerm Form with widget " + widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemCategoryForm(final LongParameter root,
|
||||||
|
final StringParameter mode) {
|
||||||
|
|
||||||
|
this(root, mode, new CategoryWidget("category", root, mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.arsdigita.categorization.ui.ACSObjectCategoryForm#getObject()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected CcmObject getObject(final PageState state) {
|
||||||
|
return CMS.getContext().getContentItem();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,180 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 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.SimpleContainer;
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.Page;
|
||||||
|
import com.arsdigita.bebop.SimpleComponent;
|
||||||
|
import com.arsdigita.bebop.event.ActionListener;
|
||||||
|
import com.arsdigita.bebop.event.ActionEvent;
|
||||||
|
import com.arsdigita.bebop.parameters.StringParameter;
|
||||||
|
import com.arsdigita.bebop.Resettable;
|
||||||
|
import com.arsdigita.bebop.parameters.LongParameter;
|
||||||
|
import com.arsdigita.web.RedirectSignal;
|
||||||
|
|
||||||
|
|
||||||
|
import com.arsdigita.cms.CMS;
|
||||||
|
|
||||||
|
|
||||||
|
import com.arsdigita.cms.ItemSelectionModel;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ItemCategoryStep extends SimpleContainer implements Resettable{
|
||||||
|
|
||||||
|
|
||||||
|
private final LongParameter rootParameter;
|
||||||
|
private final StringParameter modeParameter;
|
||||||
|
|
||||||
|
private final ItemCategorySummary itemCategorySummary;
|
||||||
|
|
||||||
|
private final SimpleComponent addComponent;
|
||||||
|
|
||||||
|
// private SimpleComponent[] extensionSummaries;
|
||||||
|
// private SimpleComponent[] extensionForms;
|
||||||
|
// private int extensionsCount;
|
||||||
|
|
||||||
|
|
||||||
|
public ItemCategoryStep(final ItemSelectionModel itemSelectionModel,
|
||||||
|
final AuthoringKitWizard authoringKitWizard) {
|
||||||
|
|
||||||
|
super("cms:categoryStep", CMS.CMS_XML_NS);
|
||||||
|
|
||||||
|
rootParameter = new LongParameter("root");
|
||||||
|
modeParameter = new StringParameter("mode");
|
||||||
|
|
||||||
|
itemCategorySummary = new ItemCategorySummary();
|
||||||
|
itemCategorySummary.registerAction(ItemCategorySummary.ACTION_ADD,
|
||||||
|
new AddActionListener("plain"));
|
||||||
|
itemCategorySummary.registerAction(ItemCategorySummary.ACTION_ADD_JS,
|
||||||
|
new AddActionListener("javascript"));
|
||||||
|
|
||||||
|
// Class addForm = CMSConfig.getConfig().getCategoryAuthoringAddForm();
|
||||||
|
// addComponent = (SimpleComponent)
|
||||||
|
// Classes.newInstance(addForm,
|
||||||
|
// new Class[] { BigDecimalParameter.class,
|
||||||
|
// StringParameter.class },
|
||||||
|
// new Object[] { rootParameter, modeParameter });
|
||||||
|
addComponent = new ItemCategoryForm(rootParameter, modeParameter);
|
||||||
|
addComponent.addCompletionListener(new ResetListener());
|
||||||
|
|
||||||
|
// Class extensionClass = ContentSection.getConfig().getCategoryAuthoringExtension();
|
||||||
|
// ItemCategoryExtension extension = (ItemCategoryExtension)
|
||||||
|
// Classes.newInstance(extensionClass);
|
||||||
|
//
|
||||||
|
// extensionSummaries = extension.getSummary();
|
||||||
|
// extensionForms = extension.getForm();
|
||||||
|
// int nSummaries = extensionSummaries.length;
|
||||||
|
// int nForms= extensionForms.length;
|
||||||
|
// Assert.isTrue(nSummaries==nForms, "invalid CategoryStep extension");
|
||||||
|
// extensionsCount = nForms;
|
||||||
|
// for (int i=0;i<extensionsCount;i++) {
|
||||||
|
// extensionSummaries[i].addCompletionListener(new ExtensionListener(i));
|
||||||
|
// extensionForms[i].addCompletionListener(new ResetListener());
|
||||||
|
// add(extensionSummaries[i]);
|
||||||
|
// add(extensionForms[i]);
|
||||||
|
// }
|
||||||
|
add(itemCategorySummary);
|
||||||
|
add(addComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(Page p) {
|
||||||
|
super.register(p);
|
||||||
|
|
||||||
|
p.setVisibleDefault(addComponent, false);
|
||||||
|
// for (int i=0;i<extensionsCount;i++) {
|
||||||
|
// p.setVisibleDefault(extensionForms[i], false);
|
||||||
|
// }
|
||||||
|
p.addGlobalStateParam(rootParameter);
|
||||||
|
p.addGlobalStateParam(modeParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset(PageState state) {
|
||||||
|
state.setValue(rootParameter, null);
|
||||||
|
state.setValue(modeParameter, null);
|
||||||
|
|
||||||
|
itemCategorySummary.setVisible(state, true);
|
||||||
|
addComponent.setVisible(state, false);
|
||||||
|
// for (int i=0;i<extensionsCount;i++) {
|
||||||
|
// extensionSummaries[i].setVisible(state, true);
|
||||||
|
// extensionForms[i].setVisible(state, false);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AddActionListener implements ActionListener {
|
||||||
|
private String m_mode;
|
||||||
|
|
||||||
|
public AddActionListener(String mode) {
|
||||||
|
m_mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
PageState state = e.getPageState();
|
||||||
|
|
||||||
|
state.setValue(rootParameter,
|
||||||
|
new BigDecimal(state.getControlEventValue()));
|
||||||
|
|
||||||
|
state.setValue(ItemCategoryStep.this.modeParameter,
|
||||||
|
m_mode);
|
||||||
|
|
||||||
|
itemCategorySummary.setVisible(state, false);
|
||||||
|
addComponent.setVisible(state, true);
|
||||||
|
// for (int i=0;i<extensionsCount;i++) {
|
||||||
|
// extensionSummaries[i].setVisible(state, false);
|
||||||
|
// extensionForms[i].setVisible(state, false);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ResetListener implements ActionListener {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
PageState state = e.getPageState();
|
||||||
|
reset(state);
|
||||||
|
throw new RedirectSignal(state.toURL(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ExtensionListener implements ActionListener {
|
||||||
|
int extensionIndex;
|
||||||
|
public ExtensionListener(int i) {
|
||||||
|
extensionIndex = i;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
PageState state = e.getPageState();
|
||||||
|
itemCategorySummary.setVisible(state, false);
|
||||||
|
addComponent.setVisible(state, false);
|
||||||
|
// for (int i=0;i<extensionsCount;i++) {
|
||||||
|
// extensionSummaries[i].setVisible(state, false);
|
||||||
|
// }
|
||||||
|
// extensionForms[extensionIndex].setVisible(state, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 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.PageState;
|
||||||
|
|
||||||
|
import org.libreccm.categorization.Category;
|
||||||
|
|
||||||
|
import com.arsdigita.categorization.ui.ACSObjectCategorySummary;
|
||||||
|
import com.arsdigita.cms.CMS;
|
||||||
|
|
||||||
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
|
import org.libreccm.security.PermissionChecker;
|
||||||
|
import org.librecms.contentsection.ContentSection;
|
||||||
|
import org.librecms.contentsection.privileges.ItemPrivileges;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ItemCategorySummary extends ACSObjectCategorySummary {
|
||||||
|
|
||||||
|
public ItemCategorySummary() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canEdit(final PageState state) {
|
||||||
|
|
||||||
|
final PermissionChecker permissionChecker = CdiUtil
|
||||||
|
.createCdiUtil()
|
||||||
|
.findBean(PermissionChecker.class);
|
||||||
|
|
||||||
|
return permissionChecker.isPermitted(ItemPrivileges.CATEGORIZE,
|
||||||
|
CMS.getContext().getContentItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.arsdigita.categorization.ui.ObjectCategorySummary#getObject()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected CcmObject getObject(final PageState state) {
|
||||||
|
|
||||||
|
return CMS.getContext().getContentItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.arsdigita.categorization.ui.ObjectCategorySummary#getXMLPrefix()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getXMLPrefix() {
|
||||||
|
return "cms";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.arsdigita.categorization.ui.ObjectCategorySummary#getXMLNameSpace()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getXMLNameSpace() {
|
||||||
|
return CMS.CMS_XML_NS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.arsdigita.categorization.ui.ObjectCategorySummary#getRootCategories()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected List<Category> getRootCategories(final PageState state) {
|
||||||
|
|
||||||
|
final ContentSection section = CMS.getContext().getContentSection();
|
||||||
|
return section
|
||||||
|
.getDomains()
|
||||||
|
.stream()
|
||||||
|
.map(domainOwnership -> domainOwnership.getDomain())
|
||||||
|
.map(domain -> domain.getRoot())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,192 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Chris Gilbert
|
||||||
|
*
|
||||||
|
* 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.categorization.ui;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.BoxPanel;
|
||||||
|
import com.arsdigita.bebop.Form;
|
||||||
|
import com.arsdigita.bebop.FormProcessException;
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.SaveCancelSection;
|
||||||
|
import com.arsdigita.bebop.event.FormInitListener;
|
||||||
|
import com.arsdigita.bebop.event.FormProcessListener;
|
||||||
|
import com.arsdigita.bebop.event.FormSectionEvent;
|
||||||
|
import com.arsdigita.bebop.event.FormSubmissionListener;
|
||||||
|
import com.arsdigita.bebop.form.Widget;
|
||||||
|
import com.arsdigita.bebop.parameters.LongParameter;
|
||||||
|
import com.arsdigita.bebop.parameters.NotNullValidationListener;
|
||||||
|
import com.arsdigita.bebop.parameters.StringParameter;
|
||||||
|
import com.arsdigita.bebop.util.GlobalizationUtil;
|
||||||
|
|
||||||
|
import org.libreccm.categorization.Category;
|
||||||
|
import org.libreccm.categorization.CategoryManager;
|
||||||
|
import org.libreccm.categorization.CategoryRepository;
|
||||||
|
import org.libreccm.categorization.ObjectNotAssignedToCategoryException;
|
||||||
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
|
import org.libreccm.core.UnexpectedErrorException;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract form for assigning categories to acs_objects. The assigned
|
||||||
|
* categories are those specified by the category widget, which is retrieved by
|
||||||
|
* the concrete subclass' implementation of getCategoryWidget.
|
||||||
|
*
|
||||||
|
* The category widget may be an implementation of CategoryWidget, which
|
||||||
|
* generates a javascript tree of categories. Implementations need only specify
|
||||||
|
* an XML prefix and namespace.
|
||||||
|
*
|
||||||
|
* The object that is to be assigned to the categories is specified by the
|
||||||
|
* concrete subclass' implentation of getObject
|
||||||
|
*
|
||||||
|
* @author chris.gilbert@westsussex.gov.uk
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
// this class has been abstracted out from the original cms specific
|
||||||
|
// category form in ccm-cms
|
||||||
|
public abstract class ACSObjectCategoryForm extends Form {
|
||||||
|
|
||||||
|
private final Widget categoryWidget;
|
||||||
|
private final SaveCancelSection saveCancelSection;
|
||||||
|
|
||||||
|
protected abstract CcmObject getObject(PageState state);
|
||||||
|
|
||||||
|
public ACSObjectCategoryForm(final LongParameter root,
|
||||||
|
final StringParameter mode,
|
||||||
|
final Widget categoryWidget) {
|
||||||
|
super("category", new BoxPanel(BoxPanel.VERTICAL));
|
||||||
|
|
||||||
|
this.categoryWidget = categoryWidget;
|
||||||
|
categoryWidget.addValidationListener(new NotNullValidationListener());
|
||||||
|
saveCancelSection = new SaveCancelSection();
|
||||||
|
|
||||||
|
add(categoryWidget);
|
||||||
|
add(saveCancelSection);
|
||||||
|
|
||||||
|
addInitListener(new FormInitListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(final FormSectionEvent event)
|
||||||
|
throws FormProcessException {
|
||||||
|
|
||||||
|
final PageState state = event.getPageState();
|
||||||
|
final CcmObject object = getObject(state);
|
||||||
|
|
||||||
|
final List<Long> selectedCats = new ArrayList<>();
|
||||||
|
final Set<Long> ancestorCats = new HashSet<>();
|
||||||
|
final List<Category> categories = object
|
||||||
|
.getCategories()
|
||||||
|
.stream()
|
||||||
|
.map(categorization -> categorization.getCategory())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
for (final Category category : categories) {
|
||||||
|
selectedCats.add(category.getObjectId());
|
||||||
|
addAncestorCats(ancestorCats, category);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Long[][] paramArray = new Long[2][];
|
||||||
|
paramArray[0] = selectedCats
|
||||||
|
.toArray(new Long[selectedCats.size()]);
|
||||||
|
paramArray[1] = ancestorCats
|
||||||
|
.toArray(new Long[ancestorCats.size()]);
|
||||||
|
|
||||||
|
categoryWidget.setValue(state, paramArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
addProcessListener(new FormProcessListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(final FormSectionEvent event)
|
||||||
|
throws FormProcessException {
|
||||||
|
|
||||||
|
final PageState state = event.getPageState();
|
||||||
|
|
||||||
|
final CcmObject object = getObject(state);
|
||||||
|
|
||||||
|
final Set<Long> curSelectedCat = object
|
||||||
|
.getCategories()
|
||||||
|
.stream()
|
||||||
|
.map(categorization -> categorization.getCategory())
|
||||||
|
.map(category -> category.getObjectId())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
final CategoryRepository categoryRepo = cdiUtil
|
||||||
|
.findBean(CategoryRepository.class);
|
||||||
|
final CategoryManager categoryManager = cdiUtil
|
||||||
|
.findBean(CategoryManager.class);
|
||||||
|
final Long[] ids = (Long[]) categoryWidget.getValue(state);
|
||||||
|
for (final Long id : ids) {
|
||||||
|
final Category cat = categoryRepo
|
||||||
|
.findById(id)
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(
|
||||||
|
String.format("No Category with ID %d in the database. "
|
||||||
|
+ "Where did that ID come from?",
|
||||||
|
id)));
|
||||||
|
if (!curSelectedCat.contains(id)) {
|
||||||
|
categoryManager.addObjectToCategory(object, cat);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
categoryManager
|
||||||
|
.removeObjectFromCategory(object, cat);
|
||||||
|
} catch (ObjectNotAssignedToCategoryException ex) {
|
||||||
|
throw new UnexpectedErrorException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fireCompletionEvent(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
addSubmissionListener(new FormSubmissionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void submitted(final FormSectionEvent event)
|
||||||
|
throws FormProcessException {
|
||||||
|
|
||||||
|
final PageState state = event.getPageState();
|
||||||
|
|
||||||
|
if (saveCancelSection.getCancelButton().isSelected(state)) {
|
||||||
|
fireCompletionEvent(state);
|
||||||
|
throw new FormProcessException("Submission cancelled",
|
||||||
|
GlobalizationUtil.globalize(
|
||||||
|
"categorization.cancel.msg"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addAncestorCats(final Set<Long> ancestorCats,
|
||||||
|
final Category category) {
|
||||||
|
|
||||||
|
ancestorCats.add(category.getParentCategory().getObjectId());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,276 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007 Chris Gilbert
|
||||||
|
*
|
||||||
|
* 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.categorization.ui;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.SimpleComponent;
|
||||||
|
import com.arsdigita.bebop.event.ActionEvent;
|
||||||
|
import com.arsdigita.bebop.event.ActionListener;
|
||||||
|
import com.arsdigita.kernel.KernelConfig;
|
||||||
|
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
|
import org.libreccm.categorization.Category;
|
||||||
|
|
||||||
|
import com.arsdigita.util.Assert;
|
||||||
|
import com.arsdigita.web.RedirectSignal;
|
||||||
|
import com.arsdigita.xml.Element;
|
||||||
|
import com.arsdigita.xml.XML;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.libreccm.categorization.CategoryManager;
|
||||||
|
import org.libreccm.categorization.CategoryRepository;
|
||||||
|
import org.libreccm.categorization.ObjectNotAssignedToCategoryException;
|
||||||
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
|
import org.libreccm.core.UnexpectedErrorException;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* abstract class for displaying the categories assigned to an object under one
|
||||||
|
* or more root nodes. Subclasses should retrieve the object to be assigned and
|
||||||
|
* supply the logic to retrieve root categories.
|
||||||
|
*
|
||||||
|
* * abstracted from ItemCategorySummary in ccm-cms
|
||||||
|
*
|
||||||
|
* @author chris.gilbert@westsussex.gov.uk
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class ACSObjectCategorySummary extends SimpleComponent {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager
|
||||||
|
.getLogger(ACSObjectCategorySummary.class);
|
||||||
|
|
||||||
|
public static final String ACTION_DELETE = "delete";
|
||||||
|
public static final String ACTION_ADD = "add";
|
||||||
|
public static final String ACTION_ADD_JS = "addJS";
|
||||||
|
|
||||||
|
private final Map<String, ActionListener> listenersLap = new HashMap<>();
|
||||||
|
|
||||||
|
public ACSObjectCategorySummary() {
|
||||||
|
registerAction(ACTION_DELETE,
|
||||||
|
new DeleteActionListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerAction(final String name,
|
||||||
|
final ActionListener listener) {
|
||||||
|
listenersLap.put(name, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void respond(final PageState state) throws ServletException {
|
||||||
|
|
||||||
|
super.respond(state);
|
||||||
|
|
||||||
|
Assert.isTrue(canEdit(state), "User can edit object");
|
||||||
|
|
||||||
|
final String name = state.getControlEventName();
|
||||||
|
final ActionListener listener = listenersLap.get(name);
|
||||||
|
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("Got event {} listener {}",
|
||||||
|
name,
|
||||||
|
listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listener != null) {
|
||||||
|
listener.actionPerformed(new ActionEvent(this, state));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default behaviour is to check for edit access on the current resource. as
|
||||||
|
* defined by getCategorizedObject. This can be overridden by subclasses, if
|
||||||
|
* for instance a specific privilege should be checked
|
||||||
|
*
|
||||||
|
* @param state
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected abstract boolean canEdit(final PageState state);
|
||||||
|
|
||||||
|
protected abstract CcmObject getObject(PageState state);
|
||||||
|
|
||||||
|
protected abstract String getXMLPrefix();
|
||||||
|
|
||||||
|
protected abstract String getXMLNameSpace();
|
||||||
|
|
||||||
|
protected abstract List<Category> getRootCategories(PageState state);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateXML(final PageState state, final Element parent) {
|
||||||
|
|
||||||
|
final boolean canEdit = canEdit(state);
|
||||||
|
|
||||||
|
final Element content = parent
|
||||||
|
.newChildElement(String.format("%s:categoryStepSummary",
|
||||||
|
getXMLPrefix()),
|
||||||
|
getXMLNameSpace());
|
||||||
|
exportAttributes(content);
|
||||||
|
|
||||||
|
final Element rootCats = content
|
||||||
|
.newChildElement(String.format("%s:categoryRoots",
|
||||||
|
getXMLPrefix()),
|
||||||
|
getXMLNameSpace());
|
||||||
|
|
||||||
|
final List<Category> roots = getRootCategories(state);
|
||||||
|
for (final Category rootCategory : roots) {
|
||||||
|
|
||||||
|
final Element root = rootCats
|
||||||
|
.newChildElement(String.format("%s:categoryRoot",
|
||||||
|
getXMLPrefix()),
|
||||||
|
getXMLNameSpace());
|
||||||
|
root.addAttribute("name", rootCategory.getName());
|
||||||
|
root.addAttribute("description",
|
||||||
|
rootCategory
|
||||||
|
.getDescription()
|
||||||
|
.getValue(KernelConfig
|
||||||
|
.getConfig()
|
||||||
|
.getDefaultLocale()));
|
||||||
|
|
||||||
|
if (canEdit) {
|
||||||
|
state.setControlEvent(this,
|
||||||
|
ACTION_ADD,
|
||||||
|
Long.toString(rootCategory.getObjectId()));
|
||||||
|
try {
|
||||||
|
root.addAttribute("addAction",
|
||||||
|
XML.format(state.stateAsURL()));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new UnexpectedErrorException("cannot generate URL",
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
state.clearControlEvent();
|
||||||
|
state.setControlEvent(this,
|
||||||
|
ACTION_ADD_JS,
|
||||||
|
Long.toString(rootCategory.getObjectId()));
|
||||||
|
try {
|
||||||
|
root.addAttribute("addJsAction",
|
||||||
|
XML.format(state.stateAsURL()));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new UnexpectedErrorException("cannot generate URL",
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
state.clearControlEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final Element itemCats = content
|
||||||
|
.newChildElement(String.format("%s:itemCategories",
|
||||||
|
getXMLPrefix()),
|
||||||
|
getXMLNameSpace());
|
||||||
|
|
||||||
|
final List<Category> categories = getObject(state)
|
||||||
|
.getCategories()
|
||||||
|
.stream()
|
||||||
|
.map(categorization -> categorization.getCategory())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
final CategoryManager categoryManager = CdiUtil
|
||||||
|
.createCdiUtil()
|
||||||
|
.findBean(CategoryManager.class);
|
||||||
|
|
||||||
|
for (final Category category : categories) {
|
||||||
|
|
||||||
|
final String path = categoryManager.getCategoryPath(category);
|
||||||
|
|
||||||
|
final Element categoryElem = itemCats
|
||||||
|
.newChildElement(String.format("%s:itemCategory",
|
||||||
|
getXMLPrefix()),
|
||||||
|
getXMLNameSpace());
|
||||||
|
categoryElem.addAttribute("name", category.getName());
|
||||||
|
categoryElem.addAttribute("description",
|
||||||
|
category
|
||||||
|
.getDescription()
|
||||||
|
.getValue(KernelConfig
|
||||||
|
.getConfig()
|
||||||
|
.getDefaultLocale()));
|
||||||
|
categoryElem.addAttribute("path", XML.format(path));
|
||||||
|
|
||||||
|
if (canEdit) {
|
||||||
|
state.setControlEvent(this,
|
||||||
|
ACTION_DELETE,
|
||||||
|
Long.toString(category.getObjectId()));
|
||||||
|
try {
|
||||||
|
categoryElem.addAttribute("deleteAction",
|
||||||
|
XML.format(state.stateAsURL()));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new UnexpectedErrorException("cannot generate URL",
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
state.clearControlEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DeleteActionListener implements ActionListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(final ActionEvent event) {
|
||||||
|
|
||||||
|
final PageState state = event.getPageState();
|
||||||
|
final String value = state.getControlEventValue();
|
||||||
|
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
final CategoryRepository categoryRepo = cdiUtil
|
||||||
|
.findBean(CategoryRepository.class);
|
||||||
|
final Category category = categoryRepo
|
||||||
|
.findById(Long.parseLong(value))
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(
|
||||||
|
String.format(
|
||||||
|
"No Category with ID %s in the database. "
|
||||||
|
+ "Where did that ID come from?",
|
||||||
|
value)));
|
||||||
|
|
||||||
|
final CcmObject object = getObject(state);
|
||||||
|
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("Removing category {} from {}",
|
||||||
|
Objects.toString(category),
|
||||||
|
Objects.toString(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
final CategoryManager categoryManager = cdiUtil
|
||||||
|
.findBean(CategoryManager.class);
|
||||||
|
try {
|
||||||
|
categoryManager.removeObjectFromCategory(object, category);
|
||||||
|
} catch(ObjectNotAssignedToCategoryException ex) {
|
||||||
|
throw new UnexpectedErrorException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.clearControlEvent();
|
||||||
|
throw new RedirectSignal(state.toURL(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue