KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > tools > jsfext > util > IncludeInputStream


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.tools.jsfext.util;
24
25 import java.io.BufferedInputStream JavaDoc;
26 import java.io.File JavaDoc;
27 import java.io.FileInputStream JavaDoc;
28 import java.io.FileNotFoundException JavaDoc;
29 import java.io.FilterInputStream JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.io.InputStream JavaDoc;
32 import java.lang.reflect.InvocationTargetException JavaDoc;
33 import java.lang.reflect.Method JavaDoc;
34
35
36 /**
37  * <p> This <code>InputStream</code> looks for lines beginning with
38  * "#include '<em>filename</em>'" where filename is the name of a file to
39  * include. It replaces the "#include" line with contents of the
40  * specified file. Any other line beginning with '#' is illegal.</p>
41  *
42  * @author Ken Paulsen (ken.paulsen@sun.com)
43  */

44 public class IncludeInputStream extends FilterInputStream JavaDoc {
45
46     /**
47      * <p> Constructor.</p>
48      */

49     public IncludeInputStream(InputStream JavaDoc input) {
50     super(input);
51     }
52
53     /**
54      * <p> This overriden method implements the include feature.</p>
55      *
56      * @return The next character.
57      */

58     public int read() throws IOException JavaDoc {
59     int intChar = -1;
60     if (redirStream != null) {
61         // We are already redirecting, delegate
62
intChar = redirStream.read();
63         if (intChar != -1) {
64         return intChar;
65         }
66
67         // Found end of redirect file, stop delegating
68
redirStream = null;
69     }
70
71     // Read next character
72
intChar = super.read();
73     char ch = (char) intChar;
74
75     // If we were at the end of the line, check for new line w/ #
76
if (eol) {
77         // Check to see if we have a '#'
78
if (ch == '#') {
79         intChar = startInclude();
80         } else {
81         eol = false;
82         }
83     }
84
85     // Flag EOL if we're at the end of a line
86
if ((ch == 0x0A) || (ch == 0x0D)) {
87         eol = true;
88     }
89
90     return intChar;
91     }
92
93     public int available() throws IOException JavaDoc {
94     return 0;
95     }
96
97     public boolean markSupported() {
98     return false;
99     }
100
101     public int read(byte[] bytes, int off, int len) throws IOException JavaDoc {
102     if (bytes == null) {
103         throw new NullPointerException JavaDoc();
104     } else if ((off < 0) || (off > bytes.length) || (len < 0)
105         || ((off + len) > bytes.length) || ((off + len) < 0)) {
106         throw new IndexOutOfBoundsException JavaDoc();
107     } else if (len == 0) {
108         return 0;
109     }
110
111     int c = read();
112     if (c == -1) {
113         return -1;
114     }
115     bytes[off] = (byte) c;
116
117     int i = 1;
118     try {
119         for (; i < len; i++) {
120         c = read();
121         if (c == -1) {
122             break;
123         }
124         if (bytes != null) {
125             bytes[off + i] = (byte) c;
126         }
127         }
128     } catch (IOException JavaDoc ee) {
129         ee.printStackTrace();
130     }
131     return i;
132     }
133
134     /**
135      *
136      */

137     private int startInclude() throws IOException JavaDoc {
138     // We have a line beginning w/ '#', verify we have "#include"
139
char ch;
140     for (int count = 0; count < INCLUDE_LEN; count++) {
141         // look for include
142
ch = (char) super.read();
143         if (Character.toLowerCase(ch) != INCLUDE.charAt(count)) {
144         throw new RuntimeException JavaDoc(
145             "\"#include\" expected in "
146             + "IncludeInputStream.");
147         }
148     }
149
150     // Skip whitespace...
151
ch = (char) super.read();
152     while ((ch == ' ') || (ch == '\t')) {
153         ch = (char) super.read();
154     }
155
156     // Skip '"' or '\''
157
if ((ch == '"') || (ch == '\'')) {
158         ch = (char) super.read();
159     }
160
161     // Read the file name
162
StringBuffer JavaDoc buf = new StringBuffer JavaDoc("");
163     while ((ch != '"')
164         && (ch != '\'')
165         && (ch != 0x0A)
166         && (ch != 0x0D)
167         && (ch != -1)) {
168         buf.append(ch);
169         ch = (char) super.read();
170     }
171
172     // Skip ending '"' or '\'', if any
173
if ((ch == '"') || (ch == '\'')) {
174         ch = (char) super.read();
175     }
176
177     // Get the file name...
178
String JavaDoc filename = buf.toString();
179
180     // Determine if we're in a JSF environment...
181
if (FACES_CONTEXT != null) {
182         // We are... get a context root relative path...
183
filename = convertRelativePath(filename);
184     }
185     File JavaDoc file = new File JavaDoc(filename);
186     // Make sure file exists (don't check read, let it throw an exception)
187
if (file.exists()) {
188         // Open the included file
189
redirStream = new IncludeInputStream(
190         new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(file)));
191     } else {
192         // Check Classpath?
193
ClassLoader JavaDoc loader = Util.getClassLoader(this);
194         InputStream JavaDoc stream = loader.getResourceAsStream(filename);
195         if (stream == null) {
196         stream = loader.getResourceAsStream("/" + filename);
197         if (stream == null) {
198             stream = loader.getResourceAsStream(
199                 "META-INF/" + filename);
200             if (stream == null) {
201             throw new FileNotFoundException JavaDoc(filename);
202             }
203         }
204         }
205         redirStream = new IncludeInputStream(
206             new BufferedInputStream JavaDoc(stream));
207     }
208
209     // Read the first character from the file to return
210
return redirStream.read();
211     }
212
213     /**
214      * <p> This method converts a context-root relative path to the actual
215      * path using the ServletContext or PortletContext. This requires
216      * the application to be running in a Servlet or Portlet
217      * environment... and further requires that it be running in JSF
218      * environment (which is used to access the Servlet or Portlet
219      * Context).</p>
220      *
221      * @param filename The relative filename to convert to a full path.
222      *
223      * @return The full path based on the app's context root.
224      */

