    001    // Copyright 2011 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
    015    package org.apache.tapestry5.internal.jpa;
    016
    017    import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
    018    import org.apache.tapestry5.jpa.TapestryPersistenceUnitInfo;
    019    import org.xml.sax.Attributes;
    020    import org.xml.sax.ContentHandler;
    021    import org.xml.sax.Locator;
    022    import org.xml.sax.SAXException;
    023
    024    import javax.persistence.SharedCacheMode;
    025    import javax.persistence.ValidationMode;
    026    import javax.persistence.spi.PersistenceUnitTransactionType;
    027    import java.util.List;
    028
    029    public class PersistenceContentHandler implements ContentHandler
    030    {
    031        private static final String NAMESPACE_URI = "http://java.sun.com/xml/ns/persistence";
    032        private static final String ELEMENT_PERSISTENCE_UNIT = "persistence-unit";
    033        private static final String ELEMENT_PROVIDER = "provider";
    034        private static final String ELEMENT_JTA_DATA_SOURCE = "jta-data-source";
    035        private static final String ELEMENT_NON_JTA_DATA_SOURCE = "non-jta-data-source";
    036        private static final String ELEMENT_MAPPING_FILE = "mapping-file";
    037        private static final String ELEMENT_JAR_FILE = "jar-file";
    038        private static final String ELEMENT_CLASS = "class";
    039        private static final String ELEMENT_EXCLUDE_UNLISTED_CLASSES = "exclude-unlisted-classes";
    040        private static final String ELEMENT_CACHING = "shared-cache-mode";
    041        private static final String ELEMENT_VALIDATION_MODE = "validation-mode";
    042        private static final String ELEMENT_PROPERTY = "property";
    043        private static final String ATTRIBUTE_NAME = "name";
    044        private static final String ATTRIBUTE_VALUE = "value";
    045        private static final String ATTRIBUTE_VERSION = "value";
    046        private static final String ATTRIBUTE_TRANSACTION_TYPE = "transaction-type";
    047
    048        private final List<TapestryPersistenceUnitInfo> persistenceUnits = CollectionFactory.newList();
    049        private PersistenceUnitInfoImpl persistenceUnitInfo;
    050        private StringBuilder characters;
    051
    052        public List<TapestryPersistenceUnitInfo> getPersistenceUnits()
    053        {
    054            return persistenceUnits;
    055        }
    056
    057        public void setDocumentLocator(final Locator locator)
    058        {
    059        }
    060
    061        public void startDocument() throws SAXException
    062        {
    063        }
    064
    065        public void endDocument() throws SAXException
    066        {
    067        }
    068
    069        public void startPrefixMapping(final String prefix, final String uri) throws SAXException
    070        {
    071        }
    072
    073        public void endPrefixMapping(final String prefix) throws SAXException
    074        {
    075        }
    076
    077        public void startElement(final String namespaceURI, final String localName, final String qName,
    078                                 final Attributes atts) throws SAXException
    079        {
    080            if (NAMESPACE_URI.equals(namespaceURI))
    081            {
    082                if (ELEMENT_PERSISTENCE_UNIT.equals(localName))
    083                {
    084                    persistenceUnitInfo = new PersistenceUnitInfoImpl(atts.getValue(ATTRIBUTE_NAME));
    085                    persistenceUnitInfo
    086                            .setPersistenceXMLSchemaVersion(atts.getValue(ATTRIBUTE_VERSION));
    087
    088                    final String transactionType = atts.getValue(ATTRIBUTE_TRANSACTION_TYPE);
    089
    090                    if (transactionType != null)
    091                    {
    092                        persistenceUnitInfo.transactionType(PersistenceUnitTransactionType
    093                                .valueOf(transactionType));
    094                    }
    095                } else if (ELEMENT_PROPERTY.equals(localName))
    096                {
    097                    final String name = atts.getValue(ATTRIBUTE_NAME);
    098                    final String value = atts.getValue(ATTRIBUTE_VALUE);
    099                    persistenceUnitInfo.getProperties().setProperty(name, value);
    100                }
    101            }
    102        }
    103
    104        public void endElement(final String namespaceURI, final String localName, final String qName)
    105                throws SAXException
    106        {
    107
    108            final String string = characters.toString().trim();
    109            characters = null;
    110
    111            if (NAMESPACE_URI.equals(namespaceURI))
    112            {
    113                if (ELEMENT_PROVIDER.equals(localName))
    114                {
    115                    persistenceUnitInfo.persistenceProviderClassName(string);
    116                }
    117                else if (ELEMENT_CLASS.equals(localName))
    118                {
    119                    persistenceUnitInfo.addManagedClassName(string);
    120                }
    121                else if (ELEMENT_CACHING.equals(localName))
    122                {
    123                    persistenceUnitInfo.sharedCacheMode(toEnum(SharedCacheMode.class, string));
    124                }
    125                else if (ELEMENT_VALIDATION_MODE.equals(localName))
    126                {
    127                    persistenceUnitInfo.validationMode(toEnum(ValidationMode.class, string));
    128                }
    129                else if (ELEMENT_MAPPING_FILE.equals(localName))
    130                {
    131                    persistenceUnitInfo.addMappingFileName(string);
    132                }
    133                else if (ELEMENT_JAR_FILE.equals(localName))
    134                {
    135                    persistenceUnitInfo.addJarFileUrl(string);
    136                }
    137                else if (ELEMENT_NON_JTA_DATA_SOURCE.equals(localName))
    138                {
    139                    persistenceUnitInfo.nonJtaDataSource(string);
    140                }
    141                else if (ELEMENT_JTA_DATA_SOURCE.equals(localName))
    142                {
    143                    persistenceUnitInfo.jtaDataSource(string);
    144                }
    145                else if (ELEMENT_PERSISTENCE_UNIT.equals(localName))
    146                {
    147                    if (persistenceUnitInfo != null)
    148                    {
    149                        persistenceUnits.add(persistenceUnitInfo);
    150                        persistenceUnitInfo = null;
    151                    }
    152                } else if (ELEMENT_EXCLUDE_UNLISTED_CLASSES.equals(localName))
    153                {
    154                    persistenceUnitInfo.excludeUnlistedClasses(Boolean.valueOf(string));
    155                }
    156            }
    157        }
    158
    159        public void characters(final char[] ch, final int start, final int length) throws SAXException
    160        {
    161            final String s = new String(ch, start, length);
    162
    163            if (characters == null)
    164            {
    165                characters = new StringBuilder(s);
    166            } else
    167            {
    168                characters.append(s);
    169            }
    170
    171        }
    172
    173        public void ignorableWhitespace(final char[] ch, final int start, final int length)
    174                throws SAXException
    175        {
    176        }
    177
    178        public void processingInstruction(final String target, final String data) throws SAXException
    179        {
    180        }
    181
    182        public void skippedEntity(final String name) throws SAXException
    183        {
    184        }
    185
    186        private <T extends Enum<T>> T toEnum(final Class<T> enumType, final String value)
    187        {
    188            return Enum.valueOf(enumType, value);
    189        }
    190    }