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