Coverage Report - org.apache.myfaces.view.facelets.compiler.SAXCompiler
 
Classes in this File Line Coverage Branch Coverage Complexity
SAXCompiler
0%
0/152
0%
0/68
3.122
SAXCompiler$1
0%
0/3
N/A
3.122
SAXCompiler$CompilationHandler
0%
0/65
0%
0/34
3.122
SAXCompiler$CompositeComponentMetadataHandler
0%
0/83
0%
0/90
3.122
SAXCompiler$ViewMetadataHandler
0%
0/83
0%
0/82
3.122
 
 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.compiler;
 20  
 
 21  
 import java.io.BufferedInputStream;
 22  
 import java.io.IOException;
 23  
 import java.io.InputStream;
 24  
 import java.net.URL;
 25  
 import java.util.regex.Matcher;
 26  
 import java.util.regex.Pattern;
 27  
 import java.security.AccessController;
 28  
 import java.security.PrivilegedExceptionAction;
 29  
 import java.security.PrivilegedActionException;
 30  
 import java.util.Map;
 31  
 
 32  
 import javax.el.ELException;
 33  
 import javax.el.MethodExpression;
 34  
 import javax.el.ValueExpression;
 35  
 import javax.faces.FacesException;
 36  
 import javax.faces.view.Location;
 37  
 import javax.faces.view.facelets.FaceletException;
 38  
 import javax.faces.view.facelets.FaceletHandler;
 39  
 import javax.faces.view.facelets.Tag;
 40  
 import javax.faces.view.facelets.TagAttribute;
 41  
 import javax.faces.view.facelets.TagAttributes;
 42  
 import javax.xml.parsers.ParserConfigurationException;
 43  
 import javax.xml.parsers.SAXParser;
 44  
 import javax.xml.parsers.SAXParserFactory;
 45  
 
 46  
 import org.apache.myfaces.config.element.FaceletsProcessing;
 47  
 import org.apache.myfaces.shared.util.ClassUtils;
 48  
 import org.apache.myfaces.view.facelets.tag.TagAttributeImpl;
 49  
 import org.apache.myfaces.view.facelets.tag.TagAttributesImpl;
 50  
 import org.apache.myfaces.view.facelets.tag.composite.CompositeLibrary;
 51  
 import org.apache.myfaces.view.facelets.tag.composite.ImplementationHandler;
 52  
 import org.apache.myfaces.view.facelets.tag.composite.InterfaceHandler;
 53  
 import org.apache.myfaces.view.facelets.tag.jsf.core.CoreLibrary;
 54  
 import org.apache.myfaces.view.facelets.tag.ui.UILibrary;
 55  
 import org.xml.sax.Attributes;
 56  
 import org.xml.sax.InputSource;
 57  
 import org.xml.sax.Locator;
 58  
 import org.xml.sax.SAXException;
 59  
 import org.xml.sax.SAXParseException;
 60  
 import org.xml.sax.XMLReader;
 61  
 import org.xml.sax.ext.LexicalHandler;
 62  
 import org.xml.sax.helpers.DefaultHandler;
 63  
 
 64  
 /**
 65  
  * Compiler implementation that uses SAX
 66  
  * 
 67  
  * @see org.apache.myfaces.view.facelets.compiler.Compiler
 68  
  * 
 69  
  * @author Jacob Hookom
 70  
  * @version $Id$
 71  
  */
 72  
 public final class SAXCompiler extends Compiler
 73  
 {
 74  
 
 75  0
     private final static Pattern XML_DECLARATION = Pattern
 76  
             .compile("^<\\?xml.+?version=['\"](.+?)['\"](.+?encoding=['\"]((.+?))['\"])?.*?\\?>");
 77  
 
 78  
     private static class CompilationHandler extends DefaultHandler implements LexicalHandler
 79  
     {
 80  
 
 81  
         private final String alias;
 82  
 
 83  0
         private boolean inDocument = false;
 84  
 
 85  
         private Locator locator;
 86  
 
 87  
         private final CompilationManager unit;
 88  
         
 89  0
         private boolean consumingCDATA = false;
 90  0
         private boolean swallowCDATAContent = false;
 91  
 
 92  
         public CompilationHandler(CompilationManager unit, String alias)
 93  0
         {
 94  0
             this.unit = unit;
 95  0
             this.alias = alias;
 96  0
         }
 97  
 
 98  
         public void characters(char[] ch, int start, int length) throws SAXException
 99  
         {
 100  0
             if (this.inDocument && (!consumingCDATA || (consumingCDATA && !swallowCDATAContent)))
 101  
             {
 102  0
                 this.unit.writeText(new String(ch, start, length));
 103  
             }
 104  0
         }
 105  
 
 106  
         public void comment(char[] ch, int start, int length) throws SAXException
 107  
         {
 108  0
             if (this.inDocument && !unit.getFaceletsProcessingInstructions().isConsumeXMLComments())
 109  
             {
 110  0
                 this.unit.writeComment(new String(ch, start, length));
 111  
             }
 112  0
         }
 113  
 
 114  
         protected TagAttributes createAttributes(Attributes attrs)
 115  
         {
 116  0
             int len = attrs.getLength();
 117  0
             TagAttribute[] ta = new TagAttribute[len];
 118  0
             for (int i = 0; i < len; i++)
 119  
             {
 120  0
                 ta[i] = new TagAttributeImpl(this.createLocation(), attrs.getURI(i), attrs.getLocalName(i), attrs
 121  
                         .getQName(i), attrs.getValue(i));
 122  
             }
 123  0
             return new TagAttributesImpl(ta);
 124  
         }
 125  
 
 126  
         protected Location createLocation()
 127  
         {
 128  0
             return new Location(this.alias, this.locator.getLineNumber(), this.locator.getColumnNumber());
 129  
         }
 130  
 
 131  
         public void endCDATA() throws SAXException
 132  
         {
 133  0
             if (this.inDocument)
 134  
             {
 135  0
                 if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
 136  
                 {
 137  0
                     this.unit.writeInstruction("]]>");
 138  
                 }
 139  
                 else
 140  
                 {
 141  0
                     this.consumingCDATA = false;
 142  0
                     this.swallowCDATAContent = false;
 143  
                 }
 144  
             }
 145  0
         }
 146  
 
 147  
         public void endDTD() throws SAXException
 148  
         {
 149  0
             this.inDocument = true;
 150  0
         }
 151  
 
 152  
         public void endElement(String uri, String localName, String qName) throws SAXException
 153  
         {
 154  0
             this.unit.popTag();
 155  0
         }
 156  
 
 157  
         public void endEntity(String name) throws SAXException
 158  
         {
 159  0
         }
 160  
 
 161  
         public void endPrefixMapping(String prefix) throws SAXException
 162  
         {
 163  0
             this.unit.popNamespace(prefix);
 164  0
         }
 165  
 
 166  
         public void fatalError(SAXParseException e) throws SAXException
 167  
         {
 168  0
             if (this.locator != null)
 169  
             {
 170  0
                 throw new SAXException("Error Traced[line: " + this.locator.getLineNumber() + "] " + e.getMessage());
 171  
             }
 172  
             else
 173  
             {
 174  0
                 throw e;
 175  
             }
 176  
         }
 177  
 
 178  
         public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
 179  
         {
 180  0
             if (this.inDocument)
 181  
             {
 182  0
                 this.unit.writeWhitespace(new String(ch, start, length));
 183  
             }
 184  0
         }
 185  
 
 186  
         public InputSource resolveEntity(String publicId, String systemId) throws SAXException
 187  
         {
 188  0
             String dtd = "org/apache/myfaces/resource/default.dtd";
 189  
             /*
 190  
              * if ("-//W3C//DTD XHTML 1.0 Transitional//EN".equals(publicId)) { dtd = "xhtml1-transitional.dtd"; } else
 191  
              * if (systemId != null && systemId.startsWith("file:/")) { return new InputSource(systemId); }
 192  
              */
 193  0
             URL url = ClassUtils.getResource(dtd);
 194  0
             return new InputSource(url.toString());
 195  
         }
 196  
 
 197  
         public void setDocumentLocator(Locator locator)
 198  
         {
 199  0
             this.locator = locator;
 200  0
         }
 201  
 
 202  
         public void startCDATA() throws SAXException
 203  
         {
 204  0
             if (this.inDocument)
 205  
             {
 206  0
                 if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
 207  
                 {
 208  0
                     this.unit.writeInstruction("<![CDATA[");
 209  
                 }
 210  
                 else
 211  
                 {
 212  0
                     this.consumingCDATA = true;
 213  0
                     this.swallowCDATAContent = this.unit.getFaceletsProcessingInstructions().isSwallowCDataContent();
 214  
                 }
 215  
             }
 216  0
         }
 217  
 
 218  
         public void startDocument() throws SAXException
 219  
         {
 220  0
             this.inDocument = true;
 221  0
         }
 222  
 
 223  
         public void startDTD(String name, String publicId, String systemId) throws SAXException
 224  
         {
 225  0
             if (this.inDocument && !unit.getFaceletsProcessingInstructions().isConsumeXmlDocType())
 226  
             {
 227  0
                 this.unit.writeDoctype(name, publicId, systemId);
 228  
                 /*
 229  
                 StringBuffer sb = new StringBuffer(64);
 230  
                 sb.append("<!DOCTYPE ").append(name);
 231  
                 if (publicId != null)
 232  
                 {
 233  
                     sb.append(" PUBLIC \"").append(publicId).append("\"");
 234  
                     if (systemId != null)
 235  
                     {
 236  
                         sb.append(" \"").append(systemId).append("\"");
 237  
                     }
 238  
                 }
 239  
                 else if (systemId != null)
 240  
                 {
 241  
                     sb.append(" SYSTEM \"").append(systemId).append("\"");
 242  
                 }
 243  
                 sb.append(" >\n");
 244  
                 this.unit.writeInstruction(sb.toString());
 245  
                 */
 246  
             }
 247  0
             this.inDocument = false;
 248  0
         }
 249  
 
 250  
         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
 251  
         {
 252  0
             this.unit.pushTag(new Tag(this.createLocation(), uri, localName, qName, this.createAttributes(attributes)));
 253  0
         }
 254  
 
 255  
         public void startEntity(String name) throws SAXException
 256  
         {
 257  0
         }
 258  
 
 259  
         public void startPrefixMapping(String prefix, String uri) throws SAXException
 260  
         {
 261  0
             this.unit.pushNamespace(prefix, uri);
 262  0
         }
 263  
 
 264  
         public void processingInstruction(String target, String data) throws SAXException
 265  
         {
 266  0
             if (this.inDocument && !this.unit.getFaceletsProcessingInstructions().isConsumeProcessingInstructions())
 267  
             {
 268  0
                 StringBuffer sb = new StringBuffer(64);
 269  0
                 sb.append("<?").append(target).append(' ').append(data).append("?>\n");
 270  0
                 this.unit.writeInstruction(sb.toString());
 271  
             }
 272  0
         }
 273  
     }
 274  
     
 275  
     /**
 276  
      * Like CompilationHandler but does not take into account everything outside f:metadata tag 
 277  
      * 
 278  
      * @since 2.0
 279  
      */
 280  
     private static class ViewMetadataHandler extends DefaultHandler implements LexicalHandler
 281  
     {
 282  
 
 283  
         private final String alias;
 284  
 
 285  0
         private boolean inDocument = false;
 286  
 
 287  
         private Locator locator;
 288  
 
 289  
         private final CompilationManager unit;
 290  
         
 291  0
         private boolean inMetadata = false;
 292  0
         private int uiRemoveCount = 0;
 293  
         
 294  0
         private boolean consumingCDATA = false;
 295  0
         private boolean swallowCDATAContent = false;
 296  
 
 297  
         public ViewMetadataHandler(CompilationManager unit, String alias)
 298  0
         {
 299  0
             this.unit = unit;
 300  0
             this.alias = alias;
 301  0
         }
 302  
 
 303  
         public void characters(char[] ch, int start, int length) throws SAXException
 304  
         {
 305  0
             if (this.inDocument && inMetadata && (!consumingCDATA || (consumingCDATA && !swallowCDATAContent)))
 306  
             {
 307  0
                 this.unit.writeText(new String(ch, start, length));
 308  
             }
 309  0
         }
 310  
 
 311  
         public void comment(char[] ch, int start, int length) throws SAXException
 312  
         {
 313  0
             if (this.inDocument && inMetadata && !unit.getFaceletsProcessingInstructions().isConsumeXMLComments())
 314  
             {
 315  0
                 this.unit.writeComment(new String(ch, start, length));
 316  
             }
 317  0
         }
 318  
 
 319  
         protected TagAttributes createAttributes(Attributes attrs)
 320  
         {
 321  0
             int len = attrs.getLength();
 322  0
             TagAttribute[] ta = new TagAttribute[len];
 323  0
             for (int i = 0; i < len; i++)
 324  
             {
 325  0
                 ta[i] = new TagAttributeImpl(this.createLocation(), attrs.getURI(i), attrs.getLocalName(i), attrs
 326  
                         .getQName(i), attrs.getValue(i));
 327  
             }
 328  0
             return new TagAttributesImpl(ta);
 329  
         }
 330  
 
 331  
         protected Location createLocation()
 332  
         {
 333  0
             return new Location(this.alias, this.locator.getLineNumber(), this.locator.getColumnNumber());
 334  
         }
 335  
 
 336  
         public void endCDATA() throws SAXException
 337  
         {
 338  0
             if (this.inDocument && inMetadata)
 339  
             {
 340  0
                 if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
 341  
                 {
 342  0
                     this.unit.writeInstruction("]]>");
 343  
                 }
 344  
                 else
 345  
                 {
 346  0
                     this.consumingCDATA = false;
 347  0
                     this.swallowCDATAContent = false;
 348  
                 }
 349  
             }
 350  0
         }
 351  
 
 352  
         public void endDTD() throws SAXException
 353  
         {
 354  0
             this.inDocument = true;
 355  0
         }
 356  
 
 357  
         public void endElement(String uri, String localName, String qName) throws SAXException
 358  
         {
 359  0
             if (inMetadata)
 360  
             {
 361  0
                 this.unit.popTag();
 362  
             }
 363  0
             if ( (CoreLibrary.NAMESPACE.equals(uri) ||
 364  
                 CoreLibrary.ALIAS_NAMESPACE.equals(uri)))
 365  
             {
 366  0
                 if ("metadata".equals(localName))
 367  
                 {
 368  0
                     this.inMetadata=false;
 369  
                 }
 370  0
                 else if (!inMetadata && "view".equals(localName))
 371  
                 {
 372  0
                     this.unit.popTag();
 373  
                 }
 374  
             }
 375  0
             else if (UILibrary.NAMESPACE.equals(uri) ||
 376  
                     UILibrary.ALIAS_NAMESPACE.equals(uri))
 377  
             {
 378  0
                 if (!inMetadata && "remove".equals(localName))
 379  
                 {
 380  0
                     this.uiRemoveCount--;
 381  
                 }
 382  
             }
 383  0
         }
 384  
 
 385  
         public void endEntity(String name) throws SAXException
 386  
         {
 387  0
         }
 388  
 
 389  
         public void endPrefixMapping(String prefix) throws SAXException
 390  
         {
 391  0
             this.unit.popNamespace(prefix);
 392  0
         }
 393  
 
 394  
         public void fatalError(SAXParseException e) throws SAXException
 395  
         {
 396  0
             if (this.locator != null)
 397  
             {
 398  0
                 throw new SAXException("Error Traced[line: " + this.locator.getLineNumber() + "] " + e.getMessage());
 399  
             }
 400  
             else
 401  
             {
 402  0
                 throw e;
 403  
             }
 404  
         }
 405  
 
 406  
         public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
 407  
         {
 408  0
             if (this.inDocument && inMetadata)
 409  
             {
 410  0
                 this.unit.writeWhitespace(new String(ch, start, length));
 411  
             }
 412  0
         }
 413  
 
 414  
         public InputSource resolveEntity(String publicId, String systemId) throws SAXException
 415  
         {
 416  0
             String dtd = "org/apache/myfaces/resource/default.dtd";
 417  
             /*
 418  
              * if ("-//W3C//DTD XHTML 1.0 Transitional//EN".equals(publicId)) { dtd = "xhtml1-transitional.dtd"; } else
 419  
              * if (systemId != null && systemId.startsWith("file:/")) { return new InputSource(systemId); }
 420  
              */
 421  0
             URL url = ClassUtils.getResource(dtd);
 422  0
             return new InputSource(url.toString());
 423  
         }
 424  
 
 425  
         public void setDocumentLocator(Locator locator)
 426  
         {
 427  0
             this.locator = locator;
 428  0
         }
 429  
 
 430  
         public void startCDATA() throws SAXException
 431  
         {
 432  0
             if (this.inDocument && inMetadata)
 433  
             {
 434  0
                 if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
 435  
                 {
 436  0
                     this.unit.writeInstruction("<![CDATA[");
 437  
                 }
 438  
                 else
 439  
                 {
 440  0
                     this.consumingCDATA = true;
 441  0
                     this.swallowCDATAContent = this.unit.getFaceletsProcessingInstructions().isSwallowCDataContent();
 442  
                 }
 443  
             }
 444  0
         }
 445  
 
 446  
         public void startDocument() throws SAXException
 447  
         {
 448  0
             this.inDocument = true;
 449  0
         }
 450  
 
 451  
         public void startDTD(String name, String publicId, String systemId) throws SAXException
 452  
         {
 453  
             // metadata does not require output doctype
 454  0
             this.inDocument = false;
 455  0
         }
 456  
 
 457  
         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
 458  
         {
 459  0
             if ( (CoreLibrary.NAMESPACE.equals(uri) ||
 460  
                   CoreLibrary.ALIAS_NAMESPACE.equals(uri)) && this.uiRemoveCount <= 0)
 461  
             {
 462  0
                 if ("metadata".equals(localName))
 463  
                 {
 464  0
                     this.inMetadata=true;
 465  
                 }
 466  0
                 else if (!inMetadata && "view".equals(localName))
 467  
                 {
 468  0
                     this.unit.pushTag(new Tag(createLocation(), uri, localName, qName, createAttributes(attributes)));
 469  
                 }
 470  
             }
 471  0
             if (inMetadata)
 472  
             {
 473  0
                 this.unit.pushTag(new Tag(createLocation(), uri, localName, qName, createAttributes(attributes)));
 474  
             }
 475  0
             else if (UILibrary.NAMESPACE.equals(uri) ||
 476  
                     UILibrary.ALIAS_NAMESPACE.equals(uri))
 477  
             {
 478  0
                 if ("remove".equals(localName))
 479  
                 {
 480  0
                     this.uiRemoveCount++;
 481  
                 }
 482  
             }
 483  0
         }
 484  
 
 485  
         public void startEntity(String name) throws SAXException
 486  
         {
 487  0
         }
 488  
 
 489  
         public void startPrefixMapping(String prefix, String uri) throws SAXException
 490  
         {
 491  0
             this.unit.pushNamespace(prefix, uri);
 492  0
         }
 493  
 
 494  
         public void processingInstruction(String target, String data) throws SAXException
 495  
         {
 496  0
             if (inDocument && inMetadata && !unit.getFaceletsProcessingInstructions().isConsumeProcessingInstructions())
 497  
             {
 498  0
                 StringBuffer sb = new StringBuffer(64);
 499  0
                 sb.append("<?").append(target).append(' ').append(data).append("?>\n");
 500  0
                 unit.writeInstruction(sb.toString());
 501  
             }
 502  0
         }        
 503  
     }
 504  
     
 505  
     /**
 506  
      * Like CompilationHandler but does not take into account everything outside cc:interface or cc:implementation tag.
 507  
      *  
 508  
      * Note inside cc:implementation it only takes into account cc:insertChildren, cc:insertFacet and cc:renderFacet,
 509  
      * all other tags, comments or text are just skipped.
 510  
      * 
 511  
      * @since 2.0.1
 512  
      */
 513  
     private static class CompositeComponentMetadataHandler extends DefaultHandler implements LexicalHandler
 514  
     {
 515  
 
 516  
         private final String alias;
 517  
 
 518  0
         private boolean inDocument = false;
 519  
 
 520  
         private Locator locator;
 521  
 
 522  
         private final CompilationManager unit;
 523  
         
 524  0
         private boolean inCompositeInterface = false;
 525  
         
 526  0
         private boolean inCompositeImplementation = false;
 527  
 
 528  0
         private boolean consumingCDATA = false;
 529  0
         private boolean swallowCDATAContent = false;
 530  
 
 531  
         public CompositeComponentMetadataHandler(CompilationManager unit, String alias)
 532  0
         {
 533  0
             this.unit = unit;
 534  0
             this.alias = alias;
 535  0
         }
 536  
 
 537  
         public void characters(char[] ch, int start, int length) throws SAXException
 538  
         {
 539  0
             if (this.inDocument && inCompositeInterface && 
 540  
                     (!consumingCDATA || (consumingCDATA && !swallowCDATAContent)))
 541  
             {
 542  0
                 this.unit.writeText(new String(ch, start, length));
 543  
             }
 544  0
         }
 545  
 
 546  
         public void comment(char[] ch, int start, int length) throws SAXException
 547  
         {
 548  0
             if (inDocument && inCompositeInterface && 
 549  
                     !unit.getFaceletsProcessingInstructions().isConsumeXMLComments())
 550  
             {
 551  0
                 this.unit.writeComment(new String(ch, start, length));
 552  
             }
 553  0
         }
 554  
 
 555  
         protected TagAttributes createAttributes(Attributes attrs)
 556  
         {
 557  0
             int len = attrs.getLength();
 558  0
             TagAttribute[] ta = new TagAttribute[len];
 559  0
             for (int i = 0; i < len; i++)
 560  
             {
 561  0
                 ta[i] = new TagAttributeImpl(this.createLocation(), attrs.getURI(i), attrs.getLocalName(i), attrs
 562  
                         .getQName(i), attrs.getValue(i));
 563  
             }
 564  0
             return new TagAttributesImpl(ta);
 565  
         }
 566  
 
 567  
         protected Location createLocation()
 568  
         {
 569  0
             return new Location(this.alias, this.locator.getLineNumber(), this.locator.getColumnNumber());
 570  
         }
 571  
 
 572  
         public void endCDATA() throws SAXException
 573  
         {
 574  0
             if (this.inDocument && inCompositeInterface)
 575  
             {
 576  0
                 if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
 577  
                 {
 578  0
                     this.unit.writeInstruction("]]>");
 579  
                 }
 580  
                 else
 581  
                 {
 582  0
                     this.consumingCDATA = false;
 583  0
                     this.swallowCDATAContent = false;
 584  
                 }
 585  
             }
 586  0
         }
 587  
 
 588  
         public void endDTD() throws SAXException
 589  
         {
 590  0
             this.inDocument = true;
 591  0
         }
 592  
 
 593  
         public void endElement(String uri, String localName, String qName) throws SAXException
 594  
         {
 595  0
             if (inCompositeInterface)
 596  
             {
 597  0
                 this.unit.popTag();
 598  
             }
 599  0
             else if (inCompositeImplementation && 
 600  
                 (CompositeLibrary.NAMESPACE.equals(uri) || CompositeLibrary.ALIAS_NAMESPACE.equals(uri)) )
 601  
             {
 602  0
                 if ( "insertFacet".equals(localName) ||
 603  
                      "renderFacet".equals(localName) ||
 604  
                      "insertChildren".equals(localName) || 
 605  
                      ImplementationHandler.NAME.equals(localName))
 606  
                 {
 607  0
                     this.unit.popTag();
 608  
                 }
 609  
             }
 610  
             
 611  0
             if (CompositeLibrary.NAMESPACE.equals(uri) || CompositeLibrary.ALIAS_NAMESPACE.equals(uri))
 612  
             {
 613  0
                 if (InterfaceHandler.NAME.equals(localName))
 614  
                 {
 615  0
                     this.inCompositeInterface=false;
 616  
                 }
 617  0
                 else if (ImplementationHandler.NAME.equals(localName))
 618  
                 {
 619  0
                     this.inCompositeImplementation=false;
 620  
                 }
 621  
             }
 622  0
         }
 623  
 
 624  
         public void endEntity(String name) throws SAXException
 625  
         {
 626  0
         }
 627  
 
 628  
         public void endPrefixMapping(String prefix) throws SAXException
 629  
         {
 630  0
             this.unit.popNamespace(prefix);
 631  0
         }
 632  
 
 633  
         public void fatalError(SAXParseException e) throws SAXException
 634  
         {
 635  0
             if (this.locator != null)
 636  
             {
 637  0
                 throw new SAXException("Error Traced[line: " + this.locator.getLineNumber() + "] " + e.getMessage());
 638  
             }
 639  
             else
 640  
             {
 641  0
                 throw e;
 642  
             }
 643  
         }
 644  
 
 645  
         public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
 646  
         {
 647  0
             if (this.inDocument && inCompositeInterface)
 648  
             {
 649  0
                 this.unit.writeWhitespace(new String(ch, start, length));
 650  
             }
 651  0
         }
 652  
 
 653  
         public InputSource resolveEntity(String publicId, String systemId) throws SAXException
 654  
         {
 655  0
             String dtd = "org/apache/myfaces/resource/default.dtd";
 656  
             /*
 657  
              * if ("-//W3C//DTD XHTML 1.0 Transitional//EN".equals(publicId)) { dtd = "xhtml1-transitional.dtd"; } else
 658  
              * if (systemId != null && systemId.startsWith("file:/")) { return new InputSource(systemId); }
 659  
              */
 660  0
             URL url = ClassUtils.getResource(dtd);
 661  0
             return new InputSource(url.toString());
 662  
         }
 663  
 
 664  
         public void setDocumentLocator(Locator locator)
 665  
         {
 666  0
             this.locator = locator;
 667  0
         }
 668  
 
 669  
         public void startCDATA() throws SAXException
 670  
         {
 671  0
             if (this.inDocument && inCompositeInterface)
 672  
             {
 673  0
                 if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
 674  
                 {
 675  0
                     this.unit.writeInstruction("<![CDATA[");
 676  
                 }
 677  
                 else
 678  
                 {
 679  0
                     this.consumingCDATA = true;
 680  0
                     this.swallowCDATAContent = this.unit.getFaceletsProcessingInstructions().isSwallowCDataContent();
 681  
                 }
 682  
             }
 683  0
         }
 684  
 
 685  
         public void startDocument() throws SAXException
 686  
         {
 687  0
             this.inDocument = true;
 688  0
         }
 689  
 
 690  
         public void startDTD(String name, String publicId, String systemId) throws SAXException
 691  
         {
 692  
             // metadata does not require output doctype
 693  0
             this.inDocument = false;
 694  0
         }
 695  
 
 696  
         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
 697  
         {
 698  0
             if (CompositeLibrary.NAMESPACE.equals(uri) || CompositeLibrary.ALIAS_NAMESPACE.equals(uri))
 699  
             {
 700  0
                 if (InterfaceHandler.NAME.equals(localName))
 701  
                 {
 702  0
                     this.inCompositeInterface=true;
 703  
                 }
 704  0
                 else if (ImplementationHandler.NAME.equals(localName))
 705  
                 {
 706  0
                     this.inCompositeImplementation=true;
 707  
                 }
 708  
             }
 709  
             
 710  0
             if (inCompositeInterface)
 711  
             {
 712  0
                 this.unit.pushTag(new Tag(createLocation(), uri, localName, qName, createAttributes(attributes)));
 713  
             }
 714  0
             else if (inCompositeImplementation && 
 715  
                 (CompositeLibrary.NAMESPACE.equals(uri) || CompositeLibrary.ALIAS_NAMESPACE.equals(uri)))
 716  
             {
 717  0
                 if ("insertFacet".equals(localName)    ||
 718  
                     "renderFacet".equals(localName)    ||
 719  
                     "insertChildren".equals(localName) ||
 720  
                     ImplementationHandler.NAME.equals(localName)   )
 721  
                 {
 722  0
                     this.unit.pushTag(new Tag(createLocation(), uri, localName, qName, createAttributes(attributes)));
 723  
                 }
 724  
             }
 725  0
         }
 726  
 
 727  
         public void startEntity(String name) throws SAXException
 728  
         {
 729  0
         }
 730  
 
 731  
         public void startPrefixMapping(String prefix, String uri) throws SAXException
 732  
         {
 733  0
             this.unit.pushNamespace(prefix, uri);
 734  0
         }
 735  
 
 736  
         public void processingInstruction(String target, String data) throws SAXException
 737  
         {
 738  0
             if (inDocument && inCompositeInterface
 739  
                 && !unit.getFaceletsProcessingInstructions().isConsumeProcessingInstructions())
 740  
             {
 741  0
                 StringBuffer sb = new StringBuffer(64);
 742  0
                 sb.append("<?").append(target).append(' ').append(data).append("?>\n");
 743  0
                 this.unit.writeInstruction(sb.toString());
 744  
             }
 745  0
         }        
 746  
     }
 747  
 
 748  
     public SAXCompiler()
 749  
     {
 750  0
         super();
 751  0
     }
 752  
 
 753  
     public FaceletHandler doCompile(URL src, String alias)
 754  
             throws IOException, FaceletException, ELException, FacesException
 755  
     {
 756  0
         CompilationManager mngr = null;
 757  0
         InputStream is = null;
 758  0
         String encoding = null;
 759  
         try
 760  
         {
 761  0
             is = new BufferedInputStream(src.openStream(), 1024);
 762  0
             mngr = new CompilationManager(alias, this, getFaceletsProcessingInstructions(src, alias));
 763  0
             encoding = writeXmlDecl(is, mngr);
 764  0
             CompilationHandler handler = new CompilationHandler(mngr, alias);
 765  0
             SAXParser parser = this.createSAXParser(handler);
 766  0
             parser.parse(is, handler);
 767  
         }
 768  0
         catch (SAXException e)
 769  
         {
 770  0
             throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
 771  
         }
 772  0
         catch (ParserConfigurationException e)
 773  
         {
 774  0
             throw new FaceletException("Error Configuring Parser " + alias + ": " + e.getMessage(), e.getCause());
 775  
         }
 776  
         finally
 777  
         {
 778  0
             if (is != null)
 779  
             {
 780  0
                 is.close();
 781  
             }
 782  
         }
 783  0
         return new EncodingHandler(mngr.createFaceletHandler(), encoding);
 784  
     }
 785  
 
 786  
     /**
 787  
      * @since 2.0
 788  
      */
 789  
     @Override
 790  
     protected FaceletHandler doCompileViewMetadata(URL src, String alias)
 791  
             throws IOException, FaceletException, ELException, FacesException
 792  
     {
 793  0
         CompilationManager mngr = null;
 794  0
         InputStream is = null;
 795  0
         String encoding = null;
 796  
         try
 797  
         {
 798  0
             is = new BufferedInputStream(src.openStream(), 1024);
 799  0
             mngr = new CompilationManager(alias, this, getFaceletsProcessingInstructions(src, alias));
 800  0
             encoding = getXmlDecl(is, mngr);
 801  0
             final ViewMetadataHandler handler = new ViewMetadataHandler(mngr, alias);
 802  0
             final SAXParser parser = this.createSAXParser(handler);
 803  
             
 804  0
             if (System.getSecurityManager() != null)
 805  
             {
 806  
                 try
 807  
                 {
 808  0
                     final InputStream finalInputStream = is;
 809  0
                     AccessController.doPrivileged(new PrivilegedExceptionAction() 
 810  0
                     {
 811  
                         public Object run() throws SAXException, IOException 
 812  
                         {
 813  0
                             parser.parse(finalInputStream, handler);
 814  0
                             return null; 
 815  
                         }
 816  
                     });
 817  
                 }
 818  0
                 catch (PrivilegedActionException pae)
 819  
                 {
 820  0
                     Exception e = pae.getException();
 821  0
                     if(e instanceof SAXException)
 822  
                     {
 823  0
                         throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
 824  
                     } 
 825  0
                     else if(e instanceof IOException)
 826  
                     {
 827  0
                         throw (IOException)e;
 828  
                     }
 829  0
                 }
 830  
             }
 831  
             else
 832  
             {
 833  0
                 parser.parse(is, handler);
 834  
             }
 835  
         }
 836  0
         catch (SAXException e)
 837  
         {
 838  0
             throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
 839  
         }
 840  0
         catch (ParserConfigurationException e)
 841  
         {
 842  0
             throw new FaceletException("Error Configuring Parser " + alias + ": " + e.getMessage(), e.getCause());
 843  
         }
 844  
         finally
 845  
         {
 846  0
             if (is != null)
 847  
             {
 848  0
                 is.close();
 849  
             }
 850  
         }
 851  0
         return new EncodingHandler(mngr.createFaceletHandler(), encoding);
 852  
     }
 853  
 
 854  
     /**
 855  
      * @since 2.0.1
 856  
      */
 857  
     @Override
 858  
     protected FaceletHandler doCompileCompositeComponentMetadata(URL src, String alias)
 859  
             throws IOException, FaceletException, ELException, FacesException
 860  
     {
 861  0
         CompilationManager mngr = null;
 862  0
         InputStream is = null;
 863  0
         String encoding = null;
 864  
         try
 865  
         {
 866  0
             is = new BufferedInputStream(src.openStream(), 1024);
 867  0
             mngr = new CompilationManager(alias, this, getFaceletsProcessingInstructions(src, alias));
 868  0
             encoding = getXmlDecl(is, mngr);
 869  0
             CompositeComponentMetadataHandler handler = new CompositeComponentMetadataHandler(mngr, alias);
 870  0
             SAXParser parser = this.createSAXParser(handler);
 871  0
             parser.parse(is, handler);
 872  
         }
 873  0
         catch (SAXException e)
 874  
         {
 875  0
             throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
 876  
         }
 877  0
         catch (ParserConfigurationException e)
 878  
         {
 879  0
             throw new FaceletException("Error Configuring Parser " + alias + ": " + e.getMessage(), e.getCause());
 880  
         }
 881  
         finally
 882  
         {
 883  0
             if (is != null)
 884  
             {
 885  0
                 is.close();
 886  
             }
 887  
         }
 888  0
         return new EncodingHandler(mngr.createFaceletHandler(), encoding);
 889  
     }
 890  
     
 891  
     @Override
 892  
     protected FaceletHandler doCompileComponent(
 893  
         String taglibURI, String tagName, Map<String, Object> attributes)
 894  
     {
 895  0
         String alias = tagName;
 896  0
         CompilationManager mngr = new CompilationManager(alias, this, getDefaultFaceletsProcessingInstructions());
 897  0
         String prefix = "oamf"; // The prefix is only a logical name.
 898  0
         mngr.pushNamespace(prefix, taglibURI);
 899  
         
 900  0
         boolean tagContainParams = ( 
 901  
                 ("include".equals(tagName) || "decorate".equals(tagName) || "composition".equals(tagName)) && 
 902  
                 (UILibrary.NAMESPACE.equals(taglibURI) || UILibrary.ALIAS_NAMESPACE.equals(taglibURI)) );
 903  
         
 904  0
         Location location = new Location(alias, 0, 0);
 905  0
         int len = attributes.size();
 906  0
         if (tagContainParams && attributes.containsKey("params"))
 907  
         {
 908  0
             len = len-1;
 909  
         }
 910  
         
 911  0
         TagAttribute[] ta = new TagAttribute[len];
 912  0
         int i = 0;
 913  0
         Map<String, Object> paramsMap = null;
 914  0
         for (Map.Entry<String, Object> entry : attributes.entrySet())
 915  
         {
 916  0
             String stringValue = null;
 917  
             
 918  0
             if (tagContainParams && "params".equals(entry.getKey()))
 919  
             {
 920  0
                 paramsMap = (Map<String, Object>) entry.getValue();
 921  
             }
 922  
             else
 923  
             {
 924  0
                 if (entry.getValue() instanceof ValueExpression)
 925  
                 {
 926  0
                     stringValue = ((ValueExpression)entry.getValue()).getExpressionString();
 927  
                 }
 928  0
                 else if (entry.getValue() instanceof MethodExpression)
 929  
                 {
 930  0
                     stringValue = ((MethodExpression)entry.getValue()).getExpressionString();
 931  
                 }
 932  0
                 else if (entry.getValue() != null)
 933  
                 {
 934  0
                     stringValue = entry.getValue().toString();
 935  
                 }
 936  0
                 ta[i] = new TagAttributeImpl(location, "", entry.getKey(), entry.getKey(), stringValue);
 937  0
                 i++;
 938  
             }
 939  0
         }        
 940  0
         mngr.pushTag(new Tag(location, taglibURI, tagName, "oamf:"+tagName, new TagAttributesImpl(ta)));
 941  
         
 942  0
         if (tagContainParams && paramsMap != null)
 943  
         {
 944  0
             for (Map.Entry<String, Object> entry : paramsMap.entrySet())
 945  
             {
 946  0
                 TagAttribute[] tap = new TagAttribute[2];
 947  0
                 String stringValue = null;
 948  0
                 if (entry.getValue() instanceof ValueExpression)
 949  
                 {
 950  0
                     stringValue = ((ValueExpression)entry.getValue()).getExpressionString();
 951  
                 }
 952  0
                 else if (entry.getValue() instanceof MethodExpression)
 953  
                 {
 954  0
                     stringValue = ((MethodExpression)entry.getValue()).getExpressionString();
 955  
                 }
 956  0
                 else if (entry.getValue() != null)
 957  
                 {
 958  0
                     stringValue = entry.getValue().toString();
 959  
                 }
 960  0
                 tap[0] = new TagAttributeImpl(location, "", "name", "name", entry.getKey());
 961  0
                 tap[1] = new TagAttributeImpl(location, "", "value", "value", stringValue);
 962  0
                 mngr.pushTag(new Tag(location, UILibrary.NAMESPACE, "param", "oamf:param", new TagAttributesImpl(tap)));
 963  0
                 mngr.popTag();
 964  0
             }
 965  
         }
 966  0
         mngr.popTag();
 967  0
         mngr.popNamespace(prefix);
 968  
         
 969  0
         FaceletHandler handler = new DynamicComponentFacelet((NamespaceHandler) mngr.createFaceletHandler());
 970  0
         return handler;
 971  
     }
 972  
     
 973  
     protected FaceletsProcessingInstructions getDefaultFaceletsProcessingInstructions()
 974  
     {
 975  0
         return FaceletsProcessingInstructions.getProcessingInstructions(FaceletsProcessing.PROCESS_AS_XHTML, false);
 976  
     }
 977  
     
 978  
     protected FaceletsProcessingInstructions getFaceletsProcessingInstructions(URL src, String alias)
 979  
     {
 980  0
         String processAs = null;
 981  0
         boolean compressSpaces = false;
 982  0
         for (FaceletsProcessing entry : getFaceletsProcessingConfigurations())
 983  
         {
 984  0
             if (src.getPath().endsWith(entry.getFileExtension()))
 985  
             {
 986  0
                 processAs = entry.getProcessAs();
 987  0
                 compressSpaces = Boolean.valueOf(entry.getOamCompressSpaces());
 988  0
                 break;
 989  
             }
 990  0
         }
 991  0
         return FaceletsProcessingInstructions.getProcessingInstructions(processAs, compressSpaces);
 992  
     }
 993  
 
 994  
     protected static String writeXmlDecl(InputStream is, CompilationManager mngr) throws IOException
 995  
     {
 996  0
         is.mark(128);
 997  0
         String encoding = null;
 998  
         try
 999  
         {
 1000  0
             byte[] b = new byte[128];
 1001  0
             if (is.read(b) > 0)
 1002  
             {
 1003  0
                 String r = new String(b);
 1004  0
                 Matcher m = XML_DECLARATION.matcher(r);
 1005  0
                 if (m.find())
 1006  
                 {
 1007  0
                     if (!mngr.getFaceletsProcessingInstructions().isConsumeXmlDeclaration())
 1008  
                     {
 1009  0
                         mngr.writeInstruction(m.group(0) + "\n");
 1010  
                     }
 1011  0
                     if (m.group(3) != null)
 1012  
                     {
 1013  0
                         encoding = m.group(3);
 1014  
                     }
 1015  
                 }
 1016  
             }
 1017  
         }
 1018  
         finally
 1019  
         {
 1020  0
             is.reset();
 1021  0
         }
 1022  0
         return encoding;
 1023  
     }
 1024  
     
 1025  
     protected static String getXmlDecl(InputStream is, CompilationManager mngr) throws IOException
 1026  
     {
 1027  0
         is.mark(128);
 1028  0
         String encoding = null;
 1029  
         try
 1030  
         {
 1031  0
             byte[] b = new byte[128];
 1032  0
             if (is.read(b) > 0)
 1033  
             {
 1034  0
                 String r = new String(b);
 1035  0
                 Matcher m = XML_DECLARATION.matcher(r);
 1036  0
                 if (m.find() && m.group(3) != null)
 1037  
                 {
 1038  0
                     encoding = m.group(3);
 1039  
                 }
 1040  
             }
 1041  
         }
 1042  
         finally
 1043  
         {
 1044  0
             is.reset();
 1045  0
         }
 1046  0
         return encoding;
 1047  
     }
 1048  
 
 1049  
     private SAXParser createSAXParser(DefaultHandler handler) throws SAXException,
 1050  
             ParserConfigurationException
 1051  
     {
 1052  0
         SAXParserFactory factory = SAXParserFactory.newInstance();
 1053  0
         factory.setNamespaceAware(true);
 1054  0
         factory.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
 1055  0
         factory.setFeature("http://xml.org/sax/features/validation", this.isValidating());
 1056  0
         factory.setValidating(this.isValidating());
 1057  0
         SAXParser parser = factory.newSAXParser();
 1058  0
         XMLReader reader = parser.getXMLReader();
 1059  0
         reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
 1060  0
         reader.setErrorHandler(handler);
 1061  0
         reader.setEntityResolver(handler);
 1062  0
         return parser;
 1063  
     }
 1064  
 
 1065  
 }