1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package jdk.tools.jlink.internal.plugins.asm;
  26 
  27 import java.util.Collection;
  28 import java.util.List;
  29 import jdk.internal.org.objectweb.asm.ClassReader;
  30 import jdk.internal.org.objectweb.asm.ClassWriter;
  31 import jdk.tools.jlink.plugin.ModuleEntry;
  32 import jdk.tools.jlink.plugin.ModulePool;
  33 
  34 /**
  35  * A pool of ClassReader and other resource files.
  36  * This class allows to transform and sort classes and resource files.
  37  * <p>
  38  * Classes in the class pool are named following java binary name specification.
  39  * For example, java.lang.Object class is named java/lang/Object
  40  * <p>
  41  * Module information has been stripped out from class and other resource files
  42  * (.properties, binary files, ...).</p>
  43  */
  44 public interface AsmPool {
  45 
  46     /**
  47      * A resource that is not a class file.
  48      * <p>
  49      * The path of a resource is a /-separated path name that identifies the
  50      * resource. For example com.foo.bar.Bundle.properties resource name is
  51      * com/foo/bar/Bundle.properties </p>
  52      * <p>
  53      */
  54     public class ResourceFile {
  55 
  56         private final String path;
  57         private final byte[] content;
  58 
  59         public ResourceFile(String path, byte[] content) {
  60             this.path = path;
  61             this.content = content;
  62         }
  63 
  64         public String getPath() {
  65             return path;
  66         }
  67 
  68         public byte[] getContent() {
  69             return content;
  70         }
  71     }
  72 
  73     /**
  74      * To visit each Class contained in the pool
  75      */
  76     public interface ClassReaderVisitor {
  77 
  78         /**
  79          * Called for each ClassReader located in the pool.
  80          *
  81          * @param reader A class reader.
  82          * @return A writer or null if the class has not been transformed.
  83          */
  84         public ClassWriter visit(ClassReader reader);
  85     }
  86 
  87     /**
  88      * To visit each Resource contained in the pool
  89      */
  90     public interface ResourceFileVisitor {
  91 
  92         /**
  93          * Called for each Resource file located in the pool.
  94          *
  95          * @param reader A resource file.
  96          * @return A resource file or null if the resource has not been
  97          * transformed.
  98          */
  99         public ResourceFile visit(ResourceFile reader);
 100     }
 101 
 102     /**
 103      * Contains the transformed classes. When the jimage file is generated,
 104      * transformed classes take precedence on unmodified ones.
 105      */
 106     public interface WritableClassPool {
 107 
 108         /**
 109          * Add a class to the pool, if a class already exists, it is replaced.
 110          *
 111          * @param writer The class writer.
 112          * @throws jdk.tools.jlink.plugin.PluginException
 113          */
 114         public void addClass(ClassWriter writer);
 115 
 116         /**
 117          * The class will be not added to the jimage file.
 118          *
 119          * @param className The class name to forget.
 120          * @throws jdk.tools.jlink.plugin.PluginException
 121          */
 122         public void forgetClass(String className);
 123 
 124         /**
 125          * Get a transformed class.
 126          *
 127          * @param binaryName The java class binary name
 128          * @return The ClassReader or null if the class is not found.
 129          * @throws jdk.tools.jlink.plugin.PluginException
 130          */
 131         public ClassReader getClassReader(String binaryName);
 132 
 133         /**
 134          * Get a transformed class.
 135          *
 136          * @param res A class resource.
 137          * @return The ClassReader or null if the class is not found.
 138          * @throws jdk.tools.jlink.plugin.PluginException
 139          */
 140         public ClassReader getClassReader(ModuleEntry res);
 141 
 142         /**
 143          * Returns all the classes contained in the writable pool.
 144          *
 145          * @return The collection of classes.
 146          */
 147         public Collection<ModuleEntry> getClasses();
 148     }
 149 
 150     /**
 151      * Contains the transformed resources. When the jimage file is generated,
 152      * transformed resources take precedence on unmodified ones.
 153      */
 154     public interface WritableResourcePool {
 155 
 156         /**
 157          * Add a resource, if the resource exists, it is replaced.
 158          *
 159          * @param resFile The resource file to add.
 160          * @throws jdk.tools.jlink.plugin.PluginException
 161          */
 162         public void addResourceFile(ResourceFile resFile);
 163 
 164         /**
 165          * The resource will be not added to the jimage file.
 166          *
 167          * @param resourceName
 168          * @throws jdk.tools.jlink.plugin.PluginException If the resource to
 169          * forget doesn't exist or is null.
 170          */
 171         public void forgetResourceFile(String resourceName);
 172 
 173         /**
 174          * Get a transformed resource.
 175          *
 176          * @param name The java resource name
 177          * @return The Resource or null if the resource is not found.
 178          */
 179         public ResourceFile getResourceFile(String name);
 180 
 181         /**
 182          * Get a transformed resource.
 183          *
 184          * @param res The java resource
 185          * @return The Resource or null if the resource is not found.
 186          */
 187         public ResourceFile getResourceFile(ModuleEntry res);
 188 
 189         /**
 190          * Returns all the resources contained in the writable pool.
 191          *
 192          * @return The array of resources.
 193          */
 194         public Collection<ModuleEntry> getResourceFiles();
 195     }
 196 
 197     /**
 198      * To order the classes and resources within a jimage file.
 199      */
 200     public interface Sorter {
 201 
 202         /**
 203          * @param resources The resources will be added to the jimage following
 204          * the order of this ResourcePool.
 205          * @return The resource paths ordered in the way to use for storage in the jimage.
 206          * @throws jdk.tools.jlink.plugin.PluginException
 207          */
 208         public List<String> sort(ModulePool resources);
 209     }
 210 
 211     /**
 212      * The writable pool used to store transformed resources.
 213      *
 214      * @return The writable pool.
 215      */
 216     public WritableClassPool getTransformedClasses();
 217 
 218     /**
 219      * The writable pool used to store transformed resource files.
 220      *
 221      * @return The writable pool.
 222      */
 223     public WritableResourcePool getTransformedResourceFiles();
 224 
 225     /**
 226      * Set a sorter instance to sort all files. If no sorter is set, then input
 227      * Resources will be added in the order they have been received followed by
 228      * newly added resources.
 229      *
 230      * @param sorter
 231      */
 232     public void setSorter(Sorter sorter);
 233 
 234     /**
 235      * Returns the classes contained in the pool.
 236      *
 237      * @return The classes.
 238      */
 239     public Collection<ModuleEntry> getClasses();
 240 
 241     /**
 242      * Returns the resources contained in the pool. Resources are all the file
 243      * that are not classes (eg: properties file, binary files, ...)
 244      *
 245      * @return The array of resource files.
 246      */
 247     public Collection<ModuleEntry> getResourceFiles();
 248 
 249     /**
 250      * Retrieves a resource based on the binary name. This name doesn't contain
 251      * the module name.
 252      * <b>NB:</b> When dealing with resources that have the same name in various
 253      * modules (eg: META-INFO/*), you should use the <code>ResourcePool</code>
 254      * referenced from this <code>AsmClassPool</code>.
 255      *
 256      * @param binaryName Name of a Java resource or null if the resource doesn't
 257      * exist.
 258      * @return
 259      */
 260     public ResourceFile getResourceFile(String binaryName);
 261 
 262     /**
 263      * Retrieves a resource for the passed resource.
 264      *
 265      * @param res The resource
 266      * @return The resource file or null if it doesn't exist.
 267      */
 268     public ResourceFile getResourceFile(ModuleEntry res);
 269 
 270     /**
 271      * Retrieve a ClassReader from the pool.
 272      *
 273      * @param binaryName Class binary name
 274      * @return A reader or null if the class is unknown
 275      * @throws jdk.tools.jlink.plugin.PluginException
 276      */
 277     public ClassReader getClassReader(String binaryName);
 278 
 279     /**
 280      * Retrieve a ClassReader from the pool.
 281      *
 282      * @param res A resource.
 283      * @return A reader or null if the class is unknown
 284      * @throws jdk.tools.jlink.plugin.PluginException
 285      */
 286     public ClassReader getClassReader(ModuleEntry res);
 287 
 288     /**
 289      * To visit the set of ClassReaders.
 290      *
 291      * @param visitor The visitor.
 292      * @throws jdk.tools.jlink.plugin.PluginException
 293      */
 294     public void visitClassReaders(ClassReaderVisitor visitor);
 295 
 296     /**
 297      * To visit the set of ClassReaders.
 298      *
 299      * @param visitor The visitor.
 300      * @throws jdk.tools.jlink.plugin.PluginException
 301      */
 302     public void visitResourceFiles(ResourceFileVisitor visitor);
 303 
 304     /**
 305      * Returns the pool of all the resources (transformed and unmodified).
 306      * The input resources are replaced by the transformed ones.
 307      * If a sorter has been set, it is used to sort the returned resources.
 308      *
 309      * @param output The pool used to fill the jimage.
 310      * @throws jdk.tools.jlink.plugin.PluginException
 311      */
 312     public void fillOutputResources(ModulePool output);
 313 
 314 }