Package com.google.eclipse.protobuf.junit.core

Source Code of com.google.eclipse.protobuf.junit.core.Finder

/*
* Copyright (c) 2011 Google Inc.
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.google.eclipse.protobuf.junit.core;

import static com.google.eclipse.protobuf.junit.core.SearchOption.IGNORE_CASE;
import static com.google.eclipse.protobuf.util.SystemProperties.lineSeparator;

import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.nodemodel.BidiTreeIterator;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.impl.AbstractNode;

import com.google.eclipse.protobuf.protobuf.DefaultValueFieldOption;
import com.google.eclipse.protobuf.protobuf.Package;

/**
* @author alruiz@google.com (Alex Ruiz)
*/
class Finder {
  // TODO remove feature names that are not used or don't exist any more.
  private static final String[] FEATURE_NAMES = { "extension", "target", "message", "name", "optionField", "property",
      "source", "type", "value" };

  private final String protoAsText;
  private final AbstractNode root;

  Finder(INode node, String protoAsText) {
    this.root = rootOf(node);
    this.protoAsText = protoAsText;
  }

  private static AbstractNode rootOf(INode node) {
    while (!(node instanceof AbstractNode)) {
      node = node.getParent();
    }
    return (AbstractNode) node;
  }

  <T extends EObject> T find(String text, int count, Class<T> type, List<SearchOption> options) {
    int offset = protoAsText.indexOf(text);
    String name = text.substring(0, count);
    Iterator<AbstractNode> iterator = root.basicIterator();
    while (iterator.hasNext()) {
      AbstractNode node = iterator.next();
      int nodeOffset = node.getOffset();
      if (nodeOffset > offset || (nodeOffset + node.getLength()) <= offset) {
        continue;
      }
      EObject e = node.getSemanticElement();
      if (isDefaultValueFieldOption(name, type, e)) {
        return type.cast(e);
      }
      if (type.isInstance(e)) {
        if (areNamesEqual(name, e, options)) {
          return type.cast(e);
        }
      }
    }
    String format = "Unable to find element. Text: '%s', count: %d, type: %s, options: %s";
    throw new AssertionError(String.format(format, text, count, type.getName(), options));
  }

  private boolean isDefaultValueFieldOption(String name, Class<?> type, EObject element) {
    return "default".equals(name) && type.isInstance(element) && element instanceof DefaultValueFieldOption;
  }

  private boolean areNamesEqual(String expected, Object e, List<SearchOption> options) {
    String realExpected = expected;
    if (realExpected.indexOf(".") != -1 && !(e instanceof Package)) {
      String[] segments = expected.split("\\.");
      QualifiedName qualifiedName = QualifiedName.create(segments);
      realExpected = qualifiedName.getLastSegment();
    }
    String actual = nameOf(e);
    if (options.contains(IGNORE_CASE)) {
      return realExpected.equalsIgnoreCase(actual);
    }
    return realExpected.equals(actual);
  }

  private String nameOf(Object o) {
    if (!(o instanceof EObject)) {
      return null;
    }
    EObject e = (EObject) o;
    for (String name : FEATURE_NAMES) {
      Object value = feature(e, name);
      if (value instanceof String) {
        return (String) value;
      }
      if (value != null) {
        return nameOf(value);
      }
    }
    return null;
  }

  private Object feature(EObject e, String featureName) {
    EStructuralFeature f = e.eClass().getEStructuralFeature(featureName);
    return (f != null) ? e.eGet(f) : null;
  }

  ILeafNode find(String text) {
    BidiTreeIterator<AbstractNode> iterator = root.basicIterator();
    while (iterator.hasNext()) {
      AbstractNode node = iterator.next();
      if (!(node instanceof ILeafNode)) {
        continue;
      }
      String nodeText = clean(node.getText());
      if (text.equals(nodeText)) {
        return (ILeafNode) node;
      }
    }
    String format = "Unable to find node. Text: '%s'";
    throw new AssertionError(String.format(format, text));
  }

  private String clean(String text) {
    return text.replace(lineSeparator(), " ").trim();
  }
}
TOP

Related Classes of com.google.eclipse.protobuf.junit.core.Finder

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.