package de.rwth.idsg.bikeman.ixsi.endpoint; import de.rwth.idsg.bikeman.ixsi.IXSIConstants; import de.rwth.idsg.bikeman.ixsi.IxsiProcessingException; import de.rwth.idsg.bikeman.ixsi.endpoint.Parser; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.xml.sax.SAXException; import xjc.schema.ixsi.IxsiMessageType; import xjc.schema.ixsi.ObjectFactory; import javax.annotation.PostConstruct; import javax.xml.XMLConstants; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.net.URL; /** * Created by max on 08/09/14. */ @Slf4j @Component public class ParserImpl implements Parser { @Autowired private JAXBContext jaxbContext; private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory(); private Schema schema; @PostConstruct public void init() throws SAXException, IOException { SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); URL xsdURL = getClass().getClassLoader().getResource(IXSIConstants.XML_SCHEMA_FILE); if (xsdURL == null) { throw new IOException("XML schema could not be found/loaded"); } else { schema = schemaFactory.newSchema(xsdURL); } } @Override public IxsiMessageType unmarshal(String str) { log.trace("Entered unmarshal..."); try { Unmarshaller um = jaxbContext.createUnmarshaller(); // Validate against the schema um.setSchema(schema); StringReader reader = new StringReader(str); StreamSource source = new StreamSource(reader); return um.unmarshal(source, IxsiMessageType.class).getValue(); } catch (JAXBException e) { throw new IxsiProcessingException("Could not unmarshal incoming message: " + str, e); } } @Override public String marshal(IxsiMessageType ixsi) { log.trace("Entered marshal..."); try { JAXBElement<IxsiMessageType> outgoing = OBJECT_FACTORY.createIxsi(ixsi); Marshaller m = jaxbContext.createMarshaller(); // Validate against the schema m.setSchema(schema); // Pretty print? m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE); // Drop the XML declaration? m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); StringWriter stringWriter = new StringWriter(); m.marshal(outgoing, stringWriter); return stringWriter.toString(); } catch (JAXBException e) { throw new IxsiProcessingException("Could not marshal outgoing message: " + ixsi.toString(), e); } } }