/*******************************************************************************
* Copyright (c) 2007 Cambridge Semantics Incorporated.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* File: $Source$
* Created by: Matthew Roy ( <a href="mailto:mroy@cambridgesemantics.com">mroy@cambridgesemantics.com </a>)
* Created on: Mar 4, 2008
* Revision: $Id$
*
* Contributors:
* Cambridge Semantics Incorporated - initial API and implementation
*******************************************************************************/
package org.openanzo.services.serialization;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.apache.commons.codec.binary.Base64;
import org.openanzo.exceptions.AnzoException;
import org.openanzo.exceptions.ExceptionConstants;
import org.openanzo.rdf.Constants;
import org.openanzo.rdf.Resource;
import org.openanzo.rdf.URI;
import org.openanzo.rdf.Value;
import org.openanzo.rdf.utils.SerializationConstants;
import org.openanzo.services.serialization.CommonSerializationUtils.NodeType;
/**
* XML parser for backup data
*
* @author Matthew Roy ( <a href="mailto:mroy@cambridgesemantics.com">mroy@cambridgesemantics.com</a>)
*
*/
public class XMLBackupReader {
private Collection<BackupRevision> revisions = null;
private String graphUri = null;
private URI namedGraphUri = null;
private URI uuid = null;
private URI metaURI = null;
private URI lastModified = null;
private Long start = null;
private Long end = null;
private boolean revisioned = false;
private boolean metadata = false;
private boolean processGraph = false;
private Resource currentSubject = null;
private URI currentPredicate = null;
private Value currentObject = null;
private URI currentNamedGraphURI = null;
private String currentValue = null;
private String nodeType = null;
private String language = null;
private String datatype = null;
private final Reader reader;
/**
* Create a new XML parser for given reader data
*
* @param reader
*/
public XMLBackupReader(Reader reader) {
this.reader = reader;
}
/**
* Read data from reader, and pass data to handler
*
* @param handler
* handler that handles data
* @throws AnzoException
*/
public void read(final IBackupHandler handler) throws AnzoException {
parseBackup(reader, handler);
}
/**
* Parse the data within the reader, passing the results to the IRepositoryHandler
*
* @param reader
* reader containing the data
* @param handler
* Handler which will handle the elements within the data
* @throws AnzoException
*/
private void parseBackup(Reader reader, final IBackupHandler handler) throws AnzoException {
try {
XMLStreamReader parser = XMLFactoryFinder.getXMLInputFactory().createXMLStreamReader(reader);
for (int event = parser.next(); event != XMLStreamConstants.END_DOCUMENT; event = parser.next()) {
switch (event) {
case XMLStreamConstants.START_ELEMENT:
if (SerializationConstants.namedGraph.equals(parser.getLocalName())) {
graphUri = parser.getAttributeValue(null, SerializationConstants.namedGraphUri);
String meta = parser.getAttributeValue(null, SerializationConstants.metadataGraphUri);
String uuidString = parser.getAttributeValue(null, SerializationConstants.namedGraphUUID);
namedGraphUri = Constants.valueFactory.createURI(graphUri);
metaURI = Constants.valueFactory.createURI(meta);
uuid = Constants.valueFactory.createURI(uuidString);
revisioned = Boolean.parseBoolean(parser.getAttributeValue(null, SerializationConstants.revisioned));
} else if (SerializationConstants.revisions.equals(parser.getLocalName())) {
revisions = new ArrayList<BackupRevision>();
} else if (SerializationConstants.revisionInfo.equals(parser.getLocalName())) {
long revision = Long.parseLong(parser.getAttributeValue(null, SerializationConstants.revision));
Long start = Long.valueOf(parser.getAttributeValue(null, SerializationConstants.start));
String endString = parser.getAttributeValue(null, SerializationConstants.end);
Long end = (endString != null) ? Long.valueOf(endString) : -1;
lastModified = Constants.valueFactory.createURI(parser.getAttributeValue(null, SerializationConstants.lastModifiedBy));
revisions.add(new BackupRevision(revision, start, end, lastModified));
} else if (SerializationConstants.statement.equals(parser.getLocalName())) {
if (processGraph) {
if (revisioned) {
String startString = parser.getAttributeValue(null, SerializationConstants.start);
String endString = parser.getAttributeValue(null, SerializationConstants.end);
if (startString != null)
start = Long.valueOf(startString);
if (endString != null)
end = Long.valueOf(endString);
}
}
} else if (SerializationConstants.statements.equals(parser.getLocalName())) {
if (processGraph) {
metadata = !parser.getAttributeValue(null, SerializationConstants.namedGraphUri).equals(graphUri);
}
} else if (SerializationConstants.subject.equals(parser.getLocalName())) {
if (processGraph) {
nodeType = parser.getAttributeValue(null, SerializationConstants.subjectType);
}
} else if (SerializationConstants.predicate.equals(parser.getLocalName())) {
} else if (SerializationConstants.object.equals(parser.getLocalName())) {
if (processGraph) {
nodeType = parser.getAttributeValue(null, SerializationConstants.objectType);
language = parser.getAttributeValue(null, SerializationConstants.language);
datatype = parser.getAttributeValue(null, SerializationConstants.dataType);
}
} else if (SerializationConstants.namedGraphUri.equals(parser.getLocalName())) {
}
break;
case XMLStreamConstants.END_ELEMENT:
if (SerializationConstants.namedGraph.equals(parser.getLocalName())) {
graphUri = null;
namedGraphUri = null;
metaURI = null;
uuid = null;
revisioned = true;
revisions = null;
} else if (SerializationConstants.revisionInfo.equals(parser.getLocalName())) {
} else if (SerializationConstants.revisions.equals(parser.getLocalName())) {
processGraph = handler.handleNamedGraph(revisioned, namedGraphUri, metaURI, uuid, revisions);
revisions = null;
} else if (SerializationConstants.statement.equals(parser.getLocalName())) {
if (processGraph) {
handler.handleStatement(metadata, revisioned, Constants.valueFactory.createStatement(currentSubject, currentPredicate, currentObject, currentNamedGraphURI), start, end);
start = null;
end = null;
}
} else if (SerializationConstants.subject.equals(parser.getLocalName())) {
if (processGraph) {
if (NodeType.BNODE.name().equals(nodeType)) {
currentSubject = Constants.valueFactory.createBNode(currentValue);
} else {
currentSubject = Constants.valueFactory.createURI(currentValue);
}
currentValue = null;
nodeType = null;
}
} else if (SerializationConstants.predicate.equals(parser.getLocalName())) {
if (processGraph) {
currentPredicate = Constants.valueFactory.createURI(currentValue);
currentValue = null;
}
} else if (SerializationConstants.object.equals(parser.getLocalName())) {
if (processGraph) {
if (NodeType.BNODE.name().equals(nodeType)) {
currentObject = Constants.valueFactory.createBNode(currentValue);
} else if (NodeType.URI.name().equals(nodeType)) {
currentObject = Constants.valueFactory.createURI(currentValue);
} else if (NodeType.LITERAL.name().equals(nodeType)) {
if (currentValue == null) {
currentValue = "";
} else if (Base64.isArrayByteBase64(currentValue.getBytes(Constants.byteEncoding))) {
currentValue = new String(Base64.decodeBase64(currentValue.getBytes(Constants.byteEncoding)), Constants.byteEncoding);
}
if (datatype != null) {
currentObject = Constants.valueFactory.createLiteral(currentValue, Constants.valueFactory.createURI(datatype));
} else if (language != null) {
currentObject = Constants.valueFactory.createLiteral(currentValue, language);
} else {
currentObject = Constants.valueFactory.createLiteral(currentValue);
}
}
currentValue = null;
nodeType = null;
language = null;
datatype = null;
}
} else if (SerializationConstants.namedGraphUri.equals(parser.getLocalName())) {
if (processGraph) {
currentNamedGraphURI = Constants.valueFactory.createURI(currentValue);
currentValue = null;
}
}
break;
case XMLStreamConstants.CHARACTERS:
if (parser.hasText())
currentValue = parser.getText();
break;
case XMLStreamConstants.CDATA:
if (parser.hasText())
currentValue = parser.getText();
break;
}
}
parser.close();
} catch (XMLStreamException ex) {
throw new AnzoException(ExceptionConstants.IO.READ_ERROR, ex, ex.getMessage());
} catch (UnsupportedEncodingException uee) {
throw new AnzoException(ExceptionConstants.IO.ENCODING_ERROR, uee);
}
}
}