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 provides table of the Module attribute. Each entry describes a service 028 * implementation that the parent module provides. 029 * 030 * @see Module 031 * @since 6.4.0 032 */ 033public final class ModuleProvides implements Cloneable, Node { 034 035 private final int providesIndex; // points to CONSTANT_Class_info 036 private final int providesWithCount; 037 private final int[] providesWithIndex; // points to CONSTANT_Class_info 038 039 /** 040 * Constructs object from file stream. 041 * 042 * @param file Input stream 043 * @throws IOException if an I/O Exception occurs in readUnsignedShort 044 */ 045 ModuleProvides(final DataInput file) throws IOException { 046 providesIndex = file.readUnsignedShort(); 047 providesWithCount = file.readUnsignedShort(); 048 providesWithIndex = new int[providesWithCount]; 049 for (int i = 0; i < providesWithCount; i++) { 050 providesWithIndex[i] = file.readUnsignedShort(); 051 } 052 } 053 054 /** 055 * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. 056 * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. 057 * 058 * @param v Visitor object 059 */ 060 @Override 061 public void accept(final Visitor v) { 062 v.visitModuleProvides(this); 063 } 064 065 // TODO add more getters and setters? 066 067 /** 068 * @return deep copy of this object 069 */ 070 public ModuleProvides copy() { 071 try { 072 return (ModuleProvides) clone(); 073 } catch (final CloneNotSupportedException e) { 074 // TODO should this throw? 075 } 076 return null; 077 } 078 079 /** 080 * Dump table entry to file stream in binary format. 081 * 082 * @param file Output file stream 083 * @throws IOException if an I/O Exception occurs in writeShort 084 */ 085 public void dump(final DataOutputStream file) throws IOException { 086 file.writeShort(providesIndex); 087 file.writeShort(providesWithCount); 088 for (final int entry : providesWithIndex) { 089 file.writeShort(entry); 090 } 091 } 092 093 /** 094 * @return String representation 095 */ 096 @Override 097 public String toString() { 098 return "provides(" + providesIndex + ", " + providesWithCount + ", ...)"; 099 } 100 101 /** 102 * @return Resolved string representation 103 */ 104 public String toString(final ConstantPool constantPool) { 105 final StringBuilder buf = new StringBuilder(); 106 final String interfaceName = constantPool.constantToString(providesIndex, Const.CONSTANT_Class); 107 buf.append(Utility.compactClassName(interfaceName, false)); 108 buf.append(", with(").append(providesWithCount).append("):\n"); 109 for (final int index : providesWithIndex) { 110 final String className = constantPool.getConstantString(index, Const.CONSTANT_Class); 111 buf.append(" ").append(Utility.compactClassName(className, false)).append("\n"); 112 } 113 return buf.substring(0, buf.length() - 1); // remove the last newline 114 } 115}