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.io.File;
22  import java.io.IOException;
23  import java.nio.file.Path;
24  import java.util.Collection;
25  import java.util.HashMap;
26  import java.util.Map;
27  import java.util.Optional;
28  import java.util.Properties;
29  import java.util.ServiceLoader;
30  import java.util.function.Function;
31  
32  import org.apache.maven.api.annotations.Nonnull;
33  import org.apache.maven.api.annotations.Nullable;
34  import org.apache.maven.api.services.model.RootLocator;
35  import org.apache.maven.cli.logging.Slf4jConfiguration;
36  import org.apache.maven.execution.MavenExecutionRequest;
37  import org.codehaus.plexus.interpolation.AbstractValueSource;
38  import org.codehaus.plexus.interpolation.BasicInterpolator;
39  import org.codehaus.plexus.interpolation.StringSearchInterpolator;
40  import org.codehaus.plexus.logging.Logger;
41  
42  import static java.util.Objects.requireNonNull;
43  
44  /**
45   * Various utilities, mostly to bridge "old" and "new" stuff, like Properties vs Maps, File vs Paths, etc.
46   */
47  public final class Utils {
48      private Utils() {}
49  
50      @Nullable
51      public static File toFile(Path path) {
52          if (path != null) {
53              return path.toFile();
54          }
55          return null;
56      }
57  
58      @Nonnull
59      public static String stripLeadingAndTrailingQuotes(String str) {
60          requireNonNull(str, "str");
61          final int length = str.length();
62          if (length > 1
63                  && str.startsWith("\"")
64                  && str.endsWith("\"")
65                  && str.substring(1, length - 1).indexOf('"') == -1) {
66              str = str.substring(1, length - 1);
67          }
68          return str;
69      }
70  
71      @Nonnull
72      public static Path getCanonicalPath(Path path) {
73          requireNonNull(path, "path");
74          try {
75              return path.toRealPath();
76          } catch (IOException e) {
77              return getCanonicalPath(path.getParent()).resolve(path.getFileName());
78          }
79      }
80  
81      @Nonnull
82      public static Map<String, String> toMap(Properties properties) {
83          requireNonNull(properties, "properties");
84          HashMap<String, String> map = new HashMap<>();
85          for (String key : properties.stringPropertyNames()) {
86              map.put(key, properties.getProperty(key));
87          }
88          return map;
89      }
90  
91      @Nonnull
92      public static Properties toProperties(Map<String, String> properties) {
93          requireNonNull(properties, "properties");
94          Properties map = new Properties();
95          for (String key : properties.keySet()) {
96              map.put(key, properties.get(key));
97          }
98          return map;
99      }
100 
101     @Nonnull
102     public static BasicInterpolator createInterpolator(Collection<Map<String, String>> properties) {
103         StringSearchInterpolator interpolator = new StringSearchInterpolator();
104         interpolator.addValueSource(new AbstractValueSource(false) {
105             @Override
106             public Object getValue(String expression) {
107                 for (Map<String, String> props : properties) {
108                     String val = props.get(expression);
109                     if (val != null) {
110                         return val;
111                     }
112                 }
113                 return null;
114             }
115         });
116         return interpolator;
117     }
118 
119     @Nonnull
120     public static Function<String, String> prefix(String prefix, Function<String, String> cb) {
121         return s -> {
122             String v = null;
123             if (s.startsWith(prefix)) {
124                 v = cb.apply(s.substring(prefix.length()));
125             }
126             return v;
127         };
128     }
129 
130     @SafeVarargs
131     @Nonnull
132     public static Function<String, String> or(Function<String, String>... callbacks) {
133         return s -> {
134             for (Function<String, String> cb : callbacks) {
135                 String r = cb.apply(s);
136                 if (r != null) {
137                     return r;
138                 }
139             }
140             return null;
141         };
142     }
143 
144     public static int toMavenExecutionRequestLoggingLevel(Slf4jConfiguration.Level level) {
145         requireNonNull(level, "level");
146         return switch (level) {
147             case DEBUG -> MavenExecutionRequest.LOGGING_LEVEL_DEBUG;
148             case INFO -> MavenExecutionRequest.LOGGING_LEVEL_INFO;
149             case ERROR -> MavenExecutionRequest.LOGGING_LEVEL_ERROR;
150         };
151     }
152 
153     public static int toPlexusLoggingLevel(Slf4jConfiguration.Level level) {
154         requireNonNull(level, "level");
155         return switch (level) {
156             case DEBUG -> Logger.LEVEL_DEBUG;
157             case INFO -> Logger.LEVEL_INFO;
158             case ERROR -> Logger.LEVEL_ERROR;
159         };
160     }
161 
162     @Nullable
163     public static Path findRoot(Path topDirectory) {
164         requireNonNull(topDirectory, "topDirectory");
165         Path rootDirectory =
166                 ServiceLoader.load(RootLocator.class).iterator().next().findRoot(topDirectory);
167         if (rootDirectory != null) {
168             return getCanonicalPath(rootDirectory);
169         }
170         return null;
171     }
172 
173     @Nonnull
174     public static Path findMandatoryRoot(Path topDirectory) {
175         requireNonNull(topDirectory, "topDirectory");
176         return getCanonicalPath(Optional.ofNullable(
177                         ServiceLoader.load(RootLocator.class).iterator().next().findMandatoryRoot(topDirectory))
178                 .orElseThrow());
179     }
180 }