1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 package com.sun.org.apache.bcel.internal.classfile; 21 22 import java.io.DataInput; 23 import java.io.DataInputStream; 24 import java.io.DataOutputStream; 25 import java.io.IOException; 26 27 import com.sun.org.apache.bcel.internal.Const; 28 29 /** 30 * Abstract super class for fields and methods. 31 * 32 * @version $Id: FieldOrMethod.java 1750029 2016-06-23 22:14:38Z sebb $ 33 */ 34 public abstract class FieldOrMethod extends AccessFlags implements Cloneable, Node { 35 private int name_index; // Points to field name in constant pool 36 private int signature_index; // Points to encoded signature 37 private Attribute[] attributes; // Collection of attributes 38 private int attributes_count; // No. of attributes 39 40 // @since 6.0 41 private AnnotationEntry[] annotationEntries; // annotations defined on the field or method 42 43 private ConstantPool constant_pool; 44 45 private String signatureAttributeString = null; 46 private boolean searchedForSignatureAttribute = false; 47 48 FieldOrMethod() { 49 } 50 51 /** 52 * Initialize from another object. Note that both objects use the same 53 * references (shallow copy). Use clone() for a physical copy. 54 */ 55 protected FieldOrMethod(final FieldOrMethod c) { 56 this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(), 57 c.getAttributes(), c.getConstantPool()); 58 } 59 60 /** 61 * Construct object from file stream. 62 * 63 * @param file Input stream 64 * @throws IOException 65 * @throws ClassFormatException 66 * @deprecated (6.0) Use 67 * {@link #FieldOrMethod(java.io.DataInput, ConstantPool)} instead. 68 */ 69 @java.lang.Deprecated 70 protected FieldOrMethod(final DataInputStream file, 71 final ConstantPool constant_pool) throws IOException, 72 ClassFormatException { 73 this((DataInput) file, constant_pool); 74 } 75 76 /** 77 * Construct object from file stream. 78 * 79 * @param file Input stream 80 * @throws IOException 81 * @throws ClassFormatException 82 */ 83 protected FieldOrMethod(final DataInput file, 84 final ConstantPool constant_pool) throws IOException, ClassFormatException { 85 this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null, 86 constant_pool); 87 attributes_count = file.readUnsignedShort(); 88 attributes = new Attribute[attributes_count]; 89 for (int i = 0; i < attributes_count; i++) { 90 attributes[i] = Attribute.readAttribute(file, constant_pool); 91 } 92 } 93 94 /** 95 * @param access_flags Access rights of method 96 * @param name_index Points to field name in constant pool 97 * @param signature_index Points to encoded signature 98 * @param attributes Collection of attributes 99 * @param constant_pool Array of constants 100 */ 101 protected FieldOrMethod(final int access_flags, final int name_index, final int signature_index, 102 final Attribute[] attributes, final ConstantPool constant_pool) { 103 super(access_flags); 104 this.name_index = name_index; 105 this.signature_index = signature_index; 106 this.constant_pool = constant_pool; 107 setAttributes(attributes); 108 } 109 110 /** 111 * Dump object to file stream on binary format. 112 * 113 * @param file Output file stream 114 * @throws IOException 115 */ 116 public final void dump(final DataOutputStream file) throws IOException { 117 file.writeShort(super.getAccessFlags()); 118 file.writeShort(name_index); 119 file.writeShort(signature_index); 120 file.writeShort(attributes_count); 121 122 for(int i=0; i < attributes_count; i++) { 123 attributes[i].dump(file); 124 } 125 } 126 127 /** 128 * @return Collection of object attributes. 129 */ 130 public final Attribute[] getAttributes() { 131 return attributes; 132 } 133 134 /** 135 * @param attributes Collection of object attributes. 136 */ 137 public final void setAttributes(final Attribute[] attributes) { 138 this.attributes = attributes; 139 this.attributes_count = attributes != null ? attributes.length : 0; 140 } 141 142 /** 143 * @return Constant pool used by this object. 144 */ 145 public final ConstantPool getConstantPool() { 146 return constant_pool; 147 } 148 149 /** 150 * @param constant_pool Constant pool to be used for this object. 151 */ 152 public final void setConstantPool(final ConstantPool constant_pool) { 153 this.constant_pool = constant_pool; 154 } 155 156 /** 157 * @return Index in constant pool of object's name. 158 */ 159 public final int getNameIndex() { 160 return name_index; 161 } 162 163 /** 164 * @param name_index Index in constant pool of object's name. 165 */ 166 public final void setNameIndex(final int name_index) { 167 this.name_index = name_index; 168 } 169 170 /** 171 * @return Index in constant pool of field signature. 172 */ 173 public final int getSignatureIndex() { 174 return signature_index; 175 } 176 177 /** 178 * @param signature_index Index in constant pool of field signature. 179 */ 180 public final void setSignatureIndex(final int signature_index) { 181 this.signature_index = signature_index; 182 } 183 184 /** 185 * @return Name of object, i.e., method name or field name 186 */ 187 public final String getName() { 188 ConstantUtf8 c; 189 c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8); 190 return c.getBytes(); 191 } 192 193 /** 194 * @return String representation of object's type signature (java style) 195 */ 196 public final String getSignature() { 197 ConstantUtf8 c; 198 c = (ConstantUtf8) constant_pool.getConstant(signature_index, Const.CONSTANT_Utf8); 199 return c.getBytes(); 200 } 201 202 /** 203 * @return deep copy of this field 204 */ 205 protected FieldOrMethod copy_(final ConstantPool _constant_pool) { 206 FieldOrMethod c = null; 207 208 try { 209 c = (FieldOrMethod) clone(); 210 } catch (final CloneNotSupportedException e) { 211 // ignored, but will cause NPE ... 212 } 213 214 c.constant_pool = constant_pool; 215 c.attributes = new Attribute[attributes_count]; 216 c.attributes_count = attributes_count; 217 218 for (int i = 0; i < attributes_count; i++) { 219 c.attributes[i] = attributes[i].copy(constant_pool); 220 } 221 222 return c; 223 } 224 225 /** 226 * @return Annotations on the field or method 227 * @since 6.0 228 */ 229 public AnnotationEntry[] getAnnotationEntries() { 230 if (annotationEntries == null) { 231 annotationEntries = AnnotationEntry.createAnnotationEntries(getAttributes()); 232 } 233 234 return annotationEntries; 235 } 236 237 /** 238 * Hunts for a signature attribute on the member and returns its contents. 239 * So where the 'regular' signature may be (Ljava/util/Vector;)V the 240 * signature attribute may in fact say 241 * 'Ljava/lang/Vector<Ljava/lang/String>;' Coded for performance - 242 * searches for the attribute only when requested - only searches for it 243 * once. 244 * 245 * @since 6.0 246 */ 247 public final String getGenericSignature() { 248 if (!searchedForSignatureAttribute) { 249 boolean found = false; 250 for (int i = 0; !found && i < attributes.length; i++) { 251 if (attributes[i] instanceof Signature) { 252 signatureAttributeString = ((Signature) attributes[i]) 253 .getSignature(); 254 found = true; 255 } 256 } 257 searchedForSignatureAttribute = true; 258 } 259 return signatureAttributeString; 260 } 261 }