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