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