View Javadoc
1   package org.djutils.io;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertNull;
5   
6   import java.io.File;
7   import java.io.FileInputStream;
8   import java.io.FileNotFoundException;
9   import java.io.FileOutputStream;
10  import java.io.IOException;
11  import java.io.InputStream;
12  import java.net.URISyntaxException;
13  import java.net.URL;
14  import java.nio.file.Files;
15  import java.nio.file.Paths;
16  import java.util.ArrayList;
17  import java.util.Arrays;
18  import java.util.List;
19  import java.util.jar.JarEntry;
20  import java.util.jar.JarOutputStream;
21  
22  import org.junit.Assert;
23  import org.junit.Test;
24  
25  /**
26   * URLResourceTest.java.
27   * <p>
28   * Copyright (c) 2002-2022 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
29   * for project information <a href="https://djutils.org" target="_blank"> https://djutils.org</a>. The DJUTILS project is
30   * distributed under a three-clause BSD-style license, which can be found at
31   * <a href="https://djutils.org/docs/license.html" target="_blank"> https://djutils.org/docs/license.html</a>.
32   * </p>
33   * @author <a href="https://www.tudelft.nl/averbraeck" target="_blank">Alexander Verbraeck</a>
34   */
35  public class URLResourceTest
36  {
37  
38      /**
39       * Test whether URLResource retrieves files.
40       * @throws IOException on I/O error
41       */
42      // TODO @Test -- this test does not run on ubuntu
43      public final void fileTest() throws IOException
44      {
45          // create a temporary file.
46          File tempFile = File.createTempFile("filetest-", ".temp");
47          String tempFilePath = tempFile.getAbsolutePath();
48          URL url1 = URLResource.getResource(tempFilePath);
49          Assert.assertNotNull(url1);
50          Assert.assertEquals(new File(url1.getPath()).getAbsolutePath().replaceAll("\\\\", "/"),
51                  tempFilePath.replaceAll("\\\\", "/"));
52  
53          URL url2 = URLResource.getResource("/" + tempFilePath);
54          Assert.assertNotNull(url2);
55          Assert.assertEquals(new File(url2.getPath()).getAbsolutePath().replaceAll("\\\\", "/"),
56                  tempFilePath.replaceAll("\\\\", "/"));
57      }
58  
59      /**
60       * Test whether URLResource retrieves files.
61       * @throws IOException on I/O error
62       * @throws URISyntaxException on URL error
63       */
64      @Test
65      public final void resourceTest() throws IOException, URISyntaxException
66      {
67          URL url = URLResource.getResource("/org/djutils-test-resources/test.txt");
68          String absolutePath = url.toURI().getPath();
69          List<String> lines = Files.readAllLines(Paths.get(url.toURI()));
70          assertEquals(3, lines.size());
71          assertEquals("abc", lines.get(0));
72  
73          url = null;
74          lines = null;
75  
76          url = URLResource.getResource("test.txt", "/org/djutils-test-resources/");
77          lines = Files.readAllLines(Paths.get(url.toURI()));
78          assertEquals(3, lines.size());
79          assertEquals("def", lines.get(1));
80  
81          url = null;
82          lines = null;
83  
84          url = URLResource.getResource("/org/djutils-test-resources/test.txt", "/");
85          lines = Files.readAllLines(Paths.get(url.toURI()));
86          assertEquals(3, lines.size());
87          assertEquals("ghi", lines.get(2));
88  
89          url = null;
90          lines = null;
91  
92          url = URLResource.getResource("file://" + absolutePath);
93          lines = Files.readAllLines(Paths.get(url.toURI()));
94          assertEquals(3, lines.size());
95          assertEquals("abc", lines.get(0));
96      }
97  
98      /**
99       * Test whether URLResource retrieves files.
100      * @throws IOException on I/O error
101      * @throws URISyntaxException on URL error
102      */
103     @Test
104     public final void resourceAsStreamTest() throws IOException, URISyntaxException
105     {
106         InputStream stream = URLResource.getResourceAsStream("/org/djutils-test-resources/test.txt");
107         byte[] barr = readAllBytes(stream);
108         stream.close();
109         assertEquals('a', barr[0]);
110 
111         assertNull(URLResource.getResourceAsStream("xxx:///org::djutils-test-resources<>test.txt"));
112 
113         stream = URLResource.getResourceAsStream("/org/djutils-test-resources/test123.txt");
114         assertNull(stream);
115     }
116 
117     /**
118      * Test whether URLResource retrieves files.
119      * @throws IOException on I/O error
120      * @throws URISyntaxException on error
121      */
122     @Test
123     public final void jarTest() throws IOException, URISyntaxException
124     {
125         // create a temporary jar file.
126         File jarFile = File.createTempFile("filetest-", ".jar");
127         File file1 = File.createTempFile("filetest-", ".f1");
128         File file2 = File.createTempFile("filetest-", ".f2");
129         File file3 = File.createTempFile("filetest-", ".f3");
130 
131         FileOutputStream fos = new FileOutputStream(jarFile.getAbsolutePath());
132         JarOutputStream jos = new JarOutputStream(fos);
133         addToJarFile(file1.getAbsolutePath(), jos);
134         addToJarFile(file2.getAbsolutePath(), jos);
135         addToJarFile(file3.getAbsolutePath(), jos);
136         jos.close();
137         fos.close();
138 
139         String jarFilePath = jarFile.getAbsolutePath();
140         URL jarURL = URLResource.getResource(jarFilePath);
141         Assert.assertNotNull(jarURL);
142         // System.out.println(jarFile.getAbsolutePath() + "!" + file1.getName());
143         // URL jar1 = URLResource.getResource(jarFile.getAbsolutePath() + "!" + file1.getName());
144         // System.out.println(jar1.toURI());
145         // Assert.assertNotNull(jar1);
146     }
147 
148     /**
149      * Copy a plain file into a jar file.
150      * @param fileName String; name of the file to copy
151      * @param jos JarOutputStream; stream for writing into the jar file
152      * @throws FileNotFoundException when the input file could not be found
153      * @throws IOException when the input file could not be read, or writing to the jar stream fails
154      */
155     public void addToJarFile(final String fileName, final JarOutputStream jos) throws FileNotFoundException, IOException
156     {
157         File file = new File(fileName);
158         FileInputStream fis = new FileInputStream(file);
159         JarEntry zipEntry = new JarEntry(file.getName());
160         jos.putNextEntry(zipEntry);
161         byte[] bytes = new byte[1024];
162         int length;
163         while ((length = fis.read(bytes)) >= 0)
164         {
165             jos.write(bytes, 0, length);
166         }
167         jos.closeEntry();
168         fis.close();
169     }
170 
171     /**
172      * Copied from Java 13 to handle readAllBytes in Java 8.
173      * @param stream the input stream to read the bytes from
174      * @return the byte array
175      * @throws IOException on I/O error
176      */
177     private byte[] readAllBytes(final InputStream stream) throws IOException
178     {
179         List<byte[]> bufs = null;
180         byte[] result = null;
181         int total = 0;
182         int remaining = Integer.MAX_VALUE;
183         int n;
184         do
185         {
186             byte[] buf = new byte[Math.min(remaining, 8192)];
187             int nread = 0;
188 
189             // read to EOF which may read more or less than buffer size
190             while ((n = stream.read(buf, nread, Math.min(buf.length - nread, remaining))) > 0)
191             {
192                 nread += n;
193                 remaining -= n;
194             }
195 
196             if (nread > 0)
197             {
198                 if (Integer.MAX_VALUE - 8 - total < nread)
199                 {
200                     throw new OutOfMemoryError("Required array size too large");
201                 }
202                 total += nread;
203                 if (result == null)
204                 {
205                     result = buf;
206                 }
207                 else
208                 {
209                     if (bufs == null)
210                     {
211                         bufs = new ArrayList<>();
212                         bufs.add(result);
213                     }
214                     bufs.add(buf);
215                 }
216             }
217             // if the last call to read returned -1 or the number of bytes
218             // requested have been read then break
219         }
220         while (n >= 0 && remaining > 0);
221 
222         if (bufs == null)
223         {
224             if (result == null)
225             {
226                 return new byte[0];
227             }
228             return result.length == total ? result : Arrays.copyOf(result, total);
229         }
230 
231         result = new byte[total];
232         int offset = 0;
233         remaining = total;
234         for (byte[] b : bufs)
235         {
236             int count = Math.min(b.length, remaining);
237             System.arraycopy(b, 0, result, offset, count);
238             offset += count;
239             remaining -= count;
240         }
241 
242         return result;
243 
244     }
245 }