Package org.sindice.siren.qparser.json.dsl

Source Code of org.sindice.siren.qparser.json.dsl.TwigQuery

/**
* 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.json.dsl;

import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
import org.apache.lucene.search.Query;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
import org.sindice.siren.qparser.json.dsl.QueryClause.Occur;
import org.sindice.siren.qparser.json.parser.BoostPropertyParser;
import org.sindice.siren.qparser.json.parser.ChildPropertyParser;
import org.sindice.siren.qparser.json.parser.DescendantPropertyParser;
import org.sindice.siren.qparser.json.parser.LevelPropertyParser;
import org.sindice.siren.qparser.json.parser.OccurPropertyParser;
import org.sindice.siren.qparser.json.parser.RangePropertyParser;
import org.sindice.siren.qparser.json.parser.RootPropertyParser;
import org.sindice.siren.qparser.json.parser.TwigPropertyParser;
import org.sindice.siren.qparser.keyword.KeywordQueryParser;
import org.sindice.siren.search.node.LuceneProxyNodeQuery;
import org.sindice.siren.search.node.NodeBooleanClause;
import org.sindice.siren.search.node.NodeQuery;

/**
* Class that represents a twig object of the JSON query syntax.
*/
public class TwigQuery extends AbstractNodeQuery {

  private boolean hasRoot = false;
  private String rootBooleanExpression;

  private final List<QueryClause> clauses;

  private final KeywordQueryParser parser;

  public TwigQuery(final ObjectMapper mapper, final KeywordQueryParser parser) {
    super(mapper);
    this.parser = parser;
    clauses = new ArrayList<QueryClause>();
  }

  @Override
  public TwigQuery setLevel(final int level) {
    return (TwigQuery) super.setLevel(level);
  }

  @Override
  public TwigQuery setRange(final int lowerBound, final int upperBound) {
    return (TwigQuery) super.setRange(lowerBound, upperBound);
  }

  @Override
  public TwigQuery setBoost(final float boost) {
    return (TwigQuery) super.setBoost(boost);
  }

  /**
   * Set the ndoe boolean query expression for the root of the twig.
   *
   * @see org.sindice.siren.search.node.TwigQuery#addRoot(NodeQuery)
   */
  void setRoot(final String booleanExpression) {
    this.rootBooleanExpression = booleanExpression;
    this.hasRoot = true;
  }

  /**
   * Adds a child clause with a
   * {@link NodeBooleanClause.Occur#MUST} operator.
   * <p>
   * Use this method for child clauses that must appear in the matching twigs.
   *
   * @see NodeBooleanClause.Occur#MUST
   * @see org.sindice.siren.search.node.TwigQuery#addChild(NodeQuery, NodeBooleanClause.Occur)
   */
  public TwigQuery with(final AbstractNodeQuery child) {
    clauses.add(new BasicQueryClause(child, Occur.MUST));
    return this;
  }

  /**
   * Adds a descendant clause with a
   * {@link NodeBooleanClause.Occur#MUST} operator.
   * <p>
   * Use this method for descendant clauses that must appear in the matching
   * twigs.
   *
   * @see NodeBooleanClause.Occur#MUST
   * @see org.sindice.siren.search.node.TwigQuery#addDescendant(int, NodeQuery, NodeBooleanClause.Occur)
   */
  public TwigQuery with(final AbstractNodeQuery descendant, final int level) {
    clauses.add(new DescendantQueryClause(descendant, Occur.MUST, level));
    return this;
  }

  /**
   * Adds a child clause with a
   * {@link NodeBooleanClause.Occur#MUST_NOT} operator.
   * <p>
   * Use this method for child clauses that must not appear in the matching
   * twigs.
   *
   * @see NodeBooleanClause.Occur#MUST_NOT
   * @see org.sindice.siren.search.node.TwigQuery#addChild(NodeQuery, NodeBooleanClause.Occur)
   */
  public TwigQuery without(final AbstractNodeQuery child) {
    clauses.add(new BasicQueryClause(child, Occur.MUST_NOT));
    return this;
  }

  /**
   * Adds a descendant clause with a
   * {@link NodeBooleanClause.Occur#MUST_NOT} operator.
   * <p>
   * Use this method for descendant clauses that must not appear in the matching
   * twigs.
   *
   * @see NodeBooleanClause.Occur#MUST_NOT
   * @see org.sindice.siren.search.node.TwigQuery#addDescendant(int, NodeQuery, NodeBooleanClause.Occur)
   */
  public TwigQuery without(final AbstractNodeQuery descendant, final int level) {
    clauses.add(new DescendantQueryClause(descendant, Occur.MUST_NOT, level));
    return this;
  }

