    001// Copyright 2011, 2014 The Apache Software Foundation
    002//
    003// Licensed under the Apache License, Version 2.0 (the "License");
    004// you may not use this file except in compliance with the License.
    005// You may obtain a copy of the License at
    006//
    007// http://www.apache.org/licenses/LICENSE-2.0
    008//
    009// Unless required by applicable law or agreed to in writing, software
    010// distributed under the License is distributed on an "AS IS" BASIS,
    011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012// See the License for the specific language governing permissions and
    013// limitations under the License.
    014
    015package org.apache.tapestry5.internal.jpa;
    016
    017import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
    018import org.apache.tapestry5.jpa.TapestryPersistenceUnitInfo;
    019import org.xml.sax.Attributes;
    020import org.xml.sax.ContentHandler;
    021import org.xml.sax.Locator;
    022import org.xml.sax.SAXException;
    023
    024import javax.persistence.SharedCacheMode;
    025import javax.persistence.ValidationMode;
    026import javax.persistence.spi.PersistenceUnitTransactionType;
    027
    028import java.util.Arrays;
    029import java.util.Collections;
    030import java.util.List;
    031import java.util.Set;
    032
    033public class PersistenceContentHandler implements ContentHandler
    034{
    035    private static final List<String> NAMESPACE_URIS = Arrays.asList(
    036                new String[]{"http://java.sun.com/xml/ns/persistence", "http://xmlns.jcp.org/xml/ns/persistence"});
    037    private static final String ELEMENT_PERSISTENCE_UNIT = "persistence-unit";
    038    private static final String ELEMENT_PROVIDER = "provider";
    039    private static final String ELEMENT_JTA_DATA_SOURCE = "jta-data-source";
    040    private static final String ELEMENT_NON_JTA_DATA_SOURCE = "non-jta-data-source";
    041    private static final String ELEMENT_MAPPING_FILE = "mapping-file";
    042    private static final String ELEMENT_JAR_FILE = "jar-file";
    043    private static final String ELEMENT_CLASS = "class";
    044    private static final String ELEMENT_EXCLUDE_UNLISTED_CLASSES = "exclude-unlisted-classes";
    045    private static final String ELEMENT_CACHING = "shared-cache-mode";
    046    private static final String ELEMENT_VALIDATION_MODE = "validation-mode";
    047    private static final String ELEMENT_PROPERTY = "property";
    048    private static final String ATTRIBUTE_NAME = "name";
    049    private static final String ATTRIBUTE_VALUE = "value";
    050    private static final String ATTRIBUTE_VERSION = "value";
    051    private static final String ATTRIBUTE_TRANSACTION_TYPE = "transaction-type";
    052
    053    private final List<TapestryPersistenceUnitInfo> persistenceUnits = CollectionFactory.newList();
    054    private PersistenceUnitInfoImpl persistenceUnitInfo;
    055    private StringBuilder characters;
    056
    057    public List<TapestryPersistenceUnitInfo> getPersistenceUnits()
    058    {
    059        return persistenceUnits;
    060    }
    061
    062    @Override
    063    public void setDocumentLocator(final Locator locator)
    064    {
    065    }
    066
    067    @Override
    068    public void startDocument() throws SAXException
    069    {
    070    }
    071
    072    @Override
    073    public void endDocument() throws SAXException
    074    {
    075    }
    076
    077    @Override
    078    public void startPrefixMapping(final String prefix, final String uri) throws SAXException
    079    {
    080    }
    081
    082    @Override
    083    public void endPrefixMapping(final String prefix) throws SAXException
    084    {
    085    }
    086
    087    @Override
    088    public void startElement(final String namespaceURI, final String localName, final String qName,
    089                             final Attributes atts) throws SAXException
    090    {
    091        if (NAMESPACE_URIS.contains(namespaceURI))
    092        {
    093            if (ELEMENT_PERSISTENCE_UNIT.equals(localName))
    094            {
    095                persistenceUnitInfo = new PersistenceUnitInfoImpl(atts.getValue(ATTRIBUTE_NAME));
    096                persistenceUnitInfo
    097                        .setPersistenceXMLSchemaVersion(atts.getValue(ATTRIBUTE_VERSION));
    098
    099                final String transactionType = atts.getValue(ATTRIBUTE_TRANSACTION_TYPE);
    100
    101                if (transactionType != null)
    102                {
    103                    persistenceUnitInfo.transactionType(PersistenceUnitTransactionType
    104                            .valueOf(transactionType));
    105                }
    106            } else if (ELEMENT_PROPERTY.equals(localName))
    107            {
    108                final String name = atts.getValue(ATTRIBUTE_NAME);
    109                final String value = atts.getValue(ATTRIBUTE_VALUE);
    110                persistenceUnitInfo.getProperties().setProperty(name, value);
    111            }
    112        }
    113    }
    114
    115    @Override
    116    public void endElement(final String namespaceURI, final String localName, final String qName)
    117            throws SAXException
    118    {
    119
    120        final String string = characters.toString().trim();
    121        characters = null;
    122
    123        if (NAMESPACE_URIS.contains(namespaceURI))
    124        {
    125            if (ELEMENT_PROVIDER.equals(localName))
    126            {
    127                persistenceUnitInfo.persistenceProviderClassName(string);
    128            }
    129            else if (ELEMENT_CLASS.equals(localName))
    130            {
    131                persistenceUnitInfo.addManagedClassName(string);
    132            }
    133            else if (ELEMENT_CACHING.equals(localName))
    134            {
    135                persistenceUnitInfo.sharedCacheMode(toEnum(SharedCacheMode.class, string));
    136            }
    137            else if (ELEMENT_VALIDATION_MODE.equals(localName))
    138            {
    139                persistenceUnitInfo.validationMode(toEnum(ValidationMode.class, string));
    140            }
    141            else if (ELEMENT_MAPPING_FILE.equals(localName))
    142            {
    143                persistenceUnitInfo.addMappingFileName(string);
    144            }
    145            else if (ELEMENT_JAR_FILE.equals(localName))
    146            {
    147                persistenceUnitInfo.addJarFileUrl(string);
    148            }
    149            else if (ELEMENT_NON_JTA_DATA_SOURCE.equals(localName))
    150            {
    151                persistenceUnitInfo.nonJtaDataSource(string);
    152            }
    153            else if (ELEMENT_JTA_DATA_SOURCE.equals(localName))
    154            {
    155                persistenceUnitInfo.jtaDataSource(string);
    156            }
    157            else if (ELEMENT_PERSISTENCE_UNIT.equals(localName))
    158            {
    159                if (persistenceUnitInfo != null)
    160                {
    161                    persistenceUnits.add(persistenceUnitInfo);
    162                    persistenceUnitInfo = null;
    163                }
    164            } else if (ELEMENT_EXCLUDE_UNLISTED_CLASSES.equals(localName))
    165            {
    166                persistenceUnitInfo.excludeUnlistedClasses(Boolean.valueOf(string));
    167            }
    168        }
    169    }
    170
    171    @Override
    172    public void characters(final char[] ch, final int start, final int length) throws SAXException
    173    {
    174        final String s = new String(ch, start, length);
    175
    176        if (characters == null)
    177        {
    178            characters = new StringBuilder(s);
    179        } else
    180        {
    181            characters.append(s);
    182        }
    183
    184    }
    185
    186    @Override
    187    public void ignorableWhitespace(final char[] ch, final int start, final int length)
    188            throws SAXException
    189    {
    190    }
    191
    192    @Override
    193    public void processingInstruction(final String target, final String data) throws SAXException
    194    {
    195    }
    196
    197    @Override
    198    public void skippedEntity(final String name) throws SAXException
    199    {
    200    }
    201
    202    private <T extends Enum<T>> T toEnum(final Class<T> enumType, final String value)
    203    {
    204        return Enum.valueOf(enumType, value);
    205    }
    206}