1 /* 2 * Copyright (c) 2009, 2010, 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 26 package org.openjdk.jigsaw; 27 28 import java.lang.module.*; 29 import java.io.*; 30 import java.net.URI; 31 import java.security.CodeSigner; 32 import java.security.SignatureException; 33 import java.util.*; 34 35 import static org.openjdk.jigsaw.Trace.*; 36 37 38 /** 39 * The abstract base class for module libraries 40 * 41 * @see SimpleLibrary 42 */ 43 44 public abstract class Library 45 extends LocatableCatalog 46 { 47 48 private static File systemLibraryPath = null; 49 50 /** 51 * <p> The system module library's path </p> 52 */ 53 public static synchronized File systemLibraryPath() { 54 if (systemLibraryPath == null) { 55 systemLibraryPath 56 = new File(new File(System.getProperty("java.home"), 57 "lib"), 58 "modules"); 59 } 60 return systemLibraryPath; 61 } 62 63 /** 64 * <p> Open the system module library </p> 65 */ 66 public static Library openSystemLibrary() 67 throws IOException 68 { 69 return SimpleLibrary.open(systemLibraryPath()); 70 } 71 72 private static final JigsawModuleSystem jms 73 = JigsawModuleSystem.instance(); 74 75 protected Library() { } 76 77 public abstract int majorVersion(); 78 public abstract int minorVersion(); 79 80 public abstract Library parent(); 81 82 /** 83 * <p> Read the module-info class bytes for the module with the given 84 * identifier, from this library only. </p> 85 * 86 * @param mid 87 * The identifier of the module being sought 88 * 89 * @return A byte array containing the content of the named module's 90 * <tt>module-info.class</tt> file, or {@code null} if no such 91 * module is present in this library 92 * 93 * @throws IllegalArgumentException 94 * If the given module identifier is not a Jigsaw module 95 * identifier 96 */ 97 protected abstract byte[] readLocalModuleInfoBytes(ModuleId mid) 98 throws IOException; 99 100 public byte[] readModuleInfoBytes(ModuleId mid) 101 throws IOException 102 { 103 Library lib = this; 104 while (lib != null) { 105 byte[] bs = lib.readLocalModuleInfoBytes(mid); 106 if (bs != null) 107 return bs; 108 lib = lib.parent(); 109 } 110 return null; 111 } 112 113 public ModuleInfo readLocalModuleInfo(ModuleId mid) 114 throws IOException 115 { 116 byte[] bs = readLocalModuleInfoBytes(mid); 117 if (bs != null) 118 return jms.parseModuleInfo(bs); 119 return null; 120 } 121 122 /** 123 * Read the class bytes of the given class within the given module in this 124 * library. 125 * 126 * @param mid 127 * The module's identifier 128 * 129 * @param className 130 * The binary name of the requested class 131 * 132 * @return The requested bytes, or {@code null} if the named module does 133 * not define such a class 134 * 135 * @throws IllegalArgumentException 136 * If the given module identifier is not a Jigsaw module 137 * identifier 138 */ 139 public abstract byte[] readLocalClass(ModuleId mid, String className) 140 throws IOException; 141 142 /** 143 * Read the class bytes of the given class within the given module, in this 144 * library or in a parent library. 145 * 146 * @param mid 147 * The module's identifier 148 * 149 * @param className 150 * The binary name of the requested class 151 * 152 * @return The requested bytes, or {@code null} if the named module does 153 * not define such a class 154 * 155 * @throws IllegalArgumentException 156 * If the given module identifier is not a Jigsaw module 157 * identifier 158 */ 159 public byte[] readClass(ModuleId mid, String className) 160 throws IOException 161 { 162 for (Library l = this; l != null; l = l.parent()) { 163 byte[] bs = l.readLocalClass(mid, className); 164 if (bs != null) 165 return bs; 166 } 167 return null; 168 } 169 170 /** 171 * Return a list of the public and, optionally, all other classes defined 172 * by the named module in this library. 173 * 174 * @param mid 175 * The module's identifier 176 * 177 * @param all 178 * Whether non-public classes should be included 179 * 180 * @return The requested class names, or null if the named module does not 181 * exist in this library 182 * 183 * @throws IllegalArgumentException 184 * If the given module identifier is not a Jigsaw module 185 * identifier 186 */ 187 public abstract List<String> listLocalClasses(ModuleId mid, boolean all) 188 throws IOException; 189 190 /** 191 * Read the stored {@link Configuration} of the named module. 192 * 193 * @param mid 194 * The module's identifier 195 * 196 * @return The named module's {@link Configuration}, or null if the named 197 * module does not exist in this library 198 * 199 * @throws IllegalArgumentException 200 * If the given module identifier is not a Jigsaw module 201 * identifier 202 */ 203 public abstract Configuration<Context> readConfiguration(ModuleId mid) 204 throws IOException; 205 206 /** 207 * <p> Install one or more modules into this library. </p> 208 * 209 * <p> The modules are first copied from the locations specified in the 210 * given manifests, and then the configurations of any affected root 211 * modules in the library are recomputed. </p> 212 * 213 * @param mfs 214 * The manifests describing the contents of the modules to be 215 * installed 216 */ 217 public abstract void installFromManifests(Collection<Manifest> mfs) 218 throws ConfigurationException, IOException; 219 220 /** 221 * <p> Install one or more module files into this library. </p> 222 * 223 * @param mfs 224 * The module files to be installed 225 * 226 * @param verifySignature 227 * Perform signature verification of signed module files, if true. 228 * Otherwise treat the module files as unsigned. 229 * 230 * @throws ConfigurationException 231 * If a valid configuration cannot be computed 232 * 233 * @throws IOException 234 * If an I/O error occurs while accessing the module library 235 * 236 * @throws SignatureException 237 * If an error occurs while validating the signature 238 */ 239 public abstract void install(Collection<File> mfs, boolean verifySignature) 240 throws ConfigurationException, IOException, SignatureException; 241 242 /** 243 * <p> Resolve the given collection of {@linkplain 244 * java.lang.module.ModuleIdQuery module-id queries} against this 245 * library. </p> 246 * 247 * @param midqs 248 * A non-empty collection of {@link java.lang.module.ModuleIdQuery 249 * ModuleIdQuery objects} 250 * 251 * @throws ConfigurationException 252 * If a valid {@link Resolution} cannot be computed 253 * 254 * @throws IOException 255 * If an I/O error occurs while accessing the module library 256 */ 257 public abstract Resolution resolve(Collection<ModuleIdQuery> midqs) 258 throws ConfigurationException, IOException; 259 260 /** 261 * <p> Install any modules required by the given {@linkplain Resolution 262 * resolution}, and configure all of its root modules. </p> 263 * 264 * @param res 265 * A {@link Resolution} previously computed by the 266 * {@link Library#install install()} method 267 * 268 * @param verifySignature 269 * Perform signature verification, if true 270 * 271 * @throws ConfigurationException 272 * If a valid configuration cannot be computed 273 * 274 * @throws IOException 275 * If an I/O error occurs while accessing the module library 276 * 277 * @throws SignatureException 278 * If an error occurs while validating the signature 279 */ 280 public abstract void install(Resolution res, boolean verifySignature) 281 throws ConfigurationException, IOException, SignatureException; 282 283 /** 284 * Remove one or more modules from this library. 285 * 286 * @param mids 287 * The module identifiers 288 * 289 * @return A list of IOExceptions, if any, that were encountered when 290 * removing the actual content of the given modules 291 * 292 * @throws ConfigurationException 293 * If the configuration of any root modules in the library 294 * require any of the given modules 295 * 296 * @throws IOException 297 * If an I/O error occurs while accessing the module library 298 */ 299 public abstract List<IOException> remove(List<ModuleId> mids, boolean dry) 300 throws ConfigurationException, IOException; 301 302 /** 303 * Forcibly remove one or more modules from this library. 304 * 305 * <p> No regard is given to configuration of any root modules in the 306 * library that may require any of the given modules. </p> 307 * 308 * @param mids 309 * The module identifiers 310 * 311 * @return A list of IOExceptions, if any, that were encountered when 312 * removing the actual content of the given modules 313 * 314 * @throws IOException 315 * If an I/O error occurs while accessing the module library 316 */ 317 public abstract List<IOException> removeForcibly(List<ModuleId> mids) 318 throws IOException; 319 320 /** 321 * Find a resource within the given module in this library. 322 * 323 * @param mid 324 * The module's identifier 325 * 326 * @param rn 327 * The name of the requested resource, in the usual 328 * slash-separated form 329 * 330 * @return A {@code File} object naming the location of the resource, 331 * or {@code null} if the named module does not define that 332 * resource 333 */ 334 // ## Returning file or jar URIs here is EVIL! 335 // ## Define a jmod: hierarchical URI scheme? 336 public abstract URI findLocalResource(ModuleId mid, String rn) 337 throws IOException; 338 339 /** 340 * Find a native library within the given module in this library. 341 * 342 * @param mid 343 * The module's identifier 344 * 345 * @param name 346 * The name of the requested library, in platform-specific 347 * form, <i>i.e.</i>, that returned by the {@link 348 * java.lang.System#mapLibraryName System.mapLibraryName} method 349 * 350 * @return A {@code File} object naming the location of the native library, 351 * or {@code null} if the named module does not contain such a 352 * library 353 */ 354 public abstract File findLocalNativeLibrary(ModuleId mid, String name) 355 throws IOException; 356 357 /** 358 * <p> Return a file path to the given module's classes. </p> 359 * 360 * @param mid 361 * The module's identifier 362 * 363 * @return A {@code File} object naming the location of the module's 364 * classes, or {@code null} if the named module does not exist 365 */ 366 public abstract File classPath(ModuleId mid) 367 throws IOException; 368 369 370 public abstract RemoteRepositoryList repositoryList() throws IOException; 371 372 /** 373 * <p> Read the CodeSigners for the module with the given identifier, from 374 * this library only. </p> 375 * 376 * @param mid 377 * The identifier of the module being sought 378 * 379 * @return An array of CodeSigners, or {@code null} if the module is not 380 * signed 381 * 382 * @throws IllegalArgumentException 383 * If the given module identifier is not a Jigsaw module 384 * identifier 385 * 386 * @throws IOException 387 * If an I/O error occurs while accessing the module library 388 */ 389 public abstract CodeSigner[] readLocalCodeSigners(ModuleId mid) 390 throws IOException; 391 392 }