View Javadoc
1   /*
2    * JBoss, Home of Professional Open Source
3    * Copyright 2014, Red Hat, Inc. and/or its affiliates, and individual
4    * contributors by the @authors tag. See the copyright.txt in the
5    * distribution for a full listing of individual contributors.
6    *
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * http://www.apache.org/licenses/LICENSE-2.0
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.jboss.as.quickstart.xml;
18  
19  import java.io.InputStream;
20  import java.text.ParseException;
21  import java.text.SimpleDateFormat;
22  import java.util.ArrayList;
23  import java.util.Date;
24  import java.util.List;
25  
26  import javax.enterprise.context.RequestScoped;
27  import javax.enterprise.inject.Default;
28  import javax.inject.Inject;
29  import javax.xml.parsers.DocumentBuilder;
30  import javax.xml.parsers.DocumentBuilderFactory;
31  
32  import org.w3c.dom.Document;
33  import org.w3c.dom.Element;
34  import org.w3c.dom.Node;
35  import org.w3c.dom.NodeList;
36  import org.xml.sax.ErrorHandler;
37  import org.xml.sax.SAXException;
38  import org.xml.sax.SAXParseException;
39  
40  /**
41   * Implementation of parser based on JAXP DOM(W3C).
42   * 
43   * @author baranowb
44   * 
45   */
46  @RequestScoped
47  @Default
48  public class DOMXMLParser extends XMLParser {
49  
50      // Inject instance of error holder
51      @Inject
52      private Errors errorHolder;
53  
54      private DocumentBuilder builder;
55      private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
56  
57      DOMXMLParser() throws Exception {
58          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
59          /*
60           * bizarrely, setValidating refers to DTD validation only, and we are using schema validation
61           */
62          factory.setValidating(false);
63          factory.setNamespaceAware(true);
64  
65          this.builder = factory.newDocumentBuilder();
66  
67          // Set SAX error handler. So errors atleast show up in console
68          this.builder.setErrorHandler(new ErrorHandler() {
69  
70              @Override
71              public void warning(SAXParseException e) throws SAXException {
72                  errorHolder.addErrorMessage("warning", e);
73              }
74  
75              @Override
76              public void fatalError(SAXParseException e) throws SAXException {
77                  errorHolder.addErrorMessage("fatal error", e);
78              }
79  
80              @Override
81              public void error(SAXParseException e) throws SAXException {
82                  errorHolder.addErrorMessage("error", e);
83              }
84          });
85  
86      }
87  
88      @Override
89      public List<Book> parseInternal(InputStream is) throws Exception {
90          System.out.println("Parsing the document using the DOMXMLParser!");
91  
92          Document document = this.builder.parse(is);
93  
94          List<Book> catalog = new ArrayList<Book>();
95  
96          Element root = document.getDocumentElement();
97          if (!root.getLocalName().equals("catalog")) {
98              throw new RuntimeException("Wrong element: " + root.getTagName());
99          }
100 
101         NodeList children = root.getChildNodes();
102         for (int index = 0; index < children.getLength(); index++) {
103 
104             Node n = children.item(index);
105             String childName = n.getLocalName();
106             if (childName == null)
107                 continue;
108 
109             if (n.getLocalName().equals("book")) {
110                 Book b = parseBook((Element) n);
111                 catalog.add(b);
112             }
113         }
114 
115         return catalog;
116 
117     }
118 
119     private Book parseBook(Element n) {
120         Book b = new Book();
121         NodeList children = n.getChildNodes();
122         /*
123          * parse book element, we have to once more iterate over children.
124          */
125         for (int index = 0; index < children.getLength(); index++) {
126             Node child = children.item(index);
127             String childName = child.getLocalName();
128             // empty/text nodes dont have name
129             if (childName == null)
130                 continue;
131 
132             if (childName.equals("author")) {
133                 Element childElement = (Element) child;
134 
135                 String textVal = getTextValue(childElement);
136                 b.setAuthor(textVal);
137             } else if (childName.equals("title")) {
138                 Element childElement = (Element) child;
139 
140                 String textVal = getTextValue(childElement);
141                 b.setTitle(textVal);
142             } else if (childName.equals("genre")) {
143                 Element childElement = (Element) child;
144 
145                 String textVal = getTextValue(childElement);
146                 b.setGenre(textVal);
147             } else if (childName.equals("price")) {
148                 Element childElement = (Element) child;
149 
150                 String textVal = getTextValue(childElement);
151                 b.setPrice(Float.parseFloat(textVal));
152             } else if (childName.equals("publish_date")) {
153                 Element childElement = (Element) child;
154 
155                 String textVal = getTextValue(childElement);
156                 Date d;
157                 try {
158 
159                     d = DATE_FORMATTER.parse(textVal);
160                     b.setPublishDate(d);
161                 } catch (ParseException e) {
162                     throw new RuntimeException(e);
163                 }
164 
165             } else if (childName.equals("description")) {
166                 Element childElement = (Element) child;
167                 String textVal = getTextValue(childElement);
168                 b.setDescription(textVal);
169             }
170 
171         }
172 
173         return b;
174     }
175 
176     private String getTextValue(Element childElement) {
177         NodeList nl = childElement.getChildNodes();
178         if (nl != null && nl.getLength() > 0) {
179             Node node = nl.item(0);
180             if (node.getNodeType() == Node.TEXT_NODE) {
181                 return node.getNodeValue();
182             }
183         }
184         return "";
185     }
186 }