View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   https://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.bcel.classfile;
21  
22  import java.io.DataInput;
23  import java.io.DataOutputStream;
24  import java.io.IOException;
25  
26  import org.apache.bcel.Const;
27  import org.apache.bcel.util.Args;
28  
29  /**
30   * This class is derived from <em>Attribute</em> and indicates the main class of a module. There may be at most one
31   * ModuleMainClass attribute in a ClassFile structure.
32   *
33   * @see Attribute
34   */
35  public final class ModuleMainClass extends Attribute {
36  
37      private int mainClassIndex;
38  
39      /**
40       * Constructs object from input stream.
41       *
42       * @param nameIndex Index in constant pool
43       * @param length Content length in bytes
44       * @param input Input stream
45       * @param constantPool Array of constants
46       * @throws IOException if an I/O error occurs.
47       */
48      ModuleMainClass(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException {
49          this(nameIndex, length, 0, constantPool);
50          mainClassIndex = input.readUnsignedShort();
51      }
52  
53      /**
54       * @param nameIndex Index in constant pool
55       * @param length Content length in bytes
56       * @param mainClassIndex Host class index
57       * @param constantPool Array of constants
58       */
59      public ModuleMainClass(final int nameIndex, final int length, final int mainClassIndex, final ConstantPool constantPool) {
60          super(Const.ATTR_NEST_MEMBERS, nameIndex, length, constantPool);
61          this.mainClassIndex = Args.requireU2(mainClassIndex, "mainClassIndex");
62      }
63  
64      /**
65       * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a
66       * physical copy.
67       *
68       * @param c Source to copy.
69       */
70      public ModuleMainClass(final ModuleMainClass c) {
71          this(c.getNameIndex(), c.getLength(), c.getHostClassIndex(), c.getConstantPool());
72      }
73  
74      /**
75       * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. I.e.,
76       * the hierarchy of methods, fields, attributes, etc. spawns a tree of objects.
77       *
78       * @param v Visitor object
79       */
80      @Override
81      public void accept(final Visitor v) {
82          v.visitModuleMainClass(this);
83      }
84  
85      /**
86       * @return deep copy of this attribute
87       */
88      @Override
89      public Attribute copy(final ConstantPool constantPool) {
90          final ModuleMainClass c = (ModuleMainClass) clone();
91          c.setConstantPool(constantPool);
92          return c;
93      }
94  
95      /**
96       * Dump ModuleMainClass attribute to file stream in binary format.
97       *
98       * @param file Output file stream
99       * @throws IOException if an I/O error occurs.
100      */
101     @Override
102     public void dump(final DataOutputStream file) throws IOException {
103         super.dump(file);
104         file.writeShort(mainClassIndex);
105     }
106 
107     /**
108      * @return index into constant pool of host class name.
109      */
110     public int getHostClassIndex() {
111         return mainClassIndex;
112     }
113 
114     /**
115      * @param mainClassIndex the host class index
116      */
117     public void setHostClassIndex(final int mainClassIndex) {
118         this.mainClassIndex = mainClassIndex;
119     }
120 
121     /**
122      * @return String representation
123      */
124     @Override
125     public String toString() {
126         final StringBuilder buf = new StringBuilder();
127         buf.append("ModuleMainClass: ");
128         final String className = super.getConstantPool().getConstantString(mainClassIndex, Const.CONSTANT_Class);
129         buf.append(Utility.compactClassName(className, false));
130         return buf.toString();
131     }
132 }