55 */
66package io .jooby ;
77
8+ import io .jooby .internal .FileAsset ;
89import io .jooby .internal .JarAsset ;
10+ import io .jooby .internal .URLAsset ;
911import sun .net .www .protocol .jar .JarURLConnection ;
1012
1113import javax .annotation .Nonnull ;
12- import java .io .FileInputStream ;
1314import java .io .IOException ;
1415import java .io .InputStream ;
1516import java .net .URISyntaxException ;
1617import java .net .URL ;
17- import java .net .URLConnection ;
1818import java .nio .ByteBuffer ;
19- import java .nio .file .Files ;
2019import java .nio .file .Path ;
2120import java .nio .file .Paths ;
2221import java .util .Base64 ;
2726 * @author edgar
2827 * @since 2.0.0
2928 */
30- public interface Asset {
31-
32- /**
33- * File system asset.
34- *
35- * @author edgar
36- * @since 2.0.0.
37- */
38- class FileAsset implements Asset {
39-
40- /** File. */
41- private Path file ;
42-
43- /**
44- * Creates a new file asset.
45- * @param file Asset file.
46- */
47- public FileAsset (@ Nonnull Path file ) {
48- this .file = file ;
49- }
50-
51- @ Override public long getSize () {
52- try {
53- return Files .size (file );
54- } catch (IOException x ) {
55- throw SneakyThrows .propagate (x );
56- }
57- }
58-
59- @ Override public long getLastModified () {
60- try {
61- return Files .getLastModifiedTime (file ).toMillis ();
62- } catch (IOException x ) {
63- throw SneakyThrows .propagate (x );
64- }
65- }
66-
67- @ Nonnull @ Override public MediaType getContentType () {
68- return MediaType .byFile (file );
69- }
70-
71- @ Override public InputStream stream () {
72- try {
73- return new FileInputStream (file .toFile ());
74- } catch (IOException x ) {
75- throw SneakyThrows .propagate (x );
76- }
77- }
78-
79- @ Override public void release () {
80- // NOOP
81- }
82-
83- @ Override public boolean isDirectory () {
84- return Files .isDirectory (file );
85- }
86-
87- @ Override public boolean equals (Object obj ) {
88- if (obj instanceof FileAsset ) {
89- return file .equals (((FileAsset ) obj ).file );
90- }
91- return false ;
92- }
93-
94- @ Override public int hashCode () {
95- return file .hashCode ();
96- }
97-
98- @ Override public String toString () {
99- return file .toString ();
100- }
101- }
102-
103- /**
104- * URL asset. Mostly represent a classpath file resource.
105- *
106- * @author edgar
107- * @since 2.0.0
108- */
109- class URLAsset implements Asset {
110-
111- /** URL. */
112- private final URL resource ;
113-
114- /** Path. */
115- private final String path ;
116-
117- /** File size. */
118- private long len ;
119-
120- /** Last modified since or <code>-1</code>. */
121- private long lastModified ;
122-
123- /** Asset content. */
124- private InputStream content ;
125-
126- /**
127- * Creates a new URL asset.
128- *
129- * @param resource Asset resource url.
130- * @param path Asset path.
131- */
132- private URLAsset (@ Nonnull URL resource , @ Nonnull String path ) {
133- this .resource = resource ;
134- this .path = path ;
135- }
136-
137- @ Override public long getSize () {
138- checkOpen ();
139- return len ;
140- }
141-
142- @ Override public long getLastModified () {
143- checkOpen ();
144- return lastModified ;
145- }
146-
147- @ Nonnull @ Override public MediaType getContentType () {
148- return MediaType .byFile (path );
149- }
150-
151- @ Override public InputStream stream () {
152- checkOpen ();
153- return content ;
154- }
155-
156- @ Override public void release () {
157- try {
158- content .close ();
159- } catch (IOException | NullPointerException x ) {
160- // NPE when content is a directory
161- }
162- }
163-
164- @ Override public boolean equals (Object obj ) {
165- if (obj instanceof URLAsset ) {
166- return path .equals (((URLAsset ) obj ).path );
167- }
168- return false ;
169- }
170-
171- @ Override public int hashCode () {
172- return path .hashCode ();
173- }
174-
175- @ Override public String toString () {
176- return path ;
177- }
178-
179- @ Override public boolean isDirectory () {
180- return false ;
181- }
182-
183- private void checkOpen () {
184- try {
185- if (content == null ) {
186- URLConnection connection = resource .openConnection ();
187- connection .setUseCaches (false );
188- len = connection .getContentLengthLong ();
189- lastModified = connection .getLastModified ();
190- content = connection .getInputStream ();
191- }
192- } catch (IOException x ) {
193- throw SneakyThrows .propagate (x );
194- }
195- }
196- }
29+ public interface Asset extends AutoCloseable {
19730
19831 /**
19932 * Creates a file system asset.
@@ -217,7 +50,7 @@ static Asset create(@Nonnull String path, @Nonnull URL resource) {
21750 return new JarAsset ((JarURLConnection ) resource .openConnection ());
21851 }
21952 if ("file" .equals (resource .getProtocol ())) {
220- return new FileAsset (Paths .get (resource .toURI ()));
53+ return create (Paths .get (resource .toURI ()));
22154 }
22255 return new URLAsset (resource , path );
22356 } catch (IOException | URISyntaxException x ) {
@@ -273,9 +106,4 @@ static Asset create(@Nonnull String path, @Nonnull URL resource) {
273106 * @return Asset content.
274107 */
275108 InputStream stream ();
276-
277- /**
278- * Release this asset.
279- */
280- void release ();
281109}
0 commit comments