Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/sun/facelets/compiler/SAXCompiler.java


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;
18  import java.io.IOException;
19  import java.io.InputStream;
20  import java.net.URL;
21  import java.util.regex.Matcher;
22  import java.util.regex.Pattern;
23  
24  import javax.el.ELException;
25  import javax.faces.FacesException;
26  import javax.xml.parsers.ParserConfigurationException;
27  import javax.xml.parsers.SAXParser;
28  import javax.xml.parsers.SAXParserFactory;
29  
30  import org.xml.sax.Attributes;
31  import org.xml.sax.InputSource;
32  import org.xml.sax.Locator;
33  import org.xml.sax.SAXException;
34  import org.xml.sax.SAXParseException;
35  import org.xml.sax.XMLReader;
36  import org.xml.sax.ext.LexicalHandler;
37  import org.xml.sax.helpers.DefaultHandler;
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 {
55      
56      private final static Pattern XmlDeclaration = Pattern.compile("^<\\?xml.+?version=['\"](.+?)['\"](.+?encoding=['\"]((.+?))['\"])?.*?\\?>");
57  
58      private static class CompilationHandler extends DefaultHandler implements
59              LexicalHandler {
60  
61          private final String alias;
62  
63          private boolean inDocument = false;
64  
65          private Locator locator;
66  
67          private final CompilationManager unit;
68  
69          public CompilationHandler(CompilationManager unit, String alias) {
70              this.unit = unit;
71              this.alias = alias;
72          }
73  
74          public void characters(char[] ch, int start, int length)
75                  throws SAXException {
76              if (this.inDocument) {
77                  this.unit.writeText(new String(ch, start, length));
78              }
79          }
80  
81          public void comment(char[] ch, int start, int length)
82                  throws SAXException {
83              if (this.inDocument) {
84                  this.unit.writeComment(new String(ch, start, length));
85              }
86          }
87  
88          protected TagAttributes createAttributes(Attributes attrs) {
89              int len = attrs.getLength();
90              TagAttribute[] ta = new TagAttribute[len];
91              for (int i = 0; i < len; i++) {
92                  ta[i] = new TagAttribute(this.createLocation(),
93                          attrs.getURI(i), attrs.getLocalName(i), attrs
94                                  .getQName(i), attrs.getValue(i));
95              }
96              return new TagAttributes(ta);
97          }
98  
99          protected Location createLocation() {
100             return new Location(this.alias, this.locator.getLineNumber(),
101                     this.locator.getColumnNumber());
102         }
103 
104         public void endCDATA() throws SAXException {
105             if (this.inDocument) {
106                 this.unit.writeInstruction("]]>");
107             }
108         }
109 
110         public void endDocument() throws SAXException {
111             super.endDocument();
112         }
113 
114         public void endDTD() throws SAXException {
115             this.inDocument = true;
116         }
117 
118         public void endElement(String uri, String localName, String qName)
119                 throws SAXException {
120             this.unit.popTag();
121         }
122 
123         public void endEntity(String name) throws SAXException {
124         }
125 
126         public void endPrefixMapping(String prefix) throws SAXException {
127             this.unit.popNamespace(prefix);
128         }
129 
130         public void fatalError(SAXParseException e) throws SAXException {
131             if (this.locator != null) {
132             throw new SAXException("Error Traced[line: "
133                     + this.locator.getLineNumber() + "] " + e.getMessage());
134             } else {
135                 throw e;
136             }
137         }
138 
139         public void ignorableWhitespace(char[] ch, int start, int length)
140                 throws SAXException {
141             if (this.inDocument) {
142                 this.unit.writeWhitespace(new String(ch, start, length));
143             }
144         }
145 
146         public InputSource resolveEntity(String publicId, String systemId)
147                 throws SAXException {
148             String dtd = "default.dtd";
149             /*if ("-//W3C//DTD XHTML 1.0 Transitional//EN".equals(publicId)) {
150                 dtd = "xhtml1-transitional.dtd";
151             } else if (systemId != null && systemId.startsWith("file:/")) {
152                 return new InputSource(systemId);
153             }*/
154             URL url = Thread.currentThread().getContextClassLoader()
155                     .getResource(dtd);
156             return new InputSource(url.toString());
157         }
158 
159         public void setDocumentLocator(Locator locator) {
160             this.locator = locator;
161         }
162 
163         public void startCDATA() throws SAXException {
164             if (this.inDocument) {
165                 this.unit.writeInstruction("<![CDATA[");
166             }
167         }
168 
169         public void startDocument() throws SAXException {
170             this.inDocument = true;
171         }
172 
173         public void startDTD(String name, String publicId, String systemId)
174                 throws SAXException {
175             if (this.inDocument) {
176                 StringBuffer sb = new StringBuffer(64);
177                 sb.append("<!DOCTYPE ").append(name);
178                 if (publicId != null) {
179                     sb.append(" PUBLIC \"").append(publicId).append("\"");
180                     if (systemId != null) {
181                         sb.append(" \"").append(systemId).append("\"");
182                     }
183                 } else if (systemId != null) {
184                     sb.append(" SYSTEM \"").append(systemId).append("\"");
185                 }
186                 sb.append(" >\n");
187                 this.unit.writeInstruction(sb.toString());
188             }
189             this.inDocument = false;
190         }
191 
192         public void startElement(String uri, String localName, String qName,
193                 Attributes attributes) throws SAXException {
194             this.unit.pushTag(new Tag(this.createLocation(), uri, localName,
195                     qName, this.createAttributes(attributes)));
196         }
197 
198         public void startEntity(String name) throws SAXException {
199         }
200 
201         public void startPrefixMapping(String prefix, String uri)
202                 throws SAXException {
203             this.unit.pushNamespace(prefix, uri);
204         }
205 
206         public void processingInstruction(String target, String data)
207                 throws SAXException {
208             if (this.inDocument) {
209                 StringBuffer sb = new StringBuffer(64);
210                 sb.append("<?").append(target).append(' ').append(data).append(
211                         "?>\n");
212                 this.unit.writeInstruction(sb.toString());
213             }
214         }
215     }
216 
217     public SAXCompiler() {
218         super();
219     }
220 
221     public FaceletHandler doCompile(URL src, String alias) throws IOException,
222             FaceletException, ELException, FacesException {
223         CompilationManager mngr = null;
224         InputStream is = null;
225         String encoding = "UTF-8";
226         try {
227             is = new BufferedInputStream(src.openStream(), 1024);
228             mngr = new CompilationManager(alias, this);
229             encoding = writeXmlDecl(is, mngr);
230             CompilationHandler handler = new CompilationHandler(mngr, alias);
231             SAXParser parser = this.createSAXParser(handler);
232             parser.parse(is, handler);
233         } catch (SAXException e) {
234             throw new FaceletException("Error Parsing " + alias + ": "
235                     + e.getMessage(), e.getCause());
236         } catch (ParserConfigurationException e) {
237             throw new FaceletException("Error Configuring Parser " + alias
238                     + ": " + e.getMessage(), e.getCause());
239         } finally {
240             if (is != null) {
241                 is.close();
242             }
243         }
244         return new EncodingHandler(mngr.createFaceletHandler(), encoding);
245     }
246 
247     protected static final String writeXmlDecl(InputStream is, CompilationManager mngr)
248             throws IOException {
249         is.mark(128);
250         String encoding = "UTF-8";
251         try {
252             byte[] b = new byte[128];
253             if (is.read(b) > 0) {
254                 String r = new String(b);
255                 Matcher m = XmlDeclaration.matcher(r);
256                 if (m.find()) {
257                     mngr.writeInstruction(m.group(0) + "\n");
258                     if (m.group(3) != null) {
259                         encoding = m.group(3);
260                     }
261                 }
262             }
263         } finally {
264             is.reset();
265         }
266         return encoding;
267     }
268 
269     private final SAXParser createSAXParser(CompilationHandler handler)
270             throws SAXException, ParserConfigurationException {
271         SAXParserFactory factory = SAXParserFactory.newInstance();
272         factory.setNamespaceAware(true);
273         factory.setFeature("http://xml.org/sax/features/namespace-prefixes",
274                 true);
275         factory.setFeature("http://xml.org/sax/features/validation", this
276                 .isValidating());
277         factory.setValidating(this.isValidating());
278         SAXParser parser = factory.newSAXParser();
279         XMLReader reader = parser.getXMLReader();
280         reader.setProperty("http://xml.org/sax/properties/lexical-handler",
281                 handler);
282         reader.setErrorHandler(handler);
283         reader.setEntityResolver(handler);
284         return parser;
285     }
286 
287 }