View Javadoc
1   package org.djutils.io;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.io.InputStream;
6   import java.net.Authenticator;
7   import java.net.MalformedURLException;
8   import java.net.PasswordAuthentication;
9   import java.net.URL;
10  
11  /**
12   * The URLResource class helps to resolve a file location in a project, JAR, or folder. The static methods return a URL of the
13   * file location that was found, or null in case it was not found.
14   * <p>
15   * Copyright (c) 2002-2019 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
16   * for project information <a href="https://djutils.org" target="_blank"> https://djutils.org</a>. The DJUTILS project is
17   * distributed under a three-clause BSD-style license, which can be found at
18   * <a href="https://djutils.org/docs/license.html" target="_blank"> https://djutils.org/docs/license.html</a>.
19   * </p>
20   * @author Peter Jacobs
21   * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
22   */
23  public final class URLResource
24  {
25      /**
26       * constructs a new URLResource.
27       */
28      private URLResource()
29      {
30          super();
31          // unreachable code
32      }
33  
34      /**
35       * Resolves a resource for name.
36       * @param name String; the name to search for
37       * @return the resolved URL
38       */
39      public static URL getResource(final String name)
40      {
41          try
42          {
43              File file = new File(name);
44  
45              if (name.startsWith("/"))
46              {
47                  URL url = URLResource.class.getResource(name);
48                  if (url != null)
49                  {
50                      return url;
51                  }
52                  url = Thread.currentThread().getContextClassLoader().getResource(name.substring(1));
53                  if (url != null)
54                  {
55                      return url;
56                  }
57                  if (file.exists())
58                  {
59                      return new URL("file:" + name);
60                  }
61              }
62              else if (name.startsWith("\\") || name.contains("\\")) // added the second part
63              {
64                  if (file.exists())
65                  {
66                      return new URL("file:" + name);
67                  }
68              }
69              else if (file.exists())
70              {
71                  return new URL("file:" + name);
72              }
73              else
74              {
75                  if (name.indexOf("@") == -1)
76                  {
77                      return new URL(name);
78                  }
79                  // we need authentication
80                  String temp = name.substring(name.indexOf("//") + 2);
81                  String userName = temp.substring(0, temp.indexOf(":"));
82                  String password = temp.substring(temp.indexOf(":") + 1);
83                  password = password.substring(0, password.indexOf("@"));
84                  String url = name.substring(0, name.indexOf("//") + 2);
85                  url = url + name.substring(name.indexOf("@") + 1);
86                  Authenticator.setDefault(new PasswordAuthenticator(userName, password));
87                  return new URL(url);
88              }
89          }
90          catch (Exception exception)
91          {
92              exception = null;
93              // We neglect exceptions since we return null
94          }
95          return null;
96      }
97  
98      /**
99       * Resolves a resource for name. For relative names, base is used to resolve to an absolute name. If name is absolute, base
100      * is ignored.
101      * @param name String; the name to search for
102      * @param base String; the base for relative paths
103      * @return the resolved URL
104      */
105     public static URL getResource(final String name, final String base)
106     {
107         URL url = null;
108 
109         // case complete URL
110         try
111         {
112             url = new URL(name);
113         }
114         catch (MalformedURLException ex)
115         {
116             // neglect exception -- just trying
117         }
118 
119         // absolute or relative case
120         if (url == null)
121         {
122             String completeName = name;
123             if (!name.startsWith(File.separator) && !name.startsWith("/") && base != null)
124             {
125                 String baseDir = "";
126                 int i = base.lastIndexOf(File.separator);
127                 if (i == -1 && !File.separator.equals("/"))
128                 {
129                     i = base.lastIndexOf("/");
130                 }
131                 if (i != -1)
132                 {
133                     baseDir = base.substring(0, i + 1);
134                 }
135                 completeName = baseDir + name;
136             }
137 
138             // case base = URL
139             try
140             {
141                 url = new URL(completeName);
142                 if (url.getProtocol().equalsIgnoreCase("file"))
143                 {
144                     File file = new File(url.getPath());
145                     if (!file.exists())
146                     {
147                         url = null;
148                     }
149                 }
150             }
151             catch (MalformedURLException ex)
152             {
153                 url = getResourceOrFile(completeName);
154             }
155 
156             // just try plain name if that's still another option
157             if (url == null && !name.equalsIgnoreCase(completeName))
158             {
159                 url = getResourceOrFile(name);
160             }
161 
162         }
163 
164         // handle authentication
165         if (url != null && url.getUserInfo() != null)
166         {
167             String ui = url.getUserInfo();
168             String userName = ui.substring(0, ui.indexOf(":"));
169             String password = ui.substring(ui.indexOf(":") + 1);
170             Authenticator.setDefault(new PasswordAuthenticator(userName, password));
171         }
172 
173         return url;
174     }
175 
176     /**
177      * Resolves a resource for a path.
178      * @param path String; the path to search for
179      * @return the resolved URL to the path
180      */
181     private static URL getResourceOrFile(String path)
182     {
183         URL url = null;
184 
185         // resource
186         if (url == null)
187         {
188             url = URLResource.class.getResource(path);
189         }
190 
191         // thread context resource
192         if (url == null)
193         {
194             url = Thread.currentThread().getContextClassLoader().getResource(path.substring(1));
195         }
196 
197         // file
198         if (url == null)
199         {
200             File file = new File(path);
201             if (file.exists())
202             {
203                 try
204                 {
205                     url = new URL("file:" + file.getCanonicalPath());
206                 }
207                 catch (IOException ex)
208                 {
209                     // ignore -- if not found, we return null
210                 }
211             }
212         }
213 
214         return url;
215     }
216 
217     /**
218      * returns the resource as stream.
219      * @param name String; the name of the resource
220      * @return the inputStream
221      */
222     public static InputStream getResourceAsStream(final String name)
223     {
224         try
225         {
226             URL url = URLResource.getResource(name);
227             if (url == null)
228             {
229                 return null;
230             }
231             return url.openStream();
232         }
233         catch (Exception exception)
234         {
235             return null;
236         }
237     }
238 
239     /**
240      * A Private password authenticator.
241      */
242     private static class PasswordAuthenticator extends Authenticator
243     {
244         /** my user name. */
245         private String userName = null;
246 
247         /** my password. */
248         private String password = null;
249 
250         /**
251          * constructs a new PasswordAuthenticator.
252          * @param userName String; my userName
253          * @param password String; my passWord
254          */
255         public PasswordAuthenticator(final String userName, final String password)
256         {
257             super();
258             this.userName = userName;
259             this.password = password;
260         }
261 
262         /** {@inheritDoc} */
263         @Override
264         protected PasswordAuthentication getPasswordAuthentication()
265         {
266             return new PasswordAuthentication(this.userName, this.password.toCharArray());
267         }
268     }
269 
270 }