001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.bcel.classfile; 019 020import java.io.DataInput; 021import java.io.DataOutputStream; 022import java.io.IOException; 023 024import org.apache.bcel.Const; 025 026/** 027 * This class represents an entry in the opens table of the Module attribute. 028 * Each entry describes a package which the parent module opens. 029 * 030 * @see Module 031 * @since 6.4.0 032 */ 033public final class ModuleOpens implements Cloneable, Node { 034 035 private final int opens_index; // points to CONSTANT_Package_info 036 private final int opens_flags; 037 private final int opens_to_count; 038 private final int[] opens_to_index; // points to CONSTANT_Module_info 039 040 041 /** 042 * Construct object from file stream. 043 * 044 * @param file Input stream 045 * @throws IOException if an I/O Exception occurs in readUnsignedShort 046 */ 047 ModuleOpens(final DataInput file) throws IOException { 048 opens_index = file.readUnsignedShort(); 049 opens_flags = file.readUnsignedShort(); 050 opens_to_count = file.readUnsignedShort(); 051 opens_to_index = new int[opens_to_count]; 052 for (int i = 0; i < opens_to_count; i++) { 053 opens_to_index[i] = file.readUnsignedShort(); 054 } 055 } 056 057 058 /** 059 * Called by objects that are traversing the nodes of the tree implicitely 060 * defined by the contents of a Java class. I.e., the hierarchy of methods, 061 * fields, attributes, etc. spawns a tree of objects. 062 * 063 * @param v Visitor object 064 */ 065 @Override 066 public void accept( final Visitor v ) { 067 v.visitModuleOpens(this); 068 } 069 070 // TODO add more getters and setters? 071 072 /** 073 * Dump table entry to file stream in binary format. 074 * 075 * @param file Output file stream 076 * @throws IOException if an I/O Exception occurs in writeShort 077 */ 078 public void dump( final DataOutputStream file ) throws IOException { 079 file.writeShort(opens_index); 080 file.writeShort(opens_flags); 081 file.writeShort(opens_to_count); 082 for (final int entry : opens_to_index) { 083 file.writeShort(entry); 084 } 085 } 086 087 088 /** 089 * @return String representation 090 */ 091 @Override 092 public String toString() { 093 return "opens(" + opens_index + ", " + opens_flags + ", " + opens_to_count + ", ...)"; 094 } 095 096 097 /** 098 * @return Resolved string representation 099 */ 100 public String toString( final ConstantPool constant_pool ) { 101 final StringBuilder buf = new StringBuilder(); 102 final String package_name = constant_pool.constantToString(opens_index, Const.CONSTANT_Package); 103 buf.append(Utility.compactClassName(package_name, false)); 104 buf.append(", ").append(String.format("%04x", opens_flags)); 105 buf.append(", to(").append(opens_to_count).append("):\n"); 106 for (final int index : opens_to_index) { 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}