/*
*
* * Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.com)
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
* *
* * For more information: http://www.orientechnologies.com
*
*/
package com.orientechnologies.orient.object.jpa.parsing;
import java.net.URL;
import java.util.Collection;
import java.util.Stack;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import com.orientechnologies.orient.object.jpa.OJPAPersistenceUnitInfo;
/**
* This code is responsible for parsing the persistence.xml into PersistenceUnits
*/
public class JPAHandler extends DefaultHandler {
/** The Persistence Units that we have parsed */
private final Stack<OJPAPersistenceUnitInfo> persistenceUnits = new Stack<OJPAPersistenceUnitInfo>();
/** root of the persistence unit */
private final URL persistenceXmlRoot;
/** The version of the persistence.xml file */
private String xmlSchemaVersion;
/** The name of the current element */
private PersistenceXml element;
/** A StringBuilder for caching the information from getCharacters */
private StringBuilder builder = new StringBuilder();
// /**
// * Create a new JPA Handler for the given persistence.xml. If no xmlSchemaVersion defined it will be parsed
// */
// public JPAHandler() {
// }
/**
* Create a new JPA Handler for the given persistence.xml
*
* @param persistenceXmlRoot
* @param jpaVersion
* the version of the JPA schema used in the xml
*/
public JPAHandler(URL persistenceXmlRoot, JPAVersion jpaVersion) {
this.persistenceXmlRoot = persistenceXmlRoot;
this.xmlSchemaVersion = jpaVersion.getVersion();
}
@Override
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
// Do this setting first as we use it later.
element = PersistenceXml.parse((localName == null || localName.isEmpty()) ? name : localName);
switch (element) {
case TAG_PERSISTENCE:
if (xmlSchemaVersion == null) {
xmlSchemaVersion = PersistenceXmlUtil.parseSchemaVersion(uri, element, attributes);
}
break;
case TAG_PERSISTENCE_UNIT:
String unitName = attributes.getValue(PersistenceXml.ATTR_UNIT_NAME.toString());
String transactionType = attributes.getValue(PersistenceXml.ATTR_TRANSACTION_TYPE.toString());
persistenceUnits.push(new OJPAPersistenceUnitInfo(unitName, transactionType, persistenceXmlRoot, xmlSchemaVersion));
break;
case TAG_EXCLUDE_UNLISTED_CLASSES:
persistenceUnits.peek().setExcludeUnlisted(true);
break;
case TAG_PROPERTY:
persistenceUnits.peek().addProperty(attributes.getValue("name"), attributes.getValue("value"));
break;
default:
}
}
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
String s = builder.toString().trim();
// This step is VERY important, otherwise we pollute subsequent
// ELEMENTS
builder = new StringBuilder();
if (s.isEmpty()) {
return;
}
OJPAPersistenceUnitInfo pu = persistenceUnits.peek();
switch (element) {
case TAG_PROVIDER:
pu.setProviderClassName(s);
break;
case TAG_JTA_DATA_SOURCE:
pu.setJtaDataSource(s);
break;
case TAG_NON_JTA_DATA_SOURCE:
pu.setNonJtaDataSource(s);
break;
case TAG_MAPPING_FILE:
pu.addMappingFileName(s);
break;
case TAG_JAR_FILE:
pu.addJarFileName(s);
break;
case TAG_CLASS:
pu.addClassName(s);
break;
case TAG_EXCLUDE_UNLISTED_CLASSES:
pu.setExcludeUnlisted(Boolean.parseBoolean(s));
break;
case TAG_SHARED_CACHE_MODE:
pu.setSharedCacheMode(s);
break;
case TAG_VALIDATION_MODE:
pu.setValidationMode(s);
break;
default:
}
}
/**
* Collect up the characters, as element's characters may be split across multiple calls. Isn't SAX lovely...
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
builder.append(ch, start, length);
}
/**
* We throw this exception to be caught further up and logged as an error there
*/
@Override
public void error(SAXParseException spe) throws SAXException {
throw spe;
}
/**
* @return The collection of persistence units that we have parsed
*/
public Collection<OJPAPersistenceUnitInfo> getPersistenceUnits() {
return persistenceUnits;
}
}