225     protected String JavaDoc convertRelativePath(String JavaDoc filename) {
226     // NOTE: This method uses reflection to avoid build/runtime
227
// NOTE: dependencies on JSF, this method is only used if the
228
// NOTE: FacesContext class is found in the classpath.
229

230     // Check for the file in docroot
231
Method JavaDoc method = null;
232     Object JavaDoc ctx = null;
233     String JavaDoc newFilename = null;
234     try {
235         // The following should work w/ a ServletContext or PortletContext
236
// Get the FacesContext...
237
method = FACES_CONTEXT.getMethod(
238             "getCurrentInstance", (Class JavaDoc []) null);
239         ctx = method.invoke((Object JavaDoc) null, (Object JavaDoc []) null);
240
241         // Get the ExternalContext...
242
method = ctx.getClass().getMethod(
243             "getExternalContext", (Class JavaDoc []) null);
244         ctx = method.invoke(ctx, (Object JavaDoc []) null);
245
246         // Get actual underlying external context...
247
method = ctx.getClass().getMethod(
248             "getContext", (Class JavaDoc []) null);
249         ctx = method.invoke(ctx, (Object JavaDoc []) null);
250
251         // Get the real path using the ServletContext/PortletContext
252
method = ctx.getClass().getMethod(
253             "getRealPath", GET_REAL_PATH_ARGS);
254         newFilename = (String JavaDoc) method.invoke(ctx, new Object JavaDoc [] {filename});
255         if (!(new File JavaDoc(newFilename)).exists()) {
256         // The file doesn't exist, fall back to absolute path
257
newFilename = filename;
258         }
259     } catch (NoSuchMethodException JavaDoc ex) {
260         throw new RuntimeException JavaDoc(ex);
261     } catch (IllegalAccessException JavaDoc ex) {
262         throw new RuntimeException JavaDoc(ex);
263     } catch (InvocationTargetException JavaDoc ex) {
264         throw new RuntimeException JavaDoc(ex);
265     }
266     return newFilename;
267     }
268
269     /**
270      * <p> Simple test case (requires a test file).</p>
271      */

272     public static void main(String JavaDoc[] args) {
273     try {
274         IncludeInputStream stream =
275         new IncludeInputStream(new FileInputStream JavaDoc(args[0]));
276         int ch = '\n';
277         while (ch != -1) {
278         System.out.print((char) ch);
279         ch = stream.read();
280         }
281     } catch (Exception JavaDoc ex) {
282         ex.printStackTrace();
283     }
284     }
285
286     private boolean eol = true;
287     private IncludeInputStream redirStream = null;
288
289     private static final Class JavaDoc [] GET_REAL_PATH_ARGS =
290         new Class JavaDoc[] {String JavaDoc.class};
291
292     private static final String JavaDoc INCLUDE = "include";
293     private static final int INCLUDE_LEN = INCLUDE.length();
294
295     private static Class JavaDoc FACES_CONTEXT;
296
297     static {
298     try {
299         FACES_CONTEXT = Class.forName("javax.faces.context.FacesContext");
300     } catch (Exception JavaDoc ex) {
301         // Ignore, this just means we're not in a JSF environment
302
FACES_CONTEXT = null;
303     }
304     }
305 }
306
Popular Tags