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.*; 022import java.net.URI; 023import java.nio.charset.StandardCharsets; 024import java.nio.file.Files; 025import java.nio.file.Path; 026 027/** 028 * A task to upload a resource to the remote repository. 029 * 030 * @see Transporter#put(PutTask) 031 */ 032public final class PutTask extends TransportTask { 033 034 private Path dataPath; 035 036 private byte[] dataBytes = EMPTY; 037 038 /** 039 * Creates a new task for the specified remote resource. 040 * 041 * @param location The relative location of the resource in the remote repository, must not be {@code null}. 042 */ 043 public PutTask(URI location) { 044 setLocation(location); 045 } 046 047 /** 048 * Opens an input stream for the data to be uploaded. The length of the stream can be queried via 049 * {@link #getDataLength()}. It's the responsibility of the caller to close the provided stream. 050 * 051 * @return The input stream for the data, never {@code null}. The stream is unbuffered. 052 * @throws IOException If the stream could not be opened. 053 */ 054 public InputStream newInputStream() throws IOException { 055 if (dataPath != null) { 056 return Files.newInputStream(dataPath); 057 } 058 return new ByteArrayInputStream(dataBytes); 059 } 060 061 /** 062 * Gets the total number of bytes to be uploaded. 063 * 064 * @return The total number of bytes to be uploaded. 065 */ 066 public long getDataLength() { 067 if (dataPath != null) { 068 try { 069 return Files.size(dataPath); 070 } catch (IOException e) { 071 throw new UncheckedIOException(e); 072 } 073 } 074 return dataBytes.length; 075 } 076 077 /** 078 * Gets the file (if any) with the data to be uploaded. 079 * 080 * @return The data file or {@code null} if the data resides in memory. 081 * @deprecated Use {@link #getDataPath()} instead. 082 */ 083 @Deprecated 084 public File getDataFile() { 085 return dataPath != null ? dataPath.toFile() : null; 086 } 087 088 /** 089 * Gets the file (if any) with the data to be uploaded. 090 * 091 * @return The data file or {@code null} if the data resides in memory. 092 * @since 2.0.0 093 */ 094 public Path getDataPath() { 095 return dataPath; 096 } 097 098 /** 099 * Sets the file with the data to be uploaded. To upload some data residing already in memory, use 100 * {@link #setDataString(String)} or {@link #setDataBytes(byte[])}. 101 * 102 * @param dataFile The data file, may be {@code null} if the resource data is provided directly from memory. 103 * @return This task for chaining, never {@code null}. 104 * @deprecated Use {@link #setDataPath(Path)} instead. 105 */ 106 @Deprecated 107 public PutTask setDataFile(File dataFile) { 108 return setDataPath(dataFile.toPath()); 109 } 110 111 /** 112 * Sets the file with the data to be uploaded. To upload some data residing already in memory, use 113 * {@link #setDataString(String)} or {@link #setDataBytes(byte[])}. 114 * 115 * @param dataPath The data file, may be {@code null} if the resource data is provided directly from memory. 116 * @return This task for chaining, never {@code null}. 117 * @since 2.0.0 118 */ 119 public PutTask setDataPath(Path dataPath) { 120 this.dataPath = dataPath; 121 dataBytes = EMPTY; 122 return this; 123 } 124 125 /** 126 * Sets the binary data to be uploaded. 127 * 128 * @param bytes The binary data, may be {@code null}. 129 * @return This task for chaining, never {@code null}. 130 */ 131 public PutTask setDataBytes(byte[] bytes) { 132 this.dataBytes = (bytes != null) ? bytes : EMPTY; 133 dataPath = null; 134 return this; 135 } 136 137 /** 138 * Sets the textual data to be uploaded. The text is encoded using UTF-8 before transmission. 139 * 140 * @param str The textual data, may be {@code null}. 141 * @return This task for chaining, never {@code null}. 142 */ 143 public PutTask setDataString(String str) { 144 return setDataBytes((str != null) ? str.getBytes(StandardCharsets.UTF_8) : null); 145 } 146 147 /** 148 * Sets the listener that is to be notified during the transfer. 149 * 150 * @param listener The listener to notify of progress, may be {@code null}. 151 * @return This task for chaining, never {@code null}. 152 */ 153 public PutTask setListener(TransportListener listener) { 154 super.setListener(listener); 155 return this; 156 } 157 158 @Override 159 public String toString() { 160 return ">> " + getLocation(); 161 } 162}