Package no.hal.jex.eval

Source Code of no.hal.jex.eval.AbstractTestAnnotationsToModelConverter

package no.hal.jex.eval;

import java.util.ArrayList;
import java.util.Collection;

import no.hal.jex.AbstractRequirement;
import no.hal.jex.Exercise;
import no.hal.jex.ExercisePart;
import no.hal.jex.JUnitTest;
import no.hal.jex.JavaClass;
import no.hal.jex.JavaClassTester;
import no.hal.jex.JavaElement;
import no.hal.jex.JavaField;
import no.hal.jex.JavaMethod;
import no.hal.jex.JavaMethodTester;
import no.hal.jex.JavaPack;
import no.hal.jex.JavaRequirement;
import no.hal.jex.JexFactory;
import no.hal.jex.JexPackage;
import no.hal.jex.Member;
import no.hal.jex.TestSuite;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EStructuralFeature;

public abstract class AbstractTestAnnotationsToModelConverter {

  public final static String JEX_ANNOTATION_NAME = "JExercise";
  public static final String JEX_TESTS_ANNOTATION_KEY = "tests";
  public static final String JEX_MARKUP_LANGUAGE_ANNOTATION_KEY = "markupLanguage";
  public static final String JEX_DESCRIPTION_ANNOTATION_KEY = "description";
  public static final String JEX_COMMENT_ANNOTATION_KEY = "comment";

  public final static String ALL_TESTS_TEST_SUITE_NAME = "AllTests";
  public final static String TEST_CLASS_NAME_SUFFIX = "Test";
  public final static String TEST_METHOD_NAME_PREFIX = "test";

  public static boolean isAllTestsName(String name) {
    int pos = name.lastIndexOf('.');
    if (pos >= 0) {
      name = name.substring(pos + 1);
    }
    return name.equals(AbstractTestAnnotationsToModelConverter.ALL_TESTS_TEST_SUITE_NAME);
  }
  public static boolean isTestClassName(String name) {
    return name.endsWith(TEST_CLASS_NAME_SUFFIX);
  }
  public static boolean isTestMethodName(String name) {
    return name.startsWith(TEST_METHOD_NAME_PREFIX);
  }

  protected static void simplifyRequirements(Exercise ex) {
    EList<AbstractRequirement> requirements = ex.getRequirements();
    if (requirements.size() == 1) {
      AbstractRequirement req = requirements.get(0);
      requirements.clear();
      requirements.addAll(req.getRequirements());
    }
  }

  protected AbstractTestAnnotationsToModelConverter(Exercise ex) {
    this.exercise = ex;
  }

  protected Exercise exercise;
  protected boolean simplifyRequirements = true;

  public Exercise convert() {
    try {
      if (canConvert()) {
        convert(exercise);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    if (simplifyRequirements) {
      simplifyRequirements(exercise);
    }
    return exercise;
  }

  public abstract boolean canConvert();
  protected abstract void convert(Exercise ex);
 
  //
 
  protected JavaPack ensureJavaPack(String packageName, Collection<?> javaElements) {
    return (JavaPack) ensureJavaElement(packageName, javaElements, JexPackage.eINSTANCE.getJavaPack());
  }

  protected JavaClass ensureJavaClass(String fullName, EClass eClass) {
    int pos = fullName.lastIndexOf('.');
    return (TestSuite) ensureJavaClass(fullName.substring(0, pos), fullName.substring(pos + 1), JexPackage.eINSTANCE.getTestSuite());
  }
  protected JavaClass ensureJavaClass(String packagePrefix, String elementName, EClass eClass) {
    JavaPack javaPack = ensureJavaPack(packagePrefix, exercise.getJavaElements());
    return (JavaClass) ensureJavaElement(elementName, javaPack.getClasses(), eClass);
  }

  protected JavaElement findJavaElement(String name, Iterable<? extends JavaElement> javaElements, EClass eClass) {
    for (JavaElement javaElement : javaElements) {
      if (eClass.isSuperTypeOf(javaElement.eClass())) {
        EStructuralFeature nameFeature = eClass.getEStructuralFeature("name");
        if (nameFeature != null) {
          Object javaElementName = javaElement.eGet(nameFeature);
          if (name == javaElementName || (name != null && name.equals(javaElementName))) {
            return (JavaElement) javaElement;
          }
        }
      }
    }
    return null;
  }

  protected JavaElement ensureJavaElement(String name, Collection javaElements, EClass eClass) {
    JavaElement javaElement = findJavaElement(name, javaElements, eClass);
    if (javaElement == null) {
      javaElement = (JavaElement) JexFactory.eINSTANCE.create(eClass);
      EStructuralFeature nameFeature = eClass.getEStructuralFeature("name");
      if (nameFeature != null) {
        javaElement.eSet(nameFeature, name);
      }
      javaElements.add(javaElement);
    }
    return javaElement;
  }

  protected JavaElement ensureJavaMethod(String name, String returnType, String[] parameterTypes, String[] exceptionTypes, Collection<Member> javaMembers) {
    outer: for (Member javaMember : javaMembers) {
      // check type and name
      if (! (javaMember instanceof JavaMethod && name.equals(javaMember.getName()))) {
        continue;
      }
      // check parameter types
      JavaMethod javaMethod = (JavaMethod) javaMember;
      if (parameterTypes.length != javaMethod.getParameters().size()) {
        continue;
      }
      for (int i = 0; i < parameterTypes.length; i++) {
        if (! parameterTypes[i].equals(javaMethod.getParameters().get(i))) {
          continue outer;
        }
      }
      // found method with desired signature
      return javaMethod;
    }
    // no method with desired signature found
    JavaMethod javaMethod = JexFactory.eINSTANCE.createJavaMethod();
    javaMethod.setName(name);
    javaMethod.setReturnType(returnType);
    addAll(javaMethod.getParameters(), parameterTypes);
    if (exceptionTypes != null) {
      addAll(javaMethod.getThrowables(), exceptionTypes);
    }
    javaMembers.add(javaMethod);
    return javaMethod;
  }

  protected <T> void addAll(Collection<T> col, T[] values) {
    for (int j = 0; j < values.length; j++) {
      col.add(values[j]);
    }
  }

  protected ExercisePart ensureExercisePart(Exercise ex, String name) {
    for (AbstractRequirement req : ex.getRequirements()) {
      if (req instanceof ExercisePart && name.equals(req.getText())) {
        return (ExercisePart) req;
      }
    }
    ExercisePart exercisePart = JexFactory.eINSTANCE.createExercisePart();
    exercisePart.setText(name);
    ex.getRequirements().add(exercisePart);
    ensureJavaPack(name, ex.getJavaElements());
    return exercisePart;
  }
 
  protected JavaRequirement ensureJavaRequirement(String packageName, String testClassName, String testedClassName, String testsAnnotation, boolean preferJunitTest) {
    JavaRequirement req = null;
    boolean hasTestsAnnotation = testsAnnotation != null && testsAnnotation.length() > 0;
    if (hasTestsAnnotation && preferJunitTest) {
      req = JexFactory.eINSTANCE.createJUnitTest();
    } else {
      if (! hasTestsAnnotation) {
        testsAnnotation = testedClassName;
      }
      req = JexFactory.eINSTANCE.createJavaRequirement();
    }
    String packagePrefix = packageName != null && packageName.length() > 0 ? packageName + "." : "";
    req.setText((req instanceof JUnitTest ? "Test " : "") + packagePrefix + testsAnnotation);
    JavaClassTester javaClassTester = (JavaClassTester) ensureJavaClass(packageName, testClassName, JexPackage.eINSTANCE.getJavaClassTester());
    String[] superClasses = {},  superInterfaces = {};
    int pos = testsAnnotation.indexOf(' ');
    if (pos >= 0) {
      testedClassName = testsAnnotation.substring(0, pos);
      testsAnnotation = testsAnnotation.substring(pos + 1);
      String EXTENDS_KEYWORD = "extends ", IMPLEMENTS_KEYWORD = "implements ";
      int extendsPos = testsAnnotation.indexOf(EXTENDS_KEYWORD), implementsPos = testsAnnotation.indexOf(IMPLEMENTS_KEYWORD);
      if (extendsPos >= 0) {
        superClasses = parseTypeList(testsAnnotation.substring(extendsPos + EXTENDS_KEYWORD.length(), implementsPos > extendsPos ? implementsPos : testsAnnotation.length()));
      }
      if (implementsPos >= 0) {
        superInterfaces = parseTypeList(testsAnnotation.substring(implementsPos + IMPLEMENTS_KEYWORD.length(), extendsPos > implementsPos ? extendsPos : testsAnnotation.length()));
      }
    } else {
      testedClassName = testsAnnotation;
    }
    int pos3 = testedClassName.lastIndexOf('.');
    if (pos3 >= 0) {
      packageName = testedClassName.substring(0, pos3);
      testedClassName = testedClassName.substring(pos3 + 1);
    }
    JavaClass javaClass = ensureJavaClass(packageName, testedClassName, JexPackage.eINSTANCE.getJavaClass());
    addAll(javaClass.getSuperclasses(), superClasses);
    addAll(javaClass.getSuperclasses(), superInterfaces);
    javaClassTester.getTestedElements().add(javaClass);
    ExercisePart part = ensureExercisePart(exercise, packageName);
    if (req instanceof JUnitTest) {
      ((JUnitTest) req).setTestRunnable(javaClassTester);
    }
    req.setJavaElement(javaClassTester); // redundant?
    part.getRequirements().add(req);
    return req;
  }
 
  private static final char TYPE_LIST_SEPARATOR = ',';

  private String[] parseTypeList(String s) {
    Collection<String> typeList = new ArrayList<String>();
    parseTypeList(s, 0, typeList);
    return typeList.toArray(new String[typeList.size()]);
  }

  private int parseTypeList(String s, int start, Collection<String> types) {
    int pos = start;
    while (pos < s.length()) {
      pos = parseType(s, pos, types);
      if (pos >= s.length()) {
        break;
      }
      char c = s.charAt(pos);
      if (c == TYPE_LIST_SEPARATOR || Character.isWhitespace(c)) {
        pos++;
      } else {
        break;
      }
    }
    return pos;
  }
 
  private int parseType(String s, int start, Collection<String> types) {
    int pos = start;
    for (; pos < s.length(); pos++) {
      char c = s.charAt(pos);
      if (Character.isJavaIdentifierPart(c) || ".?& ".indexOf(c) >= 0) {
        continue;
      } else if (c == '<') {
        pos = parseTypeList(s, pos + 1, null);
        if (s.charAt(pos) == '>') {
          pos++;
        }
        return pos;
      } else {
        break;
      }
    }
    if (types != null) {
      types.add(s.substring(start, pos).trim());
    }
    return pos;
  }
 
  private String[] visibilityPrefixes = {
    "public ",     "public",
    "+",       "public",
    "protected ",   "protected",
    "private ",   "private",
    "-",       "private",
  };
 
  protected JUnitTest ensureJunitTest(JavaMethodTester javaMethodTester, String testsAnnotation, Iterable<Member> methodParents, AbstractRequirement reqParent) {

    // create and initialize JUnit test
    JUnitTest testReq = JexFactory.eINSTANCE.createJUnitTest();
    testReq.setText("Test");
    javaMethodTester.setReturnType("void");
    testReq.setJavaElement(javaMethodTester);
    testReq.setTestRunnable(javaMethodTester);
   
    reqParent.getRequirements().add(testReq);

    JavaClass methodParent = null;
    for (Member member : methodParents) {
      if (member instanceof JavaClass) {
        methodParent = (JavaClass) member;
        break;
      }
    }
    // add java elements and requirements for the tested elements
    String[] testedElements = testsAnnotation.split(";");
    for (int i = 0; i < testedElements.length; i++) {
      String testedElementName = testedElements[i].trim();
      String returnType = null, modifiers = null;
      for (int j = 0; j < visibilityPrefixes.length; j += 2) {
        String prefix = visibilityPrefixes[j];
        if (testedElementName.startsWith(prefix)) {
          modifiers = visibilityPrefixes[j + 1];
          testedElementName = testedElementName.substring(prefix.length());
          break;
        }
      }
      testReq.setText(testReq.getText() + (i == 0 ? " " : ", ") + testedElementName);
      int pos1 = testedElementName.indexOf('('), pos = testedElementName.lastIndexOf(' ', pos1 >= 0 ? pos1 : testedElementName.length());
      if (pos >= 0) {
        returnType = testedElementName.substring(0, pos);
        pos1 -= pos + 1;
        testedElementName = testedElementName.substring(pos + 1);
      }
      int pos2 = testedElementName.lastIndexOf(')');
      Member testedElement = null;
      if (pos1 >= 0 && pos2 >= 0) {
        String[] params = {}, exceptions = {};
        if (pos2 > pos1 + 2) {
          params = parseTypeList(testedElementName.substring(pos1 + 1, pos2));
        }
        String THROWS_KEYWORD = "throws ";
        int pos3 = testedElementName.indexOf(THROWS_KEYWORD, pos2);
        if (pos3 >= pos2) {
          exceptions = parseTypeList(testedElementName.substring(pos3 + THROWS_KEYWORD.length()));
        }
        testedElementName = testedElementName.substring(0, pos1);
        if (methodParent == null) {
          continue;
        }
        if (testedElementName != methodParent.getName() && returnType == null) {
          returnType = "void";
        }
        JavaMethod javaMethod = (JavaMethod) ensureJavaMethod(testedElementName, returnType, params, exceptions, methodParent.getMembers());
        testedElement = javaMethod;
      } else {
        JavaField javaField = (JavaField) ensureJavaElement(testedElementName, methodParent.getMembers(), JexPackage.eINSTANCE.getJavaField());
        javaField.setType(returnType);
        testedElement = javaField;
      }
      javaMethodTester.getTestedElements().add(testedElement);
      JavaRequirement javaReq = JexFactory.eINSTANCE.createJavaRequirement();
      javaReq.setText("Requires " + testedElements[i].trim());
      javaReq.setJavaElement(testedElement);

      if (modifiers != null) {
        testedElement.setModifiers((Integer) JexFactory.eINSTANCE.createFromString(JexPackage.eINSTANCE.getModifiers(), modifiers));
      } else {
        javaReq.setRequiredFeatures("!modifiers");
      }
      testReq.getRequirements().add(javaReq);
    }
    return testReq;
  }
 
  protected String convertMarkupFeatures(String markupText, String markupLanguage) {
    return markupText;
  }
}
TOP

Related Classes of no.hal.jex.eval.AbstractTestAnnotationsToModelConverter

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.