View Javadoc
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.time.Instant;
23  import java.util.HashMap;
24  import java.util.Map;
25  
26  import org.apache.maven.api.annotations.Experimental;
27  import org.apache.maven.api.annotations.Nonnull;
28  import org.apache.maven.api.annotations.Nullable;
29  import org.apache.maven.api.annotations.ThreadSafe;
30  
31  import static java.util.Objects.requireNonNull;
32  
33  /**
34   * The proto session, material used to create {@link Session}.
35   *
36   * @since 4.0.0
37   */
38  @Experimental
39  @ThreadSafe
40  public interface ProtoSession {
41  
42      /**
43       * Returns immutable user properties to use for interpolation. The user properties have been configured directly
44       * by the user, e.g. via the {@code -Dkey=value} parameter on the command line.
45       *
46       * @return the user properties, never {@code null}
47       */
48      @Nonnull
49      Map<String, String> getUserProperties();
50  
51      /**
52       * Returns immutable system properties to use for interpolation. The system properties are collected from the
53       * runtime environment such as {@link System#getProperties()} and environment variables
54       * (prefixed with {@code env.}).
55       *
56       * @return the system properties, never {@code null}
57       */
58      @Nonnull
59      Map<String, String> getSystemProperties();
60  
61      /**
62       * Returns the start time of the session.
63       *
64       * @return the start time as an Instant object, never {@code null}
65       */
66      @Nonnull
67      Instant getStartTime();
68  
69      /**
70       * Gets the directory of the topmost project being built, usually the current directory or the
71       * directory pointed at by the {@code -f/--file} command line argument.
72       *
73       * @return the directory of the topmost project, never {@code null}
74       * @see Project#isTopProject()
75       * @see #getRootDirectory()
76       */
77      @Nonnull
78      Path getTopDirectory();
79  
80      /**
81       * Gets the root directory of the session, which is the root directory for the top directory project.
82       *
83       * @return the root directory, never {@code null}
84       * @throws IllegalStateException if the root directory could not be found
85       * @see #getTopDirectory()
86       * @see Project#getRootDirectory()
87       * @see Project#isRootProject()
88       */
89      @Nonnull
90      Path getRootDirectory();
91  
92      /**
93       * Returns a proto session builder of this instance.
94       */
95      @Nonnull
96      default Builder toBuilder() {
97          try {
98              return new Builder(
99                      getUserProperties(), getSystemProperties(), getStartTime(), getTopDirectory(), getRootDirectory());
100         } catch (IllegalStateException e) {
101             return new Builder(getUserProperties(), getSystemProperties(), getStartTime(), getTopDirectory(), null);
102         }
103     }
104 
105     /**
106      * Returns new builder from scratch.
107      */
108     static Builder newBuilder() {
109         return new Builder().withStartTime(MonotonicClock.now());
110     }
111 
112     class Builder {
113         private Map<String, String> userProperties;
114         private Map<String, String> systemProperties;
115         private Instant startTime;
116         private Path topDirectory;
117         private Path rootDirectory;
118 
119         private Builder() {}
120 
121         private Builder(
122                 Map<String, String> userProperties,
123                 Map<String, String> systemProperties,
124                 Instant startTime,
125                 Path topDirectory,
126                 Path rootDirectory) {
127             this.userProperties = userProperties;
128             this.systemProperties = systemProperties;
129             this.startTime = startTime;
130             this.topDirectory = topDirectory;
131             this.rootDirectory = rootDirectory;
132         }
133 
134         public Builder withUserProperties(@Nonnull Map<String, String> userProperties) {
135             this.userProperties = new HashMap<>(userProperties);
136             return this;
137         }
138 
139         public Builder withSystemProperties(@Nonnull Map<String, String> systemProperties) {
140             this.systemProperties = new HashMap<>(systemProperties);
141             return this;
142         }
143 
144         public Builder withStartTime(@Nonnull Instant startTime) {
145             this.startTime = requireNonNull(startTime, "startTime");
146             return this;
147         }
148 
149         public Builder withTopDirectory(@Nonnull Path topDirectory) {
150             this.topDirectory = requireNonNull(topDirectory, "topDirectory");
151             return this;
152         }
153 
154         public Builder withRootDirectory(@Nullable Path rootDirectory) {
155             this.rootDirectory = rootDirectory;
156             return this;
157         }
158 
159         public ProtoSession build() {
160             return new Impl(userProperties, systemProperties, startTime, topDirectory, rootDirectory);
161         }
162 
163         private static class Impl implements ProtoSession {
164             private final Map<String, String> userProperties;
165             private final Map<String, String> systemProperties;
166             private final Instant startTime;
167             private final Path topDirectory;
168             private final Path rootDirectory;
169 
170             private Impl(
171                     Map<String, String> userProperties,
172                     Map<String, String> systemProperties,
173                     Instant startTime,
174                     Path topDirectory,
175                     Path rootDirectory) {
176                 this.userProperties = requireNonNull(userProperties);
177                 this.systemProperties = requireNonNull(systemProperties);
178                 this.startTime = requireNonNull(startTime);
179                 this.topDirectory = requireNonNull(topDirectory);
180                 this.rootDirectory = rootDirectory;
181             }
182 
183             @Override
184             public Map<String, String> getUserProperties() {
185                 return userProperties;
186             }
187 
188             @Override
189             public Map<String, String> getSystemProperties() {
190                 return systemProperties;
191             }
192 
193             @Override
194             public Instant getStartTime() {
195                 return startTime;
196             }
197 
198             @Override
199             public Path getTopDirectory() {
200                 return topDirectory;
201             }
202 
203             @Override
204             public Path getRootDirectory() {
205                 if (rootDirectory == null) {
206                     throw new IllegalStateException("root directory not set");
207                 }
208                 return rootDirectory;
209             }
210         }
211     }
212 }