001/* 002 * Copyright (C) 2022 - 2023, the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.github.ascopes.jct.workspaces; 017 018import io.github.ascopes.jct.filemanagers.JctFileManager; 019import io.github.ascopes.jct.filemanagers.ModuleLocation; 020import java.io.UncheckedIOException; 021import java.nio.file.Path; 022import java.util.List; 023import java.util.Map; 024import javax.tools.JavaFileManager.Location; 025import javax.tools.StandardLocation; 026import org.apiguardian.api.API; 027import org.apiguardian.api.API.Status; 028 029/** 030 * Interface for a Workspace to hold files and directories within. 031 * 032 * <p>This acts as a nexus for managing the lifetime of test sources and directories, 033 * and should be used within a try-with-resources block to ensure temporary files get released after 034 * the test completes. 035 * 036 * <p>While this interface may seem somewhat intimidating due to the number of methods it provides, 037 * you will usually only ever need to use a small subset of them. The main ones you probably will 038 * want to use are: 039 * 040 * <ul> 041 * <li> 042 * {@link #addSourcePathPackage(Path)} - for copying a source path tree from your file system. 043 * </li> 044 * <li> 045 * {@link #createSourcePathPackage()} - for creating a new source path tree. 046 * </li> 047 * <li> 048 * {@link #addClassPathPackage(Path)} - for adding a class path resource (usually a JAR or a 049 * directory of packages of classes). 050 * </li> 051 * <li> 052 * {@link #addModulePathModule(String, Path)} - for adding a module path resource (usually a JAR 053 * or a directory of packages of classes). 054 * </li> 055 * <li> 056 * {@link #getClassPathPackages()} - for fetching all class path resources. 057 * </li> 058 * <li> 059 * {@link #getModulePathModules()} - for fetching all module path resources. 060 * </li> 061 * <li> 062 * {@link #getSourceOutputPackages()} - for fetching all generated source packages. 063 * </li> 064 * <li> 065 * {@link #getSourceOutputModules()} - for fetching all generated source modules. 066 * </li> 067 * <li> 068 * {@link #close()} - to close any resources in the temporary file system. 069 * </li> 070 * </ul> 071 * 072 * <p>A simple example of usage of this interface would be the following: 073 * 074 * <pre><code> 075 * try (Workspace workspace = Workspaces.newWorkspace(PathStrategy.TEMP_DIRECTORIES)) { 076 * workspace 077 * .createSourcePathPackage() 078 * .copyContentsFrom("src", "test", "resources", "test-data"); 079 * 080 * var compilation = someCompiler.compile(workspace); 081 * 082 * assertThat(compilation).isSuccessful(); 083 * } 084 * </code></pre> 085 * 086 * <p>Remember that files that are created as the result of a compilation can be queried via 087 * {@link JctFileManager}, which is accessible on the {@code compilation} result object. This may 088 * more accurately represent the logical project structure that is the result of various 089 * processing operations during compilation. 090 * 091 * @author Ashley Scopes 092 * @since 0.0.1 093 */ 094@API(since = "0.0.1", status = Status.STABLE) 095@SuppressWarnings({"unused", "UnusedReturnValue"}) 096public interface Workspace extends AutoCloseable { 097 098 /** 099 * Attempt to close all resources in this workspace. 100 * 101 * @throws UncheckedIOException if an error occurs. 102 */ 103 @Override 104 void close(); 105 106 /** 107 * Determine if the workspace is closed or not. 108 * 109 * @return {@code true} if closed, {@code false} if open. 110 * @since 0.4.0 111 */ 112 @API(since = "0.4.0", status = Status.STABLE) 113 boolean isClosed(); 114 115 /// 116 /// Accessor operations 117 /// 118 119 /** 120 * Get an immutable copy of the current paths to operate on. 121 * 122 * @return the paths. 123 */ 124 Map<Location, List<? extends PathRoot>> getAllPaths(); 125 126 /** 127 * Get the collection of path roots associated with the given module. 128 * 129 * <p>Usually this should only ever contain one path root at a maximum, although 130 * {@link Workspace} does not explicitly enforce this constraint. 131 * 132 * <p>If no results were found, then an empty collection is returned. 133 * 134 * @param location the module-oriented or output location. 135 * @param moduleName the module name within the location. 136 * @return the collection of paths. 137 * @throws IllegalArgumentException if the location is neither 138 * {@link Location#isModuleOrientedLocation() module-oriented} or 139 * an {@link Location#isOutputLocation() output location}. This 140 * will also be raised if this method is called with an instance 141 * of {@link ModuleLocation} (you should use 142 * {@link #getPackages(Location)} instead for this). 143 * @see #getPackages(Location) 144 * @see #getModules(Location) 145 * @since 0.1.0 146 */ 147 List<? extends PathRoot> getModule(Location location, String moduleName); 148 149 /** 150 * Get the collection of modules associated with the given location. 151 * 152 * <p>If no results were found, then an empty map is returned. 153 * 154 * @param location the location to get the modules for. 155 * @return the map of module names to lists of associated paths. 156 * @throws IllegalArgumentException if the location is neither 157 * {@link Location#isModuleOrientedLocation() module-oriented} or 158 * an {@link Location#isOutputLocation() output location}. This 159 * will also be raised if this method is called with an instance 160 * of {@link ModuleLocation}. 161 * @see #getModule(Location, String) 162 * @since 0.1.0 163 */ 164 Map<String, List<? extends PathRoot>> getModules(Location location); 165 166 /** 167 * Get the path strategy in use. 168 * 169 * @return the path strategy. 170 */ 171 PathStrategy getPathStrategy(); 172 173 /** 174 * Get the collection of path roots associated with the given location. 175 * 176 * <p>If no results were found, then an empty collection is returned. 177 * 178 * @param location the location to get. 179 * @return the collection of paths. 180 * @throws IllegalArgumentException if the location is 181 * {@link Location#isModuleOrientedLocation() module-oriented}. 182 * @see #getModule(Location, String) 183 * @since 0.1.0 184 */ 185 List<? extends PathRoot> getPackages(Location location); 186 187 /// 188 /// Mutative operations 189 /// 190 191 /** 192 * Add an existing package root to this workspace and associate it with the given location. 193 * 194 * <p>The following constraints must be met, otherwise an {@link IllegalArgumentException} 195 * will be thrown: 196 * 197 * <ul> 198 * <li> 199 * The {@code location} must not be 200 * {@link Location#isModuleOrientedLocation() module-oriented}. 201 * </li> 202 * <li> 203 * The {@code path} must exist. 204 * </li> 205 * </ul> 206 * 207 * <p>For example, this would add the package tree in {@code src/test/resources/packages} 208 * into the {@link StandardLocation#SOURCE_PATH source code path} that is used to compile files: 209 * 210 * <pre><code> 211 * var path = Path.of("src", "test", "resources", "packages"); 212 * workspace.addPackage(StandardLocation.SOURCE_PATH, path); 213 * </code></pre> 214 * 215 * @param location the location to associate with. 216 * @param path the path to add. 217 * @throws IllegalArgumentException if the inputs are invalid. 218 * @see #addModule(Location, String, Path) 219 * @see #createPackage(Location) 220 * @see #createModule(Location, String) 221 */ 222 void addPackage(Location location, Path path); 223 224 /** 225 * Add an existing package root to this workspace and associate it with the given module name in 226 * the given location. 227 * 228 * <p>The following constraints must be met, otherwise an {@link IllegalArgumentException} 229 * will be thrown: 230 * 231 * <ul> 232 * <li> 233 * The {@code location} must be {@link Location#isModuleOrientedLocation() module-oriented} 234 * or an {@link Location#isOutputLocation() output location}. 235 * </li> 236 * <li> 237 * The {@code location} must not be a {@link ModuleLocation module-location handle} already. 238 * </li> 239 * <li> 240 * The {@code path} must exist. 241 * </li> 242 * </ul> 243 * 244 * <p>For example, this would add the package tree in {@code src/test/resources/packages} 245 * into the {@link StandardLocation#MODULE_SOURCE_PATH module source code path} under the module 246 * name {@code foo.bar}: 247 * 248 * <pre><code> 249 * var path = Path.of("src", "test", "resources", "packages"); 250 * workspace.addModule(StandardLocation.MODULE_SOURCE_PATH, "foo.bar", path); 251 * </code></pre> 252 * 253 * @param location the location to associate with. 254 * @param moduleName the name of the module. 255 * @param path the path to add. 256 * @throws IllegalArgumentException if the inputs are invalid. 257 * @see #addPackage(Location, Path) 258 * @see #createPackage(Location) 259 * @see #createModule(Location, String) 260 */ 261 void addModule(Location location, String moduleName, Path path); 262 263 /** 264 * Create a new test directory for a package root and associate it with the given location. 265 * 266 * <p>This path will be destroyed when the workspace is {@link #close() closed}. 267 * 268 * <p>The following constraints must be met, otherwise an {@link IllegalArgumentException} 269 * will be thrown: 270 * 271 * <ul> 272 * <li> 273 * The {@code location} must not be 274 * {@link Location#isModuleOrientedLocation() module-oriented}. 275 * </li> 276 * </ul> 277 * 278 * <p>For example, this would create a new source root that you could add files to: 279 * 280 * <pre><code> 281 * workspace.createPackage(StandardLocation.SOURCE_PATH); 282 * </code></pre> 283 * 284 * @param location the location to associate with. 285 * @return the test directory that was created. 286 * @throws IllegalArgumentException if the inputs are invalid. 287 * @see #createModule(Location, String) 288 * @see #addPackage(Location, Path) 289 * @see #addModule(Location, String, Path) 290 */ 291 ManagedDirectory createPackage(Location location); 292 293 /** 294 * Create a new test directory for a package root and associate it with the given module name in 295 * the given location. 296 * 297 * <p>This path will be destroyed when the workspace is {@link #close() closed}. 298 * 299 * <p>The following constraints must be met, otherwise an {@link IllegalArgumentException} 300 * will be thrown: 301 * 302 * <ul> 303 * <li> 304 * The {@code location} must be {@link Location#isModuleOrientedLocation() module-oriented} 305 * or an {@link Location#isOutputLocation() output location}. 306 * </li> 307 * <li> 308 * The {@code location} must not be a {@link ModuleLocation module-location handle} already. 309 * </li> 310 * </ul> 311 * 312 * <p>For example, this would create a new multi-module source root that you could add files to, 313 * for a module named {@code foo.bar}: 314 * 315 * <pre><code> 316 * workspace.createModule(StandardLocation.MODULE_SOURCE_PATH, "foo.bar"); 317 * </code></pre> 318 * 319 * @param location the location to associate with. 320 * @param moduleName the module name to use. 321 * @return the test directory that was created. 322 * @throws IllegalArgumentException if the inputs are invalid. 323 * @see #createPackage(Location) 324 * @see #addPackage(Location, Path) 325 * @see #addModule(Location, String, Path) 326 */ 327 ManagedDirectory createModule(Location location, String moduleName); 328 329 /// 330 /// Default implementation helpers. 331 /// 332 333 /** 334 * Add a package to the {@link StandardLocation#CLASS_OUTPUT class outputs}. 335 * 336 * @param path the path to add. 337 * @throws IllegalArgumentException if the path does not exist. 338 * @see #addPackage(Location, Path) 339 * @see #addClassOutputModule(String, Path) 340 * @see #createClassOutputPackage() 341 * @see #createClassOutputModule(String) 342 */ 343 default void addClassOutputPackage(Path path) { 344 addPackage(StandardLocation.CLASS_OUTPUT, path); 345 } 346 347 /** 348 * Add a module to the {@link StandardLocation#CLASS_OUTPUT class outputs}. 349 * 350 * @param moduleName the module name. 351 * @param path the path to add. 352 * @throws IllegalArgumentException if the path does not exist. 353 * @see #addModule(Location, String, Path) 354 * @see #addClassOutputPackage(Path) 355 * @see #createClassOutputPackage() 356 * @see #createClassOutputModule(String) 357 */ 358 default void addClassOutputModule(String moduleName, Path path) { 359 addModule(StandardLocation.CLASS_OUTPUT, moduleName, path); 360 } 361 362 /** 363 * Add a package to the {@link StandardLocation#SOURCE_OUTPUT generated source outputs}. 364 * 365 * @param path the path to add. 366 * @throws IllegalArgumentException if the path does not exist. 367 * @see #addPackage(Location, Path) 368 * @see #addSourceOutputModule(String, Path) 369 * @see #createSourceOutputPackage() 370 * @see #createSourceOutputModule(String) 371 */ 372 default void addSourceOutputPackage(Path path) { 373 addPackage(StandardLocation.SOURCE_OUTPUT, path); 374 } 375 376 /** 377 * Add a module to the {@link StandardLocation#SOURCE_OUTPUT generated source outputs}. 378 * 379 * @param moduleName the module name. 380 * @param path the path to add. 381 * @throws IllegalArgumentException if the path does not exist. 382 * @see #addModule(Location, String, Path) 383 * @see #addSourceOutputPackage(Path) 384 * @see #createSourceOutputPackage() 385 * @see #createSourceOutputModule(String) 386 */ 387 default void addSourceOutputModule(String moduleName, Path path) { 388 addModule(StandardLocation.SOURCE_OUTPUT, moduleName, path); 389 } 390 391 /** 392 * Add a package to the {@link StandardLocation#CLASS_PATH class path}. 393 * 394 * <p>If you are adding JPMS modules, you may want to use 395 * {@link #addModulePathModule(String, Path)} instead. 396 * 397 * @param path the path to add. 398 * @throws IllegalArgumentException if the path does not exist. 399 * @see #addPackage(Location, Path) 400 * @see #addModulePathModule(String, Path) 401 * @see #createClassPathPackage() 402 * @see #createModulePathModule(String) 403 */ 404 default void addClassPathPackage(Path path) { 405 addPackage(StandardLocation.CLASS_PATH, path); 406 } 407 408 /** 409 * Add a module to the {@link StandardLocation#MODULE_PATH module path}. 410 * 411 * <p>If you are adding non-JPMS modules, you may want to use 412 * {@link #addClassPathPackage(Path)} instead. 413 * 414 * @param moduleName the module name. 415 * @param path the path to add. 416 * @throws IllegalArgumentException if the path does not exist. 417 * @see #addModule(Location, String, Path) 418 * @see #addClassPathPackage(Path) 419 * @see #createClassPathPackage() 420 * @see #createModulePathModule(String) 421 */ 422 default void addModulePathModule(String moduleName, Path path) { 423 addModule(StandardLocation.MODULE_PATH, moduleName, path); 424 } 425 426 /** 427 * Add a package to the {@link StandardLocation#SOURCE_PATH legacy source path}. 428 * 429 * <p>This is the location you will usually tend to use for your source code. 430 * 431 * <p>If you wish to define multiple JPMS modules in your source code tree to compile together, 432 * you will want to consider using {@link #addSourcePathModule(String, Path)} instead. For most 433 * purposes, however, this method is the one you will want to be using if your code is not in a 434 * <strong>named</strong> module directory (so not something like 435 * {@code src/my.module/org/example/...}). 436 * 437 * @param path the path to add. 438 * @throws IllegalArgumentException if the path does not exist. 439 * @see #addPackage(Location, Path) 440 * @see #addSourcePathModule(String, Path) 441 * @see #createSourcePathPackage() 442 * @see #createSourcePathModule(String) 443 */ 444 default void addSourcePathPackage(Path path) { 445 addPackage(StandardLocation.SOURCE_PATH, path); 446 } 447 448 /** 449 * Add a module to the {@link StandardLocation#MODULE_SOURCE_PATH module source path}. 450 * 451 * <p>Note that this will signal to the compiler to run in multi-module compilation mode. 452 * Any source packages that were {@link #addSourcePathPackage(Path) added} or 453 * {@link #createSourcePathPackage() created} will be ignored. 454 * 455 * <p>If you are using a single-module, you can 456 * {@link #addSourcePathPackage(Path) add a source package} and include a {@code module-info.java} 457 * in the base directory instead. 458 * 459 * @param moduleName the module name. 460 * @param path the path to add. 461 * @throws IllegalArgumentException if the path does not exist. 462 * @see #addModule(Location, String, Path) 463 * @see #addSourcePathPackage(Path) 464 * @see #createSourcePathPackage() 465 * @see #createSourcePathModule(String) 466 */ 467 default void addSourcePathModule(String moduleName, Path path) { 468 addModule(StandardLocation.MODULE_SOURCE_PATH, moduleName, path); 469 } 470 471 /** 472 * Add a package to the 473 * {@link StandardLocation#ANNOTATION_PROCESSOR_PATH annotation processor path}. 474 * 475 * <p>Note that this will be ignored if the compiler is provided with explicit annotation 476 * processor instances to run. 477 * 478 * @param path the path to add. 479 * @throws IllegalArgumentException if the path does not exist. 480 * @see #addPackage(Location, Path) 481 * @see #addAnnotationProcessorPathModule(String, Path) 482 * @see #createAnnotationProcessorPathPackage() 483 * @see #createAnnotationProcessorPathModule(String) 484 */ 485 default void addAnnotationProcessorPathPackage(Path path) { 486 addPackage(StandardLocation.ANNOTATION_PROCESSOR_PATH, path); 487 } 488 489 /** 490 * Add a module to the 491 * {@link StandardLocation#ANNOTATION_PROCESSOR_MODULE_PATH annotation processor module path}. 492 * 493 * <p>Note that this will be ignored if the compiler is provided with explicit annotation 494 * processor instances to run. 495 * 496 * @param moduleName the module name. 497 * @param path the path to add. 498 * @throws IllegalArgumentException if the path does not exist. 499 * @see #addModule(Location, String, Path) 500 * @see #addAnnotationProcessorPathPackage(Path) 501 * @see #createAnnotationProcessorPathPackage() 502 * @see #createAnnotationProcessorPathModule 503 */ 504 default void addAnnotationProcessorPathModule(String moduleName, Path path) { 505 addModule(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH, moduleName, path); 506 } 507 508 /** 509 * Add a package to the {@link StandardLocation#PLATFORM_CLASS_PATH platform class path} (also 510 * known as the boot class path). 511 * 512 * @param path the path to add. 513 * @throws IllegalArgumentException if the path does not exist. 514 * @see #addPackage(Location, Path) 515 * @see #createPlatformClassPathPackage() 516 */ 517 default void addPlatformClassPathPackage(Path path) { 518 addPackage(StandardLocation.PLATFORM_CLASS_PATH, path); 519 } 520 521 /** 522 * Add a package to the {@link StandardLocation#NATIVE_HEADER_OUTPUT native header outputs}. 523 * 524 * @param path the path to add. 525 * @throws IllegalArgumentException if the path does not exist. 526 * @see #addPackage(Location, Path) 527 * @see #addNativeHeaderOutputModule(String, Path) 528 * @see #createNativeHeaderOutputPackage() 529 * @see #createNativeHeaderOutputModule(String) 530 */ 531 default void addNativeHeaderOutputPackage(Path path) { 532 addPackage(StandardLocation.NATIVE_HEADER_OUTPUT, path); 533 } 534 535 /** 536 * Add a module to the {@link StandardLocation#NATIVE_HEADER_OUTPUT native header outputs}. 537 * 538 * @param moduleName the name of the module. 539 * @param path the path to add. 540 * @throws IllegalArgumentException if the path does not exist. 541 * @see #addPackage(Location, Path) 542 * @see #addNativeHeaderOutputPackage(Path) 543 * @see #createNativeHeaderOutputPackage() 544 * @see #createNativeHeaderOutputModule(String) 545 */ 546 default void addNativeHeaderOutputModule(String moduleName, Path path) { 547 addModule(StandardLocation.NATIVE_HEADER_OUTPUT, moduleName, path); 548 } 549 550 /** 551 * Add a module to the {@link StandardLocation#UPGRADE_MODULE_PATH upgrade module path}. 552 * 553 * @param moduleName the module name. 554 * @param path the path to add. 555 * @throws IllegalArgumentException if the path does not exist. 556 * @see #addModule(Location, String, Path) 557 * @see #createUpgradeModulePathModule(String) 558 */ 559 default void addUpgradeModulePathModule(String moduleName, Path path) { 560 addModule(StandardLocation.UPGRADE_MODULE_PATH, moduleName, path); 561 } 562 563 /** 564 * Add a module to the {@link StandardLocation#SYSTEM_MODULES system module path}. 565 * 566 * @param moduleName the module name. 567 * @param path the path to add. 568 * @throws IllegalArgumentException if the path does not exist. 569 * @see #addModule(Location, String, Path) 570 * @see #createSystemModulePathModule(String) 571 */ 572 default void addSystemModulePathModule(String moduleName, Path path) { 573 addModule(StandardLocation.SYSTEM_MODULES, moduleName, path); 574 } 575 576 /** 577 * Add a module to the {@link StandardLocation#PATCH_MODULE_PATH patch module path}. 578 * 579 * @param moduleName the module name. 580 * @param path the path to add. 581 * @throws IllegalArgumentException if the path does not exist. 582 * @see #addModule(Location, String, Path) 583 * @see #createPatchModulePathModule(String) 584 */ 585 default void addPatchModulePathModule(String moduleName, Path path) { 586 addModule(StandardLocation.PATCH_MODULE_PATH, moduleName, path); 587 } 588 589 /** 590 * Create a package in the {@link StandardLocation#CLASS_OUTPUT class outputs}. 591 * 592 * @return the created test directory. 593 * @see #createPackage(Location) 594 * @see #createClassOutputModule(String) 595 * @see #addClassOutputPackage(Path) 596 * @see #addClassOutputModule(String, Path) 597 */ 598 default ManagedDirectory createClassOutputPackage() { 599 return createPackage(StandardLocation.CLASS_OUTPUT); 600 } 601 602 /** 603 * Create a module in the {@link StandardLocation#CLASS_OUTPUT class outputs}. 604 * 605 * @param moduleName the module name. 606 * @return the created test directory. 607 * @see #createModule(Location, String) 608 * @see #createClassOutputPackage() 609 * @see #addClassOutputPackage(Path) 610 * @see #addClassOutputModule(String, Path) 611 */ 612 default ManagedDirectory createClassOutputModule(String moduleName) { 613 return createModule(StandardLocation.CLASS_OUTPUT, moduleName); 614 } 615 616 /** 617 * Create a package in the {@link StandardLocation#SOURCE_OUTPUT generated source outputs}. 618 * 619 * @return the created test directory. 620 * @see #createPackage(Location) 621 * @see #createSourceOutputModule(String) 622 * @see #addSourceOutputPackage(Path) 623 * @see #addSourceOutputModule(String, Path) 624 */ 625 default ManagedDirectory createSourceOutputPackage() { 626 return createPackage(StandardLocation.SOURCE_OUTPUT); 627 } 628 629 /** 630 * Create a module in the {@link StandardLocation#SOURCE_OUTPUT generated source outputs}. 631 * 632 * @param moduleName the module name. 633 * @return the created test directory. 634 * @see #createModule(Location, String) 635 * @see #createSourceOutputPackage() 636 * @see #addSourceOutputPackage(Path) 637 * @see #addSourceOutputModule(String, Path) 638 */ 639 default ManagedDirectory createSourceOutputModule(String moduleName) { 640 return createModule(StandardLocation.SOURCE_OUTPUT, moduleName); 641 } 642 643 /** 644 * Create a package in the {@link StandardLocation#CLASS_PATH class path}. 645 * 646 * <p>If you are adding JPMS modules, you may want to use 647 * {@link #createModulePathModule(String)} instead. 648 * 649 * @return the created test directory. 650 * @see #createPackage(Location) 651 * @see #createModulePathModule(String) 652 * @see #addClassPathPackage(Path) 653 * @see #addModulePathModule(String, Path) 654 */ 655 default ManagedDirectory createClassPathPackage() { 656 return createPackage(StandardLocation.CLASS_PATH); 657 } 658 659 /** 660 * Create a module in the {@link StandardLocation#MODULE_PATH module path}. 661 * 662 * <p>If you are adding non-JPMS modules, you may want to use 663 * {@link #createClassPathPackage()} instead. 664 * 665 * @param moduleName the module name. 666 * @return the created test directory. 667 * @see #createModule(Location, String) 668 * @see #createClassPathPackage() 669 * @see #addModulePathModule(String, Path) 670 * @see #addClassPathPackage(Path) 671 */ 672 default ManagedDirectory createModulePathModule(String moduleName) { 673 return createModule(StandardLocation.MODULE_PATH, moduleName); 674 } 675 676 /** 677 * Create a package in the {@link StandardLocation#SOURCE_PATH source path}. 678 * 679 * <p>If you wish to define multiple JPMS modules in your source code tree to compile together, 680 * you will want to consider using {@link #createSourcePathModule(String)} instead. For most 681 * purposes, however, this method is the one you will want to be using if your code is not in a 682 * <strong>named</strong> module directory (so not something like 683 * {@code src/my.module/org/example/...}). 684 * 685 * @return the created test directory. 686 * @see #createPackage(Location) 687 * @see #createSourcePathModule(String) 688 * @see #addSourcePathPackage(Path) 689 * @see #addSourcePathModule(String, Path) 690 */ 691 default ManagedDirectory createSourcePathPackage() { 692 return createPackage(StandardLocation.SOURCE_PATH); 693 } 694 695 /** 696 * Create a module in the {@link StandardLocation#MODULE_SOURCE_PATH module source path}. 697 * 698 * <p>Note that this will signal to the compiler to run in multi-module compilation mode. 699 * Any source packages that were {@link #createSourcePathPackage() created} or 700 * {@link #addSourcePathPackage(Path) added} will be ignored. 701 * 702 * <p>If you are using a single-module, you can 703 * {@link #createSourcePathPackage() create a source package} and include a 704 * {@code module-info.java} in the base directory instead. 705 * 706 * @param moduleName the module name. 707 * @return the created test directory. 708 * @see #createModule(Location, String) 709 * @see #createSourcePathPackage() 710 * @see #addSourcePathPackage(Path) 711 * @see #addSourcePathModule(String, Path) 712 */ 713 default ManagedDirectory createSourcePathModule(String moduleName) { 714 return createModule(StandardLocation.MODULE_SOURCE_PATH, moduleName); 715 } 716 717 /** 718 * Create a package in the 719 * {@link StandardLocation#ANNOTATION_PROCESSOR_PATH annotation processor path}. 720 * 721 * <p>Note that this will be ignored if the compiler is provided with explicit annotation 722 * processor instances to run. 723 * 724 * @return the created test directory. 725 * @see #createPackage(Location) 726 * @see #createAnnotationProcessorPathModule(String) 727 * @see #addAnnotationProcessorPathPackage(Path) 728 * @see #addAnnotationProcessorPathModule(String, Path) 729 */ 730 default ManagedDirectory createAnnotationProcessorPathPackage() { 731 return createPackage(StandardLocation.ANNOTATION_PROCESSOR_PATH); 732 } 733 734 /** 735 * Create a module in the 736 * {@link StandardLocation#ANNOTATION_PROCESSOR_MODULE_PATH annotation processor module path}. 737 * 738 * <p>Note that this will be ignored if the compiler is provided with explicit annotation 739 * processor instances to run. 740 * 741 * @param moduleName the module name. 742 * @return the created test directory. 743 * @see #createModule(Location, String) 744 * @see #createAnnotationProcessorPathPackage() 745 * @see #addAnnotationProcessorPathPackage(Path) 746 * @see #addAnnotationProcessorPathModule(String, Path) 747 */ 748 default ManagedDirectory createAnnotationProcessorPathModule(String moduleName) { 749 return createModule(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH, moduleName); 750 } 751 752 /** 753 * Create a package in the {@link StandardLocation#PLATFORM_CLASS_PATH platform class path} (also 754 * known as the boot class path). 755 * 756 * @return the created test directory. 757 * @see #createPackage(Location) 758 * @see #addPlatformClassPathPackage(Path) 759 */ 760 default ManagedDirectory createPlatformClassPathPackage() { 761 return createPackage(StandardLocation.PLATFORM_CLASS_PATH); 762 } 763 764 /** 765 * Create a package in the {@link StandardLocation#NATIVE_HEADER_OUTPUT native header outputs}. 766 * 767 * @return the created test directory. 768 * @see #createPackage(Location) 769 * @see #createNativeHeaderOutputModule(String) 770 * @see #addNativeHeaderOutputPackage(Path) 771 * @see #addNativeHeaderOutputModule(String, Path) 772 */ 773 default ManagedDirectory createNativeHeaderOutputPackage() { 774 return createPackage(StandardLocation.NATIVE_HEADER_OUTPUT); 775 } 776 777 /** 778 * Create a module in the {@link StandardLocation#NATIVE_HEADER_OUTPUT native header outputs}. 779 * 780 * @param moduleName the module name. 781 * @return the created test directory. 782 * @see #createModule(Location, String) 783 * @see #createNativeHeaderOutputPackage() 784 * @see #addNativeHeaderOutputPackage(Path) 785 * @see #addNativeHeaderOutputModule(String, Path) 786 */ 787 default ManagedDirectory createNativeHeaderOutputModule(String moduleName) { 788 return createModule(StandardLocation.NATIVE_HEADER_OUTPUT, moduleName); 789 } 790 791 /** 792 * Create a module in the {@link StandardLocation#UPGRADE_MODULE_PATH upgrade module path}. 793 * 794 * @param moduleName the module name. 795 * @return the created test directory. 796 * @see #createModule(Location, String) 797 * @see #addUpgradeModulePathModule(String, Path) 798 */ 799 default ManagedDirectory createUpgradeModulePathModule(String moduleName) { 800 return createModule(StandardLocation.UPGRADE_MODULE_PATH, moduleName); 801 } 802 803 /** 804 * Create a module in the {@link StandardLocation#SYSTEM_MODULES system module path}. 805 * 806 * @param moduleName the module name. 807 * @return the created test directory. 808 * @see #createModule(Location, String) 809 * @see #addSystemModulePathModule(String, Path) 810 */ 811 default ManagedDirectory createSystemModulePathModule(String moduleName) { 812 return createModule(StandardLocation.SYSTEM_MODULES, moduleName); 813 } 814 815 /** 816 * Create a module in the {@link StandardLocation#PATCH_MODULE_PATH patch module path}. 817 * 818 * @param moduleName the module name. 819 * @return the created test directory. 820 * @see #createModule(Location, String) 821 * @see #createPatchModulePathModule(String) 822 */ 823 default ManagedDirectory createPatchModulePathModule(String moduleName) { 824 return createModule(StandardLocation.PATCH_MODULE_PATH, moduleName); 825 } 826 827 /** 828 * Get the non-module path roots for {@link StandardLocation#CLASS_OUTPUT class outputs}. 829 * 830 * @return the roots in a collection, or an empty collection if none were found. 831 * @since 0.1.0 832 */ 833 default List<? extends PathRoot> getClassOutputPackages() { 834 return getPackages(StandardLocation.CLASS_OUTPUT); 835 } 836 837 /** 838 * Get the module path roots for {@link StandardLocation#CLASS_OUTPUT class outputs} for the given 839 * module name. 840 * 841 * @param moduleName the module name. 842 * @return the roots in a collection, or an empty collection if none were found. 843 * @since 0.1.0 844 */ 845 default List<? extends PathRoot> getClassOutputModule(String moduleName) { 846 return getModule(StandardLocation.CLASS_OUTPUT, moduleName); 847 } 848 849 /** 850 * Get the module path roots for {@link StandardLocation#CLASS_OUTPUT class outputs}. 851 * 852 * @return the roots in a map of module names to lists of roots, or an empty map if none were 853 * found. 854 * @since 0.1.0 855 */ 856 default Map<String, List<? extends PathRoot>> getClassOutputModules() { 857 return getModules(StandardLocation.CLASS_OUTPUT); 858 } 859 860 /** 861 * Get the non-module path roots for {@link StandardLocation#SOURCE_OUTPUT source outputs}. 862 * 863 * @return the roots in a collection, or an empty collection if none were found. 864 * @since 0.1.0 865 */ 866 default List<? extends PathRoot> getSourceOutputPackages() { 867 return getPackages(StandardLocation.SOURCE_OUTPUT); 868 } 869 870 /** 871 * Get the module path roots for {@link StandardLocation#SOURCE_OUTPUT source outputs} for the 872 * given module name. 873 * 874 * @param moduleName the module name. 875 * @return the roots in a collection, or an empty collection if none were found. 876 * @since 0.1.0 877 */ 878 default List<? extends PathRoot> getSourceOutputModule(String moduleName) { 879 return getModule(StandardLocation.SOURCE_OUTPUT, moduleName); 880 } 881 882 883 /** 884 * Get the module path roots for {@link StandardLocation#SOURCE_OUTPUT source outputs}. 885 * 886 * @return the roots in a map of module names to lists of roots, or an empty map if none were 887 * found. 888 * @since 0.1.0 889 */ 890 default Map<String, List<? extends PathRoot>> getSourceOutputModules() { 891 return getModules(StandardLocation.SOURCE_OUTPUT); 892 } 893 894 /** 895 * Get the path roots for the {@link StandardLocation#CLASS_PATH class path}. 896 * 897 * @return the roots in a collection, or an empty collection if none were found. 898 * @since 0.1.0 899 */ 900 default List<? extends PathRoot> getClassPathPackages() { 901 return getPackages(StandardLocation.CLASS_PATH); 902 } 903 904 /** 905 * Get the path roots for the {@link StandardLocation#SOURCE_PATH source path}. 906 * 907 * @return the roots in a collection, or an empty collection if none were found. 908 * @since 0.1.0 909 */ 910 default List<? extends PathRoot> getSourcePathPackages() { 911 return getPackages(StandardLocation.SOURCE_PATH); 912 } 913 914 /** 915 * Get the path roots for the 916 * {@link StandardLocation#ANNOTATION_PROCESSOR_PATH annotation processor path}. 917 * 918 * @return the roots in a collection, or an empty collection if none were found. 919 * @since 0.1.0 920 */ 921 default List<? extends PathRoot> getAnnotationProcessorPathPackages() { 922 return getPackages(StandardLocation.ANNOTATION_PROCESSOR_PATH); 923 } 924 925 /** 926 * Get the path roots for the 927 * {@link StandardLocation#ANNOTATION_PROCESSOR_MODULE_PATH annotation processor module path}. 928 * 929 * @param moduleName the module name to get. 930 * @return the roots in a collection, or an empty collection if none were found. 931 * @since 0.1.0 932 */ 933 default List<? extends PathRoot> getAnnotationProcessorPathModule(String moduleName) { 934 return getModule(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH, moduleName); 935 } 936 937 /** 938 * Get the module path roots for the 939 * {@link StandardLocation#ANNOTATION_PROCESSOR_MODULE_PATH annotation processor module path}. 940 * 941 * @return the roots in a map of module names to lists of roots, or an empty map if none were 942 * found. 943 * @since 0.1.0 944 */ 945 default Map<String, List<? extends PathRoot>> getAnnotationProcessorPathModules() { 946 return getModules(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH); 947 } 948 949 /** 950 * Get the path roots for the {@link StandardLocation#PLATFORM_CLASS_PATH platform class path} 951 * (also known as the boot class path). 952 * 953 * @return the roots in a collection, or an empty collection if none were found. 954 * @since 0.1.0 955 */ 956 default List<? extends PathRoot> getPlatformClassPathPackages() { 957 return getPackages(StandardLocation.PLATFORM_CLASS_PATH); 958 } 959 960 /** 961 * Get the non-module path roots for 962 * {@link StandardLocation#NATIVE_HEADER_OUTPUT native header outputs}. 963 * 964 * @return the roots in a collection, or an empty collection if none were found. 965 * @since 0.1.0 966 */ 967 default List<? extends PathRoot> getNativeHeaderOutputPackages() { 968 return getPackages(StandardLocation.NATIVE_HEADER_OUTPUT); 969 } 970 971 /** 972 * Get the module path roots for 973 * {@link StandardLocation#NATIVE_HEADER_OUTPUT native header outputs} for the given module name. 974 * 975 * @param moduleName the module name. 976 * @return the roots in a collection, or an empty collection if none were found. 977 * @since 0.1.0 978 */ 979 default List<? extends PathRoot> getNativeHeaderOutputModule(String moduleName) { 980 return getModule(StandardLocation.NATIVE_HEADER_OUTPUT, moduleName); 981 } 982 983 /** 984 * Get the module path roots for 985 * {@link StandardLocation#NATIVE_HEADER_OUTPUT native header outputs}. 986 * 987 * @return the roots in a map of module names to lists of roots, or an empty map if none were 988 * found. 989 * @since 0.1.0 990 */ 991 default Map<String, List<? extends PathRoot>> getNativeHeaderOutputModules() { 992 return getModules(StandardLocation.NATIVE_HEADER_OUTPUT); 993 } 994 995 /** 996 * Get the path roots for the {@link StandardLocation#MODULE_SOURCE_PATH module source path}. 997 * 998 * @param moduleName the module name to get. 999 * @return the roots in a collection, or an empty collection if none were found. 1000 * @since 0.1.0 1001 */ 1002 default List<? extends PathRoot> getSourcePathModule(String moduleName) { 1003 return getModule(StandardLocation.MODULE_SOURCE_PATH, moduleName); 1004 } 1005 1006 /** 1007 * Get the module path roots for the 1008 * {@link StandardLocation#MODULE_SOURCE_PATH module source paths}. 1009 * 1010 * @return the roots in a map of module names to lists of roots, or an empty map if none were 1011 * found. 1012 * @since 0.1.0 1013 */ 1014 default Map<String, List<? extends PathRoot>> getSourcePathModules() { 1015 return getModules(StandardLocation.MODULE_SOURCE_PATH); 1016 } 1017 1018 /** 1019 * Get the path roots for the {@link StandardLocation#UPGRADE_MODULE_PATH upgrade module path}. 1020 * 1021 * @param moduleName the module name to get. 1022 * @return the roots in a collection, or an empty collection if none were found. 1023 * @since 0.1.0 1024 */ 1025 default List<? extends PathRoot> getUpgradeModulePathModule(String moduleName) { 1026 return getModule(StandardLocation.UPGRADE_MODULE_PATH, moduleName); 1027 } 1028 1029 /** 1030 * Get the module path roots for the 1031 * {@link StandardLocation#UPGRADE_MODULE_PATH upgrade module paths}. 1032 * 1033 * @return the roots in a map of module names to lists of roots, or an empty map if none were 1034 * found. 1035 * @since 0.1.0 1036 */ 1037 default Map<String, List<? extends PathRoot>> getUpgradeModulePathModules() { 1038 return getModules(StandardLocation.UPGRADE_MODULE_PATH); 1039 } 1040 1041 /** 1042 * Get the path roots for the {@link StandardLocation#SYSTEM_MODULES system modules}. 1043 * 1044 * @param moduleName the module name to get. 1045 * @return the roots in a collection, or an empty collection if none were found. 1046 * @since 0.1.0 1047 */ 1048 default List<? extends PathRoot> getSystemModulePathModule(String moduleName) { 1049 return getModule(StandardLocation.SYSTEM_MODULES, moduleName); 1050 } 1051 1052 /** 1053 * Get the module path roots for the {@link StandardLocation#SYSTEM_MODULES system modules}. 1054 * 1055 * @return the roots in a map of module names to lists of roots, or an empty map if none were 1056 * found. 1057 * @since 0.1.0 1058 */ 1059 default Map<String, List<? extends PathRoot>> getSystemModulePathModules() { 1060 return getModules(StandardLocation.SYSTEM_MODULES); 1061 } 1062 1063 /** 1064 * Get the path roots for the {@link StandardLocation#MODULE_PATH module path}. 1065 * 1066 * @param moduleName the module name to get. 1067 * @return the roots in a collection, or an empty collection if none were found. 1068 * @since 0.1.0 1069 */ 1070 default List<? extends PathRoot> getModulePathModule(String moduleName) { 1071 return getModule(StandardLocation.MODULE_PATH, moduleName); 1072 } 1073 1074 /** 1075 * Get the module path roots for the {@link StandardLocation#MODULE_PATH module paths}. 1076 * 1077 * @return the roots in a map of module names to lists of roots, or an empty map if none were 1078 * found. 1079 * @since 0.1.0 1080 */ 1081 default Map<String, List<? extends PathRoot>> getModulePathModules() { 1082 return getModules(StandardLocation.MODULE_PATH); 1083 } 1084 1085 /** 1086 * Get the path roots for the {@link StandardLocation#PATCH_MODULE_PATH patch module path}. 1087 * 1088 * @param moduleName the module name to get. 1089 * @return the roots in a collection, or an empty collection if none were found. 1090 * @since 0.1.0 1091 */ 1092 default List<? extends PathRoot> getPatchModulePathModule(String moduleName) { 1093 return getModule(StandardLocation.PATCH_MODULE_PATH, moduleName); 1094 } 1095 1096 /** 1097 * Get the module path roots for the 1098 * {@link StandardLocation#PATCH_MODULE_PATH patch module paths}. 1099 * 1100 * @return the roots in a map of module names to lists of roots, or an empty map if none were 1101 * found. 1102 * @since 0.1.0 1103 */ 1104 default Map<String, List<? extends PathRoot>> getPatchModulePathModules() { 1105 return getModules(StandardLocation.PATCH_MODULE_PATH); 1106 } 1107}