KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > wings > resource > CssUrlFilterInputStream


1 package org.wings.resource;
2
3 import org.apache.commons.logging.Log;
4 import org.apache.commons.logging.LogFactory;
5 import org.wings.externalizer.ExternalizeManager;
6
7 import java.io.BufferedInputStream JavaDoc;
8 import java.io.IOException JavaDoc;
9 import java.io.InputStream JavaDoc;
10
11 /**
12  * filters an input stream of a css file for occurences of "url([classPath])".
13  * These image classpaths are then externalized and replaced in the resulting
14  * InputStream.
15  * This gives us the possibility to load css files and their included images
16  * via the classpath, so no external files are needed.
17  * If the image is not found at the classpath provided, the occurence is not
18  * altered.
19  * @author ole
20  * @version $$
21  *
22  */

23 public class CssUrlFilterInputStream extends BufferedInputStream JavaDoc {
24     private final transient static Log log = LogFactory.getLog(CssUrlFilterInputStream.class);
25     
26     private final static byte STATE_NONE = 0;
27     private final static byte STATE_U = 1;
28     private final static byte STATE_UR = 2;
29     private final static byte STATE_URL = 3;
30     private final static byte STATE_URL_DONE = 4;
31     private final static byte STATE_SUBST = 5;
32     private byte state = STATE_NONE;
33     
34     private byte[] urlBuffer;
35     private int bufferPos;
36
37     /**
38      * The ExternalizeManager to use for Image externalization.
39      * Externalized Resources cannot count on a session, but we need an
40      * ExternalizeManager for image externalization.
41      */

42     private ExternalizeManager extManager;
43
44     /**
45      * Creates a new Instance.
46      * @param in the InputStream to filter
47      * @param extManager The ExternalizeManager to use for Image externalization.
48      */

49     public CssUrlFilterInputStream(InputStream JavaDoc in, ExternalizeManager extManager) {
50         super(in);
51         this.extManager = extManager;
52     }
53
54     /* (non-Javadoc)
55      * @see java.io.InputStream#read()
56      */

57     public int read() throws IOException JavaDoc {
58         int result = 0;
59         if (state == STATE_SUBST) {
60             result = readFromUrlBuffer();
61         } else {
62             result = super.read();
63             if (result != -1) {
64                 analyzeState(result);
65                 if (state == STATE_URL_DONE) {
66                     substitute();
67                 }
68             }
69         }
70         return result;
71     }
72
73     /**
74      * substitutes the ocurrences of "url([classPath])" with the externalized
75      * images.
76      * @throws IOException
77      */

78     private void substitute() throws IOException JavaDoc {
79         StringBuffer JavaDoc classPathBuffer = new StringBuffer JavaDoc();
80         int tempBuffer = super.read();
81         while (tempBuffer != -1 && tempBuffer != ')') {
82             classPathBuffer.append((char)tempBuffer);
83             super.mark(2);
84             tempBuffer = super.read();
85         }
86         super.reset();
87         String JavaDoc classPath = strip(classPathBuffer.toString(), ' ');
88         classPath = strip(classPath, '\'');
89         classPath = strip(classPath, '"');
90         String JavaDoc extension = null;
91         int dotIndex = classPath.lastIndexOf('.');
92         if (dotIndex > -1) {
93             extension = classPath.substring(dotIndex + 1).toLowerCase();
94             if ("jpg".equals(extension)) extension = "jpeg";
95             
96         }
97         bufferPos = 0;
98         urlBuffer = externalizeImage(classPath, "image/" + extension).getBytes();
99         if (urlBuffer.length == 0) {
100             // not externalized, use old String
101
urlBuffer = classPathBuffer.toString().getBytes();
102         }
103         state = STATE_SUBST;
104     }
105
106     /** externalizes an Image found.
107      * @param classPath the classPath of the Image
108      * @param mimeType the mimeType of the Image
109      * @return the url of the externalized Image
110      */

111     private String JavaDoc externalizeImage(String JavaDoc classPath, String JavaDoc mimeType) {
112         ClasspathResource res = new ClasspathResource(classPath, mimeType);
113         if (res.getResourceStream() == null) {
114             // no resource found at classPath, return old string
115
log.debug("Could not find resource at classpath: " + classPath);
116             return "";
117         }
118         StringBuffer JavaDoc imageUrl = new StringBuffer JavaDoc("'");
119         imageUrl.append(extManager.externalize(res, ExternalizeManager.GLOBAL));
120         imageUrl.append("'");
121         return imageUrl.toString();
122     }
123
124     /** reads from the filename buffer. is called when an Image classPath is
125      * replaces by it's url.
126      * @return the character at the current position
127      */

128     private int readFromUrlBuffer() {
129         int result = urlBuffer[bufferPos];
130         bufferPos++;
131         if (bufferPos == urlBuffer.length) {
132             state = STATE_NONE;
133         }
134         return result;
135     }
136
137     /* (non-Javadoc)
138      * @see java.io.InputStream#read(byte[], int, int)
139      */

140     public int read(byte[] b, int off, int len) throws IOException JavaDoc {
141         int i = 0;
142         for (i = off; i < (off+len);i++) {
143             byte tempByte = (byte)read();
144             if (tempByte == -1) {
145                 break;
146             }
147             b[i] = tempByte;
148         }
149         return i - off;
150     }
151
152     /**
153      * Strips a String of occurences of character. works recursively.
154      * @param buffer the String
155      * @param character the Character to be stripped
156      * @return the stripped string
157      */

158     private String JavaDoc strip(String JavaDoc buffer, char character) {
159         if (buffer.charAt(0) == character) {
160             return strip(buffer.substring(1, buffer.length()), character);
161         }
162         if (buffer.charAt(buffer.length() - 1) == character) {
163             return strip(buffer.substring(0, buffer.length()-1), character);
164         }
165         return buffer;
166     }
167
168     /* (non-Javadoc)
169      * @see java.io.InputStream#read(byte[])
170      */

171     public int read(byte[] b) throws IOException JavaDoc {
172         return read(b, 0, b.length);
173     }
174
175     /**
176      * analyzes the Parse State and sets the state variable accordingly.
177      *
178      * @param character the character to analyze.
179      */

180     private void analyzeState(int character) {
181         switch (character) {
182         case 'u':
183             if (state == STATE_NONE) {
184                 state = STATE_U;
185             } else {
186                 state = STATE_NONE;
187             }
188             break;
189         case 'r':
190             if (state == STATE_U) {
191                 state = STATE_UR;
192             } else {
193                 state = STATE_NONE;
194             }
195             break;
196         case 'l':
197             if (state == STATE_UR) {
198                 state = STATE_URL;
199             } else {
200                 state = STATE_NONE;
201             }
202             break;
203         case '(':
204             if (state == STATE_URL) {
205                 state = STATE_URL_DONE;
206             } else {
207                 state = STATE_NONE;
208             }
209             break;
210         default:
211             state = STATE_NONE;
212             break;
213         }
214     }
215 }
216
Popular Tags