KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > facelets > compiler > SAXCompiler


1 /**
2  * Licensed under the Common Development and Distribution License,
3  * you may not use this file except in compliance with the License.
4  * You may obtain a copy of the License at
5  *
6  * http://www.sun.com/cddl/
7  *
8  * Unless required by applicable law or agreed to in writing, software
9  * distributed under the License is distributed on an "AS IS" BASIS,
10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
11  * implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */

14
15 package com.sun.facelets.compiler;
16
17 import java.io.BufferedInputStream JavaDoc;
18 import java.io.IOException JavaDoc;
19 import java.io.InputStream JavaDoc;
20 import java.net.URL JavaDoc;
21 import java.util.regex.Matcher JavaDoc;
22 import java.util.regex.Pattern JavaDoc;
23
24 import javax.el.ELException;
25 import javax.faces.FacesException;
26 import javax.xml.parsers.ParserConfigurationException JavaDoc;
27 import javax.xml.parsers.SAXParser JavaDoc;
28 import javax.xml.parsers.SAXParserFactory JavaDoc;
29
30 import org.xml.sax.Attributes JavaDoc;
31 import org.xml.sax.InputSource JavaDoc;
32 import org.xml.sax.Locator JavaDoc;
33 import org.xml.sax.SAXException JavaDoc;
34 import org.xml.sax.SAXParseException JavaDoc;
35 import org.xml.sax.XMLReader JavaDoc;
36 import org.xml.sax.ext.LexicalHandler JavaDoc;
37 import org.xml.sax.helpers.DefaultHandler JavaDoc;
38
39 import com.sun.facelets.FaceletException;
40 import com.sun.facelets.FaceletHandler;
41 import com.sun.facelets.tag.Location;
42 import com.sun.facelets.tag.Tag;
43 import com.sun.facelets.tag.TagAttribute;
44 import com.sun.facelets.tag.TagAttributes;
45
46 /**
47  * Compiler implementation that uses SAX
48  *
49  * @see com.sun.facelets.compiler.Compiler
50  *
51  * @author Jacob Hookom
52  * @version $Id: SAXCompiler.java,v 1.13 2006/05/31 04:16:46 jhook Exp $
53  */

