/** * Copyright (c) Codice Foundation * * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. * **/ package org.codice.ddf.spatial.ogc.wfs.catalog.source.reader; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.Provider; import javax.xml.XMLConstants; import org.apache.camel.builder.xml.XPathBuilder; import org.apache.camel.impl.DefaultCamelContext; import org.apache.commons.io.IOUtils; import org.apache.ws.commons.schema.XmlSchema; import org.apache.ws.commons.schema.XmlSchemaCollection; import org.codice.ddf.spatial.ogc.wfs.catalog.source.WfsUriResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.InputSource; @Provider public class XmlSchemaMessageBodyReader implements MessageBodyReader<XmlSchema> { private static final Logger LOGGER = LoggerFactory.getLogger(XmlSchemaMessageBodyReader.class); private static final String XSD_PREFIX = "xsd"; private static final String COUNT_XPATH = "count(/" + XSD_PREFIX + ":schema)"; private static final XPathBuilder COUNT_XPATH_BUILDER = new XPathBuilder(COUNT_XPATH) .namespace(XSD_PREFIX, XMLConstants.W3C_XML_SCHEMA_NS_URI).numberResult(); protected WfsUriResolver wfsUriResolver = new WfsUriResolver(); private DefaultCamelContext camelContext = new DefaultCamelContext(); @Override public boolean isReadable(Class<?> clazz, Type type, Annotation[] annotations, MediaType mediaType) { return XmlSchema.class.isAssignableFrom(clazz); } @Override public XmlSchema readFrom(Class<XmlSchema> clazz, Type type, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> headers, InputStream inStream) throws IOException, WebApplicationException { // Determine if this is an XMLSchema String input = IOUtils.toString(inStream); inStream.reset(); String count = COUNT_XPATH_BUILDER.evaluate(camelContext, input); // See if there exactly one instance of "xsd:schema" in this doc if (Integer.valueOf(count) == 1) { XmlSchema schema = null; XmlSchemaCollection schemaCollection = new XmlSchemaCollection(); schemaCollection.init(); schemaCollection.setSchemaResolver(wfsUriResolver); schema = schemaCollection.read(new InputSource(inStream)); return schema; } LOGGER.warn("Did not receive valid XML Schema, instead got: \n{}", input); return null; } }