View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.release.plugin;
18  
19  import java.io.File;
20  import java.io.IOException;
21  import java.util.Optional;
22  import java.util.function.Supplier;
23  
24  import org.apache.maven.plugin.MojoExecutionException;
25  import org.apache.maven.plugin.logging.Log;
26  import org.apache.maven.scm.provider.ScmProviderRepository;
27  import org.apache.maven.settings.Server;
28  import org.apache.maven.settings.Settings;
29  import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
30  import org.apache.maven.settings.crypto.SettingsDecrypter;
31  import org.apache.maven.settings.crypto.SettingsDecryptionResult;
32  import org.codehaus.plexus.util.FileUtils;
33  
34  /**
35   * Shared static functions for all of our Mojos.
36   *
37   * @since 1.0
38   */
39  public final class SharedFunctions {
40  
41      /**
42       * I want a buffer that is an array with 1024 elements of bytes. We declare
43       * the constant here for the sake of making the code more readable.
44       */
45      public static final int BUFFER_BYTE_SIZE = 1024;
46  
47      /**
48       * Copies a {@link File} from the <code>fromFile</code> to the <code>toFile</code> and logs the failure
49       * using the Maven {@link Log}.
50       *
51       * @param log the {@link Log}, the maven logger.
52       * @param fromFile the {@link File} from which to copy.
53       * @param toFile the {@link File} to which to copy into.
54       * @throws MojoExecutionException if an {@link IOException} or {@link NullPointerException} is caught.
55       */
56      public static void copyFile(final Log log, final File fromFile, final File toFile) throws MojoExecutionException {
57          final String format = "Unable to copy file %s to %s: %s";
58          requireNonNull(fromFile, () -> String.format(format, fromFile, toFile));
59          requireNonNull(toFile, () -> String.format(format, fromFile, toFile));
60          try {
61              FileUtils.copyFile(fromFile, toFile);
62          } catch (final IOException e) {
63              final String message = String.format(format, fromFile, toFile, e.getMessage());
64              log.error(message);
65              throw new MojoExecutionException(message, e);
66          }
67      }
68  
69      /**
70       * Cleans and then initializes an empty directory that is given by the <code>workingDirectory</code>
71       * parameter.
72       *
73       * @param log is the Maven log for output logging, particularly in regards to error management.
74       * @param workingDirectory is a {@link File} that represents the directory to first attempt to delete then create.
75       * @throws MojoExecutionException when an {@link IOException} or {@link NullPointerException} is caught for the
76       *      purpose of bubbling the exception up to Maven properly.
77       */
78      public static void initDirectory(final Log log, final File workingDirectory) throws MojoExecutionException {
79          final String format = "Unable to remove directory %s: %s";
80          requireNonNull(workingDirectory, () -> String.format(format, workingDirectory));
81          if (workingDirectory.exists()) {
82              try {
83                  FileUtils.deleteDirectory(workingDirectory);
84              } catch (final IOException e) {
85                  final String message = String.format(format, workingDirectory, e.getMessage());
86                  log.error(message);
87                  throw new MojoExecutionException(message, e);
88              }
89          }
90          if (!workingDirectory.exists()) {
91              workingDirectory.mkdirs();
92          }
93      }
94  
95      /**
96       * Checks that the specified object reference is not {@code null}. This method is designed primarily for doing parameter validation in methods and
97       * constructors, as demonstrated below: <blockquote>
98       *
99       * <pre>
100      * public Foo(Bar bar) {
101      *     this.bar = SharedFunctions.requireNonNull(bar);
102      * }
103      * </pre>
104      *
105      * </blockquote>
106      *
107      * @param obj the object reference to check for nullity
108      * @param <T> the type of the reference
109      * @return {@code obj} if not {@code null}
110      * @throws MojoExecutionException if {@code obj} is {@code null}
111      */
112     public static <T> T requireNonNull(final T obj) throws MojoExecutionException {
113         if (obj == null) {
114             throw new MojoExecutionException(new NullPointerException());
115         }
116         return obj;
117     }
118 
119     /**
120      * Checks that the specified object reference is not {@code null} and throws a customized {@link MojoExecutionException} if it is. This method is designed
121      * primarily for doing parameter validation in methods and constructors with multiple parameters, as demonstrated below: <blockquote>
122      *
123      * <pre>
124      * public Foo(Bar bar, Baz baz) {
125      *     this.bar = SharedFunctions.requireNonNull(bar, "bar must not be null");
126      *     this.baz = SharedFunctions.requireNonNull(baz, "baz must not be null");
127      * }
128      * </pre>
129      *
130      * </blockquote>
131      *
132      * @param obj the object reference to check for nullity
133      * @param message detail message to be used in the event that a {@code
134      *                NullPointerException} is thrown
135      * @param <T> the type of the reference
136      * @return {@code obj} if not {@code null}
137      * @throws MojoExecutionException if {@code obj} is {@code null}
138      */
139     public static <T> T requireNonNull(final T obj, final String message) throws MojoExecutionException {
140         if (obj == null) {
141             throw new MojoExecutionException(new NullPointerException(message));
142         }
143         return obj;
144     }
145 
146     /**
147      * Checks that the specified object reference is not {@code null} and throws a customized {@link MojoExecutionException} if it is.
148      * <p>
149      * Unlike the method {@link #requireNonNull(Object, String)}, this method allows creation of the message to be deferred until after the null check is made.
150      * While this may confer a performance advantage in the non-null case, when deciding to call this method care should be taken that the costs of creating the
151      * message supplier are less than the cost of just creating the string message directly.
152      * </p>
153      *
154      * @param obj the object reference to check for nullity
155      * @param messageSupplier supplier of the detail message to be used in the event that a {@code NullPointerException} is thrown
156      * @param <T> the type of the reference
157      * @return {@code obj} if not {@code null}
158      * @throws MojoExecutionException if {@code obj} is {@code null}
159      */
160     public static <T> T requireNonNull(final T obj, final Supplier<String> messageSupplier) throws MojoExecutionException {
161         if (obj == null) {
162             throw new MojoExecutionException(new NullPointerException(messageSupplier.get()));
163         }
164         return obj;
165     }
166 
167     /**
168      * Sets authentication information on the specified {@link ScmProviderRepository}.
169      *
170      * @param providerRepository target.
171      * @param distServer temp.
172      * @param settings temp.
173      * @param settingsDecrypter temp.
174      * @param username temp.
175      * @param password temp.
176      */
177     public static void setAuthentication(final ScmProviderRepository providerRepository,
178                                    final String distServer,
179                                    final Settings settings,
180                                    final SettingsDecrypter settingsDecrypter,
181                                    final String username,
182                                    final String password) {
183         final Optional<Server> server =
184                 Optional.ofNullable(distServer).map(settings::getServer).map(DefaultSettingsDecryptionRequest::new)
185                         .map(settingsDecrypter::decrypt).map(SettingsDecryptionResult::getServer);
186 
187         providerRepository.setUser(server.map(Server::getUsername).orElse(username));
188         providerRepository.setPassword(server.map(Server::getPassword).orElse(password));
189     }
190 
191     /**
192      * Making the constructor private because the class only contains static methods.
193      */
194     private SharedFunctions() {
195         // Utility Class
196     }
197 }