Package qwickie.util

Source Code of qwickie.util.TypeHelper

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 qwickie.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.internal.core.JavaElement;
import org.eclipse.jdt.internal.core.NamedMember;
import org.eclipse.jdt.internal.core.ResolvedBinaryMethod;
import org.eclipse.jdt.internal.core.ResolvedBinaryType;
import org.eclipse.jdt.internal.core.ResolvedSourceMethod;

/**
* @author count.negative
*
*/
@SuppressWarnings("restriction")
public final class TypeHelper {
  private static final String PACKAGE_MARKUP = "org.apache.wicket.markup";
  private static final String PACKAGE_MODEL = "org.apache.wicket.model";
  public static final String COMPONENT = "org.apache.wicket.Component";

  private TypeHelper() {
  }

  public static List<Object> getSupertypes(final IFile javaFile) {
    final List<Object> list = new ArrayList<Object>();
    if (javaFile != null) {
      final ICompilationUnit icu = JavaCore.createCompilationUnitFrom(javaFile);
      try {
        final IType[] allTypes = icu.getAllTypes();
        for (final IType type : allTypes) {
          final ITypeHierarchy sth = type.newTypeHierarchy(null);
          final IType[] supertypes = sth.getAllSupertypes(type);
          for (final IType supertype : supertypes) {
            final IClassFile classFile = supertype.getClassFile();
            final IResource res = supertype.getResource();
            // only add if there's a source
            if (classFile != null && classFile.isStructureKnown()) {
              list.add(classFile);
            } else if (res != null && res instanceof IFile) {
              list.add(res);
            }
          }
        }
      } catch (final JavaModelException e1) {
      }
    }
    return list;
  }

  public static List<JavaElement> getWicketComponentTypes(final IFile javaFile) {
    Assert.isNotNull(javaFile);
    final Set<JavaElement> set = new HashSet<JavaElement>();

    final ASTParser parser = ASTParser.newParser(AST.JLS4);
    parser.setResolveBindings(true);
    parser.setSource(JavaCore.createCompilationUnitFrom(javaFile));
    final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
    cu.accept(new ASTVisitor() {

      @Override
      public boolean visit(final ClassInstanceCreation node) {
        final ITypeBinding ntb = node.resolveTypeBinding();
        final ITypeBinding nttb = node.getType().resolveBinding();
        IJavaElement javaElement = null;
        if (ntb == null || nttb == null) {
          return true;
        }
        if (ntb.getPackage().getName().startsWith(PACKAGE_MARKUP)) {
          javaElement = ntb.getJavaElement();
        }
        if (nttb.getPackage().getName().startsWith(PACKAGE_MARKUP)) {
          javaElement = nttb.getJavaElement();
        }
        if (javaElement == null) {
          ITypeBinding superclass = ntb.getSuperclass();
          while (superclass != null) {
            if (PACKAGE_MARKUP.startsWith(superclass.getPackage().getName())) {
              javaElement = ntb.getJavaElement();
              break;
            }
            superclass = superclass.getSuperclass();
          }
        }
        if (javaElement != null) {
          set.add((JavaElement) javaElement);
          final ResolvedBinaryType rbt = (ResolvedBinaryType) javaElement.getAdapter(ResolvedBinaryType.class);
          if (rbt != null) {
            set.add(rbt);
          }
        }
        return true;
      }

    });

    return new ArrayList<JavaElement>(set);
  }

  public static List<IVariableBinding> getWicketModelTypes(final IFile javaFile) {
    Assert.isNotNull(javaFile);
    final List<IVariableBinding> list = new ArrayList<IVariableBinding>();

    final ASTParser parser = ASTParser.newParser(AST.JLS4);
    parser.setResolveBindings(true);
    parser.setSource(JavaCore.createCompilationUnitFrom(javaFile));
    final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
    cu.accept(new ASTVisitor() {

      @Override
      public boolean visit(final ClassInstanceCreation node) {
        ITypeBinding ntb = node.resolveTypeBinding();
        while (ntb != null) {
          if (ntb.getPackage().getName().startsWith(PACKAGE_MODEL)) {
            // it is a wicket model
            final ITypeBinding[] typeArguments = ntb.getTypeArguments();
            for (int i = 0; i < typeArguments.length; i++) {
              ITypeBinding typeArgument = typeArguments[i];
              if (!typeArgument.isArray() && !typeArgument.isNullType() && !typeArgument.isPrimitive() && !"java.lang.String".equals(typeArgument.getBinaryName())) {
                list.addAll(Arrays.asList(typeArgument.getDeclaredFields()));
                return false;
              }
            }
          }
          ntb = ntb.getSuperclass();
        }
        return true;
      }

    });

    return list;
  }

  private static boolean hierarchyContainsComponent(final IType type) throws JavaModelException {
    Assert.isNotNull(type);
    final ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null);
    if (hierarchy != null) {
      final IType[] supertypes = hierarchy.getAllSupertypes(type);
      for (final IType iType : supertypes) {
        if (iType.getFullyQualifiedName().equals(TypeHelper.COMPONENT)) {
          return true;
        }
      }
    }
    return false;
  }

  /**
   * checks if the JavaElement extends Component and has a String (wicketId) as the first CTOR Parameter
   *
   * @throws JavaModelException
   */
  public static boolean isWicketComponent(final IJavaElement javaElement) throws JavaModelException {
    Assert.isNotNull(javaElement);
    if (javaElement instanceof ResolvedSourceMethod) {
      final ResolvedSourceMethod method = (ResolvedSourceMethod) javaElement;
      if ("QComponent;".equals(method.getReturnType())) {
        return true;
      }
      final IType type = method.getDeclaringType();
      if (type != null) {
        if (type.getFullyQualifiedName().equals(TypeHelper.COMPONENT)) {
          return true;
        }
        return hierarchyContainsComponent(type);
      }
    }
    if ((javaElement instanceof ResolvedBinaryMethod)) {
      final ResolvedBinaryMethod method = (ResolvedBinaryMethod) javaElement;
      if ("V;".equals(method.getReturnType())) {
        return true;
      }
      final IType type = method.getDeclaringType();
      if (type != null) {
        if (type.getFullyQualifiedName().equals(TypeHelper.COMPONENT)) {
          return true;
        }
        return hierarchyContainsComponent(type);
      }
    }
    if ((javaElement instanceof ResolvedBinaryType)) {
      final ResolvedBinaryType method = (ResolvedBinaryType) javaElement;
      return hierarchyContainsComponent(method);
    }
    return false;
  }

  public static boolean isWicketJavaElement(final IJavaElement javaElement) throws JavaModelException {
    Assert.isNotNull(javaElement);
    if (javaElement != null && javaElement instanceof NamedMember) {
      if (javaElement.getElementName().equals(DocumentHelper.GET_STRING)) {
        return true;
      } else if (javaElement.getElementType() == IJavaElement.TYPE) {
        final NamedMember method = (NamedMember) javaElement;
        final IType type = method.getTypeRoot().findPrimaryType();
        return hierarchyContainsComponent(type);
      } else if (javaElement.getElementType() == IJavaElement.METHOD) {
        return isWicketComponent(javaElement);
      }
      return isWicketJavaElement(javaElement.getParent());
    }
    return false;
  }

}
TOP

Related Classes of qwickie.util.TypeHelper

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.