001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.eclipse.aether.spi.connector.transport; 020 021import java.io.ByteArrayInputStream; 022import java.io.File; 023import java.io.IOException; 024import java.io.InputStream; 025import java.io.UncheckedIOException; 026import java.net.URI; 027import java.nio.charset.StandardCharsets; 028import java.nio.file.Files; 029import java.nio.file.Path; 030 031/** 032 * A task to upload a resource to the remote repository. 033 * 034 * @see Transporter#put(PutTask) 035 */ 036public final class PutTask extends TransportTask { 037 038 private Path dataPath; 039 040 private byte[] dataBytes = EMPTY; 041 042 /** 043 * Creates a new task for the specified remote resource. 044 * 045 * @param location The relative location of the resource in the remote repository, must not be {@code null}. 046 */ 047 public PutTask(URI location) { 048 setLocation(location); 049 } 050 051 /** 052 * Opens an input stream for the data to be uploaded. The length of the stream can be queried via 053 * {@link #getDataLength()}. It's the responsibility of the caller to close the provided stream. 054 * 055 * @return The input stream for the data, never {@code null}. The stream is unbuffered. 056 * @throws IOException If the stream could not be opened. 057 */ 058 public InputStream newInputStream() throws IOException { 059 if (dataPath != null) { 060 return Files.newInputStream(dataPath); 061 } 062 return new ByteArrayInputStream(dataBytes); 063 } 064 065 /** 066 * Gets the total number of bytes to be uploaded. 067 * 068 * @return The total number of bytes to be uploaded. 069 */ 070 public long getDataLength() { 071 if (dataPath != null) { 072 try { 073 return Files.size(dataPath); 074 } catch (IOException e) { 075 throw new UncheckedIOException(e); 076 } 077 } 078 return dataBytes.length; 079 } 080 081 /** 082 * Gets the file (if any) with the data to be uploaded. 083 * 084 * @return The data file or {@code null} if the data resides in memory. 085 * @deprecated Use {@link #getDataPath()} instead. 086 */ 087 @Deprecated 088 public File getDataFile() { 089 return dataPath != null ? dataPath.toFile() : null; 090 } 091 092 /** 093 * Gets the file (if any) with the data to be uploaded. 094 * 095 * @return The data file or {@code null} if the data resides in memory. 096 * @since 2.0.0 097 */ 098 public Path getDataPath() { 099 return dataPath; 100 } 101 102 /** 103 * Sets the file with the data to be uploaded. To upload some data residing already in memory, use 104 * {@link #setDataString(String)} or {@link #setDataBytes(byte[])}. 105 * 106 * @param dataFile The data file, may be {@code null} if the resource data is provided directly from memory. 107 * @return This task for chaining, never {@code null}. 108 * @deprecated Use {@link #setDataPath(Path)} instead. 109 */ 110 @Deprecated 111 public PutTask setDataFile(File dataFile) { 112 return setDataPath(dataFile.toPath()); 113 } 114 115 /** 116 * Sets the file with the data to be uploaded. To upload some data residing already in memory, use 117 * {@link #setDataString(String)} or {@link #setDataBytes(byte[])}. 118 * 119 * @param dataPath The data file, may be {@code null} if the resource data is provided directly from memory. 120 * @return This task for chaining, never {@code null}. 121 * @since 2.0.0 122 */ 123 public PutTask setDataPath(Path dataPath) { 124 this.dataPath = dataPath; 125 dataBytes = EMPTY; 126 return this; 127 } 128 129 /** 130 * Sets the binary data to be uploaded. 131 * 132 * @param bytes The binary data, may be {@code null}. 133 * @return This task for chaining, never {@code null}. 134 */ 135 public PutTask setDataBytes(byte[] bytes) { 136 this.dataBytes = (bytes != null) ? bytes : EMPTY; 137 dataPath = null; 138 return this; 139 } 140 141 /** 142 * Sets the textual data to be uploaded. The text is encoded using UTF-8 before transmission. 143 * 144 * @param str The textual data, may be {@code null}. 145 * @return This task for chaining, never {@code null}. 146 */ 147 public PutTask setDataString(String str) { 148 return setDataBytes((str != null) ? str.getBytes(StandardCharsets.UTF_8) : null); 149 } 150 151 /** 152 * Sets the listener that is to be notified during the transfer. 153 * 154 * @param listener The listener to notify of progress, may be {@code null}. 155 * @return This task for chaining, never {@code null}. 156 */ 157 public PutTask setListener(TransportListener listener) { 158 super.setListener(listener); 159 return this; 160 } 161 162 @Override 163 public String toString() { 164 return ">> " + getLocation(); 165 } 166}