info.magnolia.cms.util.QueryUtil.java Source code

Java tutorial

Introduction

Here is the source code for info.magnolia.cms.util.QueryUtil.java

Source

/**
 * This file Copyright (c) 2003-2012 Magnolia International
 * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
 *
 *
 * This file is dual-licensed under both the Magnolia
 * Network Agreement and the GNU General Public License.
 * You may elect to use one or the other of these licenses.
 *
 * This file is distributed in the hope that it will be
 * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
 * Redistribution, except as permitted by whichever of the GPL
 * or MNA you select, is prohibited.
 *
 * 1. For the GPL license (GPL), you can redistribute and/or
 * modify this file under the terms of the GNU General
 * Public License, Version 3, as published by the Free Software
 * Foundation.  You should have received a copy of the GNU
 * General Public License, Version 3 along with this program;
 * if not, write to the Free Software Foundation, Inc., 51
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * 2. For the Magnolia Network Agreement (MNA), this file
 * and the accompanying materials are made available under the
 * terms of the MNA which accompanies this distribution, and
 * is available at http://www.magnolia-cms.com/mna.html
 *
 * Any modifications to this file must keep this entire header
 * intact.
 *
 */
package info.magnolia.cms.util;

import info.magnolia.cms.core.Content;
import info.magnolia.cms.core.ItemType;
import info.magnolia.context.MgnlContext;
import info.magnolia.jcr.util.NodeUtil;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.LoginException;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.qom.QueryObjectModel;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * Util to execute queries as simple as possible.
 * @version $Id$
 *
 */
public class QueryUtil {

    private static Logger log = LoggerFactory.getLogger(QueryUtil.class);

    /**
     * Executes a query.
     * @deprecated Since 4.5.4 use search methods.
     */
    public static Collection<Content> query(String repository, String statement) {
        return query(repository, statement, "sql");
    }

    /**
     * Executes a query.
     * @deprecated Since 4.5.4 use search methods.
     */
    public static Collection<Content> query(String repository, String statement, String language) {
        return query(repository, statement, language, ItemType.NT_BASE);
    }

    /**
    * @deprecated Since 4.5.4 use search methods.
    */
    public static Collection<Content> exceptionThrowingQuery(String repository, String statement, String language,
            String returnItemType) throws RepositoryException {
        return exceptionThrowingQuery(repository, statement, language, returnItemType, Long.MAX_VALUE);
    }

    /**
     * Executes a query, throwing any exceptions that arise as a result.
     * @deprecated Since 4.5.4 use search methods.
     */
    public static Collection<Content> exceptionThrowingQuery(String repository, String statement, String language,
            String returnItemType, long maxResultSize) throws RepositoryException {
        Collection<Content> results = new ArrayList<Content>();
        if (maxResultSize <= 0) {
            maxResultSize = Long.MAX_VALUE;
        }
        NodeIterator iterator = search(repository, statement, language, returnItemType);

        long count = 1;
        while (iterator.hasNext() && count <= maxResultSize) {
            results.add(ContentUtil.getContent(repository, iterator.nextNode().getPath()));
            count++;
        }
        return results;
    }

    /**
     * @deprecated Since 4.5.4 use search methods.
     */
    public static Collection<Content> query(String repository, String statement, String language,
            String returnItemType) {
        return query(repository, statement, language, returnItemType, Long.MAX_VALUE);
    }

    /**
     * Executes a query - if an exception is thrown, it is logged and an empty collection is
     * returned.
     * @deprecated Since 4.5.4 use search methods.
     */
    @SuppressWarnings("unchecked")
    //Collections.EMPTY_LIST;
    public static Collection<Content> query(String repository, String statement, String language,
            String returnItemType, long maxResultSize) {
        try {
            return exceptionThrowingQuery(repository, statement, language, returnItemType, maxResultSize);
        } catch (Exception e) {
            log.error("can't execute query [" + statement + "], will return empty collection", e);
        }
        return Collections.EMPTY_LIST;
    }

    /**
     * @param month 1-12 (as opposed to java.util.Calendar 0-11 notation)
     * @deprecated
     */
    public static String createDateExpression(int year, int month, int day) {
        Calendar cal = Calendar.getInstance();
        cal.set(year, month - 1, day);
        return createDateExpression(cal);
    }

    /**
     * Expression representing a date.
     * @deprecated since 4.5.4 use info.magnolia.cms.util.DateUtil.createDateExpression(calendar)
     */
    public static String createDateExpression(Calendar calendar) {
        return DateUtil.createDateExpression(calendar);
    }

    /**
     * @param month 1-12 (as opposed to java.util.Calendar 0-11 notation)
     * @deprecated
     */
    public static String createDateTimeExpression(int year, int month, int day, int hour, int minutes,
            int seconds) {
        Calendar cal = Calendar.getInstance();
        cal.set(year, month - 1, day, hour, minutes, seconds);
        return createDateTimeExpression(cal);
    }

