1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.facelets;
21
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 import javax.faces.context.ExternalContext;
26 import javax.faces.context.FacesContext;
27 import javax.servlet.ServletContext;
28 import java.io.FileNotFoundException;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.lang.invoke.MethodHandles;
32 import java.net.MalformedURLException;
33 import java.net.URL;
34 import java.net.URLConnection;
35 import java.net.URLStreamHandler;
36
37
38
39
40 public final class Resource {
41
42 private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
43
44 private Resource() {
45 }
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public static URL getResourceUrl(final FacesContext ctx, final String path) throws MalformedURLException {
60 final ExternalContext externalContext = ctx.getExternalContext();
61 URL url = externalContext.getResource(path);
62 if (LOG.isTraceEnabled()) {
63 LOG.trace("Resource-Url from external context: " + url);
64 }
65 if (url == null) {
66
67
68
69
70
71
72
73 if (resourceExist(externalContext, path)) {
74 url = getUrlForResourceAsStream(externalContext, path);
75 }
76 }
77 return url;
78 }
79
80
81
82
83 private static boolean resourceExist(final ExternalContext externalContext, final String path) {
84 if ("/".equals(path)) {
85
86 return true;
87 }
88 final Object ctx = externalContext.getContext();
89 if (ctx instanceof ServletContext) {
90 final ServletContext servletContext = (ServletContext) ctx;
91 try (final InputStream stream = servletContext.getResourceAsStream(path)) {
92 return stream != null;
93 } catch (final IOException e) {
94
95
96 }
97 }
98 return false;
99 }
100
101
102
103 private static URL getUrlForResourceAsStream(final ExternalContext externalContext, final String path)
104 throws MalformedURLException {
105 final URLStreamHandler handler = new URLStreamHandler() {
106 @Override
107 protected URLConnection openConnection(final URL u) throws IOException {
108 final String file = u.getFile();
109 return new URLConnection(u) {
110 @Override
111 public void connect() throws IOException {
112 }
113
114 @Override
115 public InputStream getInputStream() throws IOException {
116 if (LOG.isTraceEnabled()) {
117 LOG.trace("Opening internal url to " + file);
118 }
119 final Object ctx = externalContext.getContext();
120
121
122
123
124 if (ctx instanceof ServletContext) {
125 final ServletContext servletContext = (ServletContext) ctx;
126 final InputStream stream = servletContext.getResourceAsStream(file);
127 if (stream == null) {
128 throw new FileNotFoundException("Cannot open resource " + file);
129 }
130 return stream;
131 } else {
132 throw new IOException("Cannot open resource for an context of "
133 + (ctx != null ? ctx.getClass() : null));
134 }
135 }
136 };
137 }
138 };
139 return new URL("internal", null, 0, path, handler);
140 }
141 }