blob: 6ccebe68e464b9447d9e541b350379f048debb1e [file] [log] [blame]
/*
* 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.
*/
/*
* Contributor(s): Thomas Ball
*/
package org.netbeans.modules.classfile;
import java.io.*;
import java.util.*;
/**
* Base class for variables and methods.
*
* @author Thomas Ball
*/
public abstract class Field {
private int iName;
private int iType;
private String _name;
private String _type;
int access;
ClassFile classFile;
Map<ClassName,Annotation> annotations;
String typeSignature;
AttributeMap attributes;
/** Creates new Field */
Field(DataInputStream in, ConstantPool pool, ClassFile classFile,
boolean includeCode) throws IOException {
access = in.readUnsignedShort();
iName = in.readUnsignedShort();
iType = in.readUnsignedShort();
this.classFile = classFile;
attributes = AttributeMap.load(in, pool, includeCode);
}
Field(String name, String type, ClassFile classFile) {
access = 0;
_name = name;
_type = type;
this.classFile = classFile;
attributes = new AttributeMap(new HashMap<String,byte[]>(1));
}
public final String getName() {
if (_name == null && iName != 0) {
CPUTF8Info utfName = (CPUTF8Info)classFile.constantPool.get(iName);
_name = utfName.getName();
}
return _name;
}
public final String getDescriptor() {
if (_type == null && iType != 0) {
CPUTF8Info utfType = (CPUTF8Info)classFile.constantPool.get(iType);
_type = utfType.getName();
}
return _type;
}
public abstract String getDeclaration();
public final int getAccess() {
return access;
}
public final boolean isStatic() {
return Access.isStatic(access);
}
public final boolean isPublic() {
return Access.isPublic(access);
}
public final boolean isProtected() {
return Access.isProtected(access);
}
public final boolean isPackagePrivate() {
return Access.isPackagePrivate(access);
}
public final boolean isPrivate() {
return Access.isPrivate(access);
}
public final boolean isDeprecated() {
return attributes.get("Deprecated") != null;
}
public final boolean isSynthetic() {
return attributes.get("Synthetic") != null;
}
/**
* Returns the class file this field is defined in.
* @return the class file of this field.
*/
public final ClassFile getClassFile() {
return classFile;
}
/**
* Returns the generic type information associated with this field.
* If this field does not have generic type information, then null
* is returned.
*/
public String getTypeSignature() {
if (typeSignature == null) {
DataInputStream in = attributes.getStream("Signature"); // NOI18N
if (in != null) {
try {
int index = in.readUnsignedShort();
CPUTF8Info entry =
(CPUTF8Info)classFile.constantPool.get(index);
typeSignature = entry.getName();
in.close();
} catch (IOException e) {
throw new InvalidClassFileAttributeException("invalid Signature attribute", e);
}
}
}
return typeSignature;
}
void setTypeSignature(String sig) {
typeSignature = sig;
}
/**
* Returns al<ClassName,Annotation>l runtime annotations defined for this field. Inherited
* annotations are not included in this collection.
*/
public final Collection<Annotation> getAnnotations() {
loadAnnotations();
return annotations.values();
}
/**
* Returns the annotation for a specified annotation type, or null if
* no annotation of that type exists for this field.
*/
public final Annotation getAnnotation(final ClassName annotationClass) {
loadAnnotations();
return annotations.get(annotationClass);
}
/**
* Returns true if an annotation of the specified type is defined for
* this field.
*/
public final boolean isAnnotationPresent(final ClassName annotationClass) {
loadAnnotations();
return annotations.get(annotationClass) != null;
}
/**
* Returns a map of the raw attributes for this field. The
* keys for this map are the names of the attributes (as Strings,
* not constant pool indexes). The values are byte arrays that
* hold the contents of the attribute. If the ClassFile was
* created with an <code>includeCode</code> parameter that is
* false, then <b>Code</b> attributes are not included in this map.
*
* @see org.netbeans.modules.classfile.ClassFile#getAttributes
*/
public final AttributeMap getAttributes(){
return attributes;
}
void loadAnnotations() {
if (annotations == null)
annotations = ClassFile.buildAnnotationMap(classFile.constantPool,
attributes);
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
String name = getName();
if (name != null) {
sb.append(getName());
sb.append(' ');
}
if (isSynthetic())
sb.append("(synthetic)"); //NOI18N
if (isDeprecated())
sb.append("(deprecated)"); //NOI18N
sb.append("type="); //NOI18N
sb.append(getDescriptor());
if (getTypeSignature() != null) {
sb.append(", signature="); //NOI18N
sb.append(typeSignature);
}
sb.append(", access="); //NOI18N
sb.append(Access.toString(access));
loadAnnotations();
if (annotations.size() > 0) {
Iterator<Annotation> iter = annotations.values().iterator();
sb.append(", annotations={ ");
while (iter.hasNext()) {
sb.append(iter.next().toString());
if (iter.hasNext())
sb.append(", ");
}
sb.append(" }");
}
return sb.toString();
}
}