org.hibernate.jpamodelgen.util.xml.JpaNamespaceTransformingEventReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-jpamodelgen-jakarta Show documentation
Show all versions of hibernate-jpamodelgen-jakarta Show documentation
Annotation Processor to generate JPA 3 static metamodel classes
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or .
*/
package org.hibernate.jpamodelgen.util.xml;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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.Attribute;
import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.util.EventReaderDelegate;
/**
* Transforms the version attribute and namespace of the JPA configuration files (persistence.xml and orm.xml) to
* the default. For the purpose of the metamodel it is enough to parse the xml against the latest specification version
* and schema.
*
* @author Hardy Ferentschik
*/
public class JpaNamespaceTransformingEventReader extends EventReaderDelegate {
private static final String VERSION_ATTRIBUTE_NAME = "version";
private static final String DEFAULT_VERSION = "2.1";
private static final String DEFAULT_PERSISTENCE_NAMESPACE = "http://xmlns.jcp.org/xml/ns/persistence";
private static final String DEFAULT_ORM_NAMESPACE = "http://xmlns.jcp.org/xml/ns/persistence/orm";
private static final Map NAMESPACE_MAPPING = new HashMap( 2 );
static {
NAMESPACE_MAPPING.put(
"http://java.sun.com/xml/ns/persistence",
DEFAULT_PERSISTENCE_NAMESPACE
);
NAMESPACE_MAPPING.put(
"http://java.sun.com/xml/ns/persistence/orm",
DEFAULT_ORM_NAMESPACE
);
}
private static final Map START_ELEMENT_TO_NAMESPACE_URI = new HashMap( 2 );
static {
START_ELEMENT_TO_NAMESPACE_URI.put(
"persistence",
DEFAULT_PERSISTENCE_NAMESPACE
);
START_ELEMENT_TO_NAMESPACE_URI.put(
"entity-mappings",
DEFAULT_ORM_NAMESPACE
);
}
private static final String EMPTY_PREFIX = "";
private final XMLEventFactory xmlEventFactory;
private String currentDocumentNamespaceUri;
public JpaNamespaceTransformingEventReader(XMLEventReader reader) {
super( reader );
this.xmlEventFactory = XMLEventFactory.newInstance();
}
@Override
public XMLEvent peek() throws XMLStreamException {
return wrap( super.peek() );
}
@Override
public XMLEvent nextEvent() throws XMLStreamException {
return wrap( super.nextEvent() );
}
private XMLEvent wrap(XMLEvent event) {
if ( event != null && event.isStartElement() ) {
return transform( event.asStartElement() );
}
return event;
}
private StartElement transform(StartElement startElement) {
String elementName = startElement.getName().getLocalPart();
// use the start element to determine whether we have a persistence.xml or orm.xml
if ( START_ELEMENT_TO_NAMESPACE_URI.containsKey( elementName ) ) {
currentDocumentNamespaceUri = START_ELEMENT_TO_NAMESPACE_URI.get( elementName );
}
List newElementAttributeList = updateElementAttributes( startElement );
List newNamespaceList = updateElementNamespaces( startElement );
// create the new element
return xmlEventFactory.createStartElement(
new QName( currentDocumentNamespaceUri, startElement.getName().getLocalPart() ),
newElementAttributeList.iterator(),
newNamespaceList.iterator()
);
}
private List updateElementNamespaces(StartElement startElement) {
List newNamespaceList = new ArrayList();
Iterator> existingNamespaceIterator = startElement.getNamespaces();
while ( existingNamespaceIterator.hasNext() ) {
Namespace namespace = (Namespace) existingNamespaceIterator.next();
if ( NAMESPACE_MAPPING.containsKey( namespace.getNamespaceURI() ) ) {
newNamespaceList.add( xmlEventFactory.createNamespace( EMPTY_PREFIX, currentDocumentNamespaceUri ) );
}
else {
newNamespaceList.add( namespace );
}
}
// if there is no namespace at all we add the main one. All elements need the namespace
if ( newNamespaceList.isEmpty() ) {
newNamespaceList.add( xmlEventFactory.createNamespace( EMPTY_PREFIX, currentDocumentNamespaceUri ) );
}
return newNamespaceList;
}
private List updateElementAttributes(StartElement startElement) {
// adjust the version attribute
List newElementAttributeList = new ArrayList();
Iterator> existingAttributesIterator = startElement.getAttributes();
while ( existingAttributesIterator.hasNext() ) {
Attribute attribute = (Attribute) existingAttributesIterator.next();
if ( VERSION_ATTRIBUTE_NAME.equals( attribute.getName().getLocalPart() ) ) {
if ( !DEFAULT_VERSION.equals( attribute.getName().getPrefix() ) ) {
newElementAttributeList.add(
xmlEventFactory.createAttribute(
attribute.getName(),
DEFAULT_VERSION
)
);
}
}
else {
newElementAttributeList.add( attribute );
}
}
return newElementAttributeList;
}
}