54 public final class SAXCompiler extends Compiler JavaDoc {
55     
56     private final static Pattern JavaDoc XmlDeclaration = Pattern.compile("^<\\?xml.+?version=['\"](.+?)['\"](.+?encoding=['\"]((.+?))['\"])?.*?\\?>");
57
58     private static class CompilationHandler extends DefaultHandler JavaDoc implements
59             LexicalHandler JavaDoc {
60
61         private final String JavaDoc alias;
62
63         private boolean inDocument = false;
64         
65         private boolean trimDoctypeDeclaration = false;
66
67         private Locator JavaDoc locator;
68
69         private final CompilationManager unit;
70
71         public CompilationHandler(CompilationManager unit, String JavaDoc alias, boolean trimDoctypeDeclaration) {
72             this.unit = unit;
73             this.alias = alias;
74             this.trimDoctypeDeclaration = trimDoctypeDeclaration;
75         }
76
77         public void characters(char[] ch, int start, int length)
78                 throws SAXException JavaDoc {
79             if (this.inDocument) {
80                 this.unit.writeText(new String JavaDoc(ch, start, length));
81             }
82         }
83
84         public void comment(char[] ch, int start, int length)
85                 throws SAXException JavaDoc {
86             if (this.inDocument) {
87                 this.unit.writeComment(new String JavaDoc(ch, start, length));
88             }
89         }
90
91         protected TagAttributes createAttributes(Attributes JavaDoc attrs) {
92             int len = attrs.getLength();
93             TagAttribute[] ta = new TagAttribute[len];
94             for (int i = 0; i < len; i++) {
95                 ta[i] = new TagAttribute(this.createLocation(),
96                         attrs.getURI(i), attrs.getLocalName(i), attrs
97                                 .getQName(i), attrs.getValue(i));
98             }
99             return new TagAttributes(ta);
100         }
101
102         protected Location createLocation() {
103             return new Location(this.alias, this.locator.getLineNumber(),
104                     this.locator.getColumnNumber());
105         }
106
107         public void endCDATA() throws SAXException JavaDoc {
108             if (this.inDocument) {
109                 this.unit.writeInstruction("]]>");
110             }
111         }
112
113         public void endDocument() throws SAXException JavaDoc {
114             super.endDocument();
115         }
116
117         public void endDTD() throws SAXException JavaDoc {
118             this.inDocument = true;
119         }
120
121         public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName)
122                 throws SAXException JavaDoc {
123             this.unit.popTag();
124         }
125
126         public void endEntity(String JavaDoc name) throws SAXException JavaDoc {
127         }
128
129         public void endPrefixMapping(String JavaDoc prefix) throws SAXException JavaDoc {
130             this.unit.popNamespace(prefix);
131         }
132
133         public void fatalError(SAXParseException JavaDoc e) throws SAXException JavaDoc {
134             if (this.locator != null) {
135             throw new SAXException JavaDoc("Error Traced[line: "
136                     + this.locator.getLineNumber() + "] " + e.getMessage());
137             } else {
138                 throw e;
139             }
140         }
141
142         public void ignorableWhitespace(char[] ch, int start, int length)
143                 throws SAXException JavaDoc {
144             if (this.inDocument) {
145                 this.unit.writeWhitespace(new String JavaDoc(ch, start, length));
146             }
147         }
148
149         public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId)
150                 throws SAXException JavaDoc {
151             String JavaDoc dtd = "default.dtd";
152             /*if ("-//W3C//DTD XHTML 1.0 Transitional//EN".equals(publicId)) {
153                 dtd = "xhtml1-transitional.dtd";
154             } else if (systemId != null && systemId.startsWith("file:/")) {
155                 return new InputSource(systemId);
156             }*/

157             URL JavaDoc url = Thread.currentThread().getContextClassLoader()
158                     .getResource(dtd);
159             return new InputSource JavaDoc(url.toString());
160         }
161
162         public void setDocumentLocator(Locator JavaDoc locator) {
163             this.locator = locator;
164         }
165
166         public void startCDATA() throws SAXException JavaDoc {
167             if (this.inDocument) {
168                 this.unit.writeInstruction("<![CDATA[");
169             }
170         }
171
172         public void startDocument() throws SAXException JavaDoc {
173             this.inDocument = true;
174         }
175
176         public void startDTD(String JavaDoc name, String JavaDoc publicId, String JavaDoc systemId)
177                 throws SAXException JavaDoc {
178             if (this.inDocument) {
179                 if( !trimDoctypeDeclaration ) {
180                     StringBuffer JavaDoc sb = new StringBuffer JavaDoc(64);
181                     sb.append("<!DOCTYPE ").append(name);
182                     if (publicId != null) {
183                         sb.append(" PUBLIC \"").append(publicId).append("\"");
184                         if (systemId != null) {
185                             sb.append(" \"").append(systemId).append("\"");
186                         }
187                     } else if (systemId != null) {
188                         sb.append(" SYSTEM \"").append(systemId).append("\"");
189                     }
190                     sb.append(" >\n");
191                     this.unit.writeInstruction(sb.toString());
192                 }
193             }
194             this.inDocument = false;
195         }
196
197         public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName,
198                 Attributes JavaDoc attributes) throws SAXException JavaDoc {
199             this.unit.pushTag(new Tag(this.createLocation(), uri, localName,
200                     qName, this.createAttributes(attributes)));
201         }
202
203         public void startEntity(String JavaDoc name) throws SAXException JavaDoc {
204         }
205
206         public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri)
207                 throws SAXException JavaDoc {
208             this.unit.pushNamespace(prefix, uri);
209         }
210
211         public void processingInstruction(String JavaDoc target, String JavaDoc data)
212                 throws SAXException JavaDoc {
213             if (this.inDocument) {
214                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc(64);
215                 sb.append("<?").append(target).append(' ').append(data).append(
216                         "?>\n");
217                 this.unit.writeInstruction(sb.toString());
218             }
219         }
220     }
221
222     public SAXCompiler() {
223         super();
224     }
225
226     public FaceletHandler doCompile(URL JavaDoc src, String JavaDoc alias) throws IOException JavaDoc,
227             FaceletException, ELException, FacesException {
228         CompilationManager mngr = null;
229         InputStream JavaDoc is = null;
230         String JavaDoc encoding = "UTF-8";
231         try {
232             is = new BufferedInputStream JavaDoc(src.openStream(), 1024);
233             mngr = new CompilationManager(alias, this);
234             encoding = writeXmlDecl(is, mngr, isTrimmingXmlDeclarations());
235             CompilationHandler handler = new CompilationHandler(mngr, alias, isTrimmingDoctypeDeclarations());
236             SAXParser JavaDoc parser = this.createSAXParser(handler);
237             parser.parse(is, handler);
238         } catch (SAXException JavaDoc e) {
239             throw new FaceletException("Error Parsing " + alias + ": "
240                     + e.getMessage(), e.getCause());
241         } catch (ParserConfigurationException JavaDoc e) {
242             throw new FaceletException("Error Configuring Parser " + alias
243                     + ": " + e.getMessage(), e.getCause());
244         } finally {
245             if (is != null) {
246                 is.close();
247             }
248         }
249         return new EncodingHandler(mngr.createFaceletHandler(), encoding);
250     }
251
252     protected static final String JavaDoc writeXmlDecl(InputStream JavaDoc is, CompilationManager mngr, boolean trimXmlDeclaration)
253             throws IOException JavaDoc {
254         is.mark(128);
255         String JavaDoc encoding = "UTF-8";
256         try {
257             byte[] b = new byte[128];
258             if (is.read(b) > 0) {
259                 String JavaDoc r = new String JavaDoc(b);
260                 Matcher JavaDoc m = XmlDeclaration.matcher(r);
261                 if (m.find()) {
262                     if( !trimXmlDeclaration ) {
263                         mngr.writeInstruction(m.group(0) + "\n");
264                     }
265                     if (m.group(3) != null) {
266                         encoding = m.group(3);
267                     }
268                 }
269             }
270         } finally {
271             is.reset();
272         }
273         return encoding;
274     }
275
276     private final SAXParser JavaDoc createSAXParser(CompilationHandler handler)
277             throws SAXException JavaDoc, ParserConfigurationException JavaDoc {
278         SAXParserFactory JavaDoc factory = SAXParserFactory.newInstance();
279         factory.setNamespaceAware(true);
280         factory.setFeature("http://xml.org/sax/features/namespace-prefixes",
281                 true);
282         factory.setFeature("http://xml.org/sax/features/validation", this
283                 .isValidating());
284         factory.setValidating(this.isValidating());
285         SAXParser JavaDoc parser = factory.newSAXParser();
286         XMLReader JavaDoc reader = parser.getXMLReader();
287         reader.setProperty("http://xml.org/sax/properties/lexical-handler",
288                 handler);
289         reader.setErrorHandler(handler);
290         reader.setEntityResolver(handler);
291         return parser;
292     }
293
294 }
295
Popular Tags