View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.start.fileinits;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.OutputStream;
24  import java.net.HttpURLConnection;
25  import java.net.URI;
26  import java.nio.file.Files;
27  import java.nio.file.Path;
28  import java.nio.file.StandardOpenOption;
29  
30  import org.eclipse.jetty.start.BaseHome;
31  import org.eclipse.jetty.start.FS;
32  import org.eclipse.jetty.start.FileInitializer;
33  import org.eclipse.jetty.start.StartLog;
34  
35  public class UriFileInitializer implements FileInitializer
36  {
37      private final static String[] SUPPORTED_SCHEMES = { "http", "https" };
38      protected final BaseHome baseHome;
39      
40      public UriFileInitializer(BaseHome baseHome)
41      {
42          this.baseHome = baseHome;
43      }
44      
45      @Override
46      public boolean init(URI uri, Path file, String fileRef) throws IOException
47      {
48          if (!isSupportedScheme(uri))
49          {
50              // Not a supported scheme.
51              return false;
52          }
53  
54          if(isFilePresent(file, baseHome.getPath(fileRef)))
55          {
56              // All done
57              return true;
58          }
59  
60          download(uri,file);
61  
62          return true;
63      }
64  
65      protected void download(URI uri, Path file) throws IOException
66      {
67          StartLog.log("DOWNLOAD","%s to %s",uri,baseHome.toShortForm(file));
68  
69          FS.ensureDirectoryExists(file.getParent());
70          
71          HttpURLConnection http = (HttpURLConnection)uri.toURL().openConnection();
72          http.setInstanceFollowRedirects(true);
73          http.setAllowUserInteraction(false);
74          
75          int status = http.getResponseCode();
76          
77          if(status != HttpURLConnection.HTTP_OK)
78          {
79              throw new IOException("URL GET Failure [" + status + "/" + http.getResponseMessage() + "] on " + uri);
80          }
81  
82          byte[] buf = new byte[8192];
83          try (InputStream in = http.getInputStream(); OutputStream out = Files.newOutputStream(file,StandardOpenOption.CREATE_NEW,StandardOpenOption.WRITE))
84          {
85              while (true)
86              {
87                  int len = in.read(buf);
88  
89                  if (len > 0)
90                  {
91                      out.write(buf,0,len);
92                  }
93                  if (len < 0)
94                  {
95                      break;
96                  }
97              }
98          }
99      }
100 
101     /**
102      * Test if any of the Paths exist (as files)
103      * 
104      * @param paths
105      *            the list of paths to check
106      * @return true if the path exist (as a file), false if it doesn't exist
107      * @throws IOException
108      *             if the path points to a non-file, or is not readable.
109      */
110     protected boolean isFilePresent(Path... paths) throws IOException
111     {
112         for (Path file : paths)
113         {
114             if (Files.exists(file))
115             {
116                 if (Files.isDirectory(file))
117                 {
118                     throw new IOException("Directory in the way: " + file.toAbsolutePath());
119                 }
120 
121                 if (!Files.isReadable(file))
122                 {
123                     throw new IOException("File not readable: " + file.toAbsolutePath());
124                 }
125 
126                 return true;
127             }
128         }
129 
130         return false;
131     }
132 
133     private boolean isSupportedScheme(URI uri)
134     {
135         String scheme = uri.getScheme();
136         if (scheme == null)
137         {
138             return false;
139         }
140         for (String supported : SUPPORTED_SCHEMES)
141         {
142             if (supported.equalsIgnoreCase(scheme))
143             {
144                 return true;
145             }
146         }
147         return false;
148     }
149 }