View Javadoc
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 }