Removed depcrecated package com.arsdigita.london.terms.ui from ccm-cms
parent
77d73fd336
commit
b9dc94e48b
|
|
@ -75,9 +75,7 @@ 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"));
|
||||||
|
|
||||||
final String addFormClassName = CMSConfig
|
final String addFormClassName = null;
|
||||||
.getConfig()
|
|
||||||
.getCategoryAuthoringAddForm();
|
|
||||||
final Class<?> addFormClass;
|
final Class<?> addFormClass;
|
||||||
try {
|
try {
|
||||||
addFormClass = Class.forName(addFormClassName);
|
addFormClass = Class.forName(addFormClassName);
|
||||||
|
|
|
||||||
|
|
@ -1,202 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.math.BigDecimal;
|
|
||||||
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 Object value = state.getValue(rootParam);
|
|
||||||
final Long domainId;
|
|
||||||
if (value instanceof Long) {
|
|
||||||
domainId = (Long) value;
|
|
||||||
} else if (value instanceof BigDecimal) {
|
|
||||||
domainId = ((Number) value).longValue();
|
|
||||||
} else if (value instanceof String) {
|
|
||||||
domainId = Long.parseLong((String) value);
|
|
||||||
} else {
|
|
||||||
domainId = Long.parseLong(value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
|
||||||
final CategoryPickerController controller = cdiUtil
|
|
||||||
.findBean(CategoryPickerController.class);
|
|
||||||
|
|
||||||
return controller.findDomainByRootCategory(domainId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,241 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.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.persistence.EntityManager;
|
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
|
||||||
import javax.persistence.criteria.Join;
|
|
||||||
import javax.persistence.criteria.Root;
|
|
||||||
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;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private EntityManager entityManager;
|
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
|
||||||
protected Domain findDomainByRootCategory(final long rootCategoryId) {
|
|
||||||
|
|
||||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
|
||||||
final CriteriaQuery<Domain> query = builder.createQuery(Domain.class);
|
|
||||||
|
|
||||||
final Root<Domain> from = query.from(Domain.class);
|
|
||||||
final Join<Domain, Category> rootCatJoin = from.join("root");
|
|
||||||
|
|
||||||
query.where(builder.equal(rootCatJoin.get("objectId"), rootCategoryId));
|
|
||||||
|
|
||||||
return entityManager
|
|
||||||
.createQuery(query)
|
|
||||||
.getSingleResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
@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()
|
|
||||||
.stream()
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
* 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,370 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.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.libreccm.categorization.Domain;
|
|
||||||
|
|
||||||
import com.arsdigita.xml.Element;
|
|
||||||
import com.arsdigita.xml.XML;
|
|
||||||
|
|
||||||
import org.librecms.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -20,7 +20,6 @@ package org.librecms;
|
||||||
|
|
||||||
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.ItemCategoryExtension;
|
||||||
import com.arsdigita.london.terms.ui.ItemCategoryPicker;
|
|
||||||
|
|
||||||
import org.libreccm.cdi.utils.CdiUtil;
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
import org.libreccm.configuration.Configuration;
|
import org.libreccm.configuration.Configuration;
|
||||||
|
|
@ -554,12 +553,6 @@ public class CMSConfig {
|
||||||
)
|
)
|
||||||
private int xmlCacheAge = 60 * 60 * 24;
|
private int xmlCacheAge = 60 * 60 * 24;
|
||||||
|
|
||||||
@Setting(
|
|
||||||
descKey = "categoryAuthoringAddForm.desc",
|
|
||||||
labelKey = "categoryAuthoringAddForm.label"
|
|
||||||
)
|
|
||||||
private String categoryAuthoringAddForm = ItemCategoryPicker.class.getName();
|
|
||||||
|
|
||||||
@Setting(
|
@Setting(
|
||||||
descKey = "categoryAuthoringExtension.desc",
|
descKey = "categoryAuthoringExtension.desc",
|
||||||
labelKey = "categoryAuthoringExtension.label"
|
labelKey = "categoryAuthoringExtension.label"
|
||||||
|
|
@ -1136,16 +1129,6 @@ 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() {
|
public String getCategoryAuthoringExtension() {
|
||||||
return categoryAuthoringExtension;
|
return categoryAuthoringExtension;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue