Package no.hal.jex.editor.commands

Source Code of no.hal.jex.editor.commands.CreateChildrenFromJavaModelCommand

package no.hal.jex.editor.commands;

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

import no.hal.jex.ClassKind;
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.JexPackage;
import no.hal.jex.Member;
import no.hal.jex.TestRunnable;
import no.hal.jex.impl.MemberImpl;
import no.hal.jex.jdt.JdtRequirementChecker;
import no.hal.jex.jdt.JdtHelper;

import org.eclipse.emf.common.command.AbstractCommand;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.edit.command.CommandActionDelegate;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;

public class CreateChildrenFromJavaModelCommand extends AbstractCommand
  implements CommandActionDelegate {

  private JavaElement parent;
  private boolean recursive;
  private int modifiers;

  public CreateChildrenFromJavaModelCommand(no.hal.jex.JavaElement parent, int modifiers, boolean recursive) {
    this.parent = parent;
    this.recursive = recursive;
    this.modifiers = modifiers;
  }
 
  private IJavaElement javaElement;
 
  public void execute() {
    try {
      createChildrenFromJavaModel(parent, javaElement, recursive ? -1 : 1);
    } catch (Exception e) {
    }
  }

  private boolean matchesModifiers(IMember member) {
    try {
      return JdtRequirementChecker.hasModifiers(member.getFlags(), modifiers);
    } catch (JavaModelException e) {
    }
    return false;
  }

  public final static String ALL_TESTS_TEST_SUITE_NAME = "AllTests";
 
  private void createChildrenFromJavaModel(JavaElement parent, IJavaElement javaElement, int depth) throws Exception {
    if (parent instanceof JavaPack && javaElement instanceof IPackageFragment) {
      JavaPack pack = (JavaPack)parent;
      List<IMember> classes = JdtHelper.findJavaMembers((IPackageFragment) javaElement, null, IJavaElement.TYPE, IType.class);
      createJexClasses(classes, depth, pack.getClasses());
      createNamedClass(pack.getName() + "." + ALL_TESTS_TEST_SUITE_NAME, JexPackage.eINSTANCE.getTestSuite(), null, depth, pack.getClasses());
    } else if (parent instanceof JavaClass && javaElement instanceof IType) {
      JavaClass javaClass = (JavaClass)parent;
      IType type = (IType)javaElement;
      List<IMember> fields = JdtHelper.findJavaMembers(type, null, IJavaElement.FIELD, IField.class);
      for (Iterator<IMember> it = fields.iterator(); it.hasNext();) {
        IField field = (IField) it.next();
        if (matchesModifiers(field)) {
          if (parent instanceof TestRunnable) {
            continue;
          }
          ensureJexMember(JexPackage.eINSTANCE.getJavaField(), field, javaClass.getMembers());
        }
      }
      List<IMember> methods = JdtHelper.findJavaMembers(type, null, IJavaElement.METHOD, IMethod.class);
      for (Iterator<IMember> it = methods.iterator(); it.hasNext();) {
        IMethod method = (IMethod)it.next();
        if (matchesModifiers(method)) {
          EClass methodClass = JexPackage.eINSTANCE.getJavaMethod();
          if (parent instanceof TestRunnable) {
            if (! isMethodTester(method)) {
              continue;
            }
            methodClass = JexPackage.eINSTANCE.getJavaMethodTester();
          }
          JavaMethod newMethod = (JavaMethod)ensureJexMember(methodClass, method, javaClass.getMembers());
          // clear type if method is a constructor
          if (newMethod.getSimpleName().equals(javaClass.getSimpleName())) {
            newMethod.setReturnType(null);
          }
          if (newMethod instanceof JavaMethodTester && parent instanceof JavaClassTester) {
            for (Member member : ((JavaClassTester) parent).getTestedElements()) {
              Member testedMethod = findTestedMethod(newMethod.getSimpleName(), ((JavaClass) member).getMembers());
              if (testedMethod != null) {
                ((JavaMethodTester) newMethod).getTestedElements().add(testedMethod);
              }
            }
          }
        }
      }
      List<IMember> classes = JdtHelper.findJavaMembers(type, null, IJavaElement.TYPE, IType.class);
      createJexClasses(classes, depth, javaClass.getMembers());
    }
  }

  private Member findTestedMethod(String methodName, List<? extends Member> members) {
    String testMethodNamePrefix = "test";
    if (methodName.startsWith(testMethodNamePrefix)) {
      methodName = methodName.substring(testMethodNamePrefix.length());
    }
    for (Member member : members) {
      if (methodName.equals(member.getSimpleName())) {
        return member;
      }
    }
    return null;
  }
 
  public final static String TEST_METHOD_NAME_PREFIX = "test";

  public static boolean isMethodTester(IMethod method) {
    try {
      return method.getElementName().startsWith(TEST_METHOD_NAME_PREFIX) &&
        Signature.SIG_VOID.equals(method.getReturnType()) &&
        method.getParameterTypes().length == 0 &&
        Flags.isPublic(method.getFlags());
    } catch (JavaModelException e) {
    }
    return false;
  }

  public final static String TEST_CLASS_NAME_SUFFIX = "Test";

  private List<? extends Member> createJexClasses(List<IMember> classes, int depth, List<? extends Member> results) throws JavaModelException, Exception {
    for (Iterator<IMember> it = classes.iterator(); it.hasNext();) {
      IType type = (IType) it.next();
      if (matchesModifiers(type)) {
        JavaClass newClass = (JavaClass) ensureJexMember(JexPackage.eINSTANCE.getJavaClass(), type, results);
        if (depth != 0) {
          createChildrenFromJavaModel(newClass, type, depth - 1);
        }
        createNamedClass(newClass.getFullName() + TEST_CLASS_NAME_SUFFIX, JexPackage.eINSTANCE.getJavaClassTester(), newClass, depth, results);
      }
    }
    return results;
  }

  private JavaClass createNamedClass(String name, EClass eClass, Member testedElement, int depth, List<? extends Member> results) throws JavaModelException, Exception {
    IType type = JdtHelper.findJdtClass(name, JdtHelper.getJavaProject(testedElement.eResource().getURI()));
    if (type != null && matchesModifiers(type)) {
      JavaClass newClass = (JavaClass) ensureJexMember(eClass, type, results);
      if (newClass instanceof TestRunnable) {
        ((TestRunnable) newClass).getTestedElements().add(testedElement);
      }
      if (depth != 0) {
        createChildrenFromJavaModel(newClass, type, depth - 1);
      }
      return newClass;
    }
    return null;
  }

  public static void initFrom(Member jexMember, IMember jdtMember) throws JavaModelException {
    jexMember.setName(jdtMember.getElementName());
    jexMember.setModifiers(jdtMember.getFlags());
    if (jexMember instanceof JavaClass) {
      if (! (jdtMember instanceof IType)) {
        throw new IllegalArgumentException("Cannot init JavaClass from " + jdtMember);
      }
      JavaClass jexClass = (JavaClass) jexMember;
      IType jdtType = (IType) jdtMember;
      ClassKind kind = ClassKind.CLASS_KIND;
      if (jdtType.isInterface()) {
        kind = ClassKind.INTERFACE_KIND;
      } else if (jdtType.isEnum()) {
        kind = ClassKind.ENUM_KIND;
      }
      jexClass.setClassKind(kind);
      String superclassName = jdtType.getSuperclassName();
      if (superclassName != null && (! "Object".equals(superclassName))) {
        jexClass.getSuperclasses().add(superclassName);
      }
      jexClass.getSuperclasses().addAll(Arrays.asList(jdtType.getSuperInterfaceNames()));
    } else if (jexMember instanceof JavaMethod) {
      if (! (jdtMember instanceof IMethod)) {
        throw new IllegalArgumentException("Cannot init JavaMethod from " + jdtMember);
      }
      JavaMethod javaMethod = (JavaMethod) jexMember;
      javaMethod.getParameters().clear();
      IMethod method = (IMethod)jdtMember;
      String[] types = method.getParameterTypes();
      for (int i = 0; i < types.length; i++) {
        javaMethod.getParameters().add(Signature.toString(types[i]));
      }
      javaMethod.setReturnType(Signature.toString(method.getReturnType()));
      javaMethod.getThrowables().addAll(Arrays.asList(method.getExceptionTypes()));
    } else if (jexMember instanceof JavaField) {
      if (! (jdtMember instanceof IField)) {
        throw new IllegalArgumentException("Cannot init JavaField from " + jdtMember);
      }
      JavaField javaField = (JavaField) jexMember;
      javaField.setType(Signature.toString(((IField) jdtMember).getTypeSignature()));
    }
  }
 
  private <T extends Member> Member ensureJexMember(EClass eClass, IMember member, List<T> otherMembers) throws JavaModelException {
    T newMember = (T) eClass.getEPackage().getEFactoryInstance().create(eClass);
    initFrom(newMember, member);
    // reuse existing element, if it exists
    if (otherMembers != null) {
      for (int i = 0; i < otherMembers.size(); i++) {
        Member otherMember = (Member)otherMembers.get(i);
        if (newMember.overrides(otherMember)) {
          initFrom(otherMember, member);
          return otherMember;
        }
      }
      otherMembers.add(newMember);
    }
    return newMember;
  }

  public void redo() {
  }

  @Override
  protected boolean prepare() {
    javaElement = null;
    try {
      javaElement = JdtHelper.getJdtElement(parent);
    } catch (RuntimeException e) {
    }
    if (javaElement instanceof IPackageFragment) {
      return true;
    } else if (javaElement instanceof IType) {
      return true;
    }
    return false;
  }

  @Override
  public String getDescription() {
    return ("Create " + MemberImpl.getModifierString(modifiers)).trim() + " children, based on Java model" + (recursive ? ", recursively" : "");
  }

  public Object getImage() {
    return null;
  }

  public String getText() {
    return getDescription();
  }

  public String getToolTipText() {
    return getDescription();
  }
}
TOP

Related Classes of no.hal.jex.editor.commands.CreateChildrenFromJavaModelCommand

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.