Package org.apache.jackrabbit.core.query.lucene.join

Source Code of org.apache.jackrabbit.core.query.lucene.join.JahiaQueryEngine

/**
* This file is part of Jahia, next-generation open source CMS:
* Jahia's next-generation, open source CMS stems from a widely acknowledged vision
* of enterprise application convergence - web, search, document, social and portal -
* unified by the simplicity of web content management.
*
* For more information, please visit http://www.jahia.com.
*
* Copyright (C) 2002-2011 Jahia Solutions Group SA. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* As a special exception to the terms and conditions of version 2.0 of
* the GPL (or any later version), you may redistribute this Program in connection
* with Free/Libre and Open Source Software ("FLOSS") applications as described
* in Jahia's FLOSS exception. You should have received a copy of the text
* describing the FLOSS exception, and it is also available here:
* http://www.jahia.com/license
*
* Commercial and Supported Versions of the program (dual licensing):
* alternatively, commercial and supported versions of the program may be used
* in accordance with the terms and conditions contained in a separate
* written agreement between you and Jahia Solutions Group SA.
*
* If you are unsure which license is appropriate for your use,
* please contact the sales department at sales@jahia.com.
*/

package org.apache.jackrabbit.core.query.lucene.join;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.nodetype.NodeType;
import javax.jcr.query.QueryResult;
import javax.jcr.query.Row;
import javax.jcr.query.RowIterator;
import javax.jcr.query.qom.And;
import javax.jcr.query.qom.Column;
import javax.jcr.query.qom.Comparison;
import javax.jcr.query.qom.Constraint;
import javax.jcr.query.qom.DynamicOperand;
import javax.jcr.query.qom.EquiJoinCondition;
import javax.jcr.query.qom.Join;
import javax.jcr.query.qom.LowerCase;
import javax.jcr.query.qom.Not;
import javax.jcr.query.qom.Or;
import javax.jcr.query.qom.Ordering;
import javax.jcr.query.qom.PropertyValue;
import javax.jcr.query.qom.Selector;
import javax.jcr.query.qom.Source;
import javax.jcr.query.qom.UpperCase;

import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.jackrabbit.commons.iterator.RowIteratorAdapter;
import org.apache.jackrabbit.core.query.FacetedQueryResult;
import org.apache.jackrabbit.core.query.JahiaSimpleQueryResult;
import org.apache.jackrabbit.core.query.lucene.FacetRow;
import org.apache.jackrabbit.core.query.lucene.LuceneQueryFactory;
import org.jahia.api.Constants;
import org.jahia.services.content.nodetypes.NodeTypeRegistry;

/**
* Override QueryEngine :
*  - add facet handling in execute()
*/
public class JahiaQueryEngine extends QueryEngine {


    public JahiaQueryEngine(Session session, LuceneQueryFactory lqf, Map<String, Value> variables)
            throws RepositoryException {
        super(session, lqf, variables);
    }

    /**
     * Override QueryEngine.execute()
     */
    protected QueryResult execute(
            Column[] columns, Selector selector, Constraint constraint,
            Ordering[] orderings, long offset, long limit)
            throws RepositoryException {
        Map<String, NodeType> selectorMap = getSelectorNames(selector);
        String[] selectorNames =
            selectorMap.keySet().toArray(new String[selectorMap.size()]);

        Map<String, PropertyValue> columnMap =
            getColumnMap(columns, selectorMap);
        String[] columnNames =
            columnMap.keySet().toArray(new String[columnMap.size()]);

        try {
            final List<Row> rowsList = lqf.execute(columnMap, selector, constraint);
            // Added by jahia
            QueryResult result;
            if (rowsList.size() > 0 && rowsList.get(0) instanceof FacetRow) {
                FacetRow facets = (FacetRow) rowsList.remove(0);
                RowIterator rows = new RowIteratorAdapter(rowsList);
                result = new FacetedQueryResult(columnNames, selectorNames, rows, facets);
                QueryResult r = sort(result, orderings, offset, limit);
                if (r != result) {
                    result = new FacetedQueryResult(columnNames, selectorNames, r.getRows(), facets);
                }
            } else {
                RowIterator rows = new RowIteratorAdapter(rowsList);
                result = new JahiaSimpleQueryResult(columnNames, selectorNames, rows);
                QueryResult r = sort(result, orderings, offset, limit);
                if (r != result) {
                    result = new JahiaSimpleQueryResult(columnNames, selectorNames, r.getRows());
                }
            }
            return result;
            // End
        } catch (IOException e) {
            throw new RepositoryException(
                    "Failed to access the query index", e);
        }
    }

    @Override
    protected QueryResult execute(Column[] columns, Join join, Constraint constraint, Ordering[] orderings, long offset, long limit) throws RepositoryException {
        QueryResult result = isEquiJoinWithUuid(join, constraint) ? executeEquiJoin(
                columns, join, constraint, orderings, offset, limit) : super
                .execute(columns, join, constraint, orderings, offset, limit);
        if (!(result instanceof JahiaSimpleQueryResult)) {
            result = new JahiaSimpleQueryResult(result.getColumnNames(), result.getSelectorNames(),
                    result.getRows());
        }
        return result;
    }
   
    protected boolean isEquiJoinWithUuid(Join join, Constraint constraint) {
        boolean result = false;
        if (join.getJoinCondition() instanceof EquiJoinCondition) {
            EquiJoinCondition condition = (EquiJoinCondition)join.getJoinCondition();
            if (condition.getProperty2Name().equals(Constants.JCR_UUID)) {
                result = true;
            }
        }
        return result;
    }
   
