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