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 * http://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 * I want a buffer that is an array with 1024 elements of bytes. We declare 043 * the constant here for the sake of making the code more readable. 044 */ 045 public static final int BUFFER_BYTE_SIZE = 1024; 046 047 /** 048 * Copies a {@link File} from the <code>fromFile</code> to the <code>toFile</code> and logs the failure 049 * using the Maven {@link Log}. 050 * 051 * @param log the {@link Log}, the maven logger. 052 * @param fromFile the {@link File} from which to copy. 053 * @param toFile the {@link File} to which to copy into. 054 * @throws MojoExecutionException if an {@link IOException} or {@link NullPointerException} is caught. 055 */ 056 public static void copyFile(final Log log, final File fromFile, final File toFile) throws MojoExecutionException { 057 final String format = "Unable to copy file %s to %s: %s"; 058 requireNonNull(fromFile, () -> String.format(format, fromFile, toFile)); 059 requireNonNull(toFile, () -> String.format(format, fromFile, toFile)); 060 try { 061 FileUtils.copyFile(fromFile, toFile); 062 } catch (final IOException e) { 063 final String message = String.format(format, fromFile, toFile, e.getMessage()); 064 log.error(message); 065 throw new MojoExecutionException(message, e); 066 } 067 } 068 069 /** 070 * Cleans and then initializes an empty directory that is given by the <code>workingDirectory</code> 071 * parameter. 072 * 073 * @param log is the Maven log for output logging, particularly in regards to error management. 074 * @param workingDirectory is a {@link File} that represents the directory to first attempt to delete then create. 075 * @throws MojoExecutionException when an {@link IOException} or {@link NullPointerException} is caught for the 076 * purpose of bubbling the exception up to Maven properly. 077 */ 078 public static void initDirectory(final Log log, final File workingDirectory) throws MojoExecutionException { 079 final String format = "Unable to remove directory %s: %s"; 080 requireNonNull(workingDirectory, () -> String.format(format, workingDirectory)); 081 if (workingDirectory.exists()) { 082 try { 083 FileUtils.deleteDirectory(workingDirectory); 084 } catch (final IOException e) { 085 final String message = String.format(format, workingDirectory, e.getMessage()); 086 log.error(message); 087 throw new MojoExecutionException(message, e); 088 } 089 } 090 if (!workingDirectory.exists()) { 091 workingDirectory.mkdirs(); 092 } 093 } 094 095 /** 096 * Checks that the specified object reference is not {@code null}. This method is designed primarily for doing parameter validation in methods and 097 * constructors, as demonstrated below: <blockquote> 098 * 099 * <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}