Package com.gistlabs.mechanize.document.html

Source Code of com.gistlabs.mechanize.document.html.JsoupNodeHelper

/**
* Copyright (C) 2012-2014 Gist Labs, LLC. (http://gistlabs.com)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.gistlabs.mechanize.document.html;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;

import se.fishtank.css.selectors.Selector;
import se.fishtank.css.util.Assert;

import com.gistlabs.mechanize.util.css_query.NodeHelper;
import com.gistlabs.mechanize.util.css_query.NodeSelector;

public class JsoupNodeHelper implements NodeHelper<Node> {

  public static Node find(final Node node, final String selector) {
    return new NodeSelector<Node>(new JsoupNodeHelper(node), node).find(selector);
  }

  public static List<Node> findAll(final Node node, final String selector) {
    return new NodeSelector<Node>(new JsoupNodeHelper(node), node).findAll(selector);
  }


  /** The root node (document or element). */
  private final Node root;

  /**
   * Create a new instance.
   *
   * @param root The root node. Must be a document or element node.
   */
  public JsoupNodeHelper(final Node root) {
    Assert.notNull(root, "root is null!");
    Assert.isTrue(root instanceof Document || root instanceof Element, "root must be a document or element node!");
    this.root = root;
  }

  @Override
  public String getValue(final Node node) {
    if (node instanceof Element)
      return ((Element)node).text();
    else
      return null;
  }

  @Override
  public boolean hasAttribute(final Node node, final String name) {
    return node.attributes().hasKey(name);
  }

  @Override
  public String getAttribute(final Node node, final String name) {
    return node.attributes().get(name).trim();
  }

  @Override
  public Index getIndexInParent(final Node node, final boolean byType) {
    String type = byType ? getName(node) : Selector.UNIVERSAL_TAG;

    List<? extends Node> children;
    Node parent = node.parent();
    if (parent==null)
      children = Collections.emptyList();
    else
      children = getChildNodes(parent, type);

    return new Index(children.indexOf(node), children.size());
  }

  @Override
  public Collection<? extends Node> getDescendentNodes(final Node node) {
    Elements descendents;
    if (node instanceof Document)
      descendents = ((Document)node).getAllElements();
    else
      descendents = ((Element)node).getAllElements();

    descendents.remove(node); // Jsoup includes the target of getAllElements() in the result...
    return descendents;
  }

  @Override
  public List<? extends Node> getChildNodes(final Node node) {
    return getChildNodes(node, "*");
  }

  @SuppressWarnings("unchecked")
  protected List<? extends Node> getChildNodes(final Node node, final String withName) {
    if (node==null)
      return Collections.EMPTY_LIST;

    if (Selector.UNIVERSAL_TAG.equals(withName))
      return filter(node.childNodes());

    ArrayList<Node> result = new ArrayList<Node>();

    List<Node> children = node.childNodes();
    for(Node child : children)
      if (nameMatches(child, withName))
        result.add(child);

    return result;
  }

  private List<? extends Node> filter(final List<Node> nodes) {
    ArrayList<Node> result = new ArrayList<Node>();
    for(Node node : nodes)
      if (node instanceof Element)
        result.add(node);
    return result;
  }

  @Override
  public boolean isEmpty(final Node node) {
    return node.childNodes().isEmpty();
  }

  @Override
  public String getName(final Node n) {
    return n.nodeName();
  }

  @Override
  public Node getNextSibling(final Node node) {
    Index index = getIndexInParent(node, false);
    if (index.index < (index.size-1))
      return getChildNodes(node.parent()).get(index.index+1);
    else
      return null;
  }

  @Override
  public boolean nameMatches(final Node n, final String name) {
    if (name.equals(Selector.UNIVERSAL_TAG))
      return true;

    return name.equalsIgnoreCase(getName(n));
  }

  @Override
  public Node getRoot() {
    if (root instanceof Document) {
      // Get the single element child of the document node.
      // There could be a doctype node and comment nodes that we must skip.
      List<Node> children = root.childNodes();
      for(Node child : children)
        if (child instanceof Element)
          return child;
      Assert.isTrue(false, "there should be a root element!");
      return null;
    } else {
      Assert.isTrue(root instanceof Element, "root must be a document or element node!");
      return root;
    }
  }
}
TOP

Related Classes of com.gistlabs.mechanize.document.html.JsoupNodeHelper

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.