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    }