001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.release.plugin; 018 019import java.io.File; 020import java.io.IOException; 021import java.util.Optional; 022import java.util.function.Supplier; 023 024import org.apache.maven.plugin.MojoExecutionException; 025import org.apache.maven.plugin.logging.Log; 026import org.apache.maven.scm.provider.ScmProviderRepository; 027import org.apache.maven.settings.Server; 028import org.apache.maven.settings.Settings; 029import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest; 030import org.apache.maven.settings.crypto.SettingsDecrypter; 031import org.apache.maven.settings.crypto.SettingsDecryptionResult; 032import org.codehaus.plexus.util.FileUtils; 033 034/** 035 * Shared static functions for all of our Mojos. 036 * 037 * @since 1.0 038 */ 039public final class SharedFunctions { 040 041 /** 042 * The buffer size in bytes. 043 */ 044 public static final int BUFFER_BYTE_SIZE = 1024; 045 046 /** 047 * Copies a {@link File} from the <code>fromFile</code> to the <code>toFile</code> and logs the failure 048 * using the Maven {@link Log}. 049 * 050 * @param log The {@link Log}, the Maven logger. 051 * @param fromFile The {@link File} from which to copy. 052 * @param toFile The destination {@link File}. 053 * @throws MojoExecutionException Thrown if an {@link IOException} occurs. 054 */ 055 public static void copyFile(final Log log, final File fromFile, final File toFile) throws MojoExecutionException { 056 final String format = "Unable to copy file %s to %s: %s"; 057 requireNonNull(fromFile, () -> String.format(format, fromFile, toFile)); 058 requireNonNull(toFile, () -> String.format(format, fromFile, toFile)); 059 try { 060 FileUtils.copyFile(fromFile, toFile); 061 } catch (final IOException e) { 062 final String message = String.format(format, fromFile, toFile, e.getMessage()); 063 log.error(message); 064 throw new MojoExecutionException(message, e); 065 } 066 } 067 068 /** 069 * Cleans and then initializes an empty directory that is given by the <code>workingDirectory</code> 070 * parameter. 071 * 072 * @param log is the Maven log for output logging, particularly with regard to error management. 073 * @param workingDirectory is a {@link File} that represents the directory to first attempt to delete and then create. 074 * @throws MojoExecutionException Thrown if an {@link IOException} occurs. 075 */ 076 public static void initDirectory(final Log log, final File workingDirectory) throws MojoExecutionException { 077 final String format = "Unable to remove directory %s: %s"; 078 requireNonNull(workingDirectory, () -> String.format(format, workingDirectory)); 079 if (workingDirectory.exists()) { 080 try { 081 FileUtils.deleteDirectory(workingDirectory); 082 } catch (final IOException e) { 083 final String message = String.format(format, workingDirectory, e.getMessage()); 084 log.error(message); 085 throw new MojoExecutionException(message, e); 086 } 087 } 088 if (!workingDirectory.exists()) { 089 workingDirectory.mkdirs(); 090 } 091 } 092 093 /** 094 * Checks that the specified object reference is not {@code null}. This method is designed primarily for doing parameter validation in methods and 095 * constructors, as demonstrated below: <blockquote> 096 * 097 * <pre> 098 * public Foo(Bar bar) { 099 * this.bar = SharedFunctions.requireNonNull(bar); 100 * } 101 * </pre> 102 * 103 * </blockquote> 104 * 105 * @param obj The object reference to check for nullity 106 * @param <T> The type of the reference 107 * @return {@code obj} if not {@code null} 108 * @throws MojoExecutionException Thrown if {@code obj} is {@code null}. 109 */ 110 public static <T> T requireNonNull(final T obj) throws MojoExecutionException { 111 if (obj == null) { 112 throw new MojoExecutionException(new NullPointerException()); 113 } 114 return obj; 115 } 116 117 /** 118 * Checks that the specified object reference is not {@code null} and throws a customized {@link MojoExecutionException} if it is. This method is designed 119 * primarily for doing parameter validation in methods and constructors with multiple parameters, as demonstrated below: <blockquote> 120 * 121 * <pre> 122 * public Foo(Bar bar, Baz baz) { 123 * this.bar = SharedFunctions.requireNonNull(bar, "bar must not be null"); 124 * this.baz = SharedFunctions.requireNonNull(baz, "baz must not be null"); 125 * } 126 * </pre> 127 * 128 * </blockquote> 129 * 130 * @param obj The object reference to check for nullity 131 * @param message detail message to be used in the event that a {@code 132 * NullPointerException} is thrown 133 * @param <T> The type of the reference 134 * @return {@code obj} if not {@code null} 135 * @throws MojoExecutionException Thrown if {@code obj} is {@code null}. 136 */ 137 public static <T> T requireNonNull(final T obj, final String message) throws MojoExecutionException { 138 if (obj == null) { 139 throw new MojoExecutionException(new NullPointerException(message)); 140 } 141 return obj; 142 } 143 144 /** 145 * Checks that the specified object reference is not {@code null} and throws a customized {@link MojoExecutionException} if it is. 146 * <p> 147 * Unlike the method {@link #requireNonNull(Object, String)}, this method allows creation of the message to be deferred until after the null check is made. 148 * 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 149 * the message supplier are less than the cost of just creating the string message directly. 150 * </p> 151 * 152 * @param obj The object reference to check for nullity 153 * @param messageSupplier supplier of the detail message to be used in the event that a {@code NullPointerException} is thrown 154 * @param <T> The type of the reference 155 * @return {@code obj} if not {@code null} 156 * @throws MojoExecutionException Thrown if {@code obj} is {@code null}. 157 */ 158 public static <T> T requireNonNull(final T obj, final Supplier<String> messageSupplier) throws MojoExecutionException { 159 if (obj == null) { 160 throw new MojoExecutionException(new NullPointerException(messageSupplier.get())); 161 } 162 return obj; 163 } 164 165 /** 166 * Sets authentication information on the specified {@link ScmProviderRepository}. 167 * 168 * @param providerRepository The repository to configure. 169 * @param distServer The server ID used to look up credentials in Maven settings. 170 * @param settings The Maven settings. 171 * @param settingsDecrypter The decrypter for stored credentials. 172 * @param username The fallback username when no server username is available. 173 * @param password The fallback password when no server password is available. 174 */ 175 public static void setAuthentication(final ScmProviderRepository providerRepository, 176 final String distServer, 177 final Settings settings, 178 final SettingsDecrypter settingsDecrypter, 179 final String username, 180 final String password) { 181 final Optional<Server> server = 182 Optional.ofNullable(distServer).map(settings::getServer).map(DefaultSettingsDecryptionRequest::new) 183 .map(settingsDecrypter::decrypt).map(SettingsDecryptionResult::getServer); 184 185 providerRepository.setUser(server.map(Server::getUsername).orElse(username)); 186 providerRepository.setPassword(server.map(Server::getPassword).orElse(password)); 187 } 188 189 /** 190 * Prevents instantiation of this utility class. 191 */ 192 private SharedFunctions() { 193 // Utility class. 194 } 195}