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.apache.maven.internal.impl;
20  
21  import static java.util.Objects.requireNonNull;
22  
23  import java.io.IOException;
24  import java.io.UncheckedIOException;
25  import java.net.URI;
26  import java.nio.charset.Charset;
27  import java.nio.file.Files;
28  import java.nio.file.Path;
29  import java.util.Optional;
30  import javax.inject.Named;
31  import javax.inject.Singleton;
32  import org.apache.maven.api.services.Transport;
33  import org.eclipse.aether.spi.connector.transport.GetTask;
34  import org.eclipse.aether.spi.connector.transport.PutTask;
35  import org.eclipse.aether.spi.connector.transport.Transporter;
36  
37  @Named
38  @Singleton
39  public class DefaultTransport implements Transport {
40      private final URI baseURI;
41      private final Transporter transporter;
42  
43      public DefaultTransport(URI baseURI, Transporter transporter) {
44          this.baseURI = requireNonNull(baseURI);
45          this.transporter = requireNonNull(transporter);
46      }
47  
48      @Override
49      public boolean get(URI relativeSource, Path target) {
50          requireNonNull(relativeSource, "relativeSource is null");
51          requireNonNull(target, "target is null");
52          if (relativeSource.isAbsolute()) {
53              throw new IllegalArgumentException("Supplied URI is not relative");
54          }
55          URI source = baseURI.resolve(relativeSource);
56          if (!source.toASCIIString().startsWith(baseURI.toASCIIString())) {
57              throw new IllegalArgumentException("Supplied relative URI escapes baseUrl");
58          }
59          GetTask getTask = new GetTask(source);
60          getTask.setDataFile(target.toFile());
61          try {
62              transporter.get(getTask);
63              return true;
64          } catch (Exception e) {
65              if (Transporter.ERROR_NOT_FOUND != transporter.classify(e)) {
66                  throw new RuntimeException(e);
67              }
68              return false;
69          }
70      }
71  
72      @Override
73      public Optional<byte[]> getBytes(URI relativeSource) {
74          try {
75              Path tempPath = null;
76              try {
77                  tempPath = Files.createTempFile("transport-get", "tmp");
78                  if (get(relativeSource, tempPath)) {
79                      // TODO: check file size and prevent OOM?
80                      return Optional.of(Files.readAllBytes(tempPath));
81                  }
82                  return Optional.empty();
83              } finally {
84                  if (tempPath != null) {
85                      Files.deleteIfExists(tempPath);
86                  }
87              }
88          } catch (IOException e) {
89              throw new UncheckedIOException(e);
90          }
91      }
92  
93      @Override
94      public Optional<String> getString(URI relativeSource, Charset charset) {
95          requireNonNull(charset, "charset is null");
96          Optional<byte[]> data = getBytes(relativeSource);
97          return data.map(bytes -> new String(bytes, charset));
98      }
99  
100     @Override
101     public void put(Path source, URI relativeTarget) {
102         requireNonNull(source, "source is null");
103         requireNonNull(relativeTarget, "relativeTarget is null");
104         if (Files.isRegularFile(source)) {
105             throw new IllegalArgumentException("source file does not exist or is not a file");
106         }
107         if (relativeTarget.isAbsolute()) {
108             throw new IllegalArgumentException("Supplied URI is not relative");
109         }
110         URI target = baseURI.resolve(relativeTarget);
111         if (!target.toASCIIString().startsWith(baseURI.toASCIIString())) {
112             throw new IllegalArgumentException("Supplied relative URI escapes baseUrl");
113         }
114 
115         PutTask putTask = new PutTask(target);
116         putTask.setDataFile(source.toFile());
117         try {
118             transporter.put(putTask);
119         } catch (Exception e) {
120             throw new RuntimeException(e);
121         }
122     }
123 
124     @Override
125     public void putBytes(byte[] source, URI relativeTarget) {
126         requireNonNull(source, "source is null");
127         try {
128             Path tempPath = null;
129             try {
130                 tempPath = Files.createTempFile("transport-get", "tmp");
131                 Files.write(tempPath, source);
132                 put(tempPath, relativeTarget);
133             } finally {
134                 if (tempPath != null) {
135                     Files.deleteIfExists(tempPath);
136                 }
137             }
138         } catch (IOException e) {
139             throw new UncheckedIOException(e);
140         }
141     }
142 
143     @Override
144     public void putString(String source, Charset charset, URI relativeTarget) {
145         requireNonNull(source, "source string is null");
146         requireNonNull(charset, "charset is null");
147         putBytes(source.getBytes(charset), relativeTarget);
148     }
149 
150     @Override
151     public void close() {
152         transporter.close();
153     }
154 }