Java tutorial
/* * 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; } }