CCM NG: Next part of migration of ItemCategoryStep
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4997 8810af33-2d31-482b-a856-94f89814c4df
Former-commit-id: e587cf4782
pull/2/head
parent
a7aff82120
commit
15e10db65b
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.arsdigita.cms.ui.authoring;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.SimpleComponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NOOP base implementation of category authoring step extension.
|
||||||
|
* Summary component returned by #getSummary() is show on category summary page,
|
||||||
|
* usually an ActionLink which activates the Form component returned by #getForm().
|
||||||
|
*
|
||||||
|
* @author Alan Pevec
|
||||||
|
*/public class ItemCategoryExtension {
|
||||||
|
|
||||||
|
public SimpleComponent[] getSummary() {
|
||||||
|
return new SimpleComponent[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleComponent[] getForm() {
|
||||||
|
return new SimpleComponent[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -29,26 +29,25 @@ import com.arsdigita.bebop.Resettable;
|
||||||
import com.arsdigita.bebop.parameters.LongParameter;
|
import com.arsdigita.bebop.parameters.LongParameter;
|
||||||
import com.arsdigita.web.RedirectSignal;
|
import com.arsdigita.web.RedirectSignal;
|
||||||
|
|
||||||
|
|
||||||
import com.arsdigita.cms.CMS;
|
import com.arsdigita.cms.CMS;
|
||||||
|
|
||||||
|
|
||||||
import com.arsdigita.cms.ItemSelectionModel;
|
import com.arsdigita.cms.ItemSelectionModel;
|
||||||
|
import com.arsdigita.util.Classes;
|
||||||
|
|
||||||
|
import org.arsdigita.cms.CMSConfig;
|
||||||
|
import org.libreccm.core.UnexpectedErrorException;
|
||||||
import org.librecms.CmsConstants;
|
import org.librecms.CmsConstants;
|
||||||
import org.librecms.ui.authoring.ContentItemAuthoringStep;
|
import org.librecms.ui.authoring.ContentItemAuthoringStep;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
|
||||||
@ContentItemAuthoringStep(
|
@ContentItemAuthoringStep(
|
||||||
labelBundle = CmsConstants.CMS_BUNDLE,
|
labelBundle = CmsConstants.CMS_BUNDLE,
|
||||||
labelKey = "item_category_step.label",
|
labelKey = "item_category_step.label",
|
||||||
descriptionBundle = CmsConstants.CMS_BUNDLE,
|
descriptionBundle = CmsConstants.CMS_BUNDLE,
|
||||||
descriptionKey = "item_category_step.description"
|
descriptionKey = "item_category_step.description"
|
||||||
)
|
)
|
||||||
public class ItemCategoryStep extends SimpleContainer implements Resettable{
|
public class ItemCategoryStep extends SimpleContainer implements Resettable {
|
||||||
|
|
||||||
|
|
||||||
private final LongParameter rootParameter;
|
private final LongParameter rootParameter;
|
||||||
private final StringParameter modeParameter;
|
private final StringParameter modeParameter;
|
||||||
|
|
@ -57,10 +56,9 @@ public class ItemCategoryStep extends SimpleContainer implements Resettable{
|
||||||
|
|
||||||
private final SimpleComponent addComponent;
|
private final SimpleComponent addComponent;
|
||||||
|
|
||||||
// private SimpleComponent[] extensionSummaries;
|
private final SimpleComponent[] extensionSummaries;
|
||||||
// private SimpleComponent[] extensionForms;
|
private final SimpleComponent[] extensionForms;
|
||||||
// private int extensionsCount;
|
private int extensionsCount;
|
||||||
|
|
||||||
|
|
||||||
public ItemCategoryStep(final ItemSelectionModel itemSelectionModel,
|
public ItemCategoryStep(final ItemSelectionModel itemSelectionModel,
|
||||||
final AuthoringKitWizard authoringKitWizard,
|
final AuthoringKitWizard authoringKitWizard,
|
||||||
|
|
@ -77,37 +75,57 @@ public class ItemCategoryStep extends SimpleContainer implements Resettable{
|
||||||
itemCategorySummary.registerAction(ItemCategorySummary.ACTION_ADD_JS,
|
itemCategorySummary.registerAction(ItemCategorySummary.ACTION_ADD_JS,
|
||||||
new AddActionListener("javascript"));
|
new AddActionListener("javascript"));
|
||||||
|
|
||||||
// Class addForm = CMSConfig.getConfig().getCategoryAuthoringAddForm();
|
final String addFormClassName = CMSConfig
|
||||||
// addComponent = (SimpleComponent)
|
.getConfig()
|
||||||
// Classes.newInstance(addForm,
|
.getCategoryAuthoringAddForm();
|
||||||
// new Class[] { BigDecimalParameter.class,
|
final Class<?> addFormClass;
|
||||||
// StringParameter.class },
|
try {
|
||||||
// new Object[] { rootParameter, modeParameter });
|
addFormClass = Class.forName(addFormClassName);
|
||||||
addComponent = new ItemCategoryForm(rootParameter, modeParameter);
|
} catch (ClassNotFoundException ex) {
|
||||||
|
throw new UnexpectedErrorException(ex);
|
||||||
|
}
|
||||||
|
addComponent = (SimpleComponent) Classes
|
||||||
|
.newInstance(addFormClass,
|
||||||
|
new Class<?>[]{LongParameter.class,
|
||||||
|
StringParameter.class},
|
||||||
|
new Object[]{rootParameter, modeParameter});
|
||||||
addComponent.addCompletionListener(new ResetListener());
|
addComponent.addCompletionListener(new ResetListener());
|
||||||
|
|
||||||
// Class extensionClass = ContentSection.getConfig().getCategoryAuthoringExtension();
|
final String extensionClassName = CMSConfig
|
||||||
// ItemCategoryExtension extension = (ItemCategoryExtension)
|
.getConfig()
|
||||||
// Classes.newInstance(extensionClass);
|
.getCategoryAuthoringExtension();
|
||||||
//
|
final Class<?> extensionClass;
|
||||||
// extensionSummaries = extension.getSummary();
|
try {
|
||||||
// extensionForms = extension.getForm();
|
extensionClass = Class.forName(extensionClassName);
|
||||||
// int nSummaries = extensionSummaries.length;
|
} catch (ClassNotFoundException ex) {
|
||||||
// int nForms= extensionForms.length;
|
throw new UnexpectedErrorException(ex);
|
||||||
// Assert.isTrue(nSummaries==nForms, "invalid CategoryStep extension");
|
}
|
||||||
// extensionsCount = nForms;
|
final ItemCategoryExtension extension = (ItemCategoryExtension) Classes
|
||||||
// for (int i=0;i<extensionsCount;i++) {
|
.newInstance(extensionClass);
|
||||||
// extensionSummaries[i].addCompletionListener(new ExtensionListener(i));
|
|
||||||
// extensionForms[i].addCompletionListener(new ResetListener());
|
extensionSummaries = extension.getSummary();
|
||||||
// add(extensionSummaries[i]);
|
extensionForms = extension.getForm();
|
||||||
// add(extensionForms[i]);
|
int nSummaries = extensionSummaries.length;
|
||||||
// }
|
int nForms = extensionForms.length;
|
||||||
add(itemCategorySummary);
|
if (nSummaries != nForms) {
|
||||||
add(addComponent);
|
throw new UnexpectedErrorException(
|
||||||
|
"Invalid category step extension.");
|
||||||
|
}
|
||||||
|
extensionsCount = nForms;
|
||||||
|
for (int i = 0; i < extensionsCount; i++) {
|
||||||
|
extensionSummaries[i]
|
||||||
|
.addCompletionListener(new ExtensionListener(i));
|
||||||
|
extensionForms[i].addCompletionListener(new ResetListener());
|
||||||
|
super.add(extensionSummaries[i]);
|
||||||
|
super.add(extensionForms[i]);
|
||||||
|
}
|
||||||
|
super.add(itemCategorySummary);
|
||||||
|
super.add(addComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void register(Page p) {
|
public void register(Page p
|
||||||
|
) {
|
||||||
super.register(p);
|
super.register(p);
|
||||||
|
|
||||||
p.setVisibleDefault(addComponent, false);
|
p.setVisibleDefault(addComponent, false);
|
||||||
|
|
@ -119,7 +137,8 @@ public class ItemCategoryStep extends SimpleContainer implements Resettable{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset(PageState state) {
|
public void reset(PageState state
|
||||||
|
) {
|
||||||
state.setValue(rootParameter, null);
|
state.setValue(rootParameter, null);
|
||||||
state.setValue(modeParameter, null);
|
state.setValue(modeParameter, null);
|
||||||
|
|
||||||
|
|
@ -132,6 +151,7 @@ public class ItemCategoryStep extends SimpleContainer implements Resettable{
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AddActionListener implements ActionListener {
|
private class AddActionListener implements ActionListener {
|
||||||
|
|
||||||
private String m_mode;
|
private String m_mode;
|
||||||
|
|
||||||
public AddActionListener(String mode) {
|
public AddActionListener(String mode) {
|
||||||
|
|
@ -155,22 +175,28 @@ public class ItemCategoryStep extends SimpleContainer implements Resettable{
|
||||||
// extensionForms[i].setVisible(state, false);
|
// extensionForms[i].setVisible(state, false);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ResetListener implements ActionListener {
|
private class ResetListener implements ActionListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
PageState state = e.getPageState();
|
PageState state = e.getPageState();
|
||||||
reset(state);
|
reset(state);
|
||||||
throw new RedirectSignal(state.toURL(), true);
|
throw new RedirectSignal(state.toURL(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ExtensionListener implements ActionListener {
|
private class ExtensionListener implements ActionListener {
|
||||||
|
|
||||||
int extensionIndex;
|
int extensionIndex;
|
||||||
|
|
||||||
public ExtensionListener(int i) {
|
public ExtensionListener(int i) {
|
||||||
extensionIndex = i;
|
extensionIndex = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
PageState state = e.getPageState();
|
PageState state = e.getPageState();
|
||||||
|
|
@ -181,6 +207,7 @@ public class ItemCategoryStep extends SimpleContainer implements Resettable{
|
||||||
// }
|
// }
|
||||||
// extensionForms[extensionIndex].setVisible(state, true);
|
// extensionForms[extensionIndex].setVisible(state, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,198 @@
|
||||||
|
/*
|
||||||
|
* 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.london.terms.ui;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.SimpleContainer;
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.parameters.StringParameter;
|
||||||
|
import com.arsdigita.bebop.event.ActionEvent;
|
||||||
|
import com.arsdigita.bebop.event.ActionListener;
|
||||||
|
import com.arsdigita.bebop.parameters.LongParameter;
|
||||||
|
import com.arsdigita.categorization.ui.ACSObjectCategoryForm;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.libreccm.categorization.Domain;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.libreccm.categorization.DomainRepository;
|
||||||
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* abstracted from original version of c.ad.aplaws.ui.ItemCategoryPicker r1297
|
||||||
|
*
|
||||||
|
* @author Chris Gilbert
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
// NON JavaDoc:
|
||||||
|
// copied from c.ad.aplaws.ui (module ccm-ldn-aplaws) in order to avoid a
|
||||||
|
// dependency from the integration layer for forum-categorised. Otherwise you
|
||||||
|
// have had to specify the specific integration layer (i.e. ccm-???-aplaws) in
|
||||||
|
// application.xml for compiling, which may be different for each installation.
|
||||||
|
public abstract class ACSObjectCategoryPicker extends SimpleContainer {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager
|
||||||
|
.getLogger(ACSObjectCategoryPicker.class);
|
||||||
|
|
||||||
|
private final ACSObjectCategoryForm form;
|
||||||
|
private final LongParameter rootParam;
|
||||||
|
|
||||||
|
public ACSObjectCategoryPicker(final LongParameter rootParam,
|
||||||
|
final StringParameter mode) {
|
||||||
|
|
||||||
|
form = getForm(rootParam, mode);
|
||||||
|
this.rootParam = rootParam;
|
||||||
|
|
||||||
|
super.add(form);
|
||||||
|
form.addCompletionListener(new ItemCategoryFormCompletion());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract ACSObjectCategoryForm getForm(LongParameter root,
|
||||||
|
StringParameter mode);
|
||||||
|
|
||||||
|
protected abstract CcmObject getObject(PageState state);
|
||||||
|
|
||||||
|
// protected List<Long> getCurrentCategories(final Domain domain,
|
||||||
|
// final CcmObject object) {
|
||||||
|
//
|
||||||
|
// LOGGER.debug("Getting terms from {} to {}", domain, object);
|
||||||
|
// final List<Category> terms = domain.getRoot().getSubCategories();
|
||||||
|
// terms.addEqualsFilter("model.childObjects.id", object.getID());
|
||||||
|
// terms.addPath("model.id");
|
||||||
|
//
|
||||||
|
// List<Long> current = new ArrayList<>();
|
||||||
|
// while (terms.next()) {
|
||||||
|
// if (LOGGER.isDebugEnabled()) {
|
||||||
|
// LOGGER.debug("Got term " + terms.get("model.id"));
|
||||||
|
// }
|
||||||
|
// current.add(terms.get("model.id"));
|
||||||
|
// }
|
||||||
|
// return current;
|
||||||
|
// }
|
||||||
|
// TODO move out of UI code
|
||||||
|
// public static Collection getCurrentTerms(Domain domain, ACSObject object) {
|
||||||
|
// if (LOGGER.isDebugEnabled()) {
|
||||||
|
// LOGGER.debug("Getting terms from " + domain + " to " + object);
|
||||||
|
// }
|
||||||
|
// Collection current = new LinkedList();
|
||||||
|
// DomainCollection terms = domain.getTerms();
|
||||||
|
// terms.addEqualsFilter("model.childObjects.id", object.getID());
|
||||||
|
// terms.addPath("model.id");
|
||||||
|
// while (terms.next()) {
|
||||||
|
// if (LOGGER.isDebugEnabled()) {
|
||||||
|
// LOGGER.debug("Got term " + terms.get("model.id"));
|
||||||
|
// }
|
||||||
|
// current.add(terms.getDomainObject());
|
||||||
|
// }
|
||||||
|
// return current;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // TODO move out of UI code
|
||||||
|
// public static Collection getRelatedTerms(Collection src, Domain domain) {
|
||||||
|
// if (LOGGER.isDebugEnabled()) {
|
||||||
|
// LOGGER.debug("Getting related terms to " + domain);
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// if (src.isEmpty()) {
|
||||||
|
// // this is a hack, it would be better not to use a completion event listener as
|
||||||
|
// // this is called even when the form is cancelled...
|
||||||
|
// return new LinkedList();
|
||||||
|
// }
|
||||||
|
// DomainCollection terms = domain.getTerms();
|
||||||
|
// // these next two lines build the query
|
||||||
|
// terms.addEqualsFilter("model.parents.link.relationType", "related");
|
||||||
|
// terms.addFilter("model.parents.id in :ids").set("ids", src);
|
||||||
|
//
|
||||||
|
// Collection related = new LinkedList();
|
||||||
|
// while (terms.next()) {
|
||||||
|
// if (LOGGER.isDebugEnabled()) {
|
||||||
|
// LOGGER.debug("Got term " + terms.getDomainObject());
|
||||||
|
// }
|
||||||
|
// related.add(terms.getDomainObject());
|
||||||
|
// }
|
||||||
|
// return related;
|
||||||
|
// }
|
||||||
|
// protected void clearTerms(Domain domain, ACSObject object) {
|
||||||
|
// if (LOGGER.isDebugEnabled()) {
|
||||||
|
// LOGGER.debug("Removing terms from " + domain + " to " + object);
|
||||||
|
// }
|
||||||
|
// Iterator terms = getCurrentTerms(domain, object).iterator();
|
||||||
|
// while (terms.hasNext()) {
|
||||||
|
// Term term = (Term) terms.next();
|
||||||
|
// if (LOGGER.isDebugEnabled()) {
|
||||||
|
// LOGGER.debug("Removing term " + term + " from " + object);
|
||||||
|
// }
|
||||||
|
// term.removeObject(object);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // TODO move out of UI code
|
||||||
|
// public static void assignTerms(Collection terms, ACSObject object) {
|
||||||
|
// if (LOGGER.isDebugEnabled()) {
|
||||||
|
// LOGGER.debug("Assigning terms to " + object);
|
||||||
|
// }
|
||||||
|
// Iterator i = terms.iterator();
|
||||||
|
// while (i.hasNext()) {
|
||||||
|
// Term term = (Term) i.next();
|
||||||
|
// if (LOGGER.isDebugEnabled()) {
|
||||||
|
// LOGGER.debug("Assigning term " + term + " to " + object);
|
||||||
|
// }
|
||||||
|
// term.addObject(object);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
protected Domain getDomain(final PageState state) {
|
||||||
|
LOGGER.debug("Getting domain for {}", state.getValue(rootParam));
|
||||||
|
|
||||||
|
final Long domainId = (Long) state.getValue(rootParam);
|
||||||
|
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
final DomainRepository domainRepo = cdiUtil
|
||||||
|
.findBean(DomainRepository.class);
|
||||||
|
|
||||||
|
final Optional<Domain> domain = domainRepo
|
||||||
|
.findById(domainId);
|
||||||
|
|
||||||
|
if (domain.isPresent()) {
|
||||||
|
return domain.get();
|
||||||
|
} else {
|
||||||
|
LOGGER.warn("No Domain for ID {} found.", domainId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private class ItemCategoryFormCompletion implements ActionListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(final ActionEvent event) {
|
||||||
|
|
||||||
|
final PageState state = event.getPageState();
|
||||||
|
final Domain domain = getDomain(state);
|
||||||
|
final String domainKey = domain.getDomainKey();
|
||||||
|
|
||||||
|
LOGGER.debug("Saving categories in: {}", domainKey);
|
||||||
|
|
||||||
|
fireCompletionEvent(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,217 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package com.arsdigita.london.terms.ui;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.libreccm.categorization.Categorization;
|
||||||
|
import org.libreccm.categorization.CategorizationConstants;
|
||||||
|
import org.libreccm.categorization.CategorizationMarshaller;
|
||||||
|
import org.libreccm.categorization.Category;
|
||||||
|
import org.libreccm.categorization.CategoryManager;
|
||||||
|
import org.libreccm.categorization.CategoryRepository;
|
||||||
|
import org.libreccm.categorization.Domain;
|
||||||
|
import org.libreccm.categorization.DomainManager;
|
||||||
|
import org.libreccm.categorization.DomainRepository;
|
||||||
|
import org.libreccm.categorization.ObjectNotAssignedToCategoryException;
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
|
import org.libreccm.core.CcmObjectRepository;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
class CategoryPickerController {
|
||||||
|
|
||||||
|
private final static Logger LOGGER = LogManager
|
||||||
|
.getLogger(CategoryPickerController.class);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private CategoryManager categoryManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private CategoryRepository categoryRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private CcmObjectRepository ccmObjectRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private DomainRepository domainRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private DomainManager domainManager;
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
protected List<Category> getCurrentCategories(final Domain domain,
|
||||||
|
final CcmObject object) {
|
||||||
|
|
||||||
|
Objects.requireNonNull(domain);
|
||||||
|
Objects.requireNonNull(object);
|
||||||
|
|
||||||
|
final Domain catDomain = domainRepo
|
||||||
|
.findById(domain.getObjectId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No Domain with ID %d in the database.",
|
||||||
|
domain.getObjectId())));
|
||||||
|
|
||||||
|
final CcmObject ccmObject = ccmObjectRepo
|
||||||
|
.findById(object.getObjectId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No CcmObject with ID %d in the database.",
|
||||||
|
object.getObjectId())));
|
||||||
|
|
||||||
|
final Category root = catDomain.getRoot();
|
||||||
|
return collectAssignedCategories(ccmObject, root);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Category> collectAssignedCategories(final CcmObject object,
|
||||||
|
final Category root) {
|
||||||
|
|
||||||
|
final List<Category> categories = new ArrayList<>();
|
||||||
|
if (categoryManager.isAssignedToCategory(root, object)) {
|
||||||
|
categories.add(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!root.getSubCategories().isEmpty()) {
|
||||||
|
for (final Category subCategory : root.getSubCategories()) {
|
||||||
|
categories.addAll(collectAssignedCategories(object,
|
||||||
|
subCategory));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
protected void clearCategories(final Domain domain, final CcmObject object) {
|
||||||
|
|
||||||
|
Objects.requireNonNull(domain);
|
||||||
|
Objects.requireNonNull(object);
|
||||||
|
|
||||||
|
final Domain catDomain = domainRepo
|
||||||
|
.findById(domain.getObjectId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No Domain with ID %d in the database.",
|
||||||
|
domain.getObjectId())));
|
||||||
|
|
||||||
|
final CcmObject ccmObject = ccmObjectRepo
|
||||||
|
.findById(object.getObjectId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No CcmObject with ID %d in the database.",
|
||||||
|
object.getObjectId())));
|
||||||
|
|
||||||
|
final Category root = catDomain.getRoot();
|
||||||
|
final List<Category> assignedCategories = collectAssignedCategories(
|
||||||
|
ccmObject, root);
|
||||||
|
|
||||||
|
for (final Category category : assignedCategories) {
|
||||||
|
try {
|
||||||
|
categoryManager.removeObjectFromCategory(ccmObject, category);
|
||||||
|
} catch (ObjectNotAssignedToCategoryException ex) {
|
||||||
|
LOGGER.warn("Tried to remove category {} from object {} but "
|
||||||
|
+ "the object was not assigned to that category.",
|
||||||
|
Objects.toString(category),
|
||||||
|
Objects.toString(ccmObject));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
protected void assignCategories(final List<Category> categories,
|
||||||
|
final CcmObject object) {
|
||||||
|
|
||||||
|
Objects.requireNonNull(categories);
|
||||||
|
Objects.requireNonNull(object);
|
||||||
|
|
||||||
|
final CcmObject ccmObject = ccmObjectRepo
|
||||||
|
.findById(object.getObjectId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No CcmObject with ID %d in the database.",
|
||||||
|
object.getObjectId())));
|
||||||
|
|
||||||
|
for (final Category category : categories) {
|
||||||
|
|
||||||
|
final Category cat = categoryRepo
|
||||||
|
.findById(category.getObjectId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No Category with ID %d in the database.",
|
||||||
|
category.getObjectId())));
|
||||||
|
categoryManager.addObjectToCategory(ccmObject, category, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
protected Category getDomainModelCategory(final Domain domain) {
|
||||||
|
|
||||||
|
Objects.requireNonNull(domain);
|
||||||
|
|
||||||
|
final Domain catDomain = domainRepo
|
||||||
|
.findById(domain.getObjectId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No Domain with ID %d in the database.",
|
||||||
|
domain.getObjectId())));
|
||||||
|
|
||||||
|
return catDomain.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
protected List<Category> getRootCategories(final Domain domain) {
|
||||||
|
|
||||||
|
return getDomainModelCategory(domain).getSubCategories();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
protected List<Category> getSubCategories(final Category category) {
|
||||||
|
|
||||||
|
Objects.requireNonNull(category);
|
||||||
|
|
||||||
|
final Category cat = categoryRepo
|
||||||
|
.findById(category.getObjectId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No Category with ID %d in the database.",
|
||||||
|
category.getObjectId())));
|
||||||
|
|
||||||
|
return cat.getSubCategories();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
protected Category getParentCategory(final Category category) {
|
||||||
|
|
||||||
|
Objects.requireNonNull(category);
|
||||||
|
|
||||||
|
final Category cat = categoryRepo
|
||||||
|
.findById(category.getObjectId())
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException(String
|
||||||
|
.format("No Category with ID %d in the database.",
|
||||||
|
category.getObjectId())));
|
||||||
|
|
||||||
|
return cat.getParentCategory();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* 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.london.terms.ui;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.parameters.BigDecimalParameter;
|
||||||
|
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.librecms.contentsection.ContentItem;
|
||||||
|
|
||||||
|
import com.arsdigita.cms.ui.authoring.ItemCategoryForm;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replacement for cms authoring ItemCategoryForm which replaces the category
|
||||||
|
* widget with a terms based widget.
|
||||||
|
*
|
||||||
|
* Provides a ccm-cms specific concrete implementation of
|
||||||
|
* {@link com.arsdigita.london.terms.ui.ACSObjectCategoryPicker}.
|
||||||
|
*
|
||||||
|
* Is is activated / used by pointing the parameter
|
||||||
|
* {@code com.arsdigita.cms.category_authoring_add_form} to it.
|
||||||
|
*/
|
||||||
|
public class ItemCategoryPicker extends ACSObjectCategoryPicker {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager
|
||||||
|
.getLogger(ItemCategoryPicker.class);
|
||||||
|
|
||||||
|
public ItemCategoryPicker(final LongParameter root,
|
||||||
|
final StringParameter mode) {
|
||||||
|
super(root, mode);
|
||||||
|
LOGGER.debug("instantiating ItemCategoryPicker");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.arsdigita.london.terms.ui.ACSObjectCategoryPicker#getForm(
|
||||||
|
* com.arsdigita.bebop.parameters.BigDecimalParameter,
|
||||||
|
* com.arsdigita.bebop.parameters.StringParameter)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected ACSObjectCategoryForm getForm(final LongParameter root,
|
||||||
|
final StringParameter mode) {
|
||||||
|
LOGGER.debug("getForm");
|
||||||
|
return new ItemCategoryForm(root, mode, new TermWidget(mode, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.arsdigita.london.terms.ui.ACSObjectCategoryPicker#getObject()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected CcmObject getObject(final PageState state) {
|
||||||
|
|
||||||
|
return CMS.getContext().getContentItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,372 @@
|
||||||
|
/*
|
||||||
|
* 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.london.terms.ui;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.form.Widget;
|
||||||
|
import com.arsdigita.bebop.parameters.ArrayParameter;
|
||||||
|
import com.arsdigita.bebop.parameters.BigDecimalParameter;
|
||||||
|
import com.arsdigita.bebop.parameters.StringParameter;
|
||||||
|
|
||||||
|
import org.libreccm.categorization.Category;
|
||||||
|
|
||||||
|
import com.arsdigita.cms.CMS;
|
||||||
|
|
||||||
|
import org.librecms.contentsection.ContentItem;
|
||||||
|
import org.librecms.contentsection.ContentSection;
|
||||||
|
import org.libreccm.categorization.Domain;
|
||||||
|
|
||||||
|
import com.arsdigita.xml.Element;
|
||||||
|
import com.arsdigita.xml.XML;
|
||||||
|
|
||||||
|
import org.arsdigita.cms.CMSConfig;
|
||||||
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Widget for selecting Terms. Based heavily on CategoryWidget.
|
||||||
|
*
|
||||||
|
* @author mbooth@redhat.com
|
||||||
|
* @author Chris Gilbert
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*
|
||||||
|
* Chris Gilbert - updated to identify each node uniquely (correct behaviour for
|
||||||
|
* polyhierarchical trees) - also, allow ajax update on all branches or just top
|
||||||
|
* level branch
|
||||||
|
*
|
||||||
|
* nb - widget applies to allocation of categories to any ACSObject hence xml
|
||||||
|
* prefix should be more generic eg bebop rather than cms. cms retained for
|
||||||
|
* compatibility with existing stylesheets
|
||||||
|
*
|
||||||
|
* Jens Pelzetter: Variable naming etc changed to comply with usual Java
|
||||||
|
* conventions. Adapted to CCM NG.
|
||||||
|
*/
|
||||||
|
// NON Javadoc comment:
|
||||||
|
// Copied from c.ad.aplaws.ui in order to make forum-categorised independend from
|
||||||
|
// a specific ccm-???-aplaws, i.e. a specific integration layer.
|
||||||
|
public class TermWidget extends Widget {
|
||||||
|
|
||||||
|
private final StringParameter mode;
|
||||||
|
private final ACSObjectCategoryPicker picker;
|
||||||
|
|
||||||
|
public TermWidget(final StringParameter mode,
|
||||||
|
final ACSObjectCategoryPicker picker) {
|
||||||
|
|
||||||
|
super(new ArrayParameter(new BigDecimalParameter("category")));
|
||||||
|
|
||||||
|
this.mode = mode;
|
||||||
|
this.picker = picker;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getType() {
|
||||||
|
return "category";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCompound() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void generateWidget(final PageState state, final Element parent) {
|
||||||
|
final Domain domain = picker.getDomain(state);
|
||||||
|
|
||||||
|
final Element widget = parent.newChildElement("cms:categoryWidget",
|
||||||
|
CMS.CMS_XML_NS);
|
||||||
|
exportAttributes(widget);
|
||||||
|
|
||||||
|
widget.addAttribute("mode", (String) state.getValue(mode));
|
||||||
|
widget.addAttribute("name", getName());
|
||||||
|
|
||||||
|
final Set<Long> selectedCats = new HashSet<>();
|
||||||
|
|
||||||
|
//jensp 2015-03-12: In same cases we need to be able to pass the
|
||||||
|
//selected categories *and* the selected roots for displaying the
|
||||||
|
//categories nicely. To maintain backwards
|
||||||
|
//compatibility we check the type of the value and work either with the
|
||||||
|
//selected categories only or with the selected categories and their
|
||||||
|
//roots.
|
||||||
|
final Set<Long> selectedAncestors = new HashSet<>();
|
||||||
|
|
||||||
|
final Long[] values;
|
||||||
|
final Long[] selAncestorsValues; //selectedAncestors
|
||||||
|
final Object valueObj = getValue(state);
|
||||||
|
if (valueObj instanceof Long[][]) {
|
||||||
|
if (((Long[][]) valueObj).length >= 1) {
|
||||||
|
values = ((Long[][]) valueObj)[0];
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Value of TermWidget is of type BigDecimal[][] but the array is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((Long[][]) valueObj).length >= 2) {
|
||||||
|
selAncestorsValues = ((Long[][]) valueObj)[1];
|
||||||
|
} else {
|
||||||
|
selAncestorsValues = null;
|
||||||
|
}
|
||||||
|
} else if (valueObj instanceof Long[]) {
|
||||||
|
values = (Long[]) valueObj;
|
||||||
|
selAncestorsValues = null;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Value of TermWidget is not of type BigDecimal[] or BigDecimal[][]");
|
||||||
|
}
|
||||||
|
|
||||||
|
//BigDecimal[] values = (BigDecimal[]) getValue(state);
|
||||||
|
if (values != null) {
|
||||||
|
selectedCats.addAll(Arrays.asList(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selAncestorsValues != null) {
|
||||||
|
selectedAncestors.addAll(Arrays.asList(selAncestorsValues));
|
||||||
|
}
|
||||||
|
|
||||||
|
final Element selEl = widget.newChildElement(
|
||||||
|
"cms:selectedCategories", CMS.CMS_XML_NS);
|
||||||
|
selEl.addAttribute("name", getName());
|
||||||
|
final Iterator<Long> selCats = selectedCats.iterator();
|
||||||
|
// while (selCats.hasNext()) {
|
||||||
|
// final Element selCat = selEl.newChildElement("cms:category",
|
||||||
|
// CMS.CMS_XML_NS);
|
||||||
|
// selCat.addAttribute("id", selCats.next().toString());
|
||||||
|
// }
|
||||||
|
for (Long selectedCat : selectedCats) {
|
||||||
|
final Element selectedCatElem = selEl.newChildElement(
|
||||||
|
"cms:category", CMS.CMS_XML_NS);
|
||||||
|
selectedCatElem.addAttribute("id", selectedCat.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
final Element selAncestorsElem = widget.newChildElement(
|
||||||
|
"cms:selectedAncestorCategories", CMS.CMS_XML_NS);
|
||||||
|
selAncestorsElem.addAttribute("name", getName());
|
||||||
|
for (Long selAncestor : selectedAncestors) {
|
||||||
|
final Element selAncestorElem = selAncestorsElem.newChildElement(
|
||||||
|
"cms:category", CMS.CMS_XML_NS);
|
||||||
|
selAncestorElem.addAttribute("id", selAncestor.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
final CategoryPickerController controller = cdiUtil
|
||||||
|
.findBean(CategoryPickerController.class);
|
||||||
|
|
||||||
|
// only root terms at first, the rest is loaded on-demand via AJAX
|
||||||
|
final List<Category> roots = controller.getRootCategories(domain);
|
||||||
|
|
||||||
|
final Element element = generateCategory(
|
||||||
|
widget,
|
||||||
|
controller.getDomainModelCategory(domain),
|
||||||
|
selectedCats,
|
||||||
|
null);
|
||||||
|
|
||||||
|
if (CMSConfig.getConfig().isCategoryPickerAjaxExpandAll()) {
|
||||||
|
// add attribute to the parent node, so that in stylesheet
|
||||||
|
// we can look for any ancestor with this attribute (can't
|
||||||
|
// add attribute to categoryWidget element as that is not
|
||||||
|
// visible when subbranches are transformed)
|
||||||
|
element.addAttribute("expand", "all");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final Category category : roots) {
|
||||||
|
|
||||||
|
generateRootTerm(element,
|
||||||
|
category,
|
||||||
|
selectedCats,
|
||||||
|
category.getCategoryOrder());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Element generateCategory(final Element parent,
|
||||||
|
final Category category,
|
||||||
|
final Set<Long> selected,
|
||||||
|
final Long sortKey) {
|
||||||
|
|
||||||
|
final Element element = parent.newChildElement("cms:category",
|
||||||
|
CMS.CMS_XML_NS);
|
||||||
|
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
final GlobalizationHelper globalizationHelper = cdiUtil
|
||||||
|
.findBean(GlobalizationHelper.class);
|
||||||
|
|
||||||
|
element.addAttribute("id", XML.format(category.getObjectId()));
|
||||||
|
element.addAttribute("name", category.getName());
|
||||||
|
element.addAttribute(
|
||||||
|
"description",
|
||||||
|
globalizationHelper.getValueFromLocalizedString(category
|
||||||
|
.getDescription()));
|
||||||
|
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 so that we can
|
||||||
|
// correctly transform xml fragments returned by ajax
|
||||||
|
element.addAttribute("order", "sortKey");
|
||||||
|
element.addAttribute("genCat", "true");
|
||||||
|
|
||||||
|
StringBuilder path = new StringBuilder(parent.getAttribute("fullname"));
|
||||||
|
if (path.length() > 0) {
|
||||||
|
path.append(" > ");
|
||||||
|
|
||||||
|
}
|
||||||
|
path.append(category.getName());
|
||||||
|
element.addAttribute("fullname", path.toString());
|
||||||
|
|
||||||
|
// need to uniquely identify each node in polyhierarchical trees
|
||||||
|
// so that expand/contract is applied to the correct node by
|
||||||
|
// javascript getElementByID function
|
||||||
|
StringBuilder nodeID = new StringBuilder(parent.getAttribute("node-id"));
|
||||||
|
if (nodeID.length() > 0) {
|
||||||
|
nodeID.append("-");
|
||||||
|
|
||||||
|
}
|
||||||
|
nodeID.append(category.getObjectId());
|
||||||
|
element.addAttribute("node-id", nodeID.toString());
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Element generateTerm(final Element parent,
|
||||||
|
final Category category,
|
||||||
|
final Set<Long> selected,
|
||||||
|
final Long sortKey) {
|
||||||
|
final Element element = generateCategory(parent,
|
||||||
|
category,
|
||||||
|
selected,
|
||||||
|
sortKey);
|
||||||
|
|
||||||
|
element.addAttribute("pid", category.getUniqueId());
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void generateRootTerm(final Element parent,
|
||||||
|
final Category term,
|
||||||
|
final Set<Long> selected,
|
||||||
|
final Long sortKey) {
|
||||||
|
final Element element = generateTerm(parent, term, selected, sortKey);
|
||||||
|
element.addAttribute("root", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void generateSubtree(final Element parent,
|
||||||
|
final Category root,
|
||||||
|
final Set<Long> ids) {
|
||||||
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
|
final CategoryPickerController controller = cdiUtil
|
||||||
|
.findBean(CategoryPickerController.class);
|
||||||
|
|
||||||
|
final List<Category> terms = controller.getSubCategories(root);
|
||||||
|
|
||||||
|
final Map<Long, List<Category>> children = new HashMap<>();
|
||||||
|
for (final Category term : terms) {
|
||||||
|
final Long parentId = controller
|
||||||
|
.getParentCategory(term)
|
||||||
|
.getObjectId();
|
||||||
|
|
||||||
|
final List<Category> childList;
|
||||||
|
if (children.containsKey(parentId)) {
|
||||||
|
childList = children.get(parentId);
|
||||||
|
} else {
|
||||||
|
childList = new ArrayList<>();
|
||||||
|
children.put(parentId, childList);
|
||||||
|
}
|
||||||
|
|
||||||
|
childList.add(term);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Element element = generateCategory(parent, root, ids, null);
|
||||||
|
element.addAttribute("fullname", root.getName());
|
||||||
|
element.addAttribute("node-id", Long.toString(root.getObjectId()));
|
||||||
|
element.addAttribute("order", "sortKey");
|
||||||
|
if (CMSConfig.getConfig().isCategoryPickerAjaxExpandAll()) {
|
||||||
|
//recognisable attribute has to be in the XML for each snippet that
|
||||||
|
//is transformed, hence add it to the parent
|
||||||
|
element.addAttribute("expand", "all");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (children.containsKey(root.getObjectId())) {
|
||||||
|
final List<Category> roots = children.get(root.getObjectId());
|
||||||
|
for (final Category category : roots) {
|
||||||
|
generateTermWithChildren(element,
|
||||||
|
category,
|
||||||
|
ids,
|
||||||
|
category.getCategoryOrder(),
|
||||||
|
children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void generateTermWithChildren(
|
||||||
|
final Element parent,
|
||||||
|
final Category category,
|
||||||
|
final Set<Long> selected,
|
||||||
|
final Long sortKey,
|
||||||
|
final Map<Long, List<Category>> children) {
|
||||||
|
|
||||||
|
final Element element = generateCategory(parent,
|
||||||
|
category,
|
||||||
|
selected,
|
||||||
|
sortKey);
|
||||||
|
|
||||||
|
element.addAttribute("pid", category.getUniqueId());
|
||||||
|
|
||||||
|
if (children.containsKey(category.getObjectId())) {
|
||||||
|
final List<Category> childs = children.get(category.getObjectId());
|
||||||
|
for (final Category child : childs) {
|
||||||
|
if (CMSConfig.getConfig().isCategoryPickerAjaxExpandAll()) {
|
||||||
|
generateTerm(element,
|
||||||
|
child,
|
||||||
|
selected,
|
||||||
|
child.getCategoryOrder());
|
||||||
|
} else {
|
||||||
|
generateTermWithChildren(element,
|
||||||
|
child,
|
||||||
|
selected,
|
||||||
|
child.getCategoryOrder(),
|
||||||
|
children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
package org.arsdigita.cms;
|
package org.arsdigita.cms;
|
||||||
|
|
||||||
import com.arsdigita.bebop.form.DHTMLEditor;
|
import com.arsdigita.bebop.form.DHTMLEditor;
|
||||||
|
import com.arsdigita.cms.ui.authoring.ItemCategoryExtension;
|
||||||
|
import com.arsdigita.cms.ui.authoring.ItemCategoryForm;
|
||||||
|
|
||||||
import org.libreccm.cdi.utils.CdiUtil;
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
import org.libreccm.configuration.Configuration;
|
import org.libreccm.configuration.Configuration;
|
||||||
|
|
@ -369,6 +371,16 @@ public class CMSConfig {
|
||||||
@Setting
|
@Setting
|
||||||
private int xmlCacheAge = 60 * 60 * 24;
|
private int xmlCacheAge = 60 * 60 * 24;
|
||||||
|
|
||||||
|
@Setting
|
||||||
|
private String categoryAuthoringAddForm = ItemCategoryForm.class.getName();
|
||||||
|
|
||||||
|
@Setting
|
||||||
|
private String categoryAuthoringExtension = ItemCategoryExtension.class
|
||||||
|
.getName();
|
||||||
|
|
||||||
|
@Setting
|
||||||
|
private boolean categoryPickerAjaxExpandAll = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Max length of the description of a link (in database max length are 4000
|
* Max length of the description of a link (in database max length are 4000
|
||||||
* characters)
|
* characters)
|
||||||
|
|
@ -929,4 +941,32 @@ public class CMSConfig {
|
||||||
this.linkDescMaxLength = linkDescMaxLength;
|
this.linkDescMaxLength = linkDescMaxLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getCategoryAuthoringAddForm() {
|
||||||
|
return categoryAuthoringAddForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategoryAuthoringAddForm(
|
||||||
|
final String categoryAuthoringAddForm) {
|
||||||
|
|
||||||
|
this.categoryAuthoringAddForm = categoryAuthoringAddForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCategoryAuthoringExtension() {
|
||||||
|
return categoryAuthoringExtension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategoryAuthoringExtension(
|
||||||
|
final String categoryAuthoringExtension) {
|
||||||
|
this.categoryAuthoringExtension = categoryAuthoringExtension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCategoryPickerAjaxExpandAll() {
|
||||||
|
return categoryPickerAjaxExpandAll;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategoryPickerAjaxExpandAll(
|
||||||
|
final boolean categoryPickerAjaxExpandAll) {
|
||||||
|
this.categoryPickerAjaxExpandAll = categoryPickerAjaxExpandAll;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,10 @@ import org.libreccm.l10n.LocalizedString;
|
||||||
import org.libreccm.portation.Portable;
|
import org.libreccm.portation.Portable;
|
||||||
import org.libreccm.security.RecursivePermissions;
|
import org.libreccm.security.RecursivePermissions;
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
@ -41,6 +41,22 @@ import java.util.Objects;
|
||||||
import static org.libreccm.categorization.CategorizationConstants.CAT_XML_NS;
|
import static org.libreccm.categorization.CategorizationConstants.CAT_XML_NS;
|
||||||
import static org.libreccm.core.CoreConstants.DB_SCHEMA;
|
import static org.libreccm.core.CoreConstants.DB_SCHEMA;
|
||||||
|
|
||||||
|
import javax.persistence.AssociationOverride;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Embedded;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.JoinTable;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.NamedAttributeNode;
|
||||||
|
import javax.persistence.NamedEntityGraph;
|
||||||
|
import javax.persistence.NamedEntityGraphs;
|
||||||
|
import javax.persistence.NamedQueries;
|
||||||
|
import javax.persistence.NamedQuery;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The category entity represents a single category. Each category is part of a
|
* The category entity represents a single category. Each category is part of a
|
||||||
* {@link Domain}. A category can be assigned to multiple {@link CcmObject}s.
|
* {@link Domain}. A category can be assigned to multiple {@link CcmObject}s.
|
||||||
|
|
|
||||||
|
|
@ -30,17 +30,40 @@ import org.libreccm.portation.Portable;
|
||||||
import org.libreccm.security.RecursivePermissions;
|
import org.libreccm.security.RecursivePermissions;
|
||||||
import org.libreccm.web.CcmApplication;
|
import org.libreccm.web.CcmApplication;
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import javax.validation.constraints.Pattern;
|
import javax.validation.constraints.Pattern;
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import static org.libreccm.categorization.CategorizationConstants.CAT_XML_NS;
|
import static org.libreccm.categorization.CategorizationConstants.CAT_XML_NS;
|
||||||
import static org.libreccm.core.CoreConstants.DB_SCHEMA;
|
import static org.libreccm.core.CoreConstants.DB_SCHEMA;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.persistence.AssociationOverride;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Embedded;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.JoinTable;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.NamedAttributeNode;
|
||||||
|
import javax.persistence.NamedEntityGraph;
|
||||||
|
import javax.persistence.NamedEntityGraphs;
|
||||||
|
import javax.persistence.NamedQueries;
|
||||||
|
import javax.persistence.NamedQuery;
|
||||||
|
import javax.persistence.NamedSubgraph;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A domain is collection of categories designed a specific purpose. This entity
|
* A domain is collection of categories designed a specific purpose. This entity
|
||||||
* replaces the {@code Domain} entity from the old {@code ccm-ldn-terms} module
|
* replaces the {@code Domain} entity from the old {@code ccm-ldn-terms} module
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue