/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * 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 2.1 of * the License, or (at your option) any later version. * * This software 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 software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.as.jpa.jbossjpaparser; import java.util.HashMap; import java.util.Map; import javax.xml.namespace.QName; import javax.xml.stream.Location; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import org.jboss.as.jpa.config.ExtendedPersistenceInheritance; import org.jboss.as.jpa.config.JPADeploymentSettings; import org.jboss.as.server.logging.ServerLogger; import org.jboss.metadata.property.PropertyReplacer; import org.jboss.staxmapper.XMLExtendedStreamReader; /** * Parse the jboss-jpa settings in jboss-all.xml. * * @author Scott Marlow */ public class JBossJPAParser { public static final String NAMESPACE_1_0 = "http://www.jboss.com/xml/ns/javaee"; private static final JBossJPAParser INSTANCE = new JBossJPAParser(); private static final String INHERITANCE_CONSTANT = "inheritance"; public static JPADeploymentSettings parser(XMLExtendedStreamReader reader, PropertyReplacer propertyReplacer) throws XMLStreamException { JPADeploymentSettings result = new JPADeploymentSettings(); INSTANCE.readElement(reader, result, propertyReplacer); return result; } enum Element { JBOSS_JPA_DESCRIPTOR, EXTENDED_PERSISTENCE, // default unknown element UNKNOWN; private static final Map<QName, Element> elements; static { Map<QName, Element> elementsMap = new HashMap<QName, Element>(); elementsMap.put(new QName(NAMESPACE_1_0, "jboss-jpa"), Element.JBOSS_JPA_DESCRIPTOR); elementsMap.put(new QName(NAMESPACE_1_0, "extended-persistence"), Element.EXTENDED_PERSISTENCE); elements = elementsMap; } static Element of(QName qName) { QName name; if (qName.getNamespaceURI().equals("")) { name = new QName(NAMESPACE_1_0, qName.getLocalPart()); } else { name = qName; } final Element element = elements.get(name); return element == null ? UNKNOWN : element; } } enum Version { JBOSS_JPA_1_0, UNKNOWN } enum Attribute { INHERITANCE, // default unknown attribute UNKNOWN; private static final Map<QName, Attribute> attributes; static { Map<QName, Attribute> attributesMap = new HashMap<QName, Attribute>(); attributesMap.put(new QName(INHERITANCE_CONSTANT), INHERITANCE); attributes = attributesMap; } static Attribute of(QName qName) { final Attribute attribute = attributes.get(qName); return attribute == null ? UNKNOWN : attribute; } } private JBossJPAParser() { } public void readElement(final XMLExtendedStreamReader reader, final JPADeploymentSettings result, PropertyReplacer propertyReplacer) throws XMLStreamException { final int count = reader.getAttributeCount(); if (count != 0) { throw unexpectedContent(reader); } // xsd:sequence while (reader.hasNext()) { switch (reader.nextTag()) { case XMLStreamConstants.END_ELEMENT: { return; } case XMLStreamConstants.START_ELEMENT: { final Element element = Element.of(reader.getName()); switch (element) { case EXTENDED_PERSISTENCE: final String value = getAttributeValue(reader, null, INHERITANCE_CONSTANT, propertyReplacer); if (value == null || value.isEmpty()) { result.setExtendedPersistenceInheritanceType(ExtendedPersistenceInheritance.SHALLOW); } else { result.setExtendedPersistenceInheritanceType(ExtendedPersistenceInheritance.valueOf(value)); } break; default: throw unexpectedContent(reader); } break; } default: { throw unexpectedContent(reader); } } } throw endOfDocument(reader.getLocation()); } private static XMLStreamException unexpectedContent(final XMLStreamReader reader) { final String kind; switch (reader.getEventType()) { case XMLStreamConstants.ATTRIBUTE: kind = "attribute"; break; case XMLStreamConstants.CDATA: kind = "cdata"; break; case XMLStreamConstants.CHARACTERS: kind = "characters"; break; case XMLStreamConstants.COMMENT: kind = "comment"; break; case XMLStreamConstants.DTD: kind = "dtd"; break; case XMLStreamConstants.END_DOCUMENT: kind = "document end"; break; case XMLStreamConstants.END_ELEMENT: kind = "element end"; break; case XMLStreamConstants.ENTITY_DECLARATION: kind = "entity declaration"; break; case XMLStreamConstants.ENTITY_REFERENCE: kind = "entity ref"; break; case XMLStreamConstants.NAMESPACE: kind = "namespace"; break; case XMLStreamConstants.NOTATION_DECLARATION: kind = "notation declaration"; break; case XMLStreamConstants.PROCESSING_INSTRUCTION: kind = "processing instruction"; break; case XMLStreamConstants.SPACE: kind = "whitespace"; break; case XMLStreamConstants.START_DOCUMENT: kind = "document start"; break; case XMLStreamConstants.START_ELEMENT: kind = "element start"; break; default: kind = "unknown"; break; } return ServerLogger.ROOT_LOGGER.unexpectedContent(kind, (reader.hasName() ? reader.getName() : null), (reader.hasText() ? reader.getText() : null), reader.getLocation()); } private static String getAttributeValue(final XMLStreamReader reader,final String namespaceURI, final String localName, final PropertyReplacer propertyReplacer) throws XMLStreamException { return propertyReplacer.replaceProperties(reader.getAttributeValue(namespaceURI,localName)); } private static XMLStreamException endOfDocument(final Location location) { return ServerLogger.ROOT_LOGGER.unexpectedEndOfDocument(location); } }