/* * Copyright (C) 2005-2012 BetaCONCEPT Limited * * This file is part of Astroboa. * * Astroboa 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 3 of the License, or * (at your option) any later version. * * Astroboa 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 Astroboa. If not, see <http://www.gnu.org/licenses/>. */ package org.betaconceptframework.astroboa.portal.managedbean; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.betaconceptframework.astroboa.api.model.Taxonomy; import org.betaconceptframework.astroboa.api.model.Topic; import org.betaconceptframework.astroboa.api.model.io.FetchLevel; import org.betaconceptframework.astroboa.api.model.io.ResourceRepresentationType; import org.betaconceptframework.astroboa.api.model.query.CacheRegion; import org.betaconceptframework.astroboa.api.model.query.CmsOutcome; import org.betaconceptframework.astroboa.api.model.query.Order; import org.betaconceptframework.astroboa.api.model.query.QueryOperator; import org.betaconceptframework.astroboa.api.model.query.criteria.LocalizationCriterion; import org.betaconceptframework.astroboa.api.model.query.criteria.TopicCriteria; import org.betaconceptframework.astroboa.client.AstroboaClient; import org.betaconceptframework.astroboa.model.factory.CmsCriteriaFactory; import org.betaconceptframework.astroboa.model.factory.CriterionFactory; import org.betaconceptframework.astroboa.portal.utility.CmsUtils; import org.betaconceptframework.astroboa.portal.utility.LazyLoadingTopicTreeNode; import org.betaconceptframework.astroboa.portal.utility.PortalCacheConstants; import org.betaconceptframework.astroboa.portal.utility.TopicComparator; import org.betaconceptframework.astroboa.portal.utility.TopicComparator.OrderByProperty; import org.betaconceptframework.astroboa.util.CmsConstants; import org.betaconceptframework.ui.jsf.AbstractUIBean; import org.betaconceptframework.ui.jsf.utility.JSFUtilities; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; /** * * @author Gregory Chomatas (gchomatas@betaconcept.com) * @author Savvas Triantafyllou (striantafyllou@betaconcept.com) * */ @Name("topicManager") @Scope(ScopeType.SESSION) public class TopicManager extends AbstractUIBean { /** * */ private static final long serialVersionUID = 6311222629082658672L; @In(create=true) private AstroboaClient astroboaClient; @In(create=true) private CmsUtils cmsUtils; private Map<String, LazyLoadingTopicTreeNode> lazyLoadingTopicTreeNodesPerTaxonomyAndParentName = new HashMap<String, LazyLoadingTopicTreeNode>(); public LazyLoadingTopicTreeNode getTopicTreeForParentTopic(String taxonomyName, String parentTopicName, boolean orderByPosition){ String topicTreeNodeId = taxonomyName+parentTopicName; if (StringUtils.isBlank(topicTreeNodeId)){ return null; } if (lazyLoadingTopicTreeNodesPerTaxonomyAndParentName != null && lazyLoadingTopicTreeNodesPerTaxonomyAndParentName.containsKey(topicTreeNodeId)){ return lazyLoadingTopicTreeNodesPerTaxonomyAndParentName.get(topicTreeNodeId); } List<Topic> childTopics = getChildTopicsByParentTopicName(taxonomyName, parentTopicName, orderByPosition, PortalCacheConstants.TOPIC_DEFAULT_CACHE_REGION); LazyLoadingTopicTreeNode rootNode = new LazyLoadingTopicTreeNode(); if (CollectionUtils.isNotEmpty(childTopics)){ for (Topic childTopic : childTopics){ LazyLoadingTopicTreeNode childTopicTreeNode = new LazyLoadingTopicTreeNode(childTopic.getId(),childTopic, rootNode, orderByPosition ? OrderByProperty.POSITION : OrderByProperty.LABEL); rootNode.addChild(childTopicTreeNode.getIdentifier(), childTopicTreeNode); } } if (lazyLoadingTopicTreeNodesPerTaxonomyAndParentName == null){ lazyLoadingTopicTreeNodesPerTaxonomyAndParentName = new HashMap<String, LazyLoadingTopicTreeNode>(); } lazyLoadingTopicTreeNodesPerTaxonomyAndParentName.put(topicTreeNodeId, rootNode); return rootNode; } public List<Topic> getChildTopicsByParentTopicName(String taxonomyName, String parentTopicName, boolean orderByPosition) { return getChildTopicsByParentTopicName(taxonomyName, parentTopicName, orderByPosition, PortalCacheConstants.TOPIC_DEFAULT_CACHE_REGION); } public List<Topic> getRootTopicsOfTaxonomyOrderedByPosition(String taxonomyName) { return getChildTopicsByParentTopicName(taxonomyName, null, true); } public List<Topic> getRootTopicsOfTaxonomy(String taxonomyName) { return getChildTopicsByParentTopicName(taxonomyName, null); } /** * Find child topics of a topic defined under a taxonomy * If a parent topic is not provided then the root topics of the taxonomy are returned * The topics are returned alphabetically ordered * @param taxonomyName * @param parentTopicName * @return */ public List<Topic> getChildTopicsByParentTopicName(String taxonomyName, String parentTopicName) { return getChildTopicsByParentTopicName(taxonomyName, parentTopicName, false, PortalCacheConstants.TOPIC_DEFAULT_CACHE_REGION); } /** * Find child topics of a topic defined under a taxonomy * If a parent topic is not provided then the root topics of the taxonomy are returned. * If the taxonomy name is empty or null an empty list is returned. * if "orderByPosition" is true the topics are returned ordered according to their order ranking, * otherwise the topics are returned alphabetically ordered. * * If a non null cache region is provided then the query is cached in the specified region * Otherwise it is cached in the default regions for Topic queries as specified in portal settings * * @param taxonomyName * @param parentTopicName * @param orderByPosition * @param cacheRegion * @return */ public List<Topic> getChildTopicsByParentTopicName(String taxonomyName, String parentTopicName, boolean orderByPosition, CacheRegion cacheRegion) { if (cacheRegion == null) { cacheRegion = PortalCacheConstants.TOPIC_DEFAULT_CACHE_REGION; } if (StringUtils.isBlank(parentTopicName)) { if (StringUtils.isBlank(taxonomyName)) { return new ArrayList<Topic>(); } Taxonomy taxonomy = astroboaClient.getTaxonomyService().getTaxonomy(taxonomyName, ResourceRepresentationType.TAXONOMY_INSTANCE, FetchLevel.ENTITY_AND_CHILDREN, false); if (taxonomy == null) { return new ArrayList<Topic>(); } if (CollectionUtils.isNotEmpty(taxonomy.getRootTopics())){ List<Topic> rootTopics = taxonomy.getRootTopics(); if (orderByPosition){ Collections.sort(rootTopics, new TopicComparator(JSFUtilities.getLocaleAsString(), OrderByProperty.POSITION)); } return rootTopics; } else{ return new ArrayList<Topic>(); } } List<Topic> childTopics = cmsUtils.findChildTopicsByParentTopicName(parentTopicName, JSFUtilities.getLocaleAsString(), orderByPosition, cacheRegion); if (childTopics != null && CollectionUtils.isNotEmpty(childTopics)) { return childTopics; } else { return new ArrayList<Topic>(); } } public List<Topic> getChildTopicsByParentTopicName(String taxonomyName, String parentTopicName, Integer numberOfResults) { List<Topic> childTopics = getChildTopicsByParentTopicName(taxonomyName, parentTopicName); if (numberOfResults != null && numberOfResults > 0 && childTopics.size() >= numberOfResults) { return childTopics.subList(0, numberOfResults + 1); } else { return childTopics; } } /** * Find child topics of a topic defined under a taxonomy * The topics are returned ordered according to their order ranking * @param parentTopicId * @return */ public List<Topic> getChildTopicsByParentTopicId(String parentTopicId, boolean orderByPosition, boolean cacheable, CacheRegion cacheRegion) { if (StringUtils.isBlank(parentTopicId)) { return null; } List<Topic> childTopics = cmsUtils.findChildTopicsByParentTopicId(parentTopicId, JSFUtilities.getLocaleAsString(), orderByPosition, cacheRegion); if (childTopics != null) { return childTopics; } else { return new ArrayList<Topic>(); } } /** * find the topics in subject Taxonomy that their label CONTAINS the provided text * @param containingText * @return */ public List<Topic> findTopicsByTextSearch(String textContainedInLabel) { return findTopicsByTextSearch(Taxonomy.SUBJECT_TAXONOMY_NAME, textContainedInLabel); } /** * find the topics in Taxonomy with the specified system name "taxonomySystemName" that their label CONTAINS the provided text * if "taxonomySystemName" is null or empty then search in all available taxonomies * * @param taxonomySystemName * @param containingText * @return */ public List<Topic> findTopicsByTextSearch(String taxonomySystemName, String textContainedInLabel) { try { //Do not proceed if selected topic label is empty if (StringUtils.isBlank(textContainedInLabel)) return null; TopicCriteria topicCriteria = CmsCriteriaFactory.newTopicCriteria(); if (StringUtils.isNotBlank(taxonomySystemName)) { topicCriteria.addTaxonomyNameEqualsCriterion(Taxonomy.SUBJECT_TAXONOMY_NAME); } //topicCriteria.getRenderProperties().renderValuesForLocales(Arrays.asList(JSFUtilities.getLocaleAsString())); topicCriteria.addOrderByLocale(JSFUtilities.getLocaleAsString(), Order.ascending); //Localized Label criterion LocalizationCriterion localizationCriterion = CriterionFactory.newLocalizationCriterion(); localizationCriterion.setLocale(JSFUtilities.getLocaleAsString()); localizationCriterion.addLocalizedLabel(textContainedInLabel+CmsConstants.ANY_NAME); localizationCriterion.setQueryOperator(QueryOperator.CONTAINS); //localizationCriterion.addLocalizedLabel(CmsConstants.LIKE + textContainedInLabel + CmsConstants.LIKE); topicCriteria.addCriterion(localizationCriterion); topicCriteria.setCacheable(PortalCacheConstants.TOPIC_DEFAULT_CACHE_REGION); CmsOutcome<Topic> cmsOutcome = astroboaClient.getTopicService().searchTopics(topicCriteria, ResourceRepresentationType.TOPIC_LIST); return cmsOutcome.getResults(); } catch (Exception e) { logger.error("Error while loading Topics ",e); return null; } } public List<Topic> findSuggestedTopics_UIAction(Object event) { try { String selectedTopicLabel = event.toString(); //Do not proceed if selected topic label is empty if (StringUtils.isBlank(selectedTopicLabel)) return null; TopicCriteria topicCriteria = CmsCriteriaFactory.newTopicCriteria(); //topicCriteria.getRenderProperties().renderValuesForLocale(JSFUtilities.getLocaleAsString()); topicCriteria.setOffsetAndLimit(0, 30); topicCriteria.addOrderByLocale(JSFUtilities.getLocaleAsString(), Order.ascending); //Localized Label criterion LocalizationCriterion localizationCriterion = CriterionFactory.newLocalizationCriterion(); localizationCriterion.setLocale(JSFUtilities.getLocaleAsString()); localizationCriterion.addLocalizedLabel(selectedTopicLabel + CmsConstants.ANY_NAME); localizationCriterion.setQueryOperator(QueryOperator.CONTAINS); topicCriteria.addCriterion(localizationCriterion); topicCriteria.addTaxonomyNameEqualsCriterion(Taxonomy.SUBJECT_TAXONOMY_NAME); topicCriteria.setCacheable(CacheRegion.TEN_MINUTES); CmsOutcome<Topic> cmsOutcome = astroboaClient.getTopicService().searchTopics(topicCriteria, ResourceRepresentationType.TOPIC_LIST); return cmsOutcome.getResults(); } catch (Exception e) { logger.error("Error while loading Topics ",e); return null; } } }