cleanup
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / common / XmlImportBase.java
1 /**
2 * Copyright (C) 2009 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.cdm.io.common;
10
11 import java.io.File;
12 import java.io.FileInputStream;
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.net.URI;
16 import java.util.NoSuchElementException;
17
18 import javax.xml.namespace.QName;
19 import javax.xml.parsers.ParserConfigurationException;
20 import javax.xml.parsers.SAXParser;
21 import javax.xml.parsers.SAXParserFactory;
22 import javax.xml.stream.FactoryConfigurationError;
23 import javax.xml.stream.XMLEventReader;
24 import javax.xml.stream.XMLInputFactory;
25 import javax.xml.stream.XMLStreamException;
26 import javax.xml.stream.events.XMLEvent;
27
28 import org.apache.log4j.Logger;
29 import org.xml.sax.SAXException;
30
31 import eu.etaxonomy.cdm.io.common.events.IIoEvent;
32 import eu.etaxonomy.cdm.io.common.events.IIoObserver;
33
34 /**
35 * Base class for XML imports
36 * @author a.mueller
37 * @since 28.06.2011
38 */
39 public abstract class XmlImportBase<CONFIG extends XmlImportConfiguratorBase<STATE>, STATE extends XmlImportState<CONFIG, ?>>
40 extends CdmImportBase<CONFIG, STATE>
41 implements IIoObserver {
42
43 private static final long serialVersionUID = 1505202381104645545L;
44 @SuppressWarnings("unused")
45 private static final Logger logger = Logger.getLogger(XmlImportBase.class);
46
47 protected void fireSchemaConflictEventExpectedStartTag(String elName, XMLEventReader reader) throws XMLStreamException {
48 String type = "ElementStart";
49 XMLEvent next = reader.nextEvent();
50 fireSchemaConflictEvent(type, elName, next);
51 }
52
53 /**
54 * @param r
55 * @return
56 * @throws XMLStreamException
57 */
58 protected boolean validateStartOfDocument(XMLEventReader reader) throws XMLStreamException {
59 XMLEvent next = reader.nextEvent();
60 if (next.isStartDocument()){
61 return true;
62 }else {
63 fireWarningEvent("Missing start of document", next.getLocation().toString(), 16);
64 return false;
65 }
66 }
67
68
69 /**
70 * TODO namespace
71 * @param elName
72 * @param reader
73 * @return
74 * @throws XMLStreamException
75 */
76 protected boolean isStartingElement(XMLEventReader reader, String elName) throws XMLStreamException {
77 XMLEvent next;
78 try {
79 next = reader.peek();
80 } catch (NoSuchElementException e) {
81 return false;
82 }
83 return isStartingElement(next, elName);
84 }
85
86 protected boolean isStartingElement(XMLEvent event, String elName) {
87 boolean result = false;
88 boolean isStart = event.isStartElement();
89 if (isStart){
90 QName name = event.asStartElement().getName();
91 boolean equals = name.getLocalPart().equals(elName);
92 result = equals;
93 }
94 return result;
95 }
96
97 protected boolean isEndingElement(XMLEventReader reader, String elName) throws XMLStreamException {
98 XMLEvent next;
99 try {
100 next = reader.peek();
101 } catch (NoSuchElementException e) {
102 return false;
103 }
104 return isEndingElement(next, elName);
105 }
106
107 protected boolean isEndingElement(XMLEvent event, String elName) throws XMLStreamException {
108 boolean result = false;
109 boolean isEnd = event.isEndElement();
110 if (isEnd){
111 QName name = event.asEndElement().getName();
112 result = name.getLocalPart().equals(elName);
113 }
114 return result;
115 }
116
117
118 /**
119 * Returns an input stream for the given source.
120 * @param config
121 * @return
122 */
123 protected InputStream getInputStream(CONFIG config) {
124 try {
125 URI uri = config.getSource();
126 File file = new File(uri);
127 InputStream is = new FileInputStream(file);
128 return is;
129 }catch (Exception e) {
130 String message = "Problem reading source file %s. Import can not be executed. Reason: %s.";
131 message = String.format(message, config.getSource(), e.getMessage());
132 fireWarningEvent(message, "Read file", 16);
133 return null;
134 }
135 }
136
137 private void fireSchemaConflictEvent(String expectedType, String expectedName, XMLEvent next) {
138 String message = "Schema conflict: expected %s '%s' but was %s ";
139 String eventString;
140 if (next.isStartElement()){
141 eventString = next.asStartElement().getName().getLocalPart();
142 }else if(next.isEndElement()){
143 eventString = next.asEndElement().getName().getLocalPart();
144 }else{
145 eventString = next.toString();
146 }
147 message = String.format(message, expectedType, expectedName, eventString);
148 String location = "l." + next.getLocation().getLineNumber() + "/c." + next.getLocation().getColumnNumber();
149 fireWarningEvent(message, location, 16);
150 }
151
152
153 /**
154 * Returns the StAX-Reader (XMLEventReader) for the source.
155 * @param state
156 * @return
157 * @throws FactoryConfigurationError
158 * @throws XMLStreamException
159 */
160 protected XMLEventReader getStaxReader(STATE state) throws FactoryConfigurationError, XMLStreamException {
161 String fileName = state.getConfig().getSource().toString();
162 InputStream is = null;
163 is = getInputStream(state.getConfig()); //throws exception and looks like it is not needed.
164 XMLInputFactory staxFactory = XMLInputFactory.newInstance();
165 XMLEventReader reader = staxFactory.createXMLEventReader(fileName, is);
166 return reader;
167 }
168
169
170 /**
171 * Parses the source file with the given handler
172 * @param is
173 * @param handler
174 * @throws ParserConfigurationException
175 * @throws SAXException
176 * @throws IOException
177 */
178 protected void parseSAX(STATE state, ImportHandlerBase handler)
179 throws ParserConfigurationException, SAXException, IOException {
180 handler.addObserver(this);
181 InputStream is = getInputStream(state.getConfig());
182 SAXParserFactory saxFactory = SAXParserFactory.newInstance();
183 SAXParser saxParser = saxFactory.newSAXParser();
184 saxParser.parse(is, handler);
185 }
186
187
188 /* (non-Javadoc)
189 * @see eu.etaxonomy.cdm.io.common.events.IIoObserver#handleEvent(eu.etaxonomy.cdm.io.common.events.IIoEvent)
190 */
191 @Override
192 public void handleEvent(IIoEvent event) {
193 fire(event);
194 }
195
196 }