Package org.sindice.siren.qparser.keyword.nodes

Source Code of org.sindice.siren.qparser.keyword.nodes.TwigQueryNode

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

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

import org.apache.lucene.queryparser.flexible.core.nodes.FieldableNode;
import org.apache.lucene.queryparser.flexible.core.nodes.GroupQueryNode;
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNodeImpl;
import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax;
import org.sindice.siren.search.node.NodeQuery;
import org.sindice.siren.search.node.TwigQuery;

/**
* A {@link TwigQueryNode} represents a structured query, i.e., a {@link TwigQuery}.
*
* <p>
*
* It is composed of two nodes, a root and of a direct child.
*
* <p>
*
* A node with multiple children can be built by passing an
* {@link ArrayQueryNode} to the {@link #setChild(QueryNode)}.
*
* <p>
*
* A complex twig can be built by chaining multiple {@link TwigQueryNode}.
*/
public class TwigQueryNode
extends QueryNodeImpl
implements FieldableNode {

  /** The root of the Twig Query */
  private int rootLevel = -1;
  /** Position in the list of the root of the twig */
  private static final int ROOT_POS  = 0;
  /** Position in the list of the child of the twig */
  private static final int CHILD_POS = 1;

  /**
   * Build a {@link TwigQueryNode} where the root can be either
   * an {@link WildcardNodeQueryNode} or a {@link NodeBooleanQueryNode}.
   * In addition to the root, the child node can be an {@link ArrayQueryNode}
   * or another {@link TwigQueryNode}.
   *
   * @param root the {@link QueryNode} as the root of the twig
   * @param child the {@link QueryNode} as the child of the twig
   */
  public TwigQueryNode(final QueryNode root, final QueryNode child) {
    this.allocate();
    this.setLeaf(false);
    this.add(root);
    this.add(child);
  }

  /**
   * Set the root of the twig
   */
  public void setRoot(final QueryNode root) {
    final ArrayList<QueryNode> newChildren = new ArrayList<QueryNode>();
    newChildren.add(root);
    newChildren.add(this.getChild());
    this.set(newChildren);
  }

  /**
   * Returns the root of the twig.
   */
  public QueryNode getRoot() {
    return this.getChildren().get(ROOT_POS);
  }

  /**
   * Set the child of the twig.
   */
  public void setChild(final QueryNode child) {
    final ArrayList<QueryNode> newChildren = new ArrayList<QueryNode>();
    newChildren.add(this.getRoot());
    newChildren.add(child);
    this.set(newChildren);
  }

  /**
   * Returns the child of the twig.
   */
  public QueryNode getChild() {
    return this.getChildren().get(CHILD_POS);
  }

  /**
   * Set the level of the root node in the document tree.
   * @see NodeQuery#setLevelConstraint(int)
   */
  public void setRootLevel(final int rootLevel) {
    this.rootLevel = rootLevel;
  }

  /**
   * Get the level of the root node in the document tree.
   *
   * <p>
   *
   * If no root level has been set, <code>-1</code> is returned.
   * @see NodeQuery#setLevelConstraint(int)
   */
  public int getRootLevel() {
    return rootLevel;
  }

  @Override
  public CharSequence getField() {
    return this.doGetField(this.getChildren());
  }

  private CharSequence doGetField(final List<QueryNode> children) {
    if (children != null) {
      for (final QueryNode child : children) {
        if (child instanceof FieldableNode) {
          return ((FieldableNode) child).getField();
        } else if (child instanceof TwigQueryNode) {
          return ((TwigQueryNode) child).getField();
        }
        final CharSequence field = this.doGetField(child.getChildren());
        if (field != null) {
          return field;
        }
      }
    }
    return null;
  }

  @Override
  public void setField(final CharSequence fieldName) {
    this.doSetField(this.getChildren(), fieldName);
  }

  private void doSetField(final List<QueryNode> children, final CharSequence fieldName) {
    if (children != null) {
      for (final QueryNode child : children) {
        this.doSetField(child.getChildren(), fieldName);
        if (child instanceof FieldableNode) {
          ((FieldableNode) child).setField(fieldName);
        } else if (child instanceof TwigQueryNode) {
          ((TwigQueryNode) child).setField(fieldName);
        }
      }
    }
  }

  @Override
  public String toString() {
    final QueryNode att = this.getRoot();
    final QueryNode child = this.getChild();
    final String s = "<twig root=\"" + this.getRootLevel() + "\">\n" +
                 "<root>\n" + (att instanceof WildcardNodeQueryNode ? "" : att + "\n") + "</root>\n" +
                 "<child>\n" + (child instanceof WildcardNodeQueryNode ? "" : child + "\n") + "</child>\n" +
               "</twig>";
    return s;
  }

  @Override
  public CharSequence toQueryString(final EscapeQuerySyntax escapeSyntaxParser) {
    if (this.getChildren() == null || this.getChildren().size() == 0)
      return "";

    final StringBuilder sb = new StringBuilder();
    final QueryNode root = this.getRoot();
    final QueryNode child = this.getChild();
    if (root instanceof WildcardNodeQueryNode) {
      sb.append("* : ");
    } else {
      sb.append(root.toQueryString(escapeSyntaxParser)).append(" : ");
    }
    if (child instanceof WildcardNodeQueryNode) {
      sb.append("*");
    } else {
      sb.append(child.toQueryString(escapeSyntaxParser));
    }

    // in case is root or the parent is a group node avoid parenthesis
    if ((this.getParent() != null && this.getParent() instanceof GroupQueryNode) || this.isRoot()) {
      return sb.toString();
    } else {
      return "( " + sb.toString() + " )";
    }
  }

}
TOP

Related Classes of org.sindice.siren.qparser.keyword.nodes.TwigQueryNode

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.