    /**
     * Expression representing a date and time.
     * @deprecated since 4.5.4 use info.magnolia.cms.util.DateUtil.createDateTimeExpression(calendar)
     */
    public static String createDateTimeExpression(Calendar calendar) {
        return DateUtil.createDateTimeExpression(calendar);
    }

    /**
     * @param month 1-12 (as opposed to java.util.Calendar 0-11 notation)
     * @deprecated
     */
    public static String createDateTimeExpressionIgnoreTimeZone(int year, int month, int day, int hour, int minutes,
            int seconds) {
        Calendar cal = Calendar.getInstance(DateUtils.UTC_TIME_ZONE);
        cal.set(year, month - 1, day, hour, minutes, seconds);
        return createDateTimeExpression(cal);
    }

    /**
     * Do not consider the timezone.
     * @deprecated since 4.5.4 use info.magnolia.cms.util.DateUtil.createDateTimeExpressionIgnoreTimeZone(calendar)
     */
    public static String createDateTimeExpressionIgnoreTimeZone(Calendar calendar) {
        return DateUtil.createDateTimeExpressionIgnoreTimeZone(calendar);
    }

    /**
     * Executes the query based on QOM and then pops-up in the node hierarchy until returnItemType is found. If the result
     * is not returnItemType or none of its parents are then next node in result is checked.
     * Duplicate nodes are removed from result.
     * For date/time expressions use <code>DateUtil.create*Expression()</code> methods.
     * @param model
     * @param returnItemType
     * @return Result as NodeIterator
     * @throws InvalidQueryException
     * @throws RepositoryException
     */
    public static NodeIterator search(QueryObjectModel model, String returnItemType)
            throws InvalidQueryException, RepositoryException {
        return NodeUtil.filterDuplicates(NodeUtil.filterParentNodeType(model.execute().getNodes(), returnItemType));
    }

    /**
     * Executes the query with given language.Unlike in the old API item type has to be specified in query itself.
     * <code>SELECT * FROM [mgnl:page]</code> example for selecting just pages in JCR SQL2 language.
     * Duplicate nodes are removed from result.
     * For date/time expressions use <code>DateUtil.create*Expression()</code> methods.
     * @param workspace
     * @param statement
     * @param language
     * @return Result as NodeIterator
     * @throws InvalidQueryException
     * @throws RepositoryException
     */
    public static NodeIterator search(String workspace, String statement, String language)
            throws InvalidQueryException, RepositoryException {
        Session session = MgnlContext.getJCRSession(workspace);
        QueryManager manager = session.getWorkspace().getQueryManager();
        Query query = manager.createQuery(statement, language);

        return NodeUtil.filterDuplicates(query.execute().getNodes());
    }

    /**
     * Executes the query using JCR SQL2 language. Unlike in the old API item type has to be specified in query itself.
     * <code>SELECT * FROM [mgnl:page]</code> example for selecting just pages.
     * For executing old query use info.magnolia.cms.util.QueryUtil.search(String workspace, String statement, String language)
     * where you specify <code>Query.SQL</code> as the language.
     * For date/time expressions use <code>DateUtil.create*Expression()</code> methods.
     * @param workspace
     * @param statement
     * @return Result as NodeIterator
     * @throws InvalidQueryException
     * @throws RepositoryException
     */
    public static NodeIterator search(String workspace, String statement)
            throws InvalidQueryException, RepositoryException {
        return search(workspace, statement, javax.jcr.query.Query.JCR_SQL2);
    }

    /**
     * Searches for statement and then pops-up in the node hierarchy until returnItemType is found. If the result
     * is not returnItemType or none of its parents are then next node in result is checked. Duplicate nodes are
     * removed from result.
     * For date/time expressions use <code>DateUtil.create*Expression()</code> methods.
     * @param workspace
     * @param statement
     * @param language
     * @param returnItemType
     * @return query result as collection of nodes
     * @throws LoginException
     * @throws RepositoryException
     */
    public static NodeIterator search(String workspace, String statement, String language, String returnItemType)
            throws LoginException, RepositoryException {
        NodeIterator resultIterator = search(workspace, statement, language);

        return NodeUtil.filterDuplicates(NodeUtil.filterParentNodeType(resultIterator, returnItemType));
    }

    /**
     * Creates a simple SQL2 query statement.
     * 
     * @param statement
     * @param startPath
     */
    public static String buildQuery(String statement, String startPath) {
        Set<String> arguments = new HashSet<String>(
                Arrays.asList(StringUtils.splitByWholeSeparator(statement, ",")));

        Iterator<String> argIt = arguments.iterator();
        String queryString = "select * from [nt:base] as t where ISDESCENDANTNODE([" + startPath + "])";
        while (argIt.hasNext()) {
            queryString = queryString + " AND contains(t.*, '" + argIt.next() + "')";
        }
        log.debug("query string: " + queryString);
        return queryString;
    }
}