Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  
4
 *  Copyright: 2016 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Jing Tao
7
 * 
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
 */
23
package edu.ucsb.nceas.metacat.service;
24

    
25
import java.io.IOException;
26
import java.io.Reader;
27

    
28
import org.apache.log4j.Logger;
29
import org.xml.sax.Attributes;
30
import org.xml.sax.InputSource;
31
import org.xml.sax.SAXException;
32
import org.xml.sax.XMLReader;
33
import org.xml.sax.helpers.DefaultHandler;
34
import org.xml.sax.helpers.XMLReaderFactory;
35

    
36
import edu.ucsb.nceas.metacat.properties.PropertyService;
37
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
38

    
39

    
40
/**
41
 * This class will parse the root element to figure out the namespace of the root element(we also call
42
 * it the namespace of the element). If it doesn't have a namespace, but it does have an attribute of noNamespaceSchemaLocation
43
 * at the root element, it will get the value as well. 
44
 * @author tao
45
 *
46
 */
47
public class XMLNamespaceParser extends DefaultHandler {
48

    
49
    private Reader xml = null;
50
    private XMLReader parser = null;
51
    private boolean rootElement = true;
52
    private static Logger logMetacat = Logger.getLogger(XMLNamespaceParser.class);
53
    private String namespace = null;
54
    private String noNamespaceSchemaLocation = null;
55
    
56
    /**
57
     * Constructor
58
     * @param xml the xml object which will be parsed
59
     */
60
    public XMLNamespaceParser(Reader xml) throws SAXException, PropertyNotFoundException {
61
      this.xml = xml;
62
      initParser();
63
    }
64
    
65
    /*
66
     * Initialize sax parser
67
     */
68
    private void initParser() throws SAXException, PropertyNotFoundException {   
69
      // Get an instance of the parser
70
       String parserName = PropertyService.getProperty("xml.saxparser");
71
       parser = XMLReaderFactory.createXMLReader(parserName);
72
       parser.setContentHandler(this);
73
      
74
    }
75
    
76
    /**
77
     * Parse the xml file
78
     * @throws SAXException if some sax related exception happens
79
     * @throws IOException if the schema content couldn't be found
80
     */
81
    public void parse() throws SAXException, IOException {
82
        try {
83
            parser.parse(new InputSource(xml));
84
        } catch (ParsingEndException e) {
85
            logMetacat.debug("XMLNamespace.parse - The parsing process stopped.");
86
        }
87
      
88
    }
89
    
90
    /** SAX Handler that is called at the start of each XML element */
91
    @Override
92
    public void startElement(String uri, String localName, String qName,
93
            Attributes atts) throws SAXException{
94
      logMetacat.debug("XMLNamespace.startElement - uri: "+uri);
95
      logMetacat.debug("XMLNamespace.startElement - local name: "+localName);
96
      logMetacat.debug("XMLNamespace.startElement - qualified name: "+qName);
97
      if(!rootElement) {
98
          throw new ParsingEndException("We only parse the root elment. We got there and the parsing stopped.");
99
      } else {
100
          rootElement = false;
101
          if(uri != null && !uri.trim().equals("")) {
102
              namespace = uri;
103
          }
104
          logMetacat.debug("XMLNamespace.startElement - the namespace is: "+namespace);
105
          if(atts != null) {
106
              for(int i=0; i<atts.getLength(); i++) {
107
                  if((atts.getURI(i) != null && atts.getURI(i).equals("http://www.w3.org/2001/XMLSchema-instance")) &&
108
                          (atts.getLocalName(i) != null && atts.getLocalName(i).equals("noNamespaceSchemaLocation"))) {
109
                      if(atts.getValue(i) != null && !atts.getValue(i).trim().equals("")) {
110
                          noNamespaceSchemaLocation = atts.getValue(i);
111
                      }
112
                      logMetacat.debug("XMLNamespace.startElement - we found the attribute of the noNamespaceSchemaLocation and its value is: "+noNamespaceSchemaLocation);
113
                      break;
114
                  }
115
              }
116
          }
117
          
118
      }
119
    }
120
    
121
    
122
    /**
123
     * Get the namespace of the document (root element). The parse() method should be called first
124
     * @return the value of the namespace. A null will be returned if it can't be found.
125
     */
126
    public String getNamespace() {
127
        logMetacat.debug("XMLNamespace.getNamespace - the namespace is: "+namespace);
128
        return namespace;
129
    }
130
    
131
    
132
    /**
133
     * Get the value of noNamespaceSchemaLocation of the document (root element). The parse() method should be called first
134
     * @return the value of the noNamespaceSchemaLocation. A null will be returned if it can't be found.
135
     */
136
    public String getNoNamespaceSchemaLocation() {
137
        logMetacat.debug("XMLNamespace.getNoNamespaceSchemaLocation - the NoNamespaceSchemaLocation is: "+noNamespaceSchemaLocation);
138
        return noNamespaceSchemaLocation;
139
    }
140
    
141
    /**
142
     * A class signals that the parsing process stop early. 
143
     * @author tao
144
     *
145
     */
146
    class ParsingEndException extends RuntimeException {
147
        public ParsingEndException(String message) {
148
            super(message);
149
        }
150
    }
151
}
(3-3/7)