Java tutorial
/* * Copyright Addicticks 2015. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.addicticks.maven.httpsupload.mojo; import com.addicticks.net.httpsupload.UploadProgress; import com.addicticks.net.httpsupload.HttpsFileUploader; import com.addicticks.net.httpsupload.HttpsFileUploaderConfig; import com.addicticks.net.httpsupload.HttpsFileUploaderResult; import com.addicticks.net.httpsupload.UploadItem; import com.addicticks.net.httpsupload.Utils; import java.io.File; import java.io.IOException; import java.net.URL; import java.text.MessageFormat; import java.util.Date; import java.util.List; import java.util.Map; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.settings.Server; import org.apache.maven.settings.Settings; /** * * @author Addicticks */ public abstract class UploadAbstractMojo extends AbstractMojo implements UploadProgress { private static final long SIZE_1MB = (1024 * 1024); /** * The URL to upload the file(s) to. Must be either HTTP or HTTPS protocol. * * <p> * The plugin derives which protocol to use from this value. * * <p> * Examples: * <pre> * https://solar.mycompany.com/upload * http://pluto.vanilla.org/acceptfiles * </pre> * */ @Parameter(required = true) protected URL targetURL; /** * Extra fields to send along with the file upload. The keys of * the map are the field names and the value their (String) content. * * <p> * Example * <pre> * <extraFields> * <field1>value1</field1> * <field2>value2</field2> * ... * </extraFields> * </pre> * * <p> * Typical use cases: Extra fields are often used to provide information * about the uploader such as a name or an e-mail address. Or they can * convey additional information about where the server should put the * files, such as a destination folder or similar. * * <p> * NB: Don't set the {@code filename} field here. Posting content for * {@code filename} is handled automatically. */ @Parameter(required = false) protected Map<String, String> extraFields; /** * Specifies if the certificate at the endpoint should be validated or not. * Only relevant for HTTPS protocol, otherwise ignored. * * <p> * If the value is {@code false} then the server's certificate is not * validated in any way. This may be useful when working with endpoints that * use a self-signed certificate. */ @Parameter(required = false, defaultValue = "true") protected boolean validateCertificate; /** * Connect timeout (in milliseconds) to use when connecting to the endpoint. * * <p>If the URL is specified with a hostname as opposed to an IP address then * a name lookup needs to be performed. This is <i>not</i> included in the * connect timeout. The connect timeout is the time it takes to establish * the tcp connection, nothing else. The timeout for name resolution (DNS lookup) is * platform dependent. */ @Parameter(required = false, defaultValue = "10000") protected int connectTimeoutMs; /** * Read timeout (in milliseconds) to use when reading from the endpoint. This * is the time from the upload has completed until the server responds. * * <p>You may have to increase this parameter if the endpoint takes a long * time to process the uploaded data. */ @Parameter(required = false, defaultValue = "10000") protected int readTimeoutMs; /** * Sets additional overall HTTP headers to add to the upload POST request. * There's rarely a need to use this parameter. * * <p> * The following header fields are automatically set: * <pre> * "Connection" * "Cache-Control" * "Content-Type" * "Content-Length" * "Authorization" * </pre> and you must <i>never</i> set these here. (if you do they will be * ignored). * * <p> * However you might want to use this parameter to explicitly set e.g. * {@code User-Agent} or non-standard header fields that are required for your * particular endpoint. For example by overriding {@code User-Agent} you can * make the upload operation look to the endpoint as if it comes from a * browser. * * <p>Example: * <pre> * <additionalHeaders> * <!-- impersonate Safari browser on iPad --> * <User-Agent>Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405</User-Agent> * <!-- just an example of a really weird header field --> * <From>joe@mycorp.com</From> * </additionalHeaders> * </pre> * * */ @Parameter(required = false) protected Map<String, String> additionalHeaders; /** * Can be used to turn off upload progress logging (if parameter value is {@code false}). * By default upload progress logging is enabled. Progress logging can be * a bit 'chatty'. * * <p>Files larger than 100 MBytes will see a log entry for every one percent * uploaded. For files less this size there will be proportionally less log * entries. * * <p>This parameter will only turn off the actual progress logging not the logging * at the beginning and end of the file upload operation. */ @Parameter(required = false, defaultValue = "true") protected boolean indicateProgress; /** * */ @Parameter(required = false, defaultValue = "false") protected boolean useAuthentication; @Parameter(defaultValue = "${settings}", readonly = true) protected Settings settings; @Override public void uploadProgress(File file, long totalSize, int pct) { if (indicateProgress) { boolean doPrint = false; if (totalSize > (100 * SIZE_1MB)) { doPrint = true; } else if (totalSize > (50 * SIZE_1MB)) { // Notify for every 10% if ((pct % 10) == 0) { doPrint = true; } } else if (totalSize > (10 * SIZE_1MB)) { // Notify for every 25% if ((pct % 25) == 0) { doPrint = true; } } else { // Notify for every 50% if (pct == 50) { doPrint = true; } } if (doPrint || pct == 0 || pct == 100) { getLog().info(MessageFormat.format("Uploading {0} : {1,number,##0} pct completed.", file, pct)); } } } @Override public void uploadStart(int noOfFiles, long totalSizeAll) { getLog().info("Uploading " + noOfFiles + " files. Total " + Utils.fileSizeAsStr(totalSizeAll)); } @Override public void uploadEnd(long totalSizeAll, long msecondsUsed) { getLog().info("Upload completed. " + Utils.fileSizeAsStr(totalSizeAll) + " sent in " + ((double) (msecondsUsed / 1000)) + " seconds."); } protected void setEndpointCredentials(HttpsFileUploaderConfig config, URL targetURL) throws MojoExecutionException { String targetHost = targetURL.getHost().toLowerCase(); Server serverSettings = settings.getServer(targetHost); if (serverSettings != null) { if (serverSettings.getUsername() != null && serverSettings.getPassword() != null) { getLog().debug("Found Server settings in settings.xml for " + targetHost + " : username : " + serverSettings.getUsername() + ", password : *********"); config.setEndpointUsername(serverSettings.getUsername()); config.setEndpointPassword(serverSettings.getPassword()); } else { throw new MojoExecutionException("Found Server settings in settings.xml for " + targetHost + " but no username and password information was found"); } } else { throw new MojoExecutionException("No Server settings found in settings.xml for " + targetHost); } } protected HttpsFileUploaderConfig getConfig() throws MojoExecutionException { HttpsFileUploaderConfig config = new HttpsFileUploaderConfig(targetURL); config.setValidateCertificates(validateCertificate); if (useAuthentication) { setEndpointCredentials(config, targetURL); } return config; } protected void upload(HttpsFileUploaderConfig config, List<UploadItem> filesToUpload, Map<String, String> otherFields) throws MojoExecutionException { getLog().info("Uploading to " + targetURL); try { HttpsFileUploaderResult result = HttpsFileUploader.upload(config, filesToUpload, extraFields, this); if (result.isError()) { getLog().error("Uploading was unsuccesful !"); String responseText = result.getResponseTextNoHtml(); throw new MojoExecutionException("Could not upload to " + targetURL + ". Error from server was : " + System.lineSeparator() + "Status code: " + Utils.getHttpStatusCodeText(result.getHttpStatusCode()) + System.lineSeparator() + ((responseText == null) ? "<server did not return a text response>" : responseText)); } } catch (IOException ex) { throw new MojoExecutionException("Error uploading file to " + targetURL.toString(), ex); } } }