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.mvnenc;
20  
21  import java.io.InterruptedIOException;
22  import java.util.ArrayList;
23  import java.util.function.Consumer;
24  
25  import org.apache.maven.api.annotations.Nullable;
26  import org.apache.maven.api.cli.InvokerRequest;
27  import org.apache.maven.api.cli.mvnenc.EncryptOptions;
28  import org.apache.maven.api.services.Lookup;
29  import org.apache.maven.cling.invoker.LookupContext;
30  import org.apache.maven.cling.invoker.LookupInvoker;
31  import org.apache.maven.cling.utils.CLIReportingUtils;
32  import org.jline.reader.LineReaderBuilder;
33  import org.jline.reader.UserInterruptException;
34  import org.jline.terminal.Terminal;
35  import org.jline.utils.AttributedStyle;
36  import org.jline.utils.Colors;
37  
38  /**
39   * mvnenc invoker implementation.
40   */
41  public class EncryptInvoker extends LookupInvoker<EncryptContext> {
42  
43      public static final int OK = 0; // OK
44      public static final int ERROR = 1; // "generic" error
45      public static final int BAD_OPERATION = 2; // bad user input or alike
46      public static final int CANCELED = 3; // user canceled
47  
48      public EncryptInvoker(Lookup protoLookup, @Nullable Consumer<LookupContext> contextConsumer) {
49          super(protoLookup, contextConsumer);
50      }
51  
52      @Override
53      protected EncryptContext createContext(InvokerRequest invokerRequest) {
54          return new EncryptContext(
55                  invokerRequest, (EncryptOptions) invokerRequest.options().orElse(null));
56      }
57  
58      @Override
59      protected void lookup(EncryptContext context) throws Exception {
60          if (context.goals == null) {
61              super.lookup(context);
62              context.goals = context.lookup.lookupMap(Goal.class);
63          }
64      }
65  
66      @Override
67      protected int execute(EncryptContext context) throws Exception {
68          try {
69              context.header = new ArrayList<>();
70              context.style = new AttributedStyle();
71              context.addInHeader(
72                      context.style.italic().bold().foreground(Colors.rgbColor("green")),
73                      "Maven Encryption " + CLIReportingUtils.showVersionMinimal());
74              context.addInHeader("Tool for secure password management on workstations.");
75              context.addInHeader("This tool is part of Apache Maven 4 distribution.");
76              context.addInHeader("");
77  
78              context.terminal.handle(
79                      Terminal.Signal.INT, signal -> Thread.currentThread().interrupt());
80  
81              context.reader =
82                      LineReaderBuilder.builder().terminal(context.terminal).build();
83  
84              if (context.options().goals().isEmpty()
85                      || context.options().goals().get().size() != 1) {
86                  return badGoalsErrorMessage("No goal or multiple goals specified, specify only one goal.", context);
87              }
88  
89              String goalName = context.options().goals().get().get(0);
90              Goal goal = context.goals.get(goalName);
91  
92              if (goal == null) {
93                  return badGoalsErrorMessage("Unknown goal: " + goalName, context);
94              }
95  
96              return goal.execute(context);
97          } catch (InterruptedException | InterruptedIOException | UserInterruptException e) {
98              context.logger.error("Goal canceled by user.");
99              return CANCELED;
100         } catch (Exception e) {
101             if (context.options().showErrors().orElse(false)) {
102                 context.logger.error(e.getMessage(), e);
103             } else {
104                 context.logger.error(e.getMessage());
105             }
106             return ERROR;
107         }
108     }
109 
110     protected int badGoalsErrorMessage(String message, EncryptContext context) {
111         context.logger.error(message);
112         context.logger.error("Supported goals are: " + String.join(", ", context.goals.keySet()));
113         context.logger.error("Use -h to display help.");
114         return BAD_OPERATION;
115     }
116 }