1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.eclipse.aether.spi.connector.transport;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.UncheckedIOException;
26 import java.net.URI;
27 import java.nio.charset.StandardCharsets;
28 import java.nio.file.Files;
29 import java.nio.file.Path;
30
31 /**
32 * A task to upload a resource to the remote repository.
33 *
34 * @see Transporter#put(PutTask)
35 */
36 public final class PutTask extends TransportTask {
37
38 private Path dataPath;
39
40 private byte[] dataBytes = EMPTY;
41
42 /**
43 * Creates a new task for the specified remote resource.
44 *
45 * @param location The relative location of the resource in the remote repository, must not be {@code null}.
46 */
47 public PutTask(URI location) {
48 setLocation(location);
49 }
50
51 /**
52 * Opens an input stream for the data to be uploaded. The length of the stream can be queried via
53 * {@link #getDataLength()}. It's the responsibility of the caller to close the provided stream.
54 *
55 * @return The input stream for the data, never {@code null}. The stream is unbuffered.
56 * @throws IOException If the stream could not be opened.
57 */
58 public InputStream newInputStream() throws IOException {
59 if (dataPath != null) {
60 return Files.newInputStream(dataPath);
61 }
62 return new ByteArrayInputStream(dataBytes);
63 }
64
65 /**
66 * Gets the total number of bytes to be uploaded.
67 *
68 * @return The total number of bytes to be uploaded.
69 */
70 public long getDataLength() {
71 if (dataPath != null) {
72 try {
73 return Files.size(dataPath);
74 } catch (IOException e) {
75 throw new UncheckedIOException(e);
76 }
77 }
78 return dataBytes.length;
79 }
80
81 /**
82 * Gets the file (if any) with the data to be uploaded.
83 *
84 * @return The data file or {@code null} if the data resides in memory.
85 * @deprecated Use {@link #getDataPath()} instead.
86 */
87 @Deprecated
88 public File getDataFile() {
89 return dataPath != null ? dataPath.toFile() : null;
90 }
91
92 /**
93 * Gets the file (if any) with the data to be uploaded.
94 *
95 * @return The data file or {@code null} if the data resides in memory.
96 * @since 2.0.0
97 */
98 public Path getDataPath() {
99 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 }