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 
  28 import com.sun.org.apache.bcel.internal.Const;
  29 
  30 /**
  31  * This class represents an entry in the exports table of the Module attribute.
  32  * Each entry describes a package which may open the parent module.
  33  *
  34  * @see   Module
  35  * @since 6.4.0
  36  */
  37 public final class ModuleExports implements Cloneable, Node {
  38 
  39     private final int exports_index;  // points to CONSTANT_Package_info
  40     private final int exports_flags;
  41     private final int exports_to_count;
  42     private final int[] exports_to_index;  // points to CONSTANT_Module_info
  43 
  44 
  45     /**
  46      * Construct object from file stream.
  47      *
  48      * @param file Input stream
  49      * @throws IOException if an I/O Exception occurs in readUnsignedShort
  50      */
  51     ModuleExports(final DataInput file) throws IOException {
  52         exports_index = file.readUnsignedShort();
  53         exports_flags = file.readUnsignedShort();
  54         exports_to_count = file.readUnsignedShort();
  55         exports_to_index = new int[exports_to_count];
  56         for (int i = 0; i < exports_to_count; i++) {
  57             exports_to_index[i] = file.readUnsignedShort();
  58         }
  59     }
  60 
  61 
  62     /**
  63      * Called by objects that are traversing the nodes of the tree implicitely
  64      * defined by the contents of a Java class. I.e., the hierarchy of methods,
  65      * fields, attributes, etc. spawns a tree of objects.
  66      *
  67      * @param v Visitor object
  68      */
  69     @Override
  70     public void accept( final Visitor v ) {
  71         v.visitModuleExports(this);
  72     }
  73 
  74     // TODO add more getters and setters?
  75 
  76     /**
  77      * Dump table entry to file stream in binary format.
  78      *
  79      * @param file Output file stream
  80      * @throws IOException if an I/O Exception occurs in writeShort
  81      */
  82     public void dump( final DataOutputStream file ) throws IOException {
  83         file.writeShort(exports_index);
  84         file.writeShort(exports_flags);
  85         file.writeShort(exports_to_count);
  86         for (final int entry : exports_to_index) {
  87             file.writeShort(entry);
  88         }
  89     }
  90 
  91 
  92     /**
  93      * @return String representation
  94      */
  95     @Override
  96     public String toString() {
  97         return "exports(" + exports_index + ", " + exports_flags + ", " + exports_to_count + ", ...)";
  98     }
  99 
 100 
 101     /**
 102      * @return Resolved string representation
 103      */
 104     public String toString( final ConstantPool constant_pool ) {
 105         final StringBuilder buf = new StringBuilder();
 106         final String package_name = constant_pool.constantToString(exports_index, Const.CONSTANT_Package);
 107         buf.append(Utility.compactClassName(package_name, false));
 108         buf.append(", ").append(String.format("%04x", exports_flags));
 109         buf.append(", to(").append(exports_to_count).append("):\n");
 110         for (final int index : exports_to_index) {
 111             final String module_name = constant_pool.getConstantString(index, Const.CONSTANT_Module);
 112             buf.append("      ").append(Utility.compactClassName(module_name, false)).append("\n");
 113         }
 114         return buf.substring(0, buf.length()-1); // remove the last newline
 115     }
 116 
 117 
 118     /**
 119      * @return deep copy of this object
 120      */
 121     public ModuleExports copy() {
 122         try {
 123             return (ModuleExports) clone();
 124         } catch (final CloneNotSupportedException e) {
 125             // TODO should this throw?
 126         }
 127         return null;
 128     }
 129 }