1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.maven.api;
20
21 import java.nio.file.Path;
22 import java.nio.file.PathMatcher;
23 import java.util.Collection;
24 import java.util.List;
25 import java.util.Optional;
26
27 /**
28 * A root directory of source files.
29 * The sources may be Java main classes, test classes, resources or anything else identified by the scope.
30 *
31 * <h2>Default values</h2>
32 * The properties in this interface are defined in the {@code <Source>} element of the
33 * {@linkplain org.apache.maven.api.model.Model Maven project descriptor}.
34 * For each property, the default value is either empty or documented in the project descriptor.
35 */
36 public interface SourceRoot {
37 /**
38 * {@return the root directory where the sources are stored}.
39 * The path is relative to the <abbr>POM</abbr> file.
40 *
41 * <h4>Default implementation</h4>
42 * The default value depends on whether a {@linkplain #module() module name} is specified in this source root:
43 * <ul>
44 * <li>
45 * If no module name, then the default directory is
46 * <code>src/{@linkplain #scope() scope}/{@linkplain #language() language}</code>.
47 * </li><li>
48 * If a module name is present, then the default directory is
49 * <code>src/{@linkplain #module() module}/{@linkplain #scope() scope}/{@linkplain #language() language}</code>.
50 * </li>
51 * </ul>
52 *
53 * The default value is relative.
54 * Implementation may override with absolute path instead.
55 */
56 default Path directory() {
57 Path src = Path.of("src");
58 return module().map(src::resolve)
59 .orElse(src)
60 .resolve(scope().id())
61 .resolve(language().id());
62 }
63
64 /**
65 * {@return the list of patterns for the files to include}.
66 * The path separator is {@code /} on all platforms, including Windows.
67 * The prefix before the {@code :} character, if present and longer than 1 character, is the syntax.
68 * If no syntax is specified, or if its length is 1 character (interpreted as a Windows drive),
69 * the default is a Maven-specific variation of the {@code "glob"} pattern.
70 *
71 * <p>
72 * The default implementation returns an empty list, which means to apply a language-dependent pattern.
73 * For example, for the Java language, the pattern includes all files with the {@code .java} suffix.
74 *
75 * @see java.nio.file.FileSystem#getPathMatcher(String)
76 */
77 default List<String> includes() {
78 return List.of();
79 }
80
81 /**
82 * {@return the list of patterns for the files to exclude}.
83 * The exclusions are applied after the inclusions.
84 * The default implementation returns an empty list.
85 */
86 default List<String> excludes() {
87 return List.of();
88 }
89
90 /**
91 * {@return a matcher combining the include and exclude patterns}.
92 * If the user did not specify any includes, the given {@code defaultIncludes} are used.
93 * These defaults depend on the plugin.
94 * For example, the default include of the Java compiler plugin is <code>"**/*.java"</code>.
95 *
96 * <p>If the user did not specify any excludes, the default is often files generated
97 * by Source Code Management (<abbr>SCM</abbr>) software or by the operating system.
98 * Examples: <code>"**/.gitignore"</code>, <code>"**/.DS_Store"</code>.</p>
99 *
100 * @param defaultIncludes the default includes if unspecified by the user
101 * @param useDefaultExcludes whether to add the default set of patterns to exclude,
102 * mostly Source Code Management (<abbr>SCM</abbr>) files
103 */
104 PathMatcher matcher(Collection<String> defaultIncludes, boolean useDefaultExcludes);
105
106 /**
107 * {@return in which context the source files will be used}.
108 * Not to be confused with dependency scope.
109 * The default value is {@code "main"}.
110 *
111 * @see ProjectScope#MAIN
112 */
113 default ProjectScope scope() {
114 return ProjectScope.MAIN;
115 }
116
117 /**
118 * {@return the language of the source files}.
119 * The default value is {@code "java"}.
120 *
121 * @see Language#JAVA_FAMILY
122 */
123 default Language language() {
124 return Language.JAVA_FAMILY;
125 }
126
127 /**
128 * {@return the name of the Java module (or other language-specific module) which is built by the sources}.
129 * The default value is empty.
130 */
131 default Optional<String> module() {
132 return Optional.empty();
133 }
134
135 /**
136 * {@return the version of the platform where the code will be executed}.
137 * In a Java environment, this is the value of the {@code --release} compiler option.
138 * The default value is empty.
139 */
140 default Optional<Version> targetVersion() {
141 return Optional.empty();
142 }
143
144 /**
145 * {@return an explicit target path, overriding the default value}.
146 * When a target path is explicitly specified, the values of the {@link #module()} and {@link #targetVersion()}
147 * elements are not used for inferring the path (they are still used as compiler options however).
148 * It means that for scripts and resources, the files below the path specified by {@link #directory()}
149 * are copied to the path specified by {@code targetPath()} with the exact same directory structure.
150 */
151 default Optional<Path> targetPath() {
152 return Optional.empty();
153 }
154
155 /**
156 * {@return whether resources are filtered to replace tokens with parameterized values}.
157 * The default value is {@code false}.
158 */
159 default boolean stringFiltering() {
160 return false;
161 }
162
163 /**
164 * {@return whether the directory described by this source element should be included in the build}.
165 * The default value is {@code true}.
166 */
167 default boolean enabled() {
168 return true;
169 }
170 }