Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
Resource |
|
| 3.6666666666666665;3.667 | ||||
Resource$1 |
|
| 3.6666666666666665;3.667 | ||||
Resource$1$1 |
|
| 3.6666666666666665;3.667 |
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one | |
3 | * or more contributor license agreements. See the NOTICE file | |
4 | * distributed with this work for additional information | |
5 | * regarding copyright ownership. The ASF licenses this file | |
6 | * to you under the Apache License, Version 2.0 (the | |
7 | * "License"); you may not use this file except in compliance | |
8 | * with the License. You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, | |
13 | * software distributed under the License is distributed on an | |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
15 | * KIND, either express or implied. See the License for the | |
16 | * specific language governing permissions and limitations | |
17 | * under the License. | |
18 | */ | |
19 | package org.apache.myfaces.view.facelets.util; | |
20 | ||
21 | import java.io.FileNotFoundException; | |
22 | import java.io.IOException; | |
23 | import java.io.InputStream; | |
24 | import java.net.MalformedURLException; | |
25 | import java.net.URL; | |
26 | import java.net.URLConnection; | |
27 | import java.net.URLStreamHandler; | |
28 | import java.util.logging.Level; | |
29 | import java.util.logging.Logger; | |
30 | ||
31 | import javax.faces.context.ExternalContext; | |
32 | import javax.faces.context.FacesContext; | |
33 | import javax.servlet.ServletContext; | |
34 | ||
35 | /** | |
36 | * @author Roland Huss | |
37 | * | |
38 | */ | |
39 | 0 | public final class Resource |
40 | { | |
41 | ||
42 | //protected final static Logger log = Logger.getLogger("facelets.factory"); | |
43 | 0 | protected final static Logger log = Logger.getLogger(Resource.class.getName()); |
44 | ||
45 | /** | |
46 | * Get an URL of an internal resource. First, {@link javax.faces.context.ExternalContext#getResource(String)} is | |
47 | * checked for an non-null URL return value. In the case of a null return value (as it is the case for Weblogic 8.1 | |
48 | * for a packed war), a URL with a special URL handler is constructed, which can be used for <em>opening</em> a | |
49 | * serlvet resource later. Internally, this special URL handler will call | |
50 | * {@link ServletContext#getResourceAsStream(String)} when an inputstream is requested. This works even on Weblogic | |
51 | * 8.1 | |
52 | * | |
53 | * @param ctx | |
54 | * the faces context from which to retrieve the resource | |
55 | * @param path | |
56 | * an URL path | |
57 | * | |
58 | * @return an url representing the URL and on which getInputStream() can be called to get the resource | |
59 | * @throws MalformedURLException | |
60 | */ | |
61 | public static URL getResourceUrl(FacesContext ctx, String path) throws MalformedURLException | |
62 | { | |
63 | 0 | final ExternalContext externalContext = ctx.getExternalContext(); |
64 | 0 | URL url = externalContext.getResource(path); |
65 | 0 | if (log.isLoggable(Level.FINE)) |
66 | { | |
67 | 0 | log.fine("Resource-Url from external context: " + url); |
68 | } | |
69 | 0 | if (url == null) |
70 | { | |
71 | // This might happen on Servlet container which doesnot return | |
72 | // anything | |
73 | // for getResource() (like weblogic 8.1 for packaged wars) we | |
74 | // are trying | |
75 | // to use an own URL protocol in order to use | |
76 | // ServletContext.getResourceAsStream() | |
77 | // when opening the url | |
78 | 0 | if (resourceExist(externalContext, path)) |
79 | { | |
80 | 0 | url = getUrlForResourceAsStream(externalContext, path); |
81 | } | |
82 | } | |
83 | 0 | return url; |
84 | } | |
85 | ||
86 | // This method could be used above to provide a 'fail fast' if a | |
87 | // resource | |
88 | // doesnt exist. Otherwise, the URL will fail on the first access. | |
89 | private static boolean resourceExist(ExternalContext externalContext, String path) | |
90 | { | |
91 | 0 | if ("/".equals(path)) |
92 | { | |
93 | // The root context exists always | |
94 | 0 | return true; |
95 | } | |
96 | 0 | Object ctx = externalContext.getContext(); |
97 | 0 | if (ctx instanceof ServletContext) |
98 | { | |
99 | 0 | ServletContext servletContext = (ServletContext) ctx; |
100 | 0 | InputStream stream = servletContext.getResourceAsStream(path); |
101 | 0 | if (stream != null) |
102 | { | |
103 | try | |
104 | { | |
105 | 0 | stream.close(); |
106 | } | |
107 | 0 | catch (IOException e) |
108 | { | |
109 | // Ignore here, since we donnot wanted to read from this | |
110 | // resource anyway | |
111 | 0 | } |
112 | 0 | return true; |
113 | } | |
114 | } | |
115 | 0 | return false; |
116 | } | |
117 | ||
118 | // Construct URL with special URLStreamHandler for proxying | |
119 | // ServletContext.getResourceAsStream() | |
120 | private static URL getUrlForResourceAsStream(final ExternalContext externalContext, String path) | |
121 | throws MalformedURLException | |
122 | { | |
123 | 0 | URLStreamHandler handler = new URLStreamHandler() |
124 | 0 | { |
125 | protected URLConnection openConnection(URL u) throws IOException | |
126 | { | |
127 | 0 | final String file = u.getFile(); |
128 | 0 | return new URLConnection(u) |
129 | 0 | { |
130 | public void connect() throws IOException | |
131 | { | |
132 | 0 | } |
133 | ||
134 | public InputStream getInputStream() throws IOException | |
135 | { | |
136 | 0 | if (log.isLoggable(Level.FINE)) |
137 | { | |
138 | 0 | log.fine("Opening internal url to " + file); |
139 | } | |
140 | 0 | Object ctx = externalContext.getContext(); |
141 | // Or maybe fetch the external context afresh ? | |
142 | // Object ctx = | |
143 | // FacesContext.getCurrentInstance().getExternalContext().getContext(); | |
144 | ||
145 | 0 | if (ctx instanceof ServletContext) |
146 | { | |
147 | 0 | ServletContext servletContext = (ServletContext) ctx; |
148 | 0 | InputStream stream = servletContext.getResourceAsStream(file); |
149 | 0 | if (stream == null) |
150 | { | |
151 | 0 | throw new FileNotFoundException("Cannot open resource " + file); |
152 | } | |
153 | 0 | return stream; |
154 | } | |
155 | else | |
156 | { | |
157 | 0 | throw new IOException("Cannot open resource for an context of " |
158 | + (ctx != null ? ctx.getClass() : null)); | |
159 | } | |
160 | } | |
161 | }; | |
162 | } | |
163 | }; | |
164 | 0 | return new URL("internal", null, 0, path, handler); |
165 | } | |
166 | } |