d87713440a
Reviewed-by: jjg
278 lines
10 KiB
Java
278 lines
10 KiB
Java
/*
|
|
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
package toolbox;
|
|
|
|
import java.io.IOException;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.nio.file.Paths;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.LinkedHashSet;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
import java.util.stream.Collectors;
|
|
|
|
/**
|
|
* Builder for module declarations.
|
|
*/
|
|
public class ModuleBuilder {
|
|
|
|
private final ToolBox tb;
|
|
private final String name;
|
|
private String comment = "";
|
|
private boolean open;
|
|
private List<String> requires = new ArrayList<>();
|
|
private List<String> exports = new ArrayList<>();
|
|
private List<String> opens = new ArrayList<>();
|
|
private List<String> uses = new ArrayList<>();
|
|
private List<String> provides = new ArrayList<>();
|
|
private List<String> content = new ArrayList<>();
|
|
private Set<Path> modulePath = new LinkedHashSet<>();
|
|
|
|
/**
|
|
* Creates a builder for a module.
|
|
* @param tb a Toolbox that can be used to compile the module declaration
|
|
* @param name the name of the module to be built
|
|
*/
|
|
public ModuleBuilder(ToolBox tb, String name) {
|
|
this(tb, false, name);
|
|
}
|
|
|
|
/**
|
|
* Creates a builder for a module.
|
|
* @param tb a Toolbox that can be used to compile the module declaration
|
|
* @param open whether or not this is an open module
|
|
* @param name the name of the module to be built
|
|
*/
|
|
public ModuleBuilder(ToolBox tb, boolean open, String name) {
|
|
this.tb = tb;
|
|
this.open = open;
|
|
this.name = name;
|
|
}
|
|
|
|
/**
|
|
* Sets the doc comment for the declaration.
|
|
* @param comment the content of the comment, excluding the initial
|
|
* '/**', leading whitespace and asterisks, and the final trailing 'a;/'.
|
|
* @return this builder
|
|
*/
|
|
public ModuleBuilder comment(String comment) {
|
|
this.comment = comment;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Adds a "requires" directive to the declaration.
|
|
* @param module the name of the module that is required
|
|
* @param modulePath a path in while to locate the modules
|
|
* if the declaration is compiled
|
|
* @return this builder
|
|
*/
|
|
public ModuleBuilder requires(String module, Path... modulePath) {
|
|
addDirective(requires, "requires " + module + ";");
|
|
this.modulePath.addAll(Arrays.asList(modulePath));
|
|
return this;
|
|
|
|
}
|
|
|
|
/**
|
|
* Adds a "requires static" directive to the declaration.
|
|
* @param module the name of the module that is required
|
|
* @param modulePath a path in which to locate the modules
|
|
* if the declaration is compiled
|
|
* @return this builder
|
|
*/
|
|
public ModuleBuilder requiresStatic(String module, Path... modulePath) {
|
|
addDirective(requires, "requires static " + module + ";");
|
|
this.modulePath.addAll(Arrays.asList(modulePath));
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Adds a "requires transitive" directive to the declaration.
|
|
* @param module the name of the module that is required
|
|
* @param modulePath a path in which to locate the modules
|
|
* if the declaration is compiled
|
|
* @return this builder
|
|
*/
|
|
public ModuleBuilder requiresTransitive(String module, Path... modulePath) {
|
|
addDirective(requires, "requires transitive " + module + ";");
|
|
this.modulePath.addAll(Arrays.asList(modulePath));
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Adds a "requires static transitive" directive to the declaration.
|
|
* @param module the name of the module that is required
|
|
* @param modulePath a path in which to locate the modules
|
|
* if the declaration is compiled
|
|
* @return this builder
|
|
*/
|
|
public ModuleBuilder requiresStaticTransitive(String module, Path... modulePath) {
|
|
addDirective(requires, "requires static transitive " + module + ";");
|
|
this.modulePath.addAll(Arrays.asList(modulePath));
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Adds an unqualified "exports" directive to the declaration.
|
|
* @param pkg the name of the package to be exported
|
|
* @return this builder
|
|
*/
|
|
public ModuleBuilder exports(String pkg) {
|
|
return addDirective(exports, "exports " + pkg + ";");
|
|
}
|
|
|
|
/**
|
|
* Adds a qualified "exports" directive to the declaration.
|
|
* @param pkg the name of the package to be exported
|
|
* @param module the name of the module to which it is to be exported
|
|
* @return this builder
|
|
*/
|
|
public ModuleBuilder exportsTo(String pkg, String module) {
|
|
return addDirective(exports, "exports " + pkg + " to " + module + ";");
|
|
}
|
|
|
|
/**
|
|
* Adds an unqualified "opens" directive to the declaration.
|
|
* @param pkg the name of the package to be opened
|
|
* @return this builder
|
|
*/
|
|
public ModuleBuilder opens(String pkg) {
|
|
return addDirective(opens, "opens " + pkg + ";");
|
|
}
|
|
|
|
/**
|
|
* Adds a qualified "opens" directive to the declaration.
|
|
* @param pkg the name of the package to be opened
|
|
* @param module the name of the module to which it is to be opened
|
|
* @return this builder
|
|
*/
|
|
public ModuleBuilder opensTo(String pkg, String module) {
|
|
return addDirective(opens, "opens " + pkg + " to " + module + ";");
|
|
}
|
|
|
|
/**
|
|
* Adds a "uses" directive to the declaration.
|
|
* @param service the name of the service type
|
|
* @return this builder
|
|
*/
|
|
public ModuleBuilder uses(String service) {
|
|
return addDirective(uses, "uses " + service + ";");
|
|
}
|
|
|
|
/**
|
|
* Adds a "provides" directive to the declaration.
|
|
* @param service the name of the service type
|
|
* @param implementation the name of the implementation type
|
|
* @return this builder
|
|
*/
|
|
public ModuleBuilder provides(String service, String implementation) {
|
|
return addDirective(provides, "provides " + service + " with " + implementation + ";");
|
|
}
|
|
|
|
private ModuleBuilder addDirective(List<String> directives, String directive) {
|
|
directives.add(directive);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Adds type definitions to the module.
|
|
* @param content a series of strings, each representing the content of
|
|
* a compilation unit to be included with the module
|
|
* @return this builder
|
|
*/
|
|
public ModuleBuilder classes(String... content) {
|
|
this.content.addAll(Arrays.asList(content));
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Writes the module declaration and associated additional compilation
|
|
* units to a module directory within a given directory.
|
|
* @param srcDir the directory in which a directory will be created
|
|
* to contain the source files for the module
|
|
* @return the directory containing the source files for the module
|
|
*/
|
|
public Path write(Path srcDir) throws IOException {
|
|
Files.createDirectories(srcDir);
|
|
List<String> sources = new ArrayList<>();
|
|
StringBuilder sb = new StringBuilder();
|
|
if (!comment.isEmpty()) {
|
|
sb.append("/**\n * ")
|
|
.append(comment.replace("\n", "\n * "))
|
|
.append("\n */\n");
|
|
}
|
|
if (open) {
|
|
sb.append("open ");
|
|
}
|
|
sb.append("module ").append(name).append(" {\n");
|
|
requires.forEach(r -> sb.append(" " + r + "\n"));
|
|
exports.forEach(e -> sb.append(" " + e + "\n"));
|
|
opens.forEach(o -> sb.append(" " + o + "\n"));
|
|
uses.forEach(u -> sb.append(" " + u + "\n"));
|
|
provides.forEach(p -> sb.append(" " + p + "\n"));
|
|
sb.append("}");
|
|
sources.add(sb.toString());
|
|
sources.addAll(content);
|
|
Path moduleSrc = srcDir.resolve(name);
|
|
tb.writeJavaFiles(moduleSrc, sources.toArray(new String[]{}));
|
|
return moduleSrc;
|
|
}
|
|
|
|
/**
|
|
* Writes the source files for the module to an interim directory,
|
|
* and then compiles them to a given directory.
|
|
* @param modules the directory in which a directory will be created
|
|
* to contain the compiled class files for the module
|
|
* @throws IOException if an error occurs while compiling the files
|
|
*/
|
|
public void build(Path modules) throws IOException {
|
|
build(Paths.get(modules + "Src"), modules);
|
|
}
|
|
|
|
/**
|
|
* Writes the source files for the module to a specified directory,
|
|
* and then compiles them to a given directory.
|
|
* @param src the directory in which a directory will be created
|
|
* to contain the source files for the module
|
|
* @param modules the directory in which a directory will be created
|
|
* to contain the compiled class files for the module
|
|
* @throws IOException if an error occurs while compiling the files
|
|
*/
|
|
public void build(Path src, Path modules) throws IOException {
|
|
Path moduleSrc = write(src);
|
|
String mp = modulePath.stream()
|
|
.map(Path::toString)
|
|
.collect(Collectors.joining(ToolBox.pathSeparator));
|
|
new JavacTask(tb)
|
|
.outdir(Files.createDirectories(modules.resolve(name)))
|
|
.options("--module-path", mp)
|
|
.files(tb.findJavaFiles(moduleSrc))
|
|
.run()
|
|
.writeAll();
|
|
}
|
|
}
|