/******************************************************************************* * Copyright (c) 2004, 2008 IBM Corporation and others. * 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 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.swt.tools.internal; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.FieldDeclaration; import org.eclipse.jdt.core.dom.ImportDeclaration; import org.eclipse.jdt.core.dom.Javadoc; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.TagElement; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.swt.tools.internal.ASTType.TypeResolver; public class ASTClass extends ASTItem implements JNIClass { String sourcePath; MetaData metaData; ASTClass superclass; ASTField[] fields; ASTMethod[] methods; String name, simpleName, superclassName, packageName; String[] imports; String data; int start; TypeResolver resolver = new TypeResolver() { public String findPath(String simpleName) { if (simpleName.equals(ASTClass.this.simpleName)) return sourcePath; String basePath = sourcePath.substring(0, sourcePath.length() - name.length() - ".java".length()); File file = new File(basePath + packageName.replace('.', '/') + "/" + simpleName + ".java"); if (file.exists()) { return file.getAbsolutePath(); } for (int i = 0; i < imports.length; i++) { file = new File(basePath + imports[i].replace('.', '/') + "/" + simpleName + ".java"); if (file.exists()) { return file.getAbsolutePath(); } } return ""; } public String resolve(String simpleName) { if (simpleName.equals(ASTClass.this.simpleName)) return packageName + "." + simpleName; String basePath = sourcePath.substring(0, sourcePath.length() - name.length() - ".java".length()); File file = new File(basePath + packageName.replace('.', '/') + "/" + simpleName + ".java"); if (file.exists()) { return packageName + "." + simpleName; } for (int i = 0; i < imports.length; i++) { file = new File(basePath + imports[i].replace('.', '/') + "/" + simpleName + ".java"); if (file.exists()) { return imports[i] + "." + simpleName; } } return simpleName; } }; public ASTClass(String sourcePath, MetaData metaData) { this.sourcePath = sourcePath; this.metaData = metaData; String source = JNIGenerator.loadFile(sourcePath); ASTParser parser = ASTParser.newParser(AST.JLS4); parser.setSource(source.toCharArray()); CompilationUnit unit = (CompilationUnit)parser.createAST(null); TypeDeclaration type = (TypeDeclaration)unit.types().get(0); simpleName = type.getName().getIdentifier(); packageName = unit.getPackage().getName().getFullyQualifiedName(); name = packageName + "." + simpleName; superclassName = type.getSuperclassType() != null ? type.getSuperclassType().toString() : null; List<ImportDeclaration> imports = unit.imports(); this.imports = new String[imports.size()]; int count = 0; for (Iterator<ImportDeclaration> iterator = imports.iterator(); iterator.hasNext();) { ImportDeclaration imp = iterator.next(); this.imports[count++] = imp.getName().getFullyQualifiedName(); } start = type.getStartPosition(); Javadoc doc = type.getJavadoc(); List<TagElement> tags = null; if (doc != null) { tags = doc.tags(); for (Iterator<TagElement> iterator = tags.iterator(); iterator.hasNext();) { TagElement tag = iterator.next(); if ("@jniclass".equals(tag.getTagName())) { String data = tag.fragments().get(0).toString(); setMetaData(data); break; } } } FieldDeclaration[] fields = type.getFields(); ArrayList<ASTField> fid = new ArrayList<ASTField>(); for (int i = 0; i < fields.length; i++) { FieldDeclaration field = fields[i]; List<VariableDeclarationFragment> fragments = field.fragments(); for (Iterator<VariableDeclarationFragment> iterator = fragments.iterator(); iterator.hasNext();) { VariableDeclarationFragment fragment = iterator.next(); fid.add(new ASTField(this, source, field, fragment)); } } this.fields = fid.toArray(new ASTField[fid.size()]); MethodDeclaration[] methods = type.getMethods(); ArrayList<ASTMethod> mid = new ArrayList<ASTMethod>(); for (int i = 0; i < methods.length; i++) { if (methods[i].getReturnType2() == null) continue; mid.add(new ASTMethod(this, source, methods[i])); } this.methods = mid.toArray(new ASTMethod[mid.size()]); } @Override public int hashCode() { return getName().hashCode(); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof ASTClass)) return false; return ((ASTClass)obj).getName().equals(getName()); } public JNIField[] getDeclaredFields() { JNIField[] result = new JNIField[fields.length]; System.arraycopy(fields, 0, result, 0, result.length); return result; } public JNIMethod[] getDeclaredMethods() { JNIMethod[] result = new JNIMethod[methods.length]; System.arraycopy(methods, 0, result, 0, result.length); return result; } public String getName() { return name; } public JNIClass getSuperclass() { if (superclassName == null) return new ReflectClass(Object.class); if (superclass != null) return superclass; String sourcePath = resolver.findPath(superclassName); return superclass = new ASTClass(sourcePath, metaData); } public String getSimpleName() { return simpleName; } public String getExclude() { return (String)getParam("exclude"); } @Override public String getMetaData() { if (data != null) return data; String key = JNIGenerator.toC(getName()); return metaData.getMetaData(key, ""); } public void setExclude(String str) { setParam("exclude", str); } @Override public void setMetaData(String value) { data = value; } @Override public String toString() { return getName(); } }