/* * 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.console.commons; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.betaconceptframework.astroboa.api.model.RepositoryUser; import org.betaconceptframework.astroboa.api.model.Taxonomy; import org.betaconceptframework.astroboa.api.model.Topic; import org.betaconceptframework.astroboa.api.model.definition.ContentObjectTypeDefinition; import org.betaconceptframework.astroboa.api.model.definition.LocalizableCmsDefinition; import org.betaconceptframework.astroboa.api.model.exception.CmsException; 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.Criterion; import org.betaconceptframework.astroboa.api.model.query.criteria.LocalizationCriterion; import org.betaconceptframework.astroboa.api.model.query.criteria.RepositoryUserCriteria; import org.betaconceptframework.astroboa.api.model.query.criteria.TopicCriteria; import org.betaconceptframework.astroboa.api.service.RepositoryUserService; import org.betaconceptframework.astroboa.api.service.TopicService; import org.betaconceptframework.astroboa.console.commons.TopicComparator.OrderByProperty; import org.betaconceptframework.astroboa.model.factory.CmsCriteriaFactory; import org.betaconceptframework.astroboa.model.factory.CmsRepositoryEntityFactoryForActiveClient; import org.betaconceptframework.astroboa.model.factory.CriterionFactory; import org.betaconceptframework.astroboa.model.impl.item.CmsBuiltInItem; import org.betaconceptframework.astroboa.util.CmsConstants; import org.betaconceptframework.ui.jsf.utility.JSFUtilities; import org.jboss.seam.security.Identity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Commonly used search queries and methods possibly useful to all developers utilizing the repository * * @author Gregory Chomatas (gchomatas@betaconcept.com) * @author Savvas Triantafyllou (striantafyllou@betaconcept.com) * */ public class CMSUtilities { protected final Logger logger = LoggerFactory.getLogger(getClass()); private TopicService topicService; private RepositoryUserService repositoryUserService; /** * It finds a topic by means of the taxonomy name and the topic system name * The taxonomy name is the name of the taxonomy under which the topic has been defined. * If taxonomy name is blank then the DEFAULT SYSTEM TAXONOMY_INSTANCE is assumed * The provided locale is required in order to render the appropriate localized label for the returned topic * If more than one topics are found with the same system name a warning is generated and the first one is returned * @param topicName * @param locale * @param cacheable * * @return */ public Topic findTopicByTopicName(String topicName, String locale, boolean cacheable) { if (StringUtils.isBlank(topicName)) { logger.warn("The provided topic name is blank. A NULL topic will be returned"); return null; } if (StringUtils.isBlank(locale)) { logger.warn("The provided locale is blank. A NULL topic will be returned"); return null; } try { TopicCriteria topicCriteria = CmsCriteriaFactory.newTopicCriteria(); topicCriteria.addNameEqualsCriterion(topicName); if (cacheable){ topicCriteria.setCacheable(CacheRegion.TEN_MINUTES); } else{ topicCriteria.doNotCacheResults(); } //topicCriteria.getRenderProperties().renderValuesForLocale(locale); CmsOutcome<Topic> topicsFound = topicService.searchTopics(topicCriteria, ResourceRepresentationType.TOPIC_LIST); if (CollectionUtils.isNotEmpty(topicsFound.getResults())) { Topic firstTopic = topicsFound.getResults().get(0); // if more than one topics correspond to the same name then we choose the first one but we generate a warning if (topicsFound.getResults().size() > 1) logger.warn("More than one topics correspond to name: " + topicName + " The first from list will be returned. This is a BUG!! Topic Ids should be unique. Please fix it !!"); return firstTopic; } else { logger.info("The provided topic name "+topicName+" does not exist."); return null; } } catch (Exception e) { logger.error("There was an error while retreiving a topic through the topicName. The error was: ",e); return null; } } /** * Use this method instead of taxonomyService.getTopic(topicId) in * order to cache the query. * * @param topicId * @param locale * @param cacheable * @return */ public Topic findTopicByTopicId(String topicId, String locale, boolean cacheable) { if (StringUtils.isBlank(topicId)) { logger.warn("The provided topic id is blank. A NULL topic will be returned"); return null; } if (StringUtils.isBlank(locale)) { logger.warn("The provided locale is blank. A NULL topic will be returned"); return null; } try { TopicCriteria topicCriteria = CmsCriteriaFactory.newTopicCriteria(); topicCriteria.addIdEqualsCriterion(topicId); if (cacheable){ topicCriteria.setCacheable(CacheRegion.TEN_MINUTES); } else{ topicCriteria.doNotCacheResults(); } //topicCriteria.getRenderProperties().renderValuesForLocale(locale); CmsOutcome<Topic> topicsFound = topicService.searchTopics(topicCriteria, ResourceRepresentationType.TOPIC_LIST); if (CollectionUtils.isNotEmpty(topicsFound.getResults())) { Topic firstTopic = topicsFound.getResults().get(0); // if more than one topics correspond to the same id then we choose the first one but we generate a warning if (topicsFound.getResults().size() > 1) logger.warn("More than one topics correspond to id: " + topicId + " The first from list will be returned. This is a BUG!! Topic Ids should be unique. Please fix it !!"); return firstTopic; } else { logger.info("The provided topic id does not exist."); return null; } } catch (Exception e) { logger.error("There was an error while retreiving a topic through the topicName. The error was: ",e); return null; } } /** * Find child topics of a topic if we know the topic name (i.e system name). * The topics are returned ordered according to their order ranking (it should have been specified inside each returned topic) if orderByPosition is true * Otherwise topics are order by their localized label for the provided locale. * if cacheable is true the queries performed are cached * * @param parentTopicName * @param locale * @param cacheable * @param orderByPosition * @return */ public List<Topic> findChildTopicsByParentTopicName(String parentTopicName, String locale, boolean cacheable, boolean orderByPosition) { if (StringUtils.isBlank(parentTopicName)) { return null; } List<Topic> childTopics = null; try { TopicCriteria topicCriteria = CmsCriteriaFactory.newTopicCriteria(); TopicCriteria parentCriteria = CmsCriteriaFactory.newTopicCriteria(); parentCriteria.addNameEqualsCriterion(parentTopicName); topicCriteria.setAncestorCriteria(parentCriteria); //topicCriteria.getRenderProperties().renderValuesForLocale(locale); topicCriteria.searchInDirectAncestorOnly(); if (cacheable){ topicCriteria.setCacheable(CacheRegion.TEN_MINUTES); } else{ topicCriteria.doNotCacheResults(); } if (!orderByPosition) { topicCriteria.addOrderByLocale(locale, Order.ascending); } CmsOutcome<Topic> outcome = topicService.searchTopics(topicCriteria, ResourceRepresentationType.TOPIC_LIST); childTopics = outcome.getResults(); if (CollectionUtils.isNotEmpty(childTopics) && orderByPosition) { Collections.sort(childTopics, new TopicComparator(locale, OrderByProperty.POSITION)); } return childTopics; } catch (Exception e) { logger.error("",e); return null; } } /** * Find child topics of a topic if we know the topic name (i.e system name) * The topics are returned ordered according to their order ranking (it should have been specified inside each returned topic) if orderByPosition is true * Otherwise topics are order by their localized label for the provided locale. * if cacheable is true the queries performed are cached * * @param parentTopicId * @param locale * @param cacheable * @param orderByPosition * @return */ public List<Topic> findChildTopicsByParentTopicId(String parentTopicId, String locale, boolean cacheable, boolean orderByPosition) { if (StringUtils.isBlank(parentTopicId)) { return null; } List<Topic> childTopics = null; try { TopicCriteria topicCriteria = CmsCriteriaFactory.newTopicCriteria(); topicCriteria.addAncestorTopicIdEqualsCriterion(parentTopicId); topicCriteria.searchInDirectAncestorOnly(); if (cacheable){ topicCriteria.setCacheable(CacheRegion.TEN_MINUTES); } else{ topicCriteria.doNotCacheResults(); } //topicCriteria.getRenderProperties().renderValuesForLocale(locale); if (!orderByPosition) { topicCriteria.addOrderByLocale(locale, Order.ascending); } CmsOutcome<Topic> outcome = topicService.searchTopics(topicCriteria, ResourceRepresentationType.TOPIC_LIST); childTopics = outcome.getResults(); if (CollectionUtils.isNotEmpty(childTopics) && orderByPosition) { Collections.sort(childTopics, new TopicComparator(locale, OrderByProperty.POSITION)); } return childTopics; } catch (Exception e) { e.printStackTrace(); return null; } } /** * * @param topicLabel * @param locale * @return * @throws CmsException * @throws DublicateRepositoryUserExternalIdException */ public List<Topic> findTopicsByLabel(String topicLabel, String locale) throws CmsException, DublicateRepositoryUserExternalIdException { try { TopicCriteria topicCriteria = CmsCriteriaFactory.newTopicCriteria(); LocalizationCriterion localizationCriterion = CriterionFactory.newLocalizationCriterion(); // we ignore locale to search through all localized labels // localizationCriterion.setLocale(locale); localizationCriterion.addLocalizedLabel(topicLabel + "*"); localizationCriterion.setQueryOperator(QueryOperator.CONTAINS); topicCriteria.addCriterion(localizationCriterion); // topicCriteria.getRenderProperties().renderValuesForLocale(locale); topicCriteria.setOffsetAndLimit(0, 30); //topicCriteria.getResultRowRange().setRange(0, 30); CmsOutcome<Topic> cmsOutcome = topicService.searchTopics(topicCriteria, ResourceRepresentationType.TOPIC_LIST); return cmsOutcome.getResults(); } catch (Exception e) { logger.error("There was an error while retreiving topics through the topic label. The error was: ",e); return null; } } public List<Topic> findOthersTags(RepositoryUser loggegInRepositoryUser, String locale) throws CmsException { // we set criteria to retrieve all user tags and we will exclude from // them the current user tags TopicCriteria topicCriteria = CmsCriteriaFactory.newTopicCriteria(); topicCriteria.addTaxonomyNameEqualsCriterion(Taxonomy.REPOSITORY_USER_FOLKSONOMY_NAME); //topicCriteria.getRenderProperties().renderValuesForLocale(locale); CmsOutcome<Topic> cmsOutcome = topicService.searchTopics(topicCriteria, ResourceRepresentationType.TOPIC_LIST); List<Topic> allTags = cmsOutcome.getResults(); List<Topic> currentUserTags = new ArrayList<Topic>(); if (allTags != null && (!allTags.isEmpty())) { // lets keep only the tags that are not owned by the current user for (Topic userTag : allTags) { if (userTag.getOwner().getId().equals(loggegInRepositoryUser.getId())) currentUserTags.add(userTag); } if (!currentUserTags.isEmpty()) allTags.removeAll(currentUserTags); } return allTags; } public List<Topic> findMostPopularTags() throws Exception { try{ return topicService.getMostlyUsedTopics(Taxonomy.REPOSITORY_USER_FOLKSONOMY_NAME, 0,100).getResults(); } catch (Exception e) { throw e; } } public Topic createNewUserTag(String userTagLabel, String locale, RepositoryUser userTagOwner) { if (StringUtils.isNotBlank(userTagLabel)) { Topic userTag = CmsRepositoryEntityFactoryForActiveClient.INSTANCE.getFactory().newTopic(); userTag.setAllowsReferrerContentObjects(true); userTag.setTaxonomy(userTagOwner.getFolksonomy()); userTag.addLocalizedLabel(locale, userTagLabel); userTag.setOwner(userTagOwner); return userTag; } else { logger.warn("An empty label has been provided. User Tag cannot be created with an empty label. A null topic will be returned!!"); return null; } } public Topic findTopicInTopicListByTopicId(List<Topic> topicList, String topicId) { if (topicList != null) for (Topic topic : topicList) { if (topic.getId().equals(topicId)) return topic; } return null; } public Topic findTopicInTopicListByLocalizedTopicLabel(List<Topic> topicList, String localizedName) { if (topicList != null && localizedName != null) { for (Topic topic : topicList) { if (localizedName.equals(topic.getAvailableLocalizedLabel(JSFUtilities.getLocaleAsString()))) return topic; } } return null; } public ContentObjectUIWrapper findContentObjectUIWrapperInContentObjectUIWrapperListByContentObjectId(List<ContentObjectUIWrapper> contentObjectUIWrapperList, String contentObjectId) { for (ContentObjectUIWrapper contentObjectUIWrapper : contentObjectUIWrapperList) { if (contentObjectUIWrapper.getContentObject().getId().equals(contentObjectId)) return contentObjectUIWrapper; } return null; } public List<RepositoryUser> findRepositoryUsersByExternalIdOrLabelId(String externalIdOrLabel, String locale) throws CmsException, DublicateRepositoryUserExternalIdException{ if (StringUtils.isBlank(externalIdOrLabel)){ return new ArrayList<RepositoryUser>(); } RepositoryUserCriteria repositoryUserCriteria = CmsCriteriaFactory.newRepositoryUserCriteria(); Criterion externalIdCriterion = CriterionFactory.contains(CmsBuiltInItem.ExternalId.getJcrName(), CmsConstants.ANY_NAME + externalIdOrLabel + CmsConstants.ANY_NAME); Criterion labelCriterion = CriterionFactory.contains(CmsBuiltInItem.Label.getJcrName(), CmsConstants.ANY_NAME + externalIdOrLabel + CmsConstants.ANY_NAME); repositoryUserCriteria.addCriterion(CriterionFactory.or(externalIdCriterion, labelCriterion)); repositoryUserCriteria.addOrderByLabel(Order.ascending); repositoryUserCriteria.setOffsetAndLimit(0, 30); repositoryUserCriteria.doNotCacheResults(); //if (locale != null) // repositoryUserCriteria.getRenderProperties().renderValuesForLocale(locale); return repositoryUserService.searchRepositoryUsers(repositoryUserCriteria); } public RepositoryUser findRepositoryUserByUserId(String userId, String locale) throws CmsException, DublicateRepositoryUserExternalIdException{ RepositoryUserCriteria repositoryUserCriteria = CmsCriteriaFactory.newRepositoryUserCriteria(); List<RepositoryUser> resultRepositoryUsers; repositoryUserCriteria.addExternalIdEqualsCriterion(userId); //if (locale != null) // repositoryUserCriteria.getRenderProperties().renderValuesForLocale(locale); resultRepositoryUsers = repositoryUserService.searchRepositoryUsers(repositoryUserCriteria); if (resultRepositoryUsers != null && resultRepositoryUsers.size() == 1) return resultRepositoryUsers.get(0); else if (resultRepositoryUsers != null && resultRepositoryUsers.size() > 1) { // OOPS!! we found more than one user with the same id. Some problem with the repository exists throw new DublicateRepositoryUserExternalIdException(userId); } else return null; } public RepositoryUser findLoggedInRepositoryUser(String locale) throws CmsException, DublicateRepositoryUserExternalIdException, NonExistentUserIdException { String userId = Identity.instance().getPrincipal() != null? Identity.instance().getPrincipal().getName() : null; if (StringUtils.isNotEmpty(userId)) { return findRepositoryUserByUserId(userId, locale); } throw new NonExistentUserIdException(); } public String getLocalizedNameOfContentObjectProperty(LocalizableCmsDefinition propertyDefinition, String locale) { final String localizedNameForLocale = propertyDefinition.getDisplayName().getLocalizedLabelForLocale(locale); if (localizedNameForLocale == null) return propertyDefinition.getName() + " (no localized label found for locale: " + locale + ")"; else return localizedNameForLocale; } public String getLocalizedNameOfContentObjectType(ContentObjectTypeDefinition contentObjectTypeDefinition, String locale) { return getLocalizedNameOfContentObjectProperty(contentObjectTypeDefinition, locale); } public void setTopicService(TopicService topicService) { this.topicService = topicService; } public void setRepositoryUserService(RepositoryUserService repositoryUserService) { this.repositoryUserService = repositoryUserService; } }