001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.bcel.classfile; 020 021import java.io.DataInput; 022import java.io.DataOutputStream; 023import java.io.IOException; 024 025import org.apache.bcel.Const; 026import org.apache.bcel.util.Args; 027 028/** 029 * This class is derived from <em>Attribute</em> and represents a constant value, i.e., a default value for initializing 030 * a class field. This class is instantiated by the <em>Attribute.readAttribute()</em> method. 031 * 032 * <pre> 033 * ConstantValue_attribute { 034 * u2 attribute_name_index; 035 * u4 attribute_length; 036 * u2 constantvalue_index; 037 * } 038 * </pre> 039 * @see Attribute 040 */ 041public final class ConstantValue extends Attribute { 042 043 private int constantValueIndex; 044 045 /** 046 * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a 047 * physical copy. 048 * 049 * @param c Source to copy. 050 */ 051 public ConstantValue(final ConstantValue c) { 052 this(c.getNameIndex(), c.getLength(), c.getConstantValueIndex(), c.getConstantPool()); 053 } 054 055 /** 056 * Constructs object from input stream. 057 * 058 * @param nameIndex Name index in constant pool 059 * @param length Content length in bytes 060 * @param input Input stream 061 * @param constantPool Array of constants 062 * @throws IOException if an I/O error occurs. 063 */ 064 ConstantValue(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { 065 this(nameIndex, length, input.readUnsignedShort(), constantPool); 066 } 067 068 /** 069 * @param nameIndex Name index in constant pool 070 * @param length Content length in bytes 071 * @param constantValueIndex Index in constant pool 072 * @param constantPool Array of constants 073 */ 074 public ConstantValue(final int nameIndex, final int length, final int constantValueIndex, final ConstantPool constantPool) { 075 super(Const.ATTR_CONSTANT_VALUE, nameIndex, Args.require(length, 2, "ConstantValue attribute length"), constantPool); 076 this.constantValueIndex = constantValueIndex; 077 } 078 079 /** 080 * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. 081 * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. 082 * 083 * @param v Visitor object 084 */ 085 @Override 086 public void accept(final Visitor v) { 087 v.visitConstantValue(this); 088 } 089 090 /** 091 * @return deep copy of this attribute 092 */ 093 @Override 094 public Attribute copy(final ConstantPool constantPool) { 095 final ConstantValue c = (ConstantValue) clone(); 096 c.setConstantPool(constantPool); 097 return c; 098 } 099 100 /** 101 * Dump constant value attribute to file stream on binary format. 102 * 103 * @param file Output file stream 104 * @throws IOException if an I/O error occurs. 105 */ 106 @Override 107 public void dump(final DataOutputStream file) throws IOException { 108 super.dump(file); 109 file.writeShort(constantValueIndex); 110 } 111 112 /** 113 * @return Index in constant pool of constant value. 114 */ 115 public int getConstantValueIndex() { 116 return constantValueIndex; 117 } 118 119 /** 120 * @param constantValueIndex the index info the constant pool of this constant value 121 */ 122 public void setConstantValueIndex(final int constantValueIndex) { 123 this.constantValueIndex = constantValueIndex; 124 } 125 126 /** 127 * @return String representation of constant value. 128 */ 129 @Override 130 public String toString() { 131 Constant c = super.getConstantPool().getConstant(constantValueIndex); 132 final String buf; 133 final int i; 134 // Print constant to string depending on its type 135 switch (c.getTag()) { 136 case Const.CONSTANT_Long: 137 buf = String.valueOf(((ConstantLong) c).getBytes()); 138 break; 139 case Const.CONSTANT_Float: 140 buf = String.valueOf(((ConstantFloat) c).getBytes()); 141 break; 142 case Const.CONSTANT_Double: 143 buf = String.valueOf(((ConstantDouble) c).getBytes()); 144 break; 145 case Const.CONSTANT_Integer: 146 buf = String.valueOf(((ConstantInteger) c).getBytes()); 147 break; 148 case Const.CONSTANT_String: 149 i = ((ConstantString) c).getStringIndex(); 150 c = super.getConstantPool().getConstantUtf8(i); 151 buf = "\"" + Utility.convertString(((ConstantUtf8) c).getBytes()) + "\""; 152 break; 153 default: 154 throw new IllegalStateException("Type of ConstValue invalid: " + c); 155 } 156 return buf; 157 } 158}