View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau;
18  
19  import static javax.xml.stream.XMLStreamConstants.*;
20  
21  import java.io.*;
22  import java.lang.reflect.*;
23  import java.util.*;
24  
25  import javax.xml.stream.*;
26  
27  import org.apache.juneau.parser.*;
28  import org.apache.juneau.xml.*;
29  
30  /**
31   * Used to validate that the syntax of XML documents are valid.
32   *
33   * <ul class='spaced-list'>
34   * 	<li class='note'>This class is thread safe and reusable.
35   * </ul>
36   */
37  @SuppressWarnings("unchecked")
38  public class XmlValidatorParser extends XmlParser {
39  
40  	//-----------------------------------------------------------------------------------------------------------------
41  	// Instance
42  	//-----------------------------------------------------------------------------------------------------------------
43  
44  	public XmlValidatorParser() {
45  		super(create());
46  	}
47  
48  	@Override /* Context */
49  	public XmlParserSession.Builder createSession() {
50  		return new XmlParserSession.Builder(XmlParser.DEFAULT) {
51  			@Override
52  			public XmlParserSession build() {
53  				return new XmlParserSession(this) {
54  
55  					@Override
56  					protected <T> T doParse(ParserPipe pipe, ClassMeta<T> type) throws IOException, ParseException, ExecutableException {
57  						try {
58  							return type.cast(validate(pipe.getReader()));
59  						} catch (Exception e) {
60  							throw new ParseException(e);
61  						}
62  					}
63  
64  					@Override /* ReaderParser */
65  					protected <K,V> Map<K,V> doParseIntoMap(ParserPipe pipe, Map<K,V> m, Type keyType, Type valueType) throws Exception {
66  						return (Map<K,V>)validate(pipe.getReader());
67  					}
68  
69  					@Override /* ReaderParser */
70  					protected <E> Collection<E> doParseIntoCollection(ParserPipe pipe, Collection<E> c, Type elementType) throws Exception {
71  						return (Collection<E>)validate(pipe.getReader());
72  					}
73  				};
74  			}
75  		};
76  	}
77  
78  	public <T> T validate(Reader r) throws Exception {
79  		var sr = getStaxReader(r);
80  		while (sr.next() != END_DOCUMENT) {/*no-op*/}
81  		return null;
82  	}
83  
84  	protected XMLStreamReader getStaxReader(Reader in) throws Exception {
85  		var factory = XMLInputFactory.newInstance();
86  		factory.setProperty("javax.xml.stream.isNamespaceAware", false);
87  		var parser = factory.createXMLStreamReader(in);
88  		parser.nextTag();
89  		return parser;
90  	}
91  }