| /********************************************************************** |
| * Copyright (c) 2002, 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM - Initial API and implementation |
| **********************************************************************/ |
| |
| package org.eclipse.wtp.releng.tools.component.internalreference; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.Vector; |
| import org.eclipse.jdt.core.Signature; |
| import org.eclipse.jdt.core.util.ClassFormatException; |
| import org.eclipse.jdt.core.util.IClassFileReader; |
| import org.eclipse.jdt.core.util.IConstantPool; |
| import org.eclipse.jdt.core.util.IConstantPoolConstant; |
| import org.eclipse.jdt.core.util.IConstantPoolEntry; |
| import org.eclipse.jdt.core.util.IFieldInfo; |
| import org.eclipse.jdt.core.util.IMethodInfo; |
| import org.eclipse.jdt.core.util.IModifierConstants; |
| import org.eclipse.jdt.internal.core.util.ClassFileReader; |
| import org.eclipse.wtp.releng.tools.component.location.ILocation; |
| |
| /** |
| * A <code>Type</code> is a model object. Types contain references to other types. |
| */ |
| public class Type |
| { |
| private ILocation location; |
| private String name; |
| private IClassFileReader reader; |
| |
| /** |
| * Creates a new type on the given location. |
| * |
| * @param location |
| */ |
| public Type(ILocation location) |
| { |
| this.location = location; |
| reader = null; |
| } |
| |
| private void init() |
| { |
| if (reader == null) |
| { |
| try |
| { |
| reader = new ClassFileReader(getInputBytes(location), IClassFileReader.CONSTANT_POOL | IClassFileReader.METHOD_INFOS | IClassFileReader.FIELD_INFOS); |
| //reader = new ClassFileReader(getInputBytes(location), IClassFileReader.ALL); |
| } |
| catch (ClassFormatException e) |
| { |
| e.printStackTrace(); |
| } |
| catch (IOException e) |
| { |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| /* |
| * Answers the references contained in the class that the reader is reading. |
| * @param reader a class file reader @return Set a set of references. |
| */ |
| private Set getReferencedTypes(IClassFileReader reader) |
| { |
| init(); |
| Set types = new HashSet(); |
| IConstantPool constantPool = reader.getConstantPool(); |
| int poolSize = constantPool.getConstantPoolCount(); |
| for (int i = 0; i < poolSize; i++) |
| { |
| // Extract the constant's referenced class (if that is even relevant) |
| if (constantPool.getEntryKind(i) == IConstantPoolConstant.CONSTANT_Class) |
| { |
| IConstantPoolEntry classEntry = constantPool.decodeEntry(i); |
| String signature = new String(classEntry.getClassInfoName()); |
| int index = signature.lastIndexOf('['); |
| if (index > -1) |
| { |
| // could be an array of a primitive type |
| if (signature.length() - (index + 1) == 1) |
| continue; |
| signature = Signature.toString(signature); |
| signature = signature.substring(0, signature.length() - 2 * (index + 1)); |
| signature = signature.replace('.', '$'); |
| } |
| String typeName = signature.replace('/', '.'); |
| types.add(typeName); |
| } |
| } |
| return types; |
| } |
| |
| /** |
| * @return Set a set of <code>InternalTypeReference</code> objects |
| */ |
| public Set getReferencedTypes() |
| { |
| return getReferencedTypes(reader); |
| } |
| |
| /** |
| * @return String the fully qualified name of the type |
| */ |
| public String getName() |
| { |
| if (name == null) |
| { |
| init(); |
| name = toClassName(reader.getClassName()); |
| } |
| return name; |
| } |
| |
| public String getSuperClass() |
| { |
| init(); |
| char[] superClass = reader.getSuperclassName(); |
| if (superClass != null) |
| return toClassName(superClass); |
| else |
| return null; |
| } |
| |
| public String[] getInterfaces() |
| { |
| init(); |
| char[][] interfaceNames = reader.getInterfaceNames(); |
| String[] interfaces = new String[interfaceNames.length]; |
| for (int i = 0; i < interfaces.length; i++) |
| interfaces[i] = toClassName(interfaceNames[i]); |
| return interfaces; |
| } |
| |
| public IFieldInfo[] getFieldInfo() |
| { |
| init(); |
| return reader.getFieldInfos(); |
| } |
| |
| public IMethodInfo[] getMethodInfo() |
| { |
| init(); |
| return reader.getMethodInfos(); |
| } |
| |
| public IConstantPoolEntry[] getConstantPoolEntries(int kind) |
| { |
| init(); |
| List entries = new Vector(); |
| IConstantPool pool = reader.getConstantPool(); |
| int poolSize = pool.getConstantPoolCount(); |
| for (int i = 0; i < poolSize; i++) |
| if (pool.getEntryKind(i) == kind) |
| entries.add(pool.decodeEntry(i)); |
| return (IConstantPoolEntry[])entries.toArray(new IConstantPoolEntry[0]); |
| } |
| |
| public boolean isInterface() |
| { |
| init(); |
| return ((reader.getAccessFlags() & IModifierConstants.ACC_INTERFACE) == IModifierConstants.ACC_INTERFACE); |
| } |
| |
| public int getAccessFlags() |
| { |
| init(); |
| return reader.getAccessFlags(); |
| } |
| |
| private String toClassName(char[] name) |
| { |
| return new String(name).replace('/', '.'); |
| } |
| |
| /* |
| * Reads the content bytes found at the given location @param location a |
| * location, not <code> null </code> . @return byte[] the content at the |
| * location @throws IOException if a read error occured. |
| */ |
| protected byte[] getInputBytes(ILocation location) throws IOException |
| { |
| InputStream in = null; |
| byte[] fBuffer = new byte[8192]; |
| ByteArrayOutputStream fBytesOut = new ByteArrayOutputStream(8192); |
| try |
| { |
| fBytesOut.reset(); |
| in = location.getInputStream(); |
| for (int read = in.read(fBuffer); read != -1; read = in.read(fBuffer)) |
| { |
| fBytesOut.write(fBuffer, 0, read); |
| } |
| } |
| catch (FileNotFoundException e) |
| { |
| e.printStackTrace(); |
| } |
| finally |
| { |
| in.close(); |
| } |
| return fBytesOut.toByteArray(); |
| } |
| |
| public void reset() |
| { |
| reader = null; |
| } |
| } |