  /**
   * Adds a child clause with a
   * {@link NodeBooleanClause.Occur#SHOULD} operator.
   * <p>
   * Use this method for child clauses that should appear in the matching
   * twigs.
   *
   * @see NodeBooleanClause.Occur#SHOULD
   * @see org.sindice.siren.search.node.TwigQuery#addChild(NodeQuery, NodeBooleanClause.Occur)
   */
  public TwigQuery optional(final AbstractNodeQuery child) {
    clauses.add(new BasicQueryClause(child, Occur.SHOULD));
    return this;
  }

  /**
   * Adds a descendant clause with a
   * {@link NodeBooleanClause.Occur#SHOULD} operator.
   * <p>
   * Use this method for descendant clauses that should appear in the matching
   * twigs.
   *
   * @see NodeBooleanClause.Occur#SHOULD
   * @see org.sindice.siren.search.node.TwigQuery#addDescendant(int, NodeQuery, NodeBooleanClause.Occur)
   */
  public TwigQuery optional(final AbstractNodeQuery descendant, final int level) {
    clauses.add(new DescendantQueryClause(descendant, Occur.SHOULD, level));
    return this;
  }

  @Override
  public Query toQuery(final boolean proxy) throws QueryNodeException {
    final org.sindice.siren.search.node.TwigQuery query = new org.sindice.siren.search.node.TwigQuery();
    // parse and add root
    if (hasRoot) {
      query.addRoot((NodeQuery) parser.parse(rootBooleanExpression, ""));
    }
    // convert child and descendant clauses
    for (final QueryClause clause : clauses) {
      if (clause instanceof BasicQueryClause) {
        query.addChild((NodeQuery) clause.getQuery().toQuery(false),clause.getNodeBooleanOccur());
      }
      else {
        final int level = ((DescendantQueryClause) clause).getLevel();
        query.addDescendant(level, (NodeQuery) clause.getQuery().toQuery(false), clause.getNodeBooleanOccur());
      }
    }
    // add level
    if (this.hasLevel()) {
      query.setLevelConstraint(this.getLevel());
    }
    // add range
    if (this.hasRange()) {
      query.setNodeConstraint(this.getLowerBound(), this.getUpperBound());
    }
    // add boost
    if (this.hasBoost()) {
      query.setBoost(this.getBoost());
    }

    // should we wrap the query into a lucene proxy
    if (proxy) {
      return new LuceneProxyNodeQuery(query);
    }
    return query;
  }

  @Override
  ObjectNode toJson() {
    final ObjectNode obj = mapper.createObjectNode();
    final ObjectNode twig = obj.putObject(TwigPropertyParser.TWIG_PROPERTY);

    if (hasRoot) {
      twig.put(RootPropertyParser.ROOT_PROPERTY, rootBooleanExpression);
    }

    if (this.hasLevel()) {
      twig.put(LevelPropertyParser.LEVEL_PROPERTY, this.getLevel());
    }

    if (this.hasRange()) {
      final ArrayNode array = twig.putArray(RangePropertyParser.RANGE_PROPERTY);
      array.add(this.getLowerBound());
      array.add(this.getUpperBound());
    }

    if (this.hasBoost()) {
      twig.put(BoostPropertyParser.BOOST_PROPERTY, this.getBoost());
    }

    ArrayNode childArray = null;
    ArrayNode descendantArray = null;
    for (final QueryClause clause : clauses) {
      if (clause instanceof BasicQueryClause) {
        if (!twig.has(ChildPropertyParser.CHILD_PROPERTY)) { // avoid to create an empty array in the JSON
          childArray = twig.putArray(ChildPropertyParser.CHILD_PROPERTY);
        }
        final ObjectNode e = childArray.addObject();
        e.put(OccurPropertyParser.OCCUR_PROPERTY, clause.getOccur().toString());
        e.putAll(clause.getQuery().toJson());
      }
      else {
        if (!twig.has(DescendantPropertyParser.DESCENDANT_PROPERTY)) { // avoid to create an empty array in the JSON
          descendantArray = twig.putArray(DescendantPropertyParser.DESCENDANT_PROPERTY);
        }
        final ObjectNode e = descendantArray.addObject();
        e.put(OccurPropertyParser.OCCUR_PROPERTY, clause.getOccur().toString());
        e.put(LevelPropertyParser.LEVEL_PROPERTY, ((DescendantQueryClause) clause).getLevel());
        e.putAll(clause.getQuery().toJson());
      }
    }

    return obj;
  }



}
TOP

Related Classes of org.sindice.siren.qparser.json.dsl.TwigQuery

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.