RecordComponentInfo.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  *  Unless required by applicable law or agreed to in writing, software
  12.  *  distributed under the License is distributed on an "AS IS" BASIS,
  13.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  *  See the License for the specific language governing permissions and
  15.  *  limitations under the License.
  16.  */
  17. package org.apache.bcel.classfile;

  18. import java.io.DataInput;
  19. import java.io.DataOutputStream;
  20. import java.io.IOException;

  21. import org.apache.bcel.Const;

  22. /**
  23.  * Record component info from a record. Instances from this class maps
  24.  * every component from a given record.
  25.  *
  26.  * @see <a href="https://docs.oracle.com/javase/specs/jvms/se14/preview/specs/records-jvms.html#jvms-4.7.30">
  27.  *      The Java Virtual Machine Specification, Java SE 14 Edition, Records (preview)</a>
  28.  * @since 6.9.0
  29.  */
  30. public class RecordComponentInfo implements Node {

  31.     private final int index;
  32.     private final int descriptorIndex;
  33.     private final Attribute[] attributes;
  34.     private final ConstantPool constantPool;

  35.     /**
  36.      * Constructs a new instance from an input stream.
  37.      *
  38.      * @param input        Input stream
  39.      * @param constantPool Array of constants
  40.      * @throws IOException if an I/O error occurs.
  41.      */
  42.     public RecordComponentInfo(final DataInput input, final ConstantPool constantPool) throws IOException {
  43.         this.index = input.readUnsignedShort();
  44.         this.descriptorIndex = input.readUnsignedShort();
  45.         final int attributesCount = input.readUnsignedShort();
  46.         this.attributes = new Attribute[attributesCount];
  47.         for (int j = 0; j < attributesCount; j++) {
  48.             attributes[j] = Attribute.readAttribute(input, constantPool);
  49.         }
  50.         this.constantPool = constantPool;
  51.     }

  52.     @Override
  53.     public void accept(final Visitor v) {
  54.         v.visitRecordComponent(this);
  55.     }

  56.     /**
  57.      * Dumps contents into a file stream in binary format.
  58.      *
  59.      * @param file Output file stream
  60.      * @throws IOException if an I/O error occurs.
  61.      */
  62.     public void dump(final DataOutputStream file) throws IOException {
  63.         file.writeShort(index);
  64.         file.writeShort(descriptorIndex);
  65.         file.writeShort(attributes.length);
  66.         for (final Attribute attribute : attributes) {
  67.             attribute.dump(file);
  68.         }
  69.     }

  70.     /**
  71.      * Gets all attributes.
  72.      *
  73.      * @return all attributes.
  74.      */
  75.     public Attribute[] getAttributes() {
  76.         return attributes;
  77.     }

  78.     /**
  79.      * Gets the constant pool.
  80.      *
  81.      * @return Constant pool.
  82.      */
  83.     public ConstantPool getConstantPool() {
  84.         return constantPool;
  85.     }

  86.     /**
  87.      * Gets the description index.
  88.      *
  89.      * @return index in constant pool of this record component descriptor.
  90.      */
  91.     public int getDescriptorIndex() {
  92.         return descriptorIndex;
  93.     }

  94.     /**
  95.      * Gets the name index.
  96.      *
  97.      * @return index in constant pool of this record component name.
  98.      */
  99.     public int getIndex() {
  100.         return index;
  101.     }

  102.     /**
  103.      * Converts this instance to a String suitable for debugging.
  104.      *
  105.      * @return a String suitable for debugging.
  106.      */
  107.     @Override
  108.     public String toString() {
  109.         final StringBuilder buf = new StringBuilder();
  110.         buf.append("RecordComponentInfo(");
  111.         buf.append(constantPool.getConstantString(index, Const.CONSTANT_Utf8));
  112.         buf.append(",");
  113.         buf.append(constantPool.getConstantString(descriptorIndex, Const.CONSTANT_Utf8));
  114.         buf.append(",");
  115.         buf.append(attributes.length);
  116.         buf.append("):\n");
  117.         for (final Attribute attribute : attributes) {
  118.             buf.append("  ").append(attribute.toString()).append("\n");
  119.         }
  120.         return buf.substring(0, buf.length() - 1); // remove the last newline
  121.     }

  122. }