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