From b1c8641a63a67e3c64d948f9e8dce5c01e11e2dd Mon Sep 17 00:00:00 2001 From: mcentner Date: Wed, 5 May 2010 15:29:01 +0000 Subject: Merged feature branch mocca-1.2.13-id@r724 back to trunk. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@725 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../java/at/gv/egiz/slbinding/SLUnmarshaller.java | 263 +++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 utils/src/main/java/at/gv/egiz/slbinding/SLUnmarshaller.java (limited to 'utils/src/main/java/at/gv/egiz/slbinding/SLUnmarshaller.java') diff --git a/utils/src/main/java/at/gv/egiz/slbinding/SLUnmarshaller.java b/utils/src/main/java/at/gv/egiz/slbinding/SLUnmarshaller.java new file mode 100644 index 00000000..0a4ee9f3 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/slbinding/SLUnmarshaller.java @@ -0,0 +1,263 @@ +/* +* Copyright 2009 Federal Chancellery Austria and +* Graz University of Technology +* +* 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 at.gv.egiz.slbinding; + +import java.io.IOException; +import java.net.URL; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; + +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.UnmarshalException; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.ValidationEvent; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; + +import at.gv.egiz.bku.utils.ClasspathURLStreamHandler; +import at.gv.egiz.validation.ReportingValidationEventHandler; + +public class SLUnmarshaller { + + /** + * Logging facility. + */ + private final Logger log = LoggerFactory.getLogger(SLUnmarshaller.class); + + private static class DefaultSchema { + + /** + * Schema files required for Security Layer command validation. + */ + public static final String[] SCHEMA_FILES = new String[] { + "classpath:at/gv/egiz/bku/slschema/xml.xsd", + "classpath:at/gv/egiz/bku/slschema/xmldsig-core-schema.xsd", + "classpath:at/gv/egiz/bku/slschema/Core-1.2.xsd", + "classpath:at/gv/egiz/bku/slschema/Core.20020225.xsd", + "classpath:at/gv/egiz/bku/slschema/Core.20020831.xsd" }; + + private static final Schema SCHEMA; + + static { + try { + SCHEMA = createSchema(Arrays.asList(SCHEMA_FILES)); + } catch (IOException e) { + Logger log = LoggerFactory.getLogger(SLUnmarshaller.class); + log.error("Failed to load security layer schema.", e); + throw new RuntimeException(e); + } catch (SAXException e) { + Logger log = LoggerFactory.getLogger(SLUnmarshaller.class); + log.error("Failed to load security layer schema.", e); + throw new RuntimeException(e); + } + + } + } + + public static Collection getDefaultSchemaUrls() { + return Collections.unmodifiableList(Arrays.asList(DefaultSchema.SCHEMA_FILES)); + } + + private static Schema createSchema(Collection schemaUrls) throws SAXException, IOException { + Logger log = LoggerFactory.getLogger(SLUnmarshaller.class); + Source[] sources = new Source[schemaUrls.size()]; + Iterator urls = schemaUrls.iterator(); + StringBuilder sb = null; + if (log.isDebugEnabled()) { + sb = new StringBuilder(); + sb.append("Created schema using URLs: "); + } + for (int i = 0; i < sources.length && urls.hasNext(); i++) { + String url = urls.next(); + if (url != null && url.startsWith("classpath:")) { + URL schemaUrl = new URL(null, url, new ClasspathURLStreamHandler()); + sources[i] = new StreamSource(schemaUrl.openStream()); + } else { + sources[i] = new StreamSource(url); + } + if (sb != null) { + sb.append(url); + if (urls.hasNext()) { + sb.append(", "); + } + } + } + SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = schemaFactory.newSchema(sources); + if (sb != null) { + log.debug(sb.toString()); + } + return schema; + } + + private static class DefaultContext { + + private static final String[] packageNames = { + at.buergerkarte.namespaces.securitylayer._1.ObjectFactory.class.getPackage().getName(), + org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName(), + at.buergerkarte.namespaces.cardchannel.ObjectFactory.class.getPackage().getName(), + at.buergerkarte.namespaces.securitylayer._20020225_.ObjectFactory.class.getPackage().getName(), + at.buergerkarte.namespaces.securitylayer._20020831_.ObjectFactory.class.getPackage().getName() + }; + + private static final JAXBContext CONTEXT; + + static { + try { + CONTEXT = createJAXBContext(Arrays.asList(packageNames)); + } catch (JAXBException e) { + Logger log = LoggerFactory.getLogger(SLUnmarshaller.class); + log.error("Failed to setup JAXBContext security layer request/response.", e); + throw new RuntimeException(e); + } + } + + } + + public static Collection getDefaultJAXBContextPackageNames() { + return Collections.unmodifiableList(Arrays.asList(DefaultContext.packageNames)); + } + + private static JAXBContext createJAXBContext(Collection packageNames) throws JAXBException { + StringBuilder contextPath = new StringBuilder(); + for (String pkg : packageNames) { + if (contextPath.length() > 0) { + contextPath.append(':'); + } + contextPath.append(pkg); + } + return JAXBContext.newInstance(contextPath.toString()); + } + + /** + * Schema for Security Layer command validation. + */ + protected Schema slSchema = DefaultSchema.SCHEMA; + + /** + * The JAXBContext. + */ + protected JAXBContext jaxbContext = DefaultContext.CONTEXT; + + /** + * Returns the schema used for validation. + * + * @return the slSchema + */ + public Schema getSlSchema() { + return slSchema; + } + + /** + * Sets the schema for validation. + * + * @param slSchema the slSchema to set + */ + public void setSlSchema(Schema slSchema) { + this.slSchema = slSchema; + } + + /** + * Sets the schema created from the given {@code schemaUrls}. + * + * @param schemaUrls a collection of URLs of schema files (supports {@code classpath:} URLs) + * @throws SAXException if schema creation fails + * @throws IOException if an error occurs upon dereferencing the given {@code schemaUrls} + */ + public void setSchemaUrls(Collection schemaUrls) throws SAXException, IOException { + slSchema = createSchema(schemaUrls); + } + + /** + * @return the jaxbContext + */ + public JAXBContext getJaxbContext() { + return jaxbContext; + } + + /** + * @param jaxbContext the jaxbContext to set + */ + public void setJaxbContext(JAXBContext jaxbContext) { + this.jaxbContext = jaxbContext; + } + + /** + * Sets the JAXBContext for unmarshalling using the given {@code packageNames}. + * + * @param packageNames a collection of java package names + * @throws JAXBException if creating the JAXBContext with the given {@code packageNames} fails + */ + public void setJaxbContextPackageNames(Collection packageNames) throws JAXBException { + this.jaxbContext = createJAXBContext(packageNames); + } + + public Object unmarshal(Source source) throws XMLStreamException, JAXBException { + + ReportingValidationEventHandler validationEventHandler = new ReportingValidationEventHandler(); + + XMLInputFactory inputFactory = XMLInputFactory.newInstance(); + XMLEventReader eventReader = inputFactory.createXMLEventReader(source); + RedirectEventFilter redirectEventFilter = new RedirectEventFilter(); + XMLEventReader filteredReader = inputFactory.createFilteredReader(eventReader, redirectEventFilter); + + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + unmarshaller.setEventHandler(validationEventHandler); + + unmarshaller.setListener(new RedirectUnmarshallerListener(redirectEventFilter)); + unmarshaller.setSchema(slSchema); + + Object object; + try { + log.trace("Before unmarshal()."); + object = unmarshaller.unmarshal(filteredReader); + log.trace("After unmarshal()."); + } catch (UnmarshalException e) { + if (log.isDebugEnabled()) { + log.debug("Failed to unmarshall security layer message.", e); + } else { + log.info("Failed to unmarshall security layer message." + e.getMessage()); + } + + if (validationEventHandler.getErrorEvent() != null) { + ValidationEvent errorEvent = validationEventHandler.getErrorEvent(); + if (e.getLinkedException() == null) { + e.setLinkedException(errorEvent.getLinkedException()); + } + } + throw e; + } + + return object; + + } + +} -- cgit v1.2.3