    protected boolean hasLanguageConstraint(Constraint constraint) {
        boolean languageConstraint = false;
        if (constraint instanceof And) {
            And and = (And) constraint;
            languageConstraint = hasLanguageConstraint(and.getConstraint1());
            languageConstraint = languageConstraint || hasLanguageConstraint(and.getConstraint2());
        } else if (constraint instanceof Or) {
            Or or = (Or) constraint;
            languageConstraint = hasLanguageConstraint(or.getConstraint1());
            languageConstraint = languageConstraint || hasLanguageConstraint(or.getConstraint2());
        } else if (constraint instanceof Not) {
            Not not = (Not) constraint;
            languageConstraint = hasLanguageConstraint(not.getConstraint());
        } else if (constraint instanceof Comparison) {
            Comparison c = (Comparison) constraint;
            languageConstraint = hasLanguageConstraint(c.getOperand1());
        }
        return languageConstraint;
    }
   
    private boolean hasLanguageConstraint(DynamicOperand operand) {
        boolean languageConstraint = false;       
        if (operand instanceof LowerCase) {
            LowerCase lower = (LowerCase) operand;
            return hasLanguageConstraint(lower.getOperand());
        } else if (operand instanceof PropertyValue) {
            PropertyValue value = (PropertyValue) operand;
            return value.getPropertyName().equals(Constants.JCR_LANGUAGE);
        } else if (operand instanceof UpperCase) {
            UpperCase upper = (UpperCase) operand;
            return hasLanguageConstraint(upper.getOperand());
        }
        return languageConstraint;       
    }
   
    protected QueryResult executeEquiJoin(
            Column[] columns, Join join, Constraint constraint,
            Ordering[] orderings, long offset, long limit)
            throws RepositoryException {
        JahiaEquiJoinMerger merger = new JahiaEquiJoinMerger(
                join, getColumnMap(columns, getSelectorNames(join)), evaluator, qomFactory,
                (EquiJoinCondition) join.getJoinCondition());
        ConstraintSplitter splitter = new ConstraintSplitter(
                constraint, qomFactory,
                merger.getLeftSelectors(), merger.getRightSelectors());

        Source left = join.getLeft();
        Constraint leftConstraint = splitter.getLeftConstraint();
        QueryResult leftResult =
            execute(null, left, leftConstraint, null, 0, -1);
        List<Row> leftRows = new ArrayList<Row>();
        for (Row row : JcrUtils.getRows(leftResult)) {
            leftRows.add(row);
        }

        if (hasLanguageConstraint(splitter.getRightConstraint())) {
            merger.setIncludeTranslationNode(true);
        }
       
        RowIterator rightRows;
        Source right = join.getRight();
        List<Constraint> rightConstraints =
            merger.getRightJoinConstraints(leftRows);
        if (rightConstraints.size() < 500) {
            Constraint rightConstraint = Constraints.and(
                    qomFactory,
                    Constraints.or(qomFactory, rightConstraints),
                    splitter.getRightConstraint());
            rightRows =
                execute(null, right, rightConstraint, null, 0, -1).getRows();
        } else {
            List<Row> list = new ArrayList<Row>();
            for (int i = 0; i < rightConstraints.size(); i += 500) {
                Constraint rightConstraint = Constraints.and(
                        qomFactory,
                        Constraints.or(qomFactory, rightConstraints.subList(
                                i, Math.min(i + 500, rightConstraints.size()))),
                        splitter.getRightConstraint());
                QueryResult rigthResult =
                    execute(null, right, rightConstraint, null, 0, -1);
                for (Row row : JcrUtils.getRows(rigthResult)) {
                    list.add(row);
                }
            }
            rightRows = new RowIteratorAdapter(list);
        }

        QueryResult result =
            merger.merge(new RowIteratorAdapter(leftRows), rightRows);
        return sort(result, orderings, offset, limit);
    }

    @Override
    public QueryResult execute(Column[] columns, Source source, Constraint constraint, Ordering[] orderings, long offset, long limit) throws RepositoryException {
        QueryResult result = super.execute(columns, source, constraint, orderings, offset, limit);
        if (!(result instanceof JahiaSimpleQueryResult)) {
            result = new JahiaSimpleQueryResult(result.getColumnNames(), result.getSelectorNames(),
                    result.getRows());
        }
        return result;
    }

    @Override
    protected Map<String, PropertyValue> getColumnMap(String selector, NodeType type)
            throws RepositoryException {
        return super.getColumnMap(selector, NodeTypeRegistry.getInstance().getNodeType(type.getName()));
    }

    @Override
    protected Map<String, PropertyValue> getColumnMap(Column[] columns,
            Map<String, NodeType> selectors) throws RepositoryException {
        Map<String, PropertyValue> map =
            new LinkedHashMap<String, PropertyValue>();
        if (columns != null && columns.length > 0) {
            for (int i = 0; i < columns.length; i++) {
                String name = columns[i].getColumnName();
                if (name != null) {
                    map.put(name, qomFactory.propertyValue(
                            columns[i].getSelectorName(),
                            columns[i].getPropertyName()));
                } else if (!StringUtils.isEmpty(columns[i].getPropertyName())) {
                    map.put(columns[i].getSelectorName() + "." + columns[i].getPropertyName(),
                            qomFactory.propertyValue(columns[i].getSelectorName(),
                                    columns[i].getPropertyName()));                   
                } else {
                    String selector = columns[i].getSelectorName();
                    map.putAll(getColumnMap(selector, selectors.get(selector)));
                }
            }
        } else {
            for (Map.Entry<String, NodeType> selector : selectors.entrySet()) {
                map.putAll(getColumnMap(
                        selector.getKey(), selector.getValue()));
            }
        }
        return map;
    }
   

}
TOP

Related Classes of org.apache.jackrabbit.core.query.lucene.join.JahiaQueryEngine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.