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-2024 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       * Utility class; do not instantiate.
27       */
28      private URLResource()
29      {
30          // Do not instantiate
31      }
32  
33      /**
34       * Resolves a resource for name.
35       * @param name String; the name to search for
36       * @return the resolved URL
37       */
38      public static URL getResource(final String name)
39      {
40          try
41          {
42              File file = new File(name);
43  
44              if (name.startsWith("/"))
45              {
46                  URL url = URLResource.class.getResource(name);
47                  if (url != null)
48                  {
49                      return url;
50                  }
51                  url = Thread.currentThread().getContextClassLoader().getResource(name.substring(1));
52                  if (url != null)
53                  {
54                      return url;
55                  }
56                  if (file.exists())
57                  {
58                      return new URL("file:" + name);
59                  }
60              }
61              else if (name.startsWith("\\") || name.contains("\\")) // added the second part
62              {
63                  if (file.exists())
64                  {
65                      return new URL("file:" + name);
66                  }
67              }
68              else if (file.exists())
69              {
70                  return new URL("file:" + name);
71              }
72              else
73              {
74                  if (name.indexOf("@") == -1)
75                  {
76                      return new URL(name);
77                  }
78                  // we need authentication
79                  String temp = name.substring(name.indexOf("//") + 2);
80                  String userName = temp.substring(0, temp.indexOf(":"));
81                  String password = temp.substring(temp.indexOf(":") + 1);
82                  password = password.substring(0, password.indexOf("@"));
83                  String url = name.substring(0, name.indexOf("//") + 2);
84                  url = url + name.substring(name.indexOf("@") + 1);
85                  Authenticator.setDefault(new PasswordAuthenticator(userName, password));
86                  return new URL(url);
87              }
88          }
89          catch (Exception exception)
90          {
91              exception = null;
92              // We neglect exceptions since we return null
93          }
94          return null;
95      }
96  
97      /**
98       * Resolves a resource for name. For relative names, base is used to resolve to an absolute name. If name is absolute, base
99       * is ignored.
100      * @param name String; the name to search for
101      * @param base String; the base for relative paths
102      * @return the resolved URL
103      */
104     public static URL getResource(final String name, final String base)
105     {
106         URL url = null;
107 
108         // case complete URL
109         try
110         {
111             url = new URL(name);
112         }
113         catch (MalformedURLException ex)
114         {
115             // neglect exception -- just trying
116         }
117 
118         // absolute or relative case
119         if (url == null)
120         {
121             String completeName = name;
122             if (!name.startsWith(File.separator) && !name.startsWith("/") && base != null)
123             {
124                 String baseDir = "";
125                 int i = base.lastIndexOf(File.separator);
126                 if (i == -1 && !File.separator.equals("/"))
127                 {
128                     i = base.lastIndexOf("/");
129                 }
130                 if (i != -1)
131                 {
132                     baseDir = base.substring(0, i + 1);
133                 }
134                 completeName = baseDir + name;
135             }
136 
137             // case base = URL
138             try
139             {
140                 url = new URL(completeName);
141                 if (url.getProtocol().equalsIgnoreCase("file"))
142                 {
143                     File file = new File(url.getPath());
144                     if (!file.exists())
145                     {
146                         url = null;
147                     }
148                 }
149             }
150             catch (MalformedURLException ex)
151             {
152                 url = getResourceOrFile(completeName);
153             }
154 
155             // just try plain name if that's still another option
156             if (url == null && !name.equalsIgnoreCase(completeName))
157             {
158                 url = getResourceOrFile(name);
159             }
160 
161         }
162 
163         // handle authentication
164         if (url != null && url.getUserInfo() != null)
165         {
166             String ui = url.getUserInfo();
167             String userName = ui.substring(0, ui.indexOf(":"));
168             String password = ui.substring(ui.indexOf(":") + 1);
169             Authenticator.setDefault(new PasswordAuthenticator(userName, password));
170         }
171 
172         return url;
173     }
174 
175     /**
176      * Resolves a resource for a path.
177      * @param path String; the path to search for
178      * @return the resolved URL to the path
179      */
180     private static URL getResourceOrFile(final String path)
181     {
182         URL url = null;
183 
184         // resource
185         if (url == null)
186         {
187             url = URLResource.class.getResource(path);
188         }
189 
190         // thread context resource
191         if (url == null)
192         {
193             url = Thread.currentThread().getContextClassLoader().getResource(path.substring(1));
194         }
195 
196         // file
197         if (url == null)
198         {
199             File file = new File(path);
200             if (file.exists())
201             {
202                 try
203                 {
204                     url = new URL("file:" + file.getCanonicalPath());
205                 }
206                 catch (IOException ex)
207                 {
208                     // ignore -- if not found, we return null
209                 }
210             }
211         }
212 
213         return url;
214     }
215 
216     /**
217      * returns the resource as stream.
218      * @param name String; the name of the resource
219      * @return the inputStream
220      */
221     public static InputStream getResourceAsStream(final String name)
222     {
223         try
224         {
225             URL url = URLResource.getResource(name);
226             if (url == null)
227             {
228                 return null;
229             }
230             return url.openStream();
231         }
232         catch (Exception exception)
233         {
234             return null;
235         }
236     }
237 
238     /**
239      * A Private password authenticator.
240      */
241     private static class PasswordAuthenticator extends Authenticator
242     {
243         /** my user name. */
244         private String userName = null;
245 
246         /** my password. */
247         private String password = null;
248 
249         /**
250          * constructs a new PasswordAuthenticator.
251          * @param userName String; my userName
252          * @param password String; my passWord
253          */
254         PasswordAuthenticator(final String userName, final String password)
255         {
256             this.userName = userName;
257             this.password = password;
258         }
259 
260         @Override
261         protected PasswordAuthentication getPasswordAuthentication()
262         {
263             return new PasswordAuthentication(this.userName, this.password.toCharArray());
264         }
265     }
266 
267 }