ModuleExports.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.  * This class represents an entry in the exports table of the Module attribute. Each entry describes a package which may
  24.  * open the parent module.
  25.  *
  26.  * @see Module
  27.  * @since 6.4.0
  28.  */
  29. public final class ModuleExports implements Cloneable, Node {

  30.     private static String getToModuleNameAtIndex(final ConstantPool constantPool, final int index) {
  31.         return constantPool.getConstantString(index, Const.CONSTANT_Module);
  32.     }
  33.     private final int exportsIndex; // points to CONSTANT_Package_info
  34.     private final int exportsFlags;
  35.     private final int exportsToCount;

  36.     private final int[] exportsToIndex; // points to CONSTANT_Module_info

  37.     /**
  38.      * Constructs object from file stream.
  39.      *
  40.      * @param file Input stream
  41.      * @throws IOException if an I/O Exception occurs in readUnsignedShort
  42.      */
  43.     ModuleExports(final DataInput file) throws IOException {
  44.         exportsIndex = file.readUnsignedShort();
  45.         exportsFlags = file.readUnsignedShort();
  46.         exportsToCount = file.readUnsignedShort();
  47.         exportsToIndex = new int[exportsToCount];
  48.         for (int i = 0; i < exportsToCount; i++) {
  49.             exportsToIndex[i] = file.readUnsignedShort();
  50.         }
  51.     }

  52.     /**
  53.      * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class.
  54.      * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects.
  55.      *
  56.      * @param v Visitor object
  57.      */
  58.     @Override
  59.     public void accept(final Visitor v) {
  60.         v.visitModuleExports(this);
  61.     }

  62.     /**
  63.      * @return deep copy of this object
  64.      */
  65.     public ModuleExports copy() {
  66.         try {
  67.             return (ModuleExports) clone();
  68.         } catch (final CloneNotSupportedException e) {
  69.             // TODO should this throw?
  70.         }
  71.         return null;
  72.     }

  73.     /**
  74.      * Dump table entry to file stream in binary format.
  75.      *
  76.      * @param file Output file stream
  77.      * @throws IOException if an I/O Exception occurs in writeShort
  78.      */
  79.     public void dump(final DataOutputStream file) throws IOException {
  80.         file.writeShort(exportsIndex);
  81.         file.writeShort(exportsFlags);
  82.         file.writeShort(exportsToCount);
  83.         for (final int entry : exportsToIndex) {
  84.             file.writeShort(entry);
  85.         }
  86.     }

  87.     /**
  88.      * Gets the flags for this ModuleExports.
  89.      * @return the exportsFlags
  90.      * @since 6.10.0
  91.      */
  92.     public int getExportsFlags() {
  93.         return exportsFlags;
  94.     }

  95.     /**
  96.      * Gets the exported package name.
  97.      * @param constantPool the constant pool from the ClassFile
  98.      * @return the exported package name
  99.      * @since 6.10.0
  100.      */
  101.     public String getPackageName(final ConstantPool constantPool) {
  102.         return constantPool.constantToString(exportsIndex, Const.CONSTANT_Package);
  103.     }

  104.     /**
  105.      * Gets an array of module names for this ModuleExports.
  106.      * @param constantPool Array of constants usually obtained from the ClassFile object
  107.      * @return array of module names following 'exports to'
  108.      * @since 6.10.0
  109.      */
  110.     public String[] getToModuleNames(final ConstantPool constantPool) {
  111.         final String[] toModuleNames = new String[exportsToCount];
  112.         for (int i = 0; i < exportsToCount; i++) {
  113.             toModuleNames[i] = getToModuleNameAtIndex(constantPool, exportsToIndex[i]);
  114.         }
  115.         return toModuleNames;
  116.     }

  117.     /**
  118.      * @return String representation
  119.      */
  120.     @Override
  121.     public String toString() {
  122.         return "exports(" + exportsIndex + ", " + exportsFlags + ", " + exportsToCount + ", ...)";
  123.     }

  124.     /**
  125.      * @return Resolved string representation
  126.      */
  127.     public String toString(final ConstantPool constantPool) {
  128.         final StringBuilder buf = new StringBuilder();
  129.         final String packageName = getPackageName(constantPool);
  130.         buf.append(packageName);
  131.         buf.append(", ").append(String.format("%04x", exportsFlags));
  132.         buf.append(", to(").append(exportsToCount).append("):\n");
  133.         for (final int index : exportsToIndex) {
  134.             final String moduleName = getToModuleNameAtIndex(constantPool, index);
  135.             buf.append("      ").append(moduleName).append("\n");
  136.         }
  137.         return buf.substring(0, buf.length() - 1); // remove the last newline
  138.     }
  139. }