001/*** 002 * ASM: a very small and fast Java bytecode manipulation framework 003 * Copyright (c) 2000-2011 INRIA, France Telecom 004 * All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or without 007 * modification, are permitted provided that the following conditions 008 * are met: 009 * 1. Redistributions of source code must retain the above copyright 010 * notice, this list of conditions and the following disclaimer. 011 * 2. Redistributions in binary form must reproduce the above copyright 012 * notice, this list of conditions and the following disclaimer in the 013 * documentation and/or other materials provided with the distribution. 014 * 3. Neither the name of the copyright holders nor the names of its 015 * contributors may be used to endorse or promote products derived from 016 * this software without specific prior written permission. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 028 * THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package io.ebean.enhance.asm.tree; 031 032import io.ebean.enhance.asm.ClassVisitor; 033import io.ebean.enhance.asm.ModuleVisitor; 034import io.ebean.enhance.asm.Opcodes; 035 036import java.util.ArrayList; 037import java.util.List; 038 039/** 040 * A node that represents a module declaration. 041 * 042 * @author Remi Forax 043 */ 044public class ModuleNode extends ModuleVisitor { 045 /** 046 * Module name 047 */ 048 public String name; 049 050 /** 051 * Module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} 052 * and {@code ACC_MANDATED}. 053 */ 054 public int access; 055 056 /** 057 * Version of the module. 058 * May be <tt>null</tt>. 059 */ 060 public String version; 061 062 /** 063 * Name of the main class in internal form 064 * May be <tt>null</tt>. 065 */ 066 public String mainClass; 067 068 /** 069 * A list of packages that are declared by the current module. 070 * May be <tt>null</tt>. 071 */ 072 public List<String> packages; 073 074 /** 075 * A list of modules can are required by the current module. 076 * May be <tt>null</tt>. 077 */ 078 public List<ModuleRequireNode> requires; 079 080 /** 081 * A list of packages that are exported by the current module. 082 * May be <tt>null</tt>. 083 */ 084 public List<ModuleExportNode> exports; 085 086 /** 087 * A list of packages that are opened by the current module. 088 * May be <tt>null</tt>. 089 */ 090 public List<ModuleOpenNode> opens; 091 092 /** 093 * A list of classes in their internal forms that are used 094 * as a service by the current module. May be <tt>null</tt>. 095 */ 096 public List<String> uses; 097 098 /** 099 * A list of services along with their implementations provided 100 * by the current module. May be <tt>null</tt>. 101 */ 102 public List<ModuleProvideNode> provides; 103 104 public ModuleNode(final String name, final int access, 105 final String version) { 106 super(Opcodes.ASM6); 107 this.name = name; 108 this.access = access; 109 this.version = version; 110 } 111 112 public ModuleNode(final int api, 113 final String name, 114 final int access, 115 final String version, 116 final List<ModuleRequireNode> requires, 117 final List<ModuleExportNode> exports, 118 final List<ModuleOpenNode> opens, 119 final List<String> uses, 120 final List<ModuleProvideNode> provides) { 121 super(api); 122 this.name = name; 123 this.access = access; 124 this.version = version; 125 this.requires = requires; 126 this.exports = exports; 127 this.opens = opens; 128 this.uses = uses; 129 this.provides = provides; 130 if (getClass() != ModuleNode.class) { 131 throw new IllegalStateException(); 132 } 133 } 134 135 @Override 136 public void visitMainClass(String mainClass) { 137 this.mainClass = mainClass; 138 } 139 140 @Override 141 public void visitPackage(String packaze) { 142 if (packages == null) { 143 packages = new ArrayList<String>(5); 144 } 145 packages.add(packaze); 146 } 147 148 @Override 149 public void visitRequire(String module, int access, String version) { 150 if (requires == null) { 151 requires = new ArrayList<ModuleRequireNode>(5); 152 } 153 requires.add(new ModuleRequireNode(module, access, version)); 154 } 155 156 @Override 157 public void visitExport(String packaze, int access, String... modules) { 158 if (exports == null) { 159 exports = new ArrayList<ModuleExportNode>(5); 160 } 161 List<String> moduleList = null; 162 if (modules != null) { 163 moduleList = new ArrayList<String>(modules.length); 164 for (int i = 0; i < modules.length; i++) { 165 moduleList.add(modules[i]); 166 } 167 } 168 exports.add(new ModuleExportNode(packaze, access, moduleList)); 169 } 170 171 @Override 172 public void visitOpen(String packaze, int access, String... modules) { 173 if (opens == null) { 174 opens = new ArrayList<ModuleOpenNode>(5); 175 } 176 List<String> moduleList = null; 177 if (modules != null) { 178 moduleList = new ArrayList<String>(modules.length); 179 for (int i = 0; i < modules.length; i++) { 180 moduleList.add(modules[i]); 181 } 182 } 183 opens.add(new ModuleOpenNode(packaze, access, moduleList)); 184 } 185 186 @Override 187 public void visitUse(String service) { 188 if (uses == null) { 189 uses = new ArrayList<String>(5); 190 } 191 uses.add(service); 192 } 193 194 @Override 195 public void visitProvide(String service, String... providers) { 196 if (provides == null) { 197 provides = new ArrayList<ModuleProvideNode>(5); 198 } 199 ArrayList<String> providerList = 200 new ArrayList<String>(providers.length); 201 for (int i = 0; i < providers.length; i++) { 202 providerList.add(providers[i]); 203 } 204 provides.add(new ModuleProvideNode(service, providerList)); 205 } 206 207 @Override 208 public void visitEnd() { 209 } 210 211 public void accept(final ClassVisitor cv) { 212 ModuleVisitor mv = cv.visitModule(name, access, version); 213 if (mv == null) { 214 return; 215 } 216 if (mainClass != null) { 217 mv.visitMainClass(mainClass); 218 } 219 if (packages != null) { 220 for (int i = 0; i < packages.size(); i++) { 221 mv.visitPackage(packages.get(i)); 222 } 223 } 224 225 if (requires != null) { 226 for (int i = 0; i < requires.size(); i++) { 227 requires.get(i).accept(mv); 228 } 229 } 230 if (exports != null) { 231 for (int i = 0; i < exports.size(); i++) { 232 exports.get(i).accept(mv); 233 } 234 } 235 if (opens != null) { 236 for (int i = 0; i < opens.size(); i++) { 237 opens.get(i).accept(mv); 238 } 239 } 240 if (uses != null) { 241 for (int i = 0; i < uses.size(); i++) { 242 mv.visitUse(uses.get(i)); 243 } 244 } 245 if (provides != null) { 246 for (int i = 0; i < provides.size(); i++) { 247 provides.get(i).accept(mv); 248 } 249 } 250 } 251}