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 }