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
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;
027import java.util.List;
028
029public 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}