Skip to content

Commit

Permalink
HHH-7325 - Allow disabling XML validations via setting
Browse files Browse the repository at this point in the history
  • Loading branch information
sebersole committed May 18, 2012
1 parent 3791267 commit a046cc7
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 9 deletions.
@@ -0,0 +1,93 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.internal.xml;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.util.EventReaderDelegate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
* Used to wrap a StAX {@link XMLEventReader} in order to introduce namespaces into the underlying document. This
* is intended for temporary migration feature to allow legacy HBM mapping documents (DTD-based) to continue to
* parse correctly. This feature will go away eventually.
*
* @author Steve Ebersole
*/
public class NamespaceAddingEventReader extends EventReaderDelegate {
private final XMLEventFactory xmlEventFactory;
private final String namespaceUri;

public NamespaceAddingEventReader(XMLEventReader reader, String namespaceUri) {
this( reader, XMLEventFactory.newInstance(), namespaceUri );
}

public NamespaceAddingEventReader(XMLEventReader reader, XMLEventFactory xmlEventFactory, String namespaceUri) {
super( reader );
this.xmlEventFactory = xmlEventFactory;
this.namespaceUri = namespaceUri;
}

private StartElement withNamespace(StartElement startElement) {
// otherwise, wrap the start element event to provide a default namespace mapping
final List<Namespace> namespaces = new ArrayList<Namespace>();
namespaces.add( xmlEventFactory.createNamespace( "", namespaceUri ) );
Iterator<?> originalNamespaces = startElement.getNamespaces();
while ( originalNamespaces.hasNext() ) {
namespaces.add( (Namespace) originalNamespaces.next() );
}
return xmlEventFactory.createStartElement(
new QName( namespaceUri, startElement.getName().getLocalPart() ),
startElement.getAttributes(),
namespaces.iterator()
);
}

@Override
public XMLEvent nextEvent() throws XMLStreamException {
XMLEvent event = super.nextEvent();
if ( event.isStartElement() ) {
return withNamespace( event.asStartElement() );
}
return event;
}

@Override
public XMLEvent peek() throws XMLStreamException {
XMLEvent event = super.peek();
if ( event.isStartElement() ) {
return withNamespace( event.asStartElement() );
}
else {
return event;
}
}
}
Expand Up @@ -39,6 +39,7 @@
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
Expand All @@ -54,10 +55,13 @@
import org.hibernate.internal.jaxb.Origin;
import org.hibernate.internal.jaxb.mapping.hbm.JaxbHibernateMapping;
import org.hibernate.internal.jaxb.mapping.orm.JaxbEntityMappings;
import org.hibernate.internal.xml.NamespaceAddingEventReader;
import org.hibernate.metamodel.MetadataSources;
import org.hibernate.metamodel.spi.source.MappingException;
import org.hibernate.metamodel.spi.source.XsdException;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.config.spi.ConfigurationService;
import org.hibernate.service.config.spi.StandardConverters;

/**
* Helper class for unmarshalling xml configuration using StAX and JAXB.
Expand All @@ -69,11 +73,18 @@ public class JaxbHelper {
private static final Logger log = Logger.getLogger( JaxbHelper.class );

public static final String ASSUMED_ORM_XSD_VERSION = "2.0";
public static final String VALIDATE_XML_SETTING = "hibernate.xml.validate";
public static final String HIBERNATE_MAPPING_URI = "http://www.hibernate.org/xsd/hibernate-mapping";

private final MetadataSources metadataSources;
private final boolean validateXml;

public JaxbHelper(MetadataSources metadataSources) {
this.metadataSources = metadataSources;

this.validateXml = metadataSources.getServiceRegistry()
.getService( ConfigurationService.class )
.getSetting( VALIDATE_XML_SETTING, StandardConverters.BOOLEAN, true );
}

public JaxbRoot unmarshal(InputStream stream, Origin origin) {
Expand Down Expand Up @@ -138,11 +149,16 @@ private JaxbRoot unmarshal(XMLEventReader staxEventReader, final Origin origin)
if ( "entity-mappings".equals( elementName ) ) {
final Attribute attribute = event.asStartElement().getAttributeByName( ORM_VERSION_ATTRIBUTE_QNAME );
final String explicitVersion = attribute == null ? null : attribute.getValue();
validationSchema = resolveSupportedOrmXsd( explicitVersion );
validationSchema = validateXml ? resolveSupportedOrmXsd( explicitVersion ) : null;
jaxbTarget = JaxbEntityMappings.class;
}
else {
validationSchema = hbmSchema();
if ( !isNamespaced( event.asStartElement() ) ) {
// if the elements are not namespaced, wrap the reader in a reader which will namespace them as pulled.
log.debug( "HBM mapping document did not define namespaces; wrapping in custom event reader to introduce namespace information" );
staxEventReader = new NamespaceAddingEventReader( staxEventReader, HIBERNATE_MAPPING_URI );
}
validationSchema = validateXml ? hbmSchema() : null;
jaxbTarget = JaxbHibernateMapping.class;
}

Expand All @@ -155,7 +171,6 @@ private JaxbRoot unmarshal(XMLEventReader staxEventReader, final Origin origin)
unmarshaller.setEventHandler( handler );
target = unmarshaller.unmarshal( staxEventReader );
}

catch ( JAXBException e ) {
StringBuilder builder = new StringBuilder();
builder.append( "Unable to perform unmarshalling at line number " );
Expand All @@ -170,6 +185,10 @@ private JaxbRoot unmarshal(XMLEventReader staxEventReader, final Origin origin)
return new JaxbRoot( target, origin );
}

private boolean isNamespaced(StartElement startElement) {
return ! "".equals( startElement.getName().getNamespaceURI() );
}

@SuppressWarnings( { "unchecked" })
public JaxbRoot unmarshal(Document document, Origin origin) {
Element rootElement = document.getDocumentElement();
Expand All @@ -182,11 +201,11 @@ public JaxbRoot unmarshal(Document document, Origin origin) {

if ( "entity-mappings".equals( rootElement.getNodeName() ) ) {
final String explicitVersion = rootElement.getAttribute( "version" );
validationSchema = resolveSupportedOrmXsd( explicitVersion );
validationSchema = validateXml ? resolveSupportedOrmXsd( explicitVersion ) : null;
jaxbTarget = JaxbEntityMappings.class;
}
else {
validationSchema = hbmSchema();
validationSchema = validateXml ? hbmSchema() : null;
jaxbTarget = JaxbHibernateMapping.class;
}

Expand Down
@@ -1,9 +1,7 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.hibernate.test.abstractembeddedcomponents.cid">
<hibernate-mapping xmlns="http://www.hibernate.org/xsd/hibernate-mapping"
package="org.hibernate.test.abstractembeddedcomponents.cid">

<class name="MyInterface" table="MY_INTF" proxy="MyInterface">
<composite-id>
Expand Down

0 comments on commit a046cc7

Please sign in to comment.