/** * Copyright 2014 National University of Ireland, Galway. * * This file is part of the SIREn project. Project and contact information: * * https://github.com/rdelbru/SIREn * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.sindice.siren.qparser.keyword.builders; import java.util.List; import org.apache.lucene.queryparser.flexible.core.QueryNodeException; import org.apache.lucene.queryparser.flexible.core.builders.QueryTreeBuilder; import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages; import org.apache.lucene.queryparser.flexible.core.nodes.ModifierQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode; import org.apache.lucene.queryparser.flexible.messages.MessageImpl; import org.apache.lucene.queryparser.flexible.standard.builders.StandardQueryBuilder; import org.apache.lucene.search.Query; import org.sindice.siren.qparser.keyword.nodes.ArrayQueryNode; import org.sindice.siren.qparser.keyword.nodes.TwigQueryNode; import org.sindice.siren.qparser.keyword.nodes.WildcardNodeQueryNode; import org.sindice.siren.search.node.NodeBooleanClause; import org.sindice.siren.search.node.NodeBooleanClause.Occur; import org.sindice.siren.search.node.NodeQuery; import org.sindice.siren.search.node.TwigQuery; /** * Builds a {@link TwigQuery} from a {@link TwigQueryNode}. Both the root * and the child must be already tagged using a * {@link QueryTreeBuilder#QUERY_TREE_BUILDER_TAGID} with a {@link Query} object. * * <p> * * It takes in consideration if a value is a {@link ModifierQueryNode} to * define its {@link NodeBooleanClause}. */ public class TwigQueryNodeBuilder implements StandardQueryBuilder { public TwigQueryNodeBuilder() {} @Override public Query build(final QueryNode queryNode) throws QueryNodeException { final TwigQueryNode tqn = (TwigQueryNode) queryNode; final QueryNode root = tqn.getRoot(); final QueryNode child = tqn.getChild(); final TwigQuery twigQuery; final int rootLevel = tqn.getRootLevel(); if (root == null && child == null) { throw new QueryNodeException(new MessageImpl(QueryParserMessages.EMPTY_MESSAGE)); } if (tqn.getChildren().size() != 2) { throw new IllegalArgumentException("A TwigQueryNode cannot have more " + "than 2 children:\n" + tqn.getChildren().toString()); } if (child instanceof WildcardNodeQueryNode && root instanceof WildcardNodeQueryNode) { throw new QueryNodeException(new MessageImpl("Twig with both root and " + "child empty is not allowed.")); } // Build the root operand if (root instanceof WildcardNodeQueryNode) { // Empty root query twigQuery = new TwigQuery(rootLevel); } else { final Object attQuery = root.getTag(QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID); if (attQuery != null) { twigQuery = new TwigQuery(rootLevel); twigQuery.addRoot((NodeQuery) attQuery); } else { throw new QueryNodeException(new MessageImpl(QueryParserMessages.INVALID_SYNTAX, "Unable to get the root of the Twig query")); } } if (!(child instanceof WildcardNodeQueryNode)) { // Build the child operand final Object v = child.getTag(QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID); if (v instanceof ArrayQuery) { // array of children nodes final ArrayQueryNode aqn = (ArrayQueryNode) child; final List<Query> children = ((ArrayQuery) v).getElements(); for (int i = 0; i < children.size(); i++) { twigQuery.addChild((NodeQuery) children.get(i), NodeQueryBuilderUtil.getModifierValue(aqn.getChildren().get(i), NodeBooleanClause.Occur.MUST)); } } else if (v instanceof Query) { final NodeQuery valQuery = (NodeQuery) v; twigQuery.addChild(valQuery, Occur.MUST); } else { throw new QueryNodeException(new MessageImpl(QueryParserMessages.INVALID_SYNTAX, "Unexpected class of a Twig Query clause: " + v == null ? "null" : v.getClass().getName())); } } return twigQuery; } }