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