1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.bcel.internal.classfile;
  23 
  24 import java.io.DataInput;
  25 import java.io.DataOutputStream;
  26 import java.io.IOException;
  27 import java.util.Arrays;
  28 
  29 import com.sun.org.apache.bcel.internal.Const;
  30 
  31 /**
  32  * This class represents a bootstrap method attribute, i.e., the bootstrap
  33  * method ref, the number of bootstrap arguments and an array of the
  34  * bootstrap arguments.
  35  *
  36  * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.23">
  37  * The class File Format : The BootstrapMethods Attribute</a>
  38  * @since 6.0
  39  */
  40 public class BootstrapMethod implements Cloneable {
  41 
  42     /** Index of the CONSTANT_MethodHandle_info structure in the constant_pool table */
  43     private int bootstrap_method_ref;
  44 
  45     /** Array of references to the constant_pool table */
  46     private int[] bootstrap_arguments;
  47 
  48 
  49     /**
  50      * Initialize from another object.
  51      */
  52     public BootstrapMethod(final BootstrapMethod c) {
  53         this(c.getBootstrapMethodRef(), c.getBootstrapArguments());
  54     }
  55 
  56     /**
  57      * Construct object from input stream.
  58      *
  59      * @param input Input stream
  60      * @throws IOException
  61      */
  62     BootstrapMethod(final DataInput input) throws IOException {
  63         this(input.readUnsignedShort(), input.readUnsignedShort());
  64 
  65         for (int i = 0; i < bootstrap_arguments.length; i++) {
  66             bootstrap_arguments[i] = input.readUnsignedShort();
  67         }
  68     }
  69 
  70     // helper method
  71     private BootstrapMethod(final int bootstrap_method_ref, final int num_bootstrap_arguments) {
  72         this(bootstrap_method_ref, new int[num_bootstrap_arguments]);
  73     }
  74 
  75     /**
  76      * @param bootstrap_method_ref int index into constant_pool of CONSTANT_MethodHandle
  77      * @param bootstrap_arguments int[] indices into constant_pool of CONSTANT_<type>_info
  78      */
  79     public BootstrapMethod(final int bootstrap_method_ref, final int[] bootstrap_arguments) {
  80         this.bootstrap_method_ref = bootstrap_method_ref;
  81         this.bootstrap_arguments = bootstrap_arguments;
  82     }
  83 
  84     /**
  85      * @return index into constant_pool of bootstrap_method
  86      */
  87     public int getBootstrapMethodRef() {
  88         return bootstrap_method_ref;
  89     }
  90 
  91     /**
  92      * @param bootstrap_method_ref int index into constant_pool of CONSTANT_MethodHandle
  93      */
  94     public void setBootstrapMethodRef(final int bootstrap_method_ref) {
  95         this.bootstrap_method_ref = bootstrap_method_ref;
  96     }
  97 
  98     /**
  99      * @return int[] of bootstrap_method indices into constant_pool of CONSTANT_<type>_info
 100      */
 101     public int[] getBootstrapArguments() {
 102         return bootstrap_arguments;
 103     }
 104 
 105     /**
 106      * @return count of number of boostrap arguments
 107      */
 108     public int getNumBootstrapArguments() {
 109         return bootstrap_arguments.length;
 110     }
 111 
 112     /**
 113      * @param bootstrap_arguments int[] indices into constant_pool of CONSTANT_<type>_info
 114      */
 115     public void setBootstrapArguments(final int[] bootstrap_arguments) {
 116         this.bootstrap_arguments = bootstrap_arguments;
 117     }
 118 
 119     /**
 120      * @return String representation.
 121      */
 122     @Override
 123     public final String toString() {
 124         return "BootstrapMethod(" + bootstrap_method_ref + ", " + bootstrap_arguments.length + ", "
 125                + Arrays.toString(bootstrap_arguments) + ")";
 126     }
 127 
 128     /**
 129      * @return Resolved string representation
 130      */
 131     public final String toString( final ConstantPool constant_pool ) {
 132         final StringBuilder buf = new StringBuilder();
 133         String bootstrap_method_name;
 134         bootstrap_method_name = constant_pool.constantToString(bootstrap_method_ref,
 135                 Const.CONSTANT_MethodHandle);
 136         buf.append(Utility.compactClassName(bootstrap_method_name));
 137         final int num_bootstrap_arguments = bootstrap_arguments.length;
 138         if (num_bootstrap_arguments > 0) {
 139             buf.append("\n     Method Arguments:");
 140             for (int i = 0; i < num_bootstrap_arguments; i++) {
 141                 buf.append("\n     ").append(i).append(": ");
 142                 buf.append(constant_pool.constantToString(constant_pool.getConstant(bootstrap_arguments[i])));
 143             }
 144         }
 145         return buf.toString();
 146     }
 147 
 148     /**
 149      * Dump object to file stream in binary format.
 150      *
 151      * @param file Output file stream
 152      * @throws IOException
 153      */
 154     public final void dump(final DataOutputStream file) throws IOException {
 155         file.writeShort(bootstrap_method_ref);
 156         file.writeShort(bootstrap_arguments.length);
 157         for (final int bootstrap_argument : bootstrap_arguments) {
 158             file.writeShort(bootstrap_argument);
 159         }
 160     }
 161 
 162     /**
 163      * @return deep copy of this object
 164      */
 165     public BootstrapMethod copy() {
 166         try {
 167             return (BootstrapMethod) clone();
 168         } catch (final CloneNotSupportedException e) {
 169             // TODO should this throw?
 170         }
 171         return null;
 172     }
 173 }