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.cling.invoker;
20  
21  import java.nio.file.Path;
22  import java.util.ArrayList;
23  import java.util.Collections;
24  import java.util.HashMap;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Set;
28  import java.util.function.Consumer;
29  import java.util.function.Function;
30  
31  import org.apache.maven.api.ProtoSession;
32  import org.apache.maven.api.cli.InvokerException;
33  import org.apache.maven.api.cli.InvokerRequest;
34  import org.apache.maven.api.cli.Logger;
35  import org.apache.maven.api.services.Lookup;
36  import org.apache.maven.api.settings.Settings;
37  import org.apache.maven.cling.logging.Slf4jConfiguration;
38  import org.apache.maven.logging.BuildEventListener;
39  import org.jline.terminal.Terminal;
40  import org.slf4j.ILoggerFactory;
41  
42  import static java.util.Objects.requireNonNull;
43  
44  @SuppressWarnings("VisibilityModifier")
45  public class LookupContext implements AutoCloseable {
46      public final InvokerRequest invokerRequest;
47      public final Function<String, Path> cwdResolver;
48      public final Function<String, Path> installationResolver;
49      public final Function<String, Path> userResolver;
50  
51      protected LookupContext(InvokerRequest invokerRequest) {
52          this.invokerRequest = requireNonNull(invokerRequest);
53          this.cwdResolver = s -> invokerRequest.cwd().resolve(s).normalize().toAbsolutePath();
54          this.installationResolver = s ->
55                  invokerRequest.installationDirectory().resolve(s).normalize().toAbsolutePath();
56          this.userResolver =
57                  s -> invokerRequest.userHomeDirectory().resolve(s).normalize().toAbsolutePath();
58          this.logger = invokerRequest.parserRequest().logger();
59  
60          Map<String, String> user = new HashMap<>(invokerRequest.userProperties());
61          user.put("session.topDirectory", invokerRequest.topDirectory().toString());
62          if (invokerRequest.rootDirectory().isPresent()) {
63              user.put(
64                      "session.rootDirectory",
65                      invokerRequest.rootDirectory().get().toString());
66          }
67          this.protoSession = ProtoSession.newBuilder()
68                  .withSystemProperties(invokerRequest.systemProperties())
69                  .withUserProperties(user)
70                  .withTopDirectory(invokerRequest.topDirectory())
71                  .withRootDirectory(invokerRequest.rootDirectory().orElse(null))
72                  .build();
73      }
74  
75      // this one "evolves" as process progresses (instance is immutable but instances are replaced)
76      public ProtoSession protoSession;
77      // here we track which user properties we pushed to Java System Properties (internal only)
78      public Set<String> pushedUserProperties;
79  
80      public Logger logger;
81      public ILoggerFactory loggerFactory;
82      public Slf4jConfiguration slf4jConfiguration;
83      public Slf4jConfiguration.Level loggerLevel;
84      public Boolean coloredOutput;
85      public Terminal terminal;
86      public Consumer<String> writer;
87      public ContainerCapsule containerCapsule;
88      public Lookup lookup;
89  
90      public BuildEventListener buildEventListener;
91  
92      // paths user can override from CLI, and we need to set on MavenExReq
93      public Path installationSettingsPath;
94      public Path projectSettingsPath;
95      public Path userSettingsPath;
96  
97      public boolean interactive;
98      public Path localRepositoryPath;
99      public Settings effectiveSettings;
100 
101     public final List<AutoCloseable> closeables = new ArrayList<>();
102 
103     @Override
104     public void close() throws InvokerException {
105         List<Exception> causes = null;
106         List<AutoCloseable> cs = new ArrayList<>(closeables);
107         Collections.reverse(cs);
108         for (AutoCloseable c : cs) {
109             if (c != null) {
110                 try {
111                     c.close();
112                 } catch (Exception e) {
113                     if (causes == null) {
114                         causes = new ArrayList<>();
115                     }
116                     causes.add(e);
117                 }
118             }
119         }
120         if (causes != null) {
121             InvokerException exception = new InvokerException("Unable to close context");
122             causes.forEach(exception::addSuppressed);
123             throw exception;
124         }
125     }
126 
127     protected void closeContainer() {
128         if (containerCapsule != null) {
129             try {
130                 containerCapsule.close();
131             } finally {
132                 lookup = null;
133                 containerCapsule = null;
134             }
135         }
136     }
137 }