/*
* Copyright 2013, 2014, 2015 EnergyOS.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.energyos.espi.common.utils;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.UnmarshallerHandler;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.XMLGregorianCalendar;
import org.energyos.espi.common.models.atom.EntryType;
import org.energyos.espi.common.service.EntryProcessorService;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.NamespaceSupport;
import org.xml.sax.helpers.XMLFilterImpl;
public class ATOMContentHandler extends XMLFilterImpl {
private final JAXBContext context;
private int depth;
private UnmarshallerHandler unmarshallerHandler;
private Locator locator;
private NamespaceSupport namespaces = new NamespaceSupport();
private EntryProcessorService procssor;
private List<EntryType> entries = new ArrayList<EntryType>();
private XMLGregorianCalendar minUpdated = null;
private XMLGregorianCalendar maxUpdated = null;
public ATOMContentHandler(JAXBContext context,
EntryProcessorService procssor) {
this.context = context;
this.procssor = procssor;
}
public List<EntryType> getEntries() {
return entries;
}
public XMLGregorianCalendar getMinUpdated() {
return minUpdated;
}
public XMLGregorianCalendar getMaxUpdated() {
return maxUpdated;
}
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) throws SAXException {
if (depth != 0) {
depth++;
super.startElement(namespaceURI, localName, qName, atts);
return;
}
if (localName.equals("entry")) {
Unmarshaller unmarshaller;
try {
unmarshaller = context.createUnmarshaller();
} catch (JAXBException e) {
throw new SAXException(e);
}
unmarshallerHandler = unmarshaller.getUnmarshallerHandler();
setContentHandler(unmarshallerHandler);
unmarshallerHandler.startDocument();
unmarshallerHandler.setDocumentLocator(locator);
@SuppressWarnings("unchecked")
Enumeration<String> e = namespaces.getPrefixes();
while (e.hasMoreElements()) {
String prefix = e.nextElement();
String uri = namespaces.getURI(prefix);
unmarshallerHandler.startPrefixMapping(prefix, uri);
}
String defaultURI = namespaces.getURI("");
if (defaultURI != null)
unmarshallerHandler.startPrefixMapping("", defaultURI);
super.startElement(namespaceURI, localName, qName, atts);
depth = 1;
}
}
@SuppressWarnings("unchecked")
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
super.endElement(namespaceURI, localName, qName);
if (depth != 0) {
depth--;
if (depth == 0) {
Enumeration<String> e = namespaces.getPrefixes();
while (e.hasMoreElements()) {
String prefix = e.nextElement();
unmarshallerHandler.endPrefixMapping(prefix);
}
String defaultURI = namespaces.getURI("");
if (defaultURI != null)
unmarshallerHandler.endPrefixMapping("");
unmarshallerHandler.endDocument();
setContentHandler(new DefaultHandler());
if (localName.equals("entry")) {
JAXBElement<EntryType> result = null;
try {
result = (JAXBElement<EntryType>) unmarshallerHandler
.getResult();
} catch (JAXBException x) {
throw new SAXException("Unable to unmarshall <entry>",
x);
}
procssor.process(result.getValue());
entries.add(result.getValue());
// and update the min/max import range for later
// subscription publication
if ((minUpdated == null)
|| (result.getValue().getPublished().getValue()
.compare(minUpdated) == DatatypeConstants.LESSER)) {
minUpdated = result.getValue().getPublished()
.getValue();
}
if ((maxUpdated == null)
|| (result.getValue().getUpdated().getValue()
.compare(maxUpdated) == DatatypeConstants.GREATER)) {
maxUpdated = result.getValue().getUpdated().getValue();
}
}
unmarshallerHandler = null;
}
}
}
public void setDocumentLocator(Locator locator) {
super.setDocumentLocator(locator);
this.locator = locator;
}
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
namespaces.pushContext();
namespaces.declarePrefix(prefix, uri);
super.startPrefixMapping(prefix, uri);
}
public void endPrefixMapping(String prefix) throws SAXException {
namespaces.popContext();
super.endPrefixMapping(prefix);
}
public void setEntryProcessorService(
EntryProcessorService entryProcessorService) {
this.procssor = entryProcessorService;
}
}