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.commons.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}