org.betaconceptframework.astroboa.model.impl.query.criteria.TopicReferenceCriterionImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.betaconceptframework.astroboa.model.impl.query.criteria.TopicReferenceCriterionImpl.java

Source

/*
 * 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.model.impl.query.criteria;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
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.exception.CmsException;
import org.betaconceptframework.astroboa.api.model.query.CacheRegion;
import org.betaconceptframework.astroboa.api.model.query.Condition;
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.SimpleCriterion;
import org.betaconceptframework.astroboa.api.model.query.criteria.TopicReferenceCriterion;
import org.betaconceptframework.astroboa.context.AstroboaClientContextHolder;
import org.betaconceptframework.astroboa.model.factory.CriterionFactory;
import org.betaconceptframework.astroboa.model.lazy.LazyLoader;
import org.betaconceptframework.astroboa.util.CmsConstants;
import org.slf4j.LoggerFactory;

/**
 * @author Gregory Chomatas (gchomatas@betaconcept.com)
 * @author Savvas Triantafyllou (striantafyllou@betaconcept.com)
 * 
 */
public class TopicReferenceCriterionImpl extends SimpleCriterionImpl
        implements TopicReferenceCriterion, Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 6034509558499684454L;

    private boolean includeSubTopics;

    public TopicReferenceCriterionImpl() {
        //InternalCondition must be nullified
        setInternalCondition(null);
    }

    @Override
    public void propertyIsComplex() {
        //Properties of these type are never complex
        //Do nothing
    }

    @Override
    public void setCaseMatching(CaseMatching caseMatching) {
        //Case matching does not play any role in this context
    }

    @Override
    public void setOperator(QueryOperator operator) {
        //Only QueryOperator.EQUALS and QueryOperator.NOT_EQUALS are allowed
        if (operator != null && QueryOperator.EQUALS != operator && QueryOperator.NOT_EQUALS != operator
                && QueryOperator.IS_NULL != operator && QueryOperator.IS_NOT_NULL != operator) {
            throw new CmsException("Invalid query operator " + operator + " for topic reference criterion");
        }

        super.setOperator(operator);
    }

    @Override
    public void addTopicAsAValue(Topic topicReference) {
        if (topicReference != null) {
            if (StringUtils.isNotBlank(topicReference.getId())) {
                addValue(topicReference.getId());
            } else if (StringUtils.isNotBlank(topicReference.getName())) {
                addValue(CmsConstants.TOPIC_REFERENCE_CRITERION_VALUE_PREFIX + topicReference.getName());
            } else {
                LoggerFactory.getLogger(getClass()).warn(
                        "Topic {} has neither an identifier nor a name and therefore cannot be used as a criterion value ",
                        topicReference.toString());
            }
        } else {
            LoggerFactory.getLogger(getClass())
                    .warn("Topic is null and therefore cannot be used as a criterion value ");
        }

    }

    @Override
    public void addTopicsAsValues(List<Topic> topicReferences) {

        if (CollectionUtils.isNotEmpty(topicReferences)) {
            for (Topic topicReference : topicReferences) {
                addTopicAsAValue(topicReference);
            }
        }

    }

    @Override
    public String getXPath() {

        LazyLoader lazyLoaderForActiveClient = AstroboaClientContextHolder.getLazyLoaderForActiveClient();

        String activeAuthenticationToken = AstroboaClientContextHolder.getActiveAuthenticationToken();

        Map<String, List<String>> topicPropertyPathsPerTaxonomies = null;

        if (lazyLoaderForActiveClient != null) {
            topicPropertyPathsPerTaxonomies = lazyLoaderForActiveClient
                    .getTopicPropertyPathsPerTaxonomies(activeAuthenticationToken);
        }

        Condition internalCondition = getInternalCondition();

        if (internalCondition == null) {
            internalCondition = Condition.OR;
        }

        Criterion criterion = null;

        if (CollectionUtils.isEmpty(getValues())) {
            Set<String> possiblePropertyPaths = loadTopicPropertyPaths(null, topicPropertyPathsPerTaxonomies);

            for (String topicPropertyPath : possiblePropertyPaths) {
                criterion = createCriterionForProperty(internalCondition, topicPropertyPath, criterion, null);
            }

        } else {
            for (Object value : getValues()) {

                List parentAndChildIds = new ArrayList();

                String taxonomyName = null;

                String topicId = checkIfValueIsAReferenceAndLoadReferenceId((String) value);

                if (topicId != null) {
                    parentAndChildIds.add(topicId);

                    if (lazyLoaderForActiveClient != null) {

                        if (includeSubTopics) {
                            lazyLoaderForActiveClient.loadChildTopicIdsForSpecifiedProfileSubjectIds(
                                    parentAndChildIds, activeAuthenticationToken, CacheRegion.NONE);
                        }

                        try {
                            Taxonomy taxonomy = lazyLoaderForActiveClient.lazyLoadTaxonomyForTopic(topicId,
                                    activeAuthenticationToken);

                            if (taxonomy != null) {
                                taxonomyName = taxonomy.getName();
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }

                Set<String> possiblePropertyPaths = loadTopicPropertyPaths(taxonomyName,
                        topicPropertyPathsPerTaxonomies);

                for (String topicPropertyPath : possiblePropertyPaths) {
                    criterion = createCriterionForProperty(internalCondition, topicPropertyPath, criterion,
                            parentAndChildIds);
                }

            }

        }

        if (criterion == null) {
            return "";
        } else {
            return criterion.getXPath();
        }
    }

    private Criterion createCriterionForProperty(Condition internalCondition, String topicPropertyPath,
            Criterion topicCriterion, List parentAndChildIds) {

        Criterion parentAndChildCriterion = createSimpleCriterionForItem(getOperator(), parentAndChildIds,
                Condition.OR, topicPropertyPath);

        if (topicCriterion == null) {
            topicCriterion = parentAndChildCriterion;
        } else {
            switch (internalCondition) {
            case AND:
                topicCriterion = CriterionFactory.and(topicCriterion, parentAndChildCriterion);
                break;
            case OR:
                topicCriterion = CriterionFactory.or(topicCriterion, parentAndChildCriterion);
                break;
            default:
                break;
            }
        }
        return topicCriterion;
    }

    private Set<String> loadTopicPropertyPaths(String taxonomyName,
            Map<String, List<String>> topicPropertyPathsPerTaxonomies) {

        Set<String> possiblePropertyPaths = new HashSet<String>();

        if (getProperty() != null) {
            possiblePropertyPaths.add(getProperty());
        } else {

            if (MapUtils.isNotEmpty(topicPropertyPathsPerTaxonomies)) {

                //Build one criterion for each topic property that belongs to the specified taxonomy
                //If no taxonomy is provided, all topic properties will be included
                if (StringUtils.isBlank(taxonomyName)) {
                    for (List<String> topicProperyPaths : topicPropertyPathsPerTaxonomies.values()) {
                        if (CollectionUtils.isNotEmpty(topicProperyPaths)) {
                            for (String topicPropertyPath : topicProperyPaths) {
                                possiblePropertyPaths.add(topicPropertyPath);
                            }
                        }
                    }
                } else {
                    //Get all topicProperties for provided taxonomy
                    List<String> topicPropertyPathsForTaxonomy = topicPropertyPathsPerTaxonomies.get(taxonomyName);
                    if (CollectionUtils.isNotEmpty(topicPropertyPathsForTaxonomy)) {
                        for (String topicPropertyPath : topicPropertyPathsForTaxonomy) {
                            possiblePropertyPaths.add(topicPropertyPath);
                        }
                    }

                    //Finally add all topic properties that are not connected to any taxonomy
                    List<String> topicPropertyPathsWithoutTaxonomy = topicPropertyPathsPerTaxonomies
                            .get(CmsConstants.ANY_TAXONOMY);
                    if (CollectionUtils.isNotEmpty(topicPropertyPathsWithoutTaxonomy)) {
                        for (String topicPropertyPath : topicPropertyPathsWithoutTaxonomy) {
                            possiblePropertyPaths.add(topicPropertyPath);
                        }
                    }
                }
            }
        }

        return possiblePropertyPaths;
    }

    private SimpleCriterion createSimpleCriterionForItem(QueryOperator queryOperator, List values,
            Condition internalCondition, String property) {
        SimpleCriterion criterion = CriterionFactory.newSimpleCriterion();
        criterion.setValues(values);
        criterion.setInternalCondition(internalCondition);
        criterion.setProperty(property);
        criterion.setOperator(queryOperator);

        return criterion;
    }

    @Override
    public void expandCriterionToIncludeSubTopics() {
        includeSubTopics = true;
    }

    @Override
    public void addValue(Object value) {

        if (value != null) {
            if (value instanceof Topic) {
                addTopicAsAValue((Topic) value);
            } else {
                if (value instanceof String
                        && ((String) value).endsWith(CmsConstants.INCLUDE_CHILDREN_EXPRESSION)) {
                    expandCriterionToIncludeSubTopics();
                    super.addValue(StringUtils.substringBeforeLast((String) value,
                            CmsConstants.INCLUDE_CHILDREN_EXPRESSION));
                } else {
                    super.addValue(value);
                }
            }
        }
    }

    @Override
    public void setValues(List<Object> values) {
        if (values != null) {
            for (Object value : values) {
                addValue(value);
            }
        }
    }

}