View Javadoc
1   /*
2    * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package com.sun.tools.internal.xjc.reader.internalizer;
27  
28  import java.util.Set;
29  import java.util.HashSet;
30  import java.util.Arrays;
31  
32  import com.sun.tools.internal.xjc.reader.Const;
33  
34  import org.xml.sax.Attributes;
35  import org.xml.sax.ContentHandler;
36  import org.xml.sax.EntityResolver;
37  import org.xml.sax.ErrorHandler;
38  import org.xml.sax.Locator;
39  import org.xml.sax.SAXException;
40  import org.xml.sax.SAXParseException;
41  import org.xml.sax.XMLReader;
42  import org.xml.sax.helpers.LocatorImpl;
43  import org.xml.sax.helpers.XMLFilterImpl;
44  
45  /**
46   * Checks the jaxb:version attribute on a XML Schema document.
47   *
48   * jaxb:version is optional if no binding customization is used,
49   * but if present, its value must be "1.0".
50   *
51   * @author
52   *     Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
53   */
54  public class VersionChecker extends XMLFilterImpl {
55  
56      /**
57       * We store the value of the version attribute in this variable
58       * when we hit the root element.
59       */
60      private String version = null ;
61  
62      /** Will be set to true once we hit the root element. */
63      private boolean seenRoot = false;
64  
65      /** Will be set to true once we hit a binding declaration. */
66      private boolean seenBindings = false;
67  
68      private Locator locator;
69  
70      /**
71       * Stores the location of the start tag of the root tag.
72       */
73      private Locator rootTagStart;
74  
75      public VersionChecker( XMLReader parent ) {
76          setParent(parent);
77      }
78  
79      public VersionChecker( ContentHandler handler,ErrorHandler eh,EntityResolver er ) {
80          setContentHandler(handler);
81          if(eh!=null)    setErrorHandler(eh);
82          if(er!=null)    setEntityResolver(er);
83      }
84  
85      public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
86          throws SAXException {
87  
88          super.startElement(namespaceURI, localName, qName, atts);
89  
90          if(!seenRoot) {
91              // if this is the root element
92              seenRoot = true;
93              rootTagStart = new LocatorImpl(locator);
94  
95              version = atts.getValue(Const.JAXB_NSURI,"version");
96              if( namespaceURI.equals(Const.JAXB_NSURI) ) {
97                  String version2 = atts.getValue("","version");
98                  if( version!=null && version2!=null ) {
99                      // we have both @version and @jaxb:version. error.
100                     SAXParseException e = new SAXParseException(
101                         Messages.format( Messages.TWO_VERSION_ATTRIBUTES ), locator );
102                     getErrorHandler().error(e);
103                 }
104                 if( version==null )
105                     version = version2;
106             }
107 
108         }
109 
110         if( Const.JAXB_NSURI.equals(namespaceURI) )
111             seenBindings = true;
112     }
113 
114     public void endDocument() throws SAXException {
115         super.endDocument();
116 
117         if( seenBindings && version==null ) {
118             // if we see a binding declaration but not version attribute
119             SAXParseException e = new SAXParseException(
120                 Messages.format(Messages.ERR_VERSION_NOT_FOUND),rootTagStart);
121             getErrorHandler().error(e);
122         }
123 
124         // if present, the value must be either 1.0 or 2.0
125         if( version!=null && !VERSIONS.contains(version) ) {
126             SAXParseException e = new SAXParseException(
127                 Messages.format(Messages.ERR_INCORRECT_VERSION),rootTagStart);
128             getErrorHandler().error(e);
129         }
130     }
131 
132     public void setDocumentLocator(Locator locator) {
133         super.setDocumentLocator(locator);
134         this.locator = locator;
135     }
136 
137     private static final Set<String> VERSIONS = new HashSet<String>(Arrays.asList("1.0","2.0","2.1"));
138 
139 }