package org.uncertweb.ps.encoding.xml;
import java.io.ByteArrayInputStream;
import java.util.Iterator;
import org.jdom.Content;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.filter.Filter;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import org.uncertweb.api.om.io.StaxObservationParser;
import org.uncertweb.api.om.io.XBObservationEncoder;
import org.uncertweb.api.om.observation.AbstractObservation;
import org.uncertweb.api.om.observation.collections.IObservationCollection;
import org.uncertweb.ps.encoding.EncodeException;
import org.uncertweb.ps.encoding.ParseException;
public class OMEncoding extends AbstractXMLEncoding {
@Override
public boolean isSupportedType(Class<?> type) {
for (Class<?> interf : type.getInterfaces()) {
if (interf.equals(IObservationCollection.class)) {
return true;
}
}
Class<?> superClass = type.getSuperclass();
if (superClass != null) {
return superClass.equals(AbstractObservation.class);
}
return false;
}
@Override
public <T> T parse(Content content, Class<T> type) throws ParseException {
try {
// this is a workaround for broken parser
Element element = (Element)content;
Iterator<?> fois = element.getDescendants(new Filter() {
private static final long serialVersionUID = 1L;
public boolean matches(Object obj) {
if (obj instanceof Element) {
Element e = (Element)obj;
return e.getName().equals("featureOfInterest");
}
return false;
}
});
while (fois.hasNext()) {
Element e = (Element)fois.next();
Element ssf = e.getChild("SF_SpatialSamplingFeature", Namespace.getNamespace("http://www.opengis.net/samplingSpatial/2.0"));
if (ssf != null) {
Element shape = ssf.getChild("shape", Namespace.getNamespace("http://www.opengis.net/samplingSpatial/2.0"));
shape.removeAttribute("type");
}
}
// convert to string for external parsing
String om = new XMLOutputter().outputString(element);
StaxObservationParser parser = new StaxObservationParser();
if (element.getName().endsWith("Collection")) {
return type.cast(parser.parseObservationCollection(om));
}
else {
return type.cast(parser.parseObservation(om));
}
}
catch (Exception e) {
throw new ParseException("Couldn't parse O&M: " + e.getMessage(), e);
}
}
@Override
public <T> Content encode(T object) throws EncodeException {
try {
// generate random char
// to ensure we are encoding valid o&m, some instances will have multiple collections in one document
char idPrefix = (char) (System.nanoTime() % 26 + 'a');
// and encode
XBObservationEncoder encoder = new XBObservationEncoder();
String om;
if (object instanceof IObservationCollection) {
om = encoder.encodeObservationCollectionWithId((IObservationCollection)object, String.valueOf(idPrefix));
}
else {
om = encoder.encodeObservationWithId((AbstractObservation)object, String.valueOf(idPrefix));
}
Document document = new SAXBuilder().build(new ByteArrayInputStream(om.getBytes()));
return document.getRootElement();
}
catch (Exception e) {
throw new EncodeException("Couldn't encode O&M: " + e.getMessage(), e);
}
}
@Override
public String getNamespace() {
return "http://www.opengis.net/om/2.0";
}
@Override
public String getSchemaLocation() {
return "http://52north.org/schema/geostatistics/uncertweb/Profiles/OM/UncertWeb_OM.xsd";
}
@Override
public Include getInclude(Class<?> type) {
return new IncludeRef("OM_" + type.getSimpleName());
}
}