Coverage Report - org.apache.myfaces.config.ConfigFilesXmlValidationUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
ConfigFilesXmlValidationUtils
0%
0/92
0%
0/28
2.471
ConfigFilesXmlValidationUtils$1
N/A
N/A
2.471
ConfigFilesXmlValidationUtils$FacesConfigVersionCheckHandler
0%
0/22
0%
0/18
2.471
ConfigFilesXmlValidationUtils$LSInputImpl
0%
0/22
N/A
2.471
ConfigFilesXmlValidationUtils$ValidationErrorHandler
0%
0/8
N/A
2.471
ConfigFilesXmlValidationUtils$ValidatorLSResourceResolver
0%
0/11
0%
0/14
2.471
ConfigFilesXmlValidationUtils$VersionCheckHandler
0%
0/10
0%
0/10
2.471
 
 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.config;
 20  
 
 21  
 import java.io.IOException;
 22  
 import java.io.InputStream;
 23  
 import java.io.Reader;
 24  
 import java.net.URL;
 25  
 import java.net.URLConnection;
 26  
 import java.util.logging.Level;
 27  
 import java.util.logging.Logger;
 28  
 
 29  
 import javax.faces.context.ExternalContext;
 30  
 import javax.xml.XMLConstants;
 31  
 import javax.xml.parsers.ParserConfigurationException;
 32  
 import javax.xml.parsers.SAXParser;
 33  
 import javax.xml.parsers.SAXParserFactory;
 34  
 import javax.xml.transform.Source;
 35  
 import javax.xml.transform.stream.StreamSource;
 36  
 import javax.xml.validation.Schema;
 37  
 import javax.xml.validation.SchemaFactory;
 38  
 import javax.xml.validation.Validator;
 39  
 
 40  
 import org.apache.myfaces.shared.util.ClassUtils;
 41  
 import org.w3c.dom.ls.LSInput;
 42  
 import org.w3c.dom.ls.LSResourceResolver;
 43  
 import org.xml.sax.Attributes;
 44  
 import org.xml.sax.ErrorHandler;
 45  
 import org.xml.sax.SAXException;
 46  
 import org.xml.sax.SAXParseException;
 47  
 import org.xml.sax.helpers.DefaultHandler;
 48  
 
 49  0
 public class ConfigFilesXmlValidationUtils
 50  
 {
 51  0
     public final static LSResourceResolver JAVAEE_5_LS_RESOURCE_RESOLVER = new ValidatorLSResourceResolver();
 52  0
     public final static ErrorHandler VALIDATION_ERROR_HANDLER = new ValidationErrorHandler(); 
 53  
 
 54  
     private final static String FACES_CONFIG_SCHEMA_PATH_12 = "org/apache/myfaces/resource/web-facesconfig_1_2.xsd";
 55  
     private final static String FACES_CONFIG_SCHEMA_PATH_20 = "org/apache/myfaces/resource/web-facesconfig_2_0.xsd";
 56  
     private final static String FACES_CONFIG_SCHEMA_PATH_21 = "org/apache/myfaces/resource/web-facesconfig_2_1.xsd";
 57  
     private final static String FACES_TAGLIB_SCHEMA_PATH = "org/apache/myfaces/resource/web-facelettaglibrary_2_0.xsd";
 58  
 
 59  
     public static class LSInputImpl implements LSInput
 60  
     {
 61  
         private final String _publicId;
 62  
         private final String _systemId;
 63  
         private final String _baseURI;
 64  
         private final InputStream _input;
 65  
         
 66  
         public LSInputImpl(String publicId,
 67  
                 String systemId, String baseURI, InputStream input)
 68  
         {
 69  0
             super();
 70  0
             _publicId = publicId;
 71  0
             _systemId = systemId;
 72  0
             _baseURI = baseURI;
 73  0
             _input = input;
 74  0
         }
 75  
 
 76  
         public String getBaseURI()
 77  
         {
 78  0
             return _baseURI;
 79  
         }
 80  
 
 81  
         public InputStream getByteStream()
 82  
         {
 83  0
             return _input;
 84  
         }
 85  
 
 86  
         public boolean getCertifiedText()
 87  
         {
 88  0
             return false;
 89  
         }
 90  
 
 91  
         public Reader getCharacterStream()
 92  
         {
 93  0
             return null;
 94  
         }
 95  
 
 96  
         public String getEncoding()
 97  
         {
 98  0
             return null;
 99  
         }
 100  
 
 101  
         public String getPublicId()
 102  
         {
 103  0
             return _publicId;
 104  
         }
 105  
 
 106  
         public String getStringData()
 107  
         {
 108  0
             return null;
 109  
         }
 110  
 
 111  
         public String getSystemId()
 112  
         {
 113  0
             return _systemId;
 114  
         }
 115  
 
 116  
         public void setBaseURI(String baseURI)
 117  
         {
 118  0
         }
 119  
 
 120  
         public void setByteStream(InputStream byteStream)
 121  
         {
 122  0
         }
 123  
 
 124  
         public void setCertifiedText(boolean certifiedText)
 125  
         {
 126  0
         }
 127  
 
 128  
         public void setCharacterStream(Reader characterStream)
 129  
         {
 130  0
         }
 131  
 
 132  
         public void setEncoding(String encoding)
 133  
         {
 134  0
         }
 135  
 
 136  
         public void setPublicId(String publicId)
 137  
         {
 138  0
         }
 139  
 
 140  
         public void setStringData(String stringData)
 141  
         {
 142  0
         }
 143  
 
 144  
         public void setSystemId(String systemId)
 145  
         {
 146  0
         }
 147  
     }
 148  
     
 149  0
     public static class ValidatorLSResourceResolver implements LSResourceResolver
 150  
     {
 151  
 
 152  
         public LSInput resolveResource(String type, String namespaceURI,
 153  
                 String publicId, String systemId, String baseURI)
 154  
         {
 155  0
             if ("http://www.w3.org/TR/REC-xml".equals(type) && "datatypes.dtd".equals(systemId))
 156  
             {
 157  0
                 return new LSInputImpl(publicId, systemId, baseURI,
 158  
                         ClassUtils.getResourceAsStream("org/apache/myfaces/resource/datatypes.dtd"));
 159  
             }
 160  0
             if ("-//W3C//DTD XMLSCHEMA 200102//EN".equals(publicId) && "XMLSchema.dtd".equals(systemId))
 161  
             {
 162  0
                 return new LSInputImpl(publicId, systemId, baseURI,
 163  
                         ClassUtils.getResourceAsStream("org/apache/myfaces/resource/XMLSchema.dtd"));
 164  
             }
 165  0
             if ("http://java.sun.com/xml/ns/javaee".equals(namespaceURI))
 166  
             {
 167  0
                 if ("javaee_5.xsd".equals(systemId))
 168  
                 {
 169  0
                     return new LSInputImpl(publicId, systemId, baseURI,
 170  
                             ClassUtils.getResourceAsStream("org/apache/myfaces/resource/javaee_5.xsd"));
 171  
                 }
 172  
             }
 173  0
             if ("http://www.w3.org/XML/1998/namespace".equals(namespaceURI))
 174  
             {
 175  0
                 return new LSInputImpl(publicId, systemId, baseURI,
 176  
                         ClassUtils.getResourceAsStream("org/apache/myfaces/resource/xml.xsd"));
 177  
             }
 178  0
             return null;
 179  
         }
 180  
         
 181  
     } 
 182  
     
 183  0
     public static class ValidationErrorHandler implements ErrorHandler
 184  
     {
 185  
         public void fatalError(SAXParseException exception) throws SAXException
 186  
         {
 187  0
             throw exception;
 188  
         }
 189  
         
 190  
         public void error(SAXParseException exception) throws SAXException
 191  
         {
 192  0
             Logger log = Logger.getLogger(ConfigFilesXmlValidationUtils.class.getName());
 193  0
             log.log(Level.SEVERE, exception.getMessage(), exception);
 194  0
         }
 195  
 
 196  
         public void warning(SAXParseException exception) throws SAXException
 197  
         {
 198  0
             Logger log = Logger.getLogger(ConfigFilesXmlValidationUtils.class.getName());
 199  0
             log.log(Level.WARNING, exception.getMessage(), exception);
 200  0
         }
 201  
     }
 202  
     
 203  
     public static void validateFacesConfigFile(URL xmlFile,
 204  
             ExternalContext externalContext, String version) throws SAXException, IOException
 205  
     {
 206  0
         SchemaFactory schemaFactory = SchemaFactory
 207  
                 .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
 208  
 
 209  0
         Source schemaFile = getFacesConfigSchemaFileAsSource(externalContext, version);
 210  0
         if (schemaFile == null)
 211  
         {
 212  0
             throw new IOException("Could not find schema file for validation.");
 213  
         }
 214  
         
 215  0
         schemaFactory.setResourceResolver(JAVAEE_5_LS_RESOURCE_RESOLVER);
 216  0
         Schema schema = schemaFactory.newSchema(schemaFile);
 217  
 
 218  0
         Validator validator = schema.newValidator();
 219  0
         URLConnection conn = xmlFile.openConnection();
 220  0
         conn.setUseCaches(false);
 221  0
         InputStream is = conn.getInputStream();
 222  0
         Source source = new StreamSource(is);
 223  0
         validator.setErrorHandler(VALIDATION_ERROR_HANDLER);
 224  0
         validator.validate(source);
 225  0
     }
 226  
 
 227  
     private static Source getFacesConfigSchemaFileAsSource(ExternalContext externalContext, String version)
 228  
     {
 229  0
         String xmlSchema = "1.2".equals(version)
 230  
                             ? FACES_CONFIG_SCHEMA_PATH_12
 231  
                             : ("2.0".equals(version) ? FACES_CONFIG_SCHEMA_PATH_20 : FACES_CONFIG_SCHEMA_PATH_21);
 232  
         
 233  0
         InputStream stream = ClassUtils.getResourceAsStream(xmlSchema);
 234  
         
 235  0
         if (stream == null)
 236  
         {
 237  0
            stream = externalContext.getResourceAsStream(xmlSchema);
 238  
         }
 239  
 
 240  0
         if (stream == null)
 241  
         {
 242  0
             return null;
 243  
         }
 244  
         
 245  0
         return new StreamSource(stream);
 246  
     }
 247  
 
 248  
     public static final String getFacesConfigVersion(URL url)
 249  
     {
 250  0
         URLConnection conn = null;
 251  0
         InputStream input = null;
 252  0
         String result = "2.0";
 253  
 
 254  
         try
 255  
         {
 256  0
             SAXParserFactory factory = SAXParserFactory.newInstance();
 257  
             SAXParser parser;
 258  0
             FacesConfigVersionCheckHandler handler = new FacesConfigVersionCheckHandler();
 259  
 
 260  
             // We need to create a non-validating, non-namespace aware parser used to simply check
 261  
             // which version of the facelets taglib document we are dealing with.
 262  
 
 263  0
             factory.setNamespaceAware(false);
 264  0
             factory.setFeature("http://xml.org/sax/features/validation", false);
 265  0
             factory.setValidating(false);
 266  
 
 267  0
             parser = factory.newSAXParser();
 268  
 
 269  0
             conn = url.openConnection();
 270  0
             conn.setUseCaches(false);
 271  0
             input = conn.getInputStream();
 272  
 
 273  
             try
 274  
             {
 275  0
                 parser.parse(input, handler);
 276  
             }
 277  
 
 278  0
             catch (SAXException e)
 279  
             {
 280  
                 // This is as a result of our aborted parse, so ignore.
 281  0
             }
 282  
 
 283  0
             result = handler.isVersion21OrLater() ? "2.1" : (handler.isVersion20() ? "2.0" : (handler
 284  
                     .isVersion12() ? "1.2" : "1.1"));
 285  
         }
 286  
 
 287  0
         catch (Throwable e)
 288  
         {
 289  
             // Most likely a result of our aborted parse, so ignore.
 290  
         }
 291  
 
 292  
         finally
 293  
         {
 294  0
             if (input != null)
 295  
             {
 296  
                 try
 297  
                 {
 298  0
                     input.close();
 299  
                 }
 300  
 
 301  0
                 catch (Throwable e)
 302  
                 {
 303  0
                 }
 304  
             }
 305  
         }
 306  
 
 307  0
         return result;
 308  
     }
 309  
 
 310  0
     private static class FacesConfigVersionCheckHandler extends DefaultHandler
 311  
     {
 312  
         private boolean version12;
 313  
         private boolean version20;
 314  
         private boolean version21OrLater;
 315  
 
 316  
         public boolean isVersion12()
 317  
         {
 318  0
             return this.version12;
 319  
         }
 320  
 
 321  
         public boolean isVersion20()
 322  
         {
 323  0
             return this.version20 || this.version21OrLater;
 324  
         }
 325  
         
 326  
         public boolean isVersion21OrLater()
 327  
         {
 328  0
             return version21OrLater;
 329  
         }
 330  
 
 331  
         @Override
 332  
         public void startElement(String uri, String localName, String name,
 333  
                 Attributes attributes) throws SAXException
 334  
         {
 335  0
             if (name.equals("faces-config"))
 336  
             {
 337  0
                 int length = attributes.getLength();
 338  
 
 339  0
                 for (int i = 0; i < length; i++)
 340  
                 {
 341  0
                     String attrName = attributes.getLocalName(i);
 342  0
                     attrName = (attrName != null) ? ((attrName.length() > 0) ? attrName
 343  
                             : attributes.getQName(i))
 344  
                             : attributes.getQName(i);
 345  0
                     if (attrName.equals("version"))
 346  
                     {
 347  0
                         if (attributes.getValue(i).equals("1.2"))
 348  
                         {
 349  0
                             this.version12 = true;
 350  0
                             this.version20 = false;
 351  0
                             this.version21OrLater = false;
 352  
                         }
 353  0
                         else if (attributes.getValue(i).equals("2.0"))
 354  
                         {
 355  0
                             this.version21OrLater = false;
 356  0
                             this.version20 = true;
 357  0
                             this.version12 = false;
 358  
                         }
 359  
                         else
 360  
                         {
 361  0
                             this.version21OrLater = true;
 362  0
                             this.version20 = false;
 363  0
                             this.version12 = false;
 364  
                         }
 365  
                     }
 366  
                 }
 367  
             }
 368  0
         }
 369  
     }
 370  
     
 371  
     public static void validateFaceletTagLibFile(URL xmlFile, ExternalContext externalContext, String version)
 372  
         throws SAXException, IOException, ParserConfigurationException
 373  
     {
 374  0
         SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
 375  
         
 376  0
         Source schemaFile = getFaceletSchemaFileAsSource(externalContext);
 377  0
         if (schemaFile == null)
 378  
         {
 379  0
             throw new IOException("Could not find schema file for validation.");
 380  
         }
 381  0
         schemaFactory.setResourceResolver(ConfigFilesXmlValidationUtils.JAVAEE_5_LS_RESOURCE_RESOLVER);
 382  0
         Schema schema = schemaFactory.newSchema(schemaFile);
 383  
     
 384  0
         Validator validator = schema.newValidator();
 385  0
         URLConnection conn = xmlFile.openConnection();
 386  0
         conn.setUseCaches(false);
 387  0
         InputStream is = conn.getInputStream();
 388  0
         Source source = new StreamSource(is);
 389  0
         validator.setErrorHandler(VALIDATION_ERROR_HANDLER);
 390  0
         validator.validate(source);
 391  0
     }
 392  
     
 393  
     private static Source getFaceletSchemaFileAsSource(ExternalContext externalContext)
 394  
     {
 395  0
         InputStream stream = ClassUtils.getResourceAsStream(FACES_TAGLIB_SCHEMA_PATH);
 396  
         
 397  0
         if (stream == null)
 398  
         {
 399  0
            stream = externalContext.getResourceAsStream(FACES_TAGLIB_SCHEMA_PATH);
 400  
         }
 401  
     
 402  0
         if (stream == null)
 403  
         {
 404  0
             return null;
 405  
         }
 406  
         
 407  0
         return new StreamSource(stream);
 408  
     }
 409  
     
 410  
     public static final String getFaceletTagLibVersion(URL url)
 411  
     {
 412  0
         if (isTaglibDocument20OrLater(url))
 413  
         {
 414  0
             return "2.0";
 415  
         }
 416  
         else
 417  
         {
 418  0
             return "1.0";
 419  
         }
 420  
     }
 421  
 
 422  
     private static final boolean isTaglibDocument20OrLater (URL url)
 423  
     {
 424  0
         URLConnection conn = null;
 425  0
         InputStream input = null;
 426  0
         boolean result = false;
 427  
         
 428  
         try
 429  
         {
 430  0
             SAXParserFactory factory = SAXParserFactory.newInstance();
 431  
             SAXParser parser;
 432  0
             VersionCheckHandler handler = new VersionCheckHandler();
 433  
             
 434  
             // We need to create a non-validating, non-namespace aware parser used to simply check
 435  
             // which version of the facelets taglib document we are dealing with.
 436  
 
 437  0
             factory.setNamespaceAware(false);
 438  0
             factory.setFeature("http://xml.org/sax/features/validation", false);
 439  0
             factory.setValidating(false);
 440  
             
 441  0
             parser = factory.newSAXParser();
 442  
             
 443  0
             conn = url.openConnection();
 444  0
             conn.setUseCaches(false);
 445  0
             input = conn.getInputStream();
 446  
             
 447  
             try
 448  
             {
 449  0
                 parser.parse (input, handler);
 450  
             }
 451  
             
 452  0
             catch (SAXException e)
 453  
             {
 454  
                 // This is as a result of our aborted parse, so ignore.
 455  0
             }
 456  
             
 457  0
             result = handler.isVersion20OrLater();
 458  
         }
 459  
         
 460  0
         catch (Throwable e)
 461  
         {
 462  
             // Most likely a result of our aborted parse, so ignore.
 463  
         }
 464  
         
 465  
         finally
 466  
         {
 467  0
             if (input != null)
 468  
             {
 469  
                 try
 470  
                 {
 471  0
                     input.close();
 472  
                 }
 473  
                 
 474  0
                 catch (Throwable e)
 475  
                 {
 476  0
                 }
 477  
             }
 478  
         }
 479  
         
 480  0
         return result;
 481  
     }
 482  
 
 483  
     
 484  
     /*
 485  
      * We need this class to do a quick check on a facelets taglib document to see if it's
 486  
      * a pre-2.0 document.  If it is, we really need to construct a DTD validating, non-namespace
 487  
      * aware parser. Otherwise, we have to construct a schema validating, namespace-aware parser.
 488  
      */
 489  0
     private static class VersionCheckHandler extends DefaultHandler
 490  
     {
 491  
         private boolean version20OrLater;
 492  
         
 493  
         public boolean isVersion20OrLater ()
 494  
         {
 495  0
             return this.version20OrLater;
 496  
         }
 497  
         
 498  
         @Override
 499  
         public void startElement (String uri, String localName, String name, Attributes attributes) throws SAXException
 500  
         {
 501  0
             if (name.equals ("facelet-taglib"))
 502  
             {
 503  0
                 int length = attributes.getLength();
 504  
                 
 505  0
                 for (int i = 0; i < length; i++)
 506  
                 {
 507  0
                     String attrName = attributes.getLocalName(i);
 508  0
                     attrName = (attrName != null)
 509  
                             ? ( (attrName.length() > 0) ? attrName : attributes.getQName(i))
 510  
                             : attributes.getQName(i);
 511  0
                     if (attrName.equals ("version"))
 512  
                     {
 513  
                         // This document has a "version" attribute in the <facelet-taglib> element, so
 514  
                         // it must be a 2.0 or later document as this attribute was never required before.
 515  
 
 516  0
                         this.version20OrLater = true;
 517  
                     }
 518  
                 }
 519  
                 
 520  
                 // Throw a dummy parsing exception to terminate parsing as there really isn't any need to go any
 521  
                 // further.
 522  
                 // -= Leonardo Uribe =- THIS IS NOT GOOD PRACTICE! It is better to let the checker continue that
 523  
                 // throw an exception, and run this one only when project stage != production.
 524  
                 //throw new SAXException();
 525  
             }
 526  0
         }
 527  
     }
 528  
 }