HHH-7387 - Integrate Draft 6 of the JPA 2.1 spec : AttributeConverter + HEM boot cleanup (HHH-6159)

This commit is contained in:
Steve Ebersole 2012-07-11 09:19:31 -05:00
parent ad2a9ef651
commit 9ce3afd8da
28 changed files with 3133 additions and 158 deletions

View File

@ -168,7 +168,7 @@ subprojects { subProject ->
deployerJars "org.apache.maven.wagon:wagon-http:1.0"
}
aptDumpDir = file( "${buildDir}/tmp/apt" )
aptDumpDir = subProject.file( "${buildDir}/tmp/apt" )
sourceSets.main {
compileClasspath += configurations.provided
@ -200,7 +200,7 @@ subprojects { subProject ->
);
outputs.dir sourceSets.main.generatedLoggingSrcDir;
doFirst {
source = sourceSets.main.originalJavaSrcDirs
// source = sourceSets.main.originalJavaSrcDirs
sourceSets.main.generatedLoggingSrcDir.mkdirs()
}
}

View File

@ -10,19 +10,17 @@ dependencies {
compile( libraries.jpa )
compile( libraries.javassist )
compile( libraries.antlr )
compile( libraries.jandex )
compile( libraries.classmate )
antlr( libraries.antlr )
provided( libraries.jandex )
provided( libraries.classmate )
provided( libraries.ant )
provided( libraries.jacc )
provided( libraries.validation )
testCompile( project(':hibernate-testing') )
testCompile( libraries.validation )
testCompile( libraries.jandex )
testCompile( libraries.classmate )
testCompile( libraries.validator ) {
// for test runtime
transitive = true

View File

@ -36,6 +36,7 @@ import org.hibernate.engine.transaction.spi.TransactionFactory;
import org.hibernate.engine.transaction.spi.TransactionImplementor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.classloading.spi.ClassLoadingException;
import org.hibernate.service.spi.BasicServiceInitiator;
import org.hibernate.service.spi.ServiceRegistryImplementor;
@ -60,24 +61,53 @@ public class TransactionFactoryInitiator<T extends TransactionImplementor> imple
@SuppressWarnings( {"unchecked"})
public TransactionFactory initiateService(Map configurationValues, ServiceRegistryImplementor registry) {
final Object strategy = configurationValues.get( Environment.TRANSACTION_STRATEGY );
if ( TransactionFactory.class.isInstance( strategy ) ) {
return (TransactionFactory) strategy;
}
if ( strategy == null ) {
LOG.usingDefaultTransactionStrategy();
return new JdbcTransactionFactory();
}
final String strategyClassName = mapLegacyNames( strategy.toString() );
LOG.transactionStrategy( strategyClassName );
if ( TransactionFactory.class.isInstance( strategy ) ) {
return (TransactionFactory) strategy;
}
Class<? extends TransactionFactory> transactionFactoryClass;
if ( Class.class.isInstance( strategy ) ) {
final Class theClass = (Class) strategy;
LOG.transactionStrategy( theClass.getName() );
try {
transactionFactoryClass = (Class<? extends TransactionFactory>) theClass;
}
catch (ClassCastException e) {
throw new ClassLoadingException(
String.format(
"TransactionFactory implementation class [%s] did not implement TransactionFactory interface",
theClass.getName()
)
);
}
}
else {
final String strategyClassName = mapLegacyNames( strategy.toString() );
LOG.transactionStrategy( strategyClassName );
try {
transactionFactoryClass = registry.getService( ClassLoaderService.class ).classForName( strategyClassName );
}
catch (ClassCastException e) {
throw new ClassLoadingException(
String.format(
"TransactionFactory implementation class [%s] did not implement TransactionFactory interface",
strategyClassName
)
);
}
}
ClassLoaderService classLoaderService = registry.getService( ClassLoaderService.class );
try {
return (TransactionFactory) classLoaderService.classForName( strategyClassName ).newInstance();
return transactionFactoryClass.newInstance();
}
catch ( Exception e ) {
throw new HibernateException( "Unable to instantiate specified TransactionFactory class [" + strategyClassName + "]", e );
throw new HibernateException( "Unable to instantiate specified TransactionFactory class [" + transactionFactoryClass.getName() + "]", e );
}
}

View File

@ -35,6 +35,8 @@ import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ColumnResult;
import javax.persistence.Convert;
import javax.persistence.Converter;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
@ -129,6 +131,8 @@ public interface JPADotNames {
DotName COLLECTION_TABLE = DotName.createSimple( CollectionTable.class.getName() );
DotName COLUMN = DotName.createSimple( Column.class.getName() );
DotName COLUMN_RESULT = DotName.createSimple( ColumnResult.class.getName() );
DotName CONVERT = DotName.createSimple( Convert.class.getName() );
DotName CONVERTER = DotName.createSimple( Converter.class.getName() );
DotName DISCRIMINATOR_COLUMN = DotName.createSimple( DiscriminatorColumn.class.getName() );
DotName DISCRIMINATOR_TYPE = DotName.createSimple( DiscriminatorType.class.getName() );
DotName DISCRIMINATOR_VALUE = DotName.createSimple( DiscriminatorValue.class.getName() );

View File

@ -0,0 +1,93 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.service;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.jboss.logging.Logger;
import org.hibernate.internal.jaxb.Origin;
import org.hibernate.internal.jaxb.SourceType;
import org.hibernate.internal.jaxb.cfg.JaxbHibernateConfiguration;
import org.hibernate.internal.util.ValueHolder;
import org.hibernate.internal.util.config.ConfigurationException;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.internal.JaxbProcessor;
/**
* Loads {@code cfg.xml} files.
*
* @author Steve Ebersole
*/
public class ConfigLoader {
private static final Logger log = Logger.getLogger( ConfigLoader.class );
private final BootstrapServiceRegistry bootstrapServiceRegistry;
private ValueHolder<JaxbProcessor> jaxbProcessorHolder = new ValueHolder<JaxbProcessor>(
new ValueHolder.DeferredInitializer<JaxbProcessor>() {
@Override
public JaxbProcessor initialize() {
return new JaxbProcessor( bootstrapServiceRegistry.getService( ClassLoaderService.class ) );
}
}
);
public ConfigLoader(BootstrapServiceRegistry bootstrapServiceRegistry) {
this.bootstrapServiceRegistry = bootstrapServiceRegistry;
}
public JaxbHibernateConfiguration loadConfigXmlResource(String cfgXmlResourceName) {
final InputStream stream = bootstrapServiceRegistry.getService( ClassLoaderService.class ).locateResourceStream( cfgXmlResourceName );
if ( stream == null ) {
throw new ConfigurationException( "Could not locate cfg.xml resource [" + cfgXmlResourceName + "]" );
}
return jaxbProcessorHolder.getValue().unmarshal( stream, new Origin( SourceType.RESOURCE, cfgXmlResourceName ) );
}
public Properties loadProperties(String resourceName) {
final InputStream stream = bootstrapServiceRegistry.getService( ClassLoaderService.class ).locateResourceStream( resourceName );
try {
Properties properties = new Properties();
properties.load( stream );
return properties;
}
catch (IOException e) {
throw new ConfigurationException( "Unable to apply settings from properties file [" + resourceName + "]", e );
}
finally {
try {
stream.close();
}
catch (IOException e) {
log.debug(
String.format( "Unable to close properties file [%s] stream", resourceName ),
e
);
}
}
}
}

View File

@ -23,29 +23,19 @@
*/
package org.hibernate.service;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.jboss.logging.Logger;
import org.hibernate.cfg.Environment;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.integrator.spi.IntegratorService;
import org.hibernate.integrator.spi.ServiceContributingIntegrator;
import org.hibernate.internal.jaxb.Origin;
import org.hibernate.internal.jaxb.SourceType;
import org.hibernate.internal.jaxb.cfg.JaxbHibernateConfiguration;
import org.hibernate.internal.util.ValueHolder;
import org.hibernate.internal.util.config.ConfigurationException;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.internal.BootstrapServiceRegistryImpl;
import org.hibernate.service.internal.JaxbProcessor;
import org.hibernate.service.internal.ProvidedService;
import org.hibernate.service.internal.StandardServiceRegistryImpl;
import org.hibernate.service.spi.BasicServiceInitiator;
@ -59,8 +49,6 @@ import org.hibernate.service.spi.BasicServiceInitiator;
* @see BootstrapServiceRegistryBuilder
*/
public class ServiceRegistryBuilder {
private static final Logger log = Logger.getLogger( ServiceRegistryBuilder.class );
public static final String DEFAULT_CFG_RESOURCE_NAME = "hibernate.cfg.xml";
private final Map settings;
@ -68,6 +56,7 @@ public class ServiceRegistryBuilder {
private final List<ProvidedService> providedServices = new ArrayList<ProvidedService>();
private final BootstrapServiceRegistry bootstrapServiceRegistry;
private final ConfigLoader configLoader;
/**
* Create a default builder
@ -84,6 +73,7 @@ public class ServiceRegistryBuilder {
public ServiceRegistryBuilder(BootstrapServiceRegistry bootstrapServiceRegistry) {
this.settings = Environment.getProperties();
this.bootstrapServiceRegistry = bootstrapServiceRegistry;
this.configLoader = new ConfigLoader( bootstrapServiceRegistry );
}
/**
@ -110,27 +100,7 @@ public class ServiceRegistryBuilder {
*/
@SuppressWarnings( {"unchecked"})
public ServiceRegistryBuilder loadProperties(String resourceName) {
InputStream stream = bootstrapServiceRegistry.getService( ClassLoaderService.class ).locateResourceStream( resourceName );
try {
Properties properties = new Properties();
properties.load( stream );
settings.putAll( properties );
}
catch (IOException e) {
throw new ConfigurationException( "Unable to apply settings from properties file [" + resourceName + "]", e );
}
finally {
try {
stream.close();
}
catch (IOException e) {
log.debug(
String.format( "Unable to close properties file [%s] stream", resourceName ),
e
);
}
}
settings.putAll( configLoader.loadProperties( resourceName ) );
return this;
}
@ -158,11 +128,7 @@ public class ServiceRegistryBuilder {
*/
@SuppressWarnings( {"unchecked"})
public ServiceRegistryBuilder configure(String resourceName) {
InputStream stream = bootstrapServiceRegistry.getService( ClassLoaderService.class ).locateResourceStream( resourceName );
JaxbHibernateConfiguration configurationElement = jaxbProcessorHolder.getValue().unmarshal(
stream,
new Origin( SourceType.RESOURCE, resourceName )
);
JaxbHibernateConfiguration configurationElement = configLoader.loadConfigXmlResource( resourceName );
for ( JaxbHibernateConfiguration.JaxbSessionFactory.JaxbProperty xmlProperty : configurationElement.getSessionFactory().getProperty() ) {
settings.put( xmlProperty.getName(), xmlProperty.getValue() );
}
@ -170,15 +136,6 @@ public class ServiceRegistryBuilder {
return this;
}
private ValueHolder<JaxbProcessor> jaxbProcessorHolder = new ValueHolder<JaxbProcessor>(
new ValueHolder.DeferredInitializer<JaxbProcessor>() {
@Override
public JaxbProcessor initialize() {
return new JaxbProcessor( bootstrapServiceRegistry.getService( ClassLoaderService.class ) );
}
}
);
/**
* Apply a setting value
*

View File

@ -35,6 +35,8 @@ import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import org.jboss.logging.Logger;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.classloading.spi.ClassLoadingException;
@ -45,6 +47,8 @@ import org.hibernate.service.classloading.spi.ClassLoadingException;
* @author Steve Ebersole
*/
public class ClassLoaderServiceImpl implements ClassLoaderService {
private static final Logger log = Logger.getLogger( ClassLoaderServiceImpl.class );
private final ClassLoader classClassLoader;
private final ClassLoader resourcesClassLoader;
@ -164,17 +168,43 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
public InputStream locateResourceStream(String name) {
// first we try name as a URL
try {
log.tracef( "trying via [new URL(\"%s\")]", name );
return new URL( name ).openStream();
}
catch ( Exception ignore ) {
}
try {
return resourcesClassLoader.getResourceAsStream( name );
log.tracef( "trying via [ClassLoader.getResourceAsStream(\"%s\")]", name );
InputStream stream = resourcesClassLoader.getResourceAsStream( name );
if ( stream != null ) {
return stream;
}
}
catch ( Exception ignore ) {
}
final String stripped = name.startsWith( "/" ) ? name.substring(1) : null;
if ( stripped != null ) {
try {
log.tracef( "trying via [new URL(\"%s\")]", stripped );
return new URL( stripped ).openStream();
}
catch ( Exception ignore ) {
}
try {
log.tracef( "trying via [ClassLoader.getResourceAsStream(\"%s\")]", stripped );
InputStream stream = resourcesClassLoader.getResourceAsStream( stripped );
if ( stream != null ) {
return stream;
}
}
catch ( Exception ignore ) {
}
}
return null;
}

View File

@ -26,6 +26,9 @@ package org.hibernate.service.internal;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
@ -33,9 +36,15 @@ import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.ValidationEventLocator;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.util.EventReaderDelegate;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
@ -56,6 +65,8 @@ import org.hibernate.service.classloading.spi.ClassLoaderService;
public class JaxbProcessor {
private static final Logger log = Logger.getLogger( JaxbProcessor.class );
public static final String HIBERNATE_CONFIGURATION_URI = "http://www.hibernate.org/xsd/hibernate-configuration";
private final ClassLoaderService classLoaderService;
public JaxbProcessor(ClassLoaderService classLoaderService) {
@ -64,7 +75,7 @@ public class JaxbProcessor {
public JaxbHibernateConfiguration unmarshal(InputStream stream, Origin origin) {
try {
XMLStreamReader staxReader = staxFactory().createXMLStreamReader( stream );
XMLEventReader staxReader = staxFactory().createXMLEventReader( stream );
try {
return unmarshal( staxReader, origin );
}
@ -97,7 +108,29 @@ public class JaxbProcessor {
}
@SuppressWarnings( { "unchecked" })
private JaxbHibernateConfiguration unmarshal(XMLStreamReader staxReader, final Origin origin) {
private JaxbHibernateConfiguration unmarshal(XMLEventReader staxEventReader, final Origin origin) {
XMLEvent event;
try {
event = staxEventReader.peek();
while ( event != null && !event.isStartElement() ) {
staxEventReader.nextEvent();
event = staxEventReader.peek();
}
}
catch ( Exception e ) {
throw new MappingException( "Error accessing stax stream", e, origin );
}
if ( event == null ) {
throw new MappingException( "Could not locate root element", origin );
}
if ( !isNamespaced( event.asStartElement() ) ) {
// if the elements are not namespaced, wrap the reader in a reader which will namespace them as pulled.
log.debug( "cfg.xml document did not define namespaces; wrapping in custom event reader to introduce namespace information" );
staxEventReader = new NamespaceAddingEventReader( staxEventReader, HIBERNATE_CONFIGURATION_URI );
}
final Object target;
final ContextProvidingValidationEventHandler handler = new ContextProvidingValidationEventHandler();
try {
@ -105,7 +138,7 @@ public class JaxbProcessor {
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
unmarshaller.setSchema( schema() );
unmarshaller.setEventHandler( handler );
target = unmarshaller.unmarshal( staxReader );
target = unmarshaller.unmarshal( staxEventReader );
return (JaxbHibernateConfiguration) target;
}
catch ( JAXBException e ) {
@ -121,6 +154,10 @@ public class JaxbProcessor {
}
}
private boolean isNamespaced(StartElement startElement) {
return ! "".equals( startElement.getName().getNamespaceURI() );
}
private Schema schema;
private Schema schema() {
@ -192,4 +229,54 @@ public class JaxbProcessor {
return message;
}
}
public class NamespaceAddingEventReader extends EventReaderDelegate {
private final XMLEventFactory xmlEventFactory;
private final String namespaceUri;
public NamespaceAddingEventReader(XMLEventReader reader, String namespaceUri) {
this( reader, XMLEventFactory.newInstance(), namespaceUri );
}
public NamespaceAddingEventReader(XMLEventReader reader, XMLEventFactory xmlEventFactory, String namespaceUri) {
super( reader );
this.xmlEventFactory = xmlEventFactory;
this.namespaceUri = namespaceUri;
}
private StartElement withNamespace(StartElement startElement) {
// otherwise, wrap the start element event to provide a default namespace mapping
final List<Namespace> namespaces = new ArrayList<Namespace>();
namespaces.add( xmlEventFactory.createNamespace( "", namespaceUri ) );
Iterator<?> originalNamespaces = startElement.getNamespaces();
while ( originalNamespaces.hasNext() ) {
namespaces.add( (Namespace) originalNamespaces.next() );
}
return xmlEventFactory.createStartElement(
new QName( namespaceUri, startElement.getName().getLocalPart() ),
startElement.getAttributes(),
namespaces.iterator()
);
}
@Override
public XMLEvent nextEvent() throws XMLStreamException {
XMLEvent event = super.nextEvent();
if ( event.isStartElement() ) {
return withNamespace( event.asStartElement() );
}
return event;
}
@Override
public XMLEvent peek() throws XMLStreamException {
XMLEvent event = super.peek();
if ( event.isStartElement() ) {
return withNamespace( event.asStartElement() );
}
else {
return event;
}
}
}
}

View File

@ -0,0 +1,186 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.jboss.jandex;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* Aggregates information from multiple {@link Index} instances.
*
* @author John Bailey
* @author Steve Ebersole
*/
public class CompositeIndex implements IndexResult {
private final List<Index> indexes;
public CompositeIndex(Index... indexes) {
this( Arrays.asList( indexes ) );
}
public CompositeIndex(List<Index> indexes) {
this.indexes = indexes;
}
@Override
public Collection<AnnotationInstance> getAnnotations(DotName annotationName) {
final Set<AnnotationInstance> allInstances = new HashSet<AnnotationInstance>();
for (Index index : indexes) {
copy( index.getAnnotations( annotationName ), allInstances );
}
return Collections.unmodifiableSet( allInstances );
}
private <T> void copy(Collection<T> source, Collection<T> target) {
if ( source != null ) {
target.addAll( source );
}
}
@Override
public Collection<ClassInfo> getKnownClasses() {
final List<ClassInfo> allKnown = new ArrayList<ClassInfo>();
for ( Index index : indexes ) {
copy( index.getKnownClasses(), allKnown );
}
return Collections.unmodifiableCollection( allKnown );
}
@Override
public ClassInfo getClassByName(DotName className) {
for ( Index index : indexes ) {
final ClassInfo info = index.getClassByName( className );
if ( info != null ) {
return info;
}
}
return null;
}
@Override
public Collection<ClassInfo> getKnownDirectSubclasses(DotName className) {
final Set<ClassInfo> allKnown = new HashSet<ClassInfo>();
for ( Index index : indexes ) {
copy( index.getKnownDirectSubclasses( className ), allKnown );
}
return Collections.unmodifiableSet( allKnown );
}
@Override
public Set<ClassInfo> getAllKnownSubclasses(final DotName className) {
final Set<ClassInfo> allKnown = new HashSet<ClassInfo>();
final Set<DotName> processedClasses = new HashSet<DotName>();
getAllKnownSubClasses(className, allKnown, processedClasses);
return allKnown;
}
private void getAllKnownSubClasses(DotName className, Set<ClassInfo> allKnown, Set<DotName> processedClasses) {
final Set<DotName> subClassesToProcess = new HashSet<DotName>();
subClassesToProcess.add(className);
while (!subClassesToProcess.isEmpty()) {
final Iterator<DotName> toProcess = subClassesToProcess.iterator();
DotName name = toProcess.next();
toProcess.remove();
processedClasses.add(name);
getAllKnownSubClasses(name, allKnown, subClassesToProcess, processedClasses);
}
}
private void getAllKnownSubClasses(
DotName name,
Set<ClassInfo> allKnown,
Set<DotName> subClassesToProcess,
Set<DotName> processedClasses) {
for ( Index index : indexes ) {
final Collection<ClassInfo> list = index.getKnownDirectSubclasses( name );
if ( list != null ) {
for ( final ClassInfo clazz : list ) {
final DotName className = clazz.name();
if ( !processedClasses.contains( className ) ) {
allKnown.add( clazz );
subClassesToProcess.add( className );
}
}
}
}
}
@Override
public Collection<ClassInfo> getKnownDirectImplementors(DotName className) {
final Set<ClassInfo> allKnown = new HashSet<ClassInfo>();
for ( Index index : indexes ) {
copy( index.getKnownDirectImplementors( className ), allKnown );
}
return Collections.unmodifiableSet(allKnown); }
@Override
public Collection<ClassInfo> getAllKnownImplementors(DotName interfaceName) {
final Set<ClassInfo> allKnown = new HashSet<ClassInfo>();
final Set<DotName> subInterfacesToProcess = new HashSet<DotName>();
final Set<DotName> processedClasses = new HashSet<DotName>();
subInterfacesToProcess.add( interfaceName );
while ( !subInterfacesToProcess.isEmpty() ) {
final Iterator<DotName> toProcess = subInterfacesToProcess.iterator();
DotName name = toProcess.next();
toProcess.remove();
processedClasses.add( name );
getKnownImplementors( name, allKnown, subInterfacesToProcess, processedClasses );
}
return allKnown;
}
private void getKnownImplementors(
DotName name,
Set<ClassInfo> allKnown,
Set<DotName> subInterfacesToProcess,
Set<DotName> processedClasses) {
for (Index index : indexes) {
final List<ClassInfo> list = index.getKnownDirectImplementors(name);
if (list != null) {
for (final ClassInfo clazz : list) {
final DotName className = clazz.name();
if (!processedClasses.contains(className)) {
if ( Modifier.isInterface( clazz.flags() )) {
subInterfacesToProcess.add(className);
}
else {
if (!allKnown.contains(clazz)) {
allKnown.add(clazz);
processedClasses.add(className);
getAllKnownSubClasses(className, allKnown, processedClasses);
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,56 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.jboss.jandex;
import java.util.Collection;
/**
* The basic contract for accessing Jandex indexed information.
*
* @author Jason Greene
* @author Steve Ebersole
*/
public interface IndexResult {
public Collection<ClassInfo> getKnownClasses();
public ClassInfo getClassByName(DotName className);
public Collection<ClassInfo> getKnownDirectSubclasses(DotName className);
/**
* Returns all known (including non-direct) sub classes of the given class. I.e., returns all known classes
* that are assignable to the given class.
*
* @param className The class
*
* @return All known subclasses
*/
public Collection<ClassInfo> getAllKnownSubclasses(final DotName className);
public Collection<ClassInfo> getKnownDirectImplementors(DotName className);
public Collection<ClassInfo> getAllKnownImplementors(final DotName interfaceName);
public Collection<AnnotationInstance> getAnnotations(DotName annotationName);
}

View File

@ -31,7 +31,7 @@ package org.hibernate.ejb;
*
* @author Steve Ebersole
*/
public class AvailableSettings {
public interface AvailableSettings {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JPA defined settings

View File

@ -34,6 +34,7 @@ import javax.persistence.TypedQuery;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -532,8 +533,8 @@ public abstract class BaseQueryImpl implements Query {
@Override
@SuppressWarnings("unchecked")
public Set<Parameter<?>> getParameters() {
return (Set<Parameter<?>>) parameterBindingMap().keySet();
public Set getParameters() {
return parameterBindingMap().keySet();
}
@Override

View File

@ -23,15 +23,6 @@
*/
package org.hibernate.ejb;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import javax.persistence.Cache;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
@ -43,6 +34,14 @@ import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.spi.LoadState;
import javax.persistence.spi.PersistenceUnitTransactionType;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.jboss.logging.Logger;
@ -50,6 +49,7 @@ import org.hibernate.Hibernate;
import org.hibernate.SessionFactory;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.ejb.boot.internal.SettingsImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.internal.EntityManagerFactoryRegistry;
import org.hibernate.ejb.metamodel.MetamodelImpl;
@ -100,10 +100,26 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
Configuration cfg,
ServiceRegistry serviceRegistry,
String persistenceUnitName) {
this.sessionFactory = (SessionFactoryImpl) cfg.buildSessionFactory( serviceRegistry );
this.transactionType = transactionType;
this.discardOnClose = discardOnClose;
this.sessionInterceptorClass = sessionInterceptorClass;
this(
persistenceUnitName,
(SessionFactoryImplementor) cfg.buildSessionFactory( serviceRegistry ),
new SettingsImpl().setReleaseResourcesOnCloseEnabled( discardOnClose ).setSessionInterceptorClass( sessionInterceptorClass ).setTransactionType( transactionType ),
cfg.getProperties(),
cfg
);
}
public EntityManagerFactoryImpl(
String persistenceUnitName,
SessionFactoryImplementor sessionFactory,
SettingsImpl settings,
Map<?, ?> configurationValues,
Configuration cfg) {
this.sessionFactory = (SessionFactoryImpl) sessionFactory;
this.transactionType = settings.getTransactionType();
this.discardOnClose = settings.isReleaseResourcesOnCloseEnabled();
this.sessionInterceptorClass = settings.getSessionInterceptorClass();
final Iterator<PersistentClass> classes = cfg.getClassMappings();
final JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting = determineJpaMetaModelPopulationSetting( cfg );
if ( JpaMetaModelPopulationSetting.DISABLED == jpaMetaModelPopulationSetting ) {
@ -112,7 +128,7 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
else {
this.metamodel = MetamodelImpl.buildMetamodel(
classes,
( SessionFactoryImplementor ) sessionFactory,
sessionFactory,
JpaMetaModelPopulationSetting.IGNORE_UNSUPPORTED == jpaMetaModelPopulationSetting
);
}
@ -120,8 +136,9 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
this.util = new HibernatePersistenceUnitUtil( this );
HashMap<String,Object> props = new HashMap<String, Object>();
addAll( props, ( (SessionFactoryImplementor) sessionFactory ).getProperties() );
addAll( props, sessionFactory.getProperties() );
addAll( props, cfg.getProperties() );
addAll( props, configurationValues );
this.properties = Collections.unmodifiableMap( props );
String entityManagerFactoryName = (String)this.properties.get(AvailableSettings.ENTITY_MANAGER_FACTORY_NAME);
if (entityManagerFactoryName == null) {
@ -133,7 +150,7 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
this.entityManagerFactoryName = entityManagerFactoryName;
EntityManagerFactoryRegistry.INSTANCE.addEntityManagerFactory(entityManagerFactoryName, this);
}
private enum JpaMetaModelPopulationSetting {
ENABLED,
DISABLED,
@ -171,10 +188,10 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
return JpaMetaModelPopulationSetting.parse( setting );
}
private static void addAll(HashMap<String, Object> propertyMap, Properties properties) {
for ( Map.Entry entry : properties.entrySet() ) {
private static void addAll(HashMap<String, Object> destination, Map<?,?> source) {
for ( Map.Entry entry : source.entrySet() ) {
if ( String.class.isInstance( entry.getKey() ) ) {
propertyMap.put( (String)entry.getKey(), entry.getValue() );
destination.put( (String) entry.getKey(), entry.getValue() );
}
}
}

View File

@ -23,87 +23,73 @@
*/
package org.hibernate.ejb;
import java.util.Map;
import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.LoadState;
import javax.persistence.spi.PersistenceProvider;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.ProviderUtil;
import org.hibernate.ejb.boot.internal.HibernatePersistenceProvider;
import org.hibernate.ejb.util.PersistenceUtilHelper;
/**
* Hibernate EJB3 persistence provider implementation
*
* @deprecated Use {@link org.hibernate.ejb.boot.internal.HibernatePersistenceProvider} instead
*
* @author Gavin King
*/
public class HibernatePersistence extends AvailableSettings implements PersistenceProvider {
@Deprecated
public class HibernatePersistence extends HibernatePersistenceProvider implements PersistenceProvider, AvailableSettings {
private final PersistenceUtilHelper.MetadataCache cache = new PersistenceUtilHelper.MetadataCache();
/**
* Get an entity manager factory by its entity manager name, using the specified
* properties (they override any found in the peristence.xml file).
* <p/>
* This is the form used in JSE environments.
*
* @param persistenceUnitName entity manager name
* @param properties The explicit property values
*
* @return initialized EntityManagerFactory
*/
public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) {
Ejb3Configuration cfg = new Ejb3Configuration();
Ejb3Configuration configured = cfg.configure( persistenceUnitName, properties );
return configured != null ? configured.buildEntityManagerFactory() : null;
}
// /**
// * Get an entity manager factory by its entity manager name, using the specified
// * properties (they override any found in the peristence.xml file).
// * <p/>
// * This is the form used in JSE environments.
// *
// * @param persistenceUnitName entity manager name
// * @param properties The explicit property values
// *
// * @return initialized EntityManagerFactory
// */
// public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) {
// Ejb3Configuration cfg = new Ejb3Configuration();
// Ejb3Configuration configured = cfg.configure( persistenceUnitName, properties );
// return configured != null ? configured.buildEntityManagerFactory() : null;
// }
/**
* Create an entity manager factory from the given persistence unit info, using the specified
* properties (they override any on the PUI).
* <p/>
* This is the form used by the container in a JEE environment.
*
* @param info The persistence unit information
* @param properties The explicit property values
*
* @return initialized EntityManagerFactory
*/
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) {
Ejb3Configuration cfg = new Ejb3Configuration();
Ejb3Configuration configured = cfg.configure( info, properties );
return configured != null ? configured.buildEntityManagerFactory() : null;
}
// /**
// * Create an entity manager factory from the given persistence unit info, using the specified
// * properties (they override any on the PUI).
// * <p/>
// * This is the form used by the container in a JEE environment.
// *
// * @param info The persistence unit information
// * @param properties The explicit property values
// *
// * @return initialized EntityManagerFactory
// */
// public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) {
// Ejb3Configuration cfg = new Ejb3Configuration();
// Ejb3Configuration configured = cfg.configure( info, properties );
// return configured != null ? configured.buildEntityManagerFactory() : null;
// }
/**
* create a factory from a canonical version
* @deprecated
*/
@Deprecated
public EntityManagerFactory createEntityManagerFactory(Map properties) {
// This is used directly by JBoss so don't remove until further notice. bill@jboss.org
Ejb3Configuration cfg = new Ejb3Configuration();
return cfg.createEntityManagerFactory( properties );
}
private final ProviderUtil providerUtil = new ProviderUtil() {
public LoadState isLoadedWithoutReference(Object proxy, String property) {
return PersistenceUtilHelper.isLoadedWithoutReference( proxy, property, cache );
}
// private final ProviderUtil providerUtil = new ProviderUtil() {
// public LoadState isLoadedWithoutReference(Object proxy, String property) {
// return PersistenceUtilHelper.isLoadedWithoutReference( proxy, property, cache );
// }
//
// public LoadState isLoadedWithReference(Object proxy, String property) {
// return PersistenceUtilHelper.isLoadedWithReference( proxy, property, cache );
// }
//
// public LoadState isLoaded(Object o) {
// return PersistenceUtilHelper.isLoaded(o);
// }
// };
public LoadState isLoadedWithReference(Object proxy, String property) {
return PersistenceUtilHelper.isLoadedWithReference( proxy, property, cache );
}
public LoadState isLoaded(Object o) {
return PersistenceUtilHelper.isLoaded(o);
}
};
/**
* {@inheritDoc}
*/
public ProviderUtil getProviderUtil() {
return providerUtil;
}
// public ProviderUtil getProviderUtil() {
// return providerUtil;
// }
}

View File

@ -0,0 +1,131 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA\
*/
package org.hibernate.ejb.boot.internal;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceException;
import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.LoadState;
import javax.persistence.spi.PersistenceProvider;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.ProviderUtil;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.jboss.logging.Logger;
import org.hibernate.ejb.AvailableSettings;
import org.hibernate.ejb.boot.spi.ProviderChecker;
import org.hibernate.ejb.instrument.InterceptFieldClassFileTransformer;
import org.hibernate.ejb.internal.EntityManagerMessageLogger;
import org.hibernate.ejb.util.PersistenceUtilHelper;
/**
* The Hibernate {@link PersistenceProvider} implementation
*
* @todo Deprecate {@link org.hibernate.ejb.HibernatePersistence} and have it extend this one...
*
* @author Gavin King
* @author Steve Ebersole
*/
public class HibernatePersistenceProvider implements PersistenceProvider {
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(
EntityManagerMessageLogger.class,
HibernatePersistenceProvider.class.getName()
);
private final PersistenceUtilHelper.MetadataCache cache = new PersistenceUtilHelper.MetadataCache();
/**
* {@inheritDoc}
* <p/>
* Note: per-spec, the values passed as {@code properties} override values found in {@code persistence.xml}
*/
@Override
public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) {
final Map integration = wrap( properties );
final List<ParsedPersistenceXmlDescriptor> units = PersistenceXmlParser.locatePersistenceUnits( integration );
if ( persistenceUnitName == null && units.size() > 1 ) {
// no persistence-unit name to look for was given and we found multiple persistence-units
throw new PersistenceException( "No name provided and multiple persistence units found" );
}
for ( ParsedPersistenceXmlDescriptor persistenceUnit : units ) {
boolean matches = persistenceUnitName == null || persistenceUnit.getName().equals( persistenceUnitName );
if ( !matches ) {
continue;
}
// See if we (Hibernate) are the persistence provider
if ( ! ProviderChecker.isProvider( persistenceUnit, properties ) ) {
continue;
}
return new EntityManagerFactoryBuilderImpl( persistenceUnit, properties ).buildEntityManagerFactory();
}
return null;
}
@SuppressWarnings("unchecked")
private static Map wrap(Map properties) {
return properties== null ? Collections.emptyMap() : Collections.unmodifiableMap( properties );
}
/**
* {@inheritDoc}
* <p/>
* Note: per-spec, the values passed as {@code properties} override values found in {@link PersistenceUnitInfo}
*/
@Override
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map integration) {
EntityManagerFactoryBuilderImpl entityManagerFactoryBuilder = new EntityManagerFactoryBuilderImpl(
new PersistenceUnitInfoDescriptor( info ),
integration
);
return entityManagerFactoryBuilder.buildEntityManagerFactory();
}
private final ProviderUtil providerUtil = new ProviderUtil() {
public LoadState isLoadedWithoutReference(Object proxy, String property) {
return PersistenceUtilHelper.isLoadedWithoutReference( proxy, property, cache );
}
public LoadState isLoadedWithReference(Object proxy, String property) {
return PersistenceUtilHelper.isLoadedWithReference( proxy, property, cache );
}
public LoadState isLoaded(Object o) {
return PersistenceUtilHelper.isLoaded(o);
}
};
@Override
public ProviderUtil getProviderUtil() {
return providerUtil;
}
}

View File

@ -0,0 +1,197 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.boot.internal;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.spi.PersistenceUnitTransactionType;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
/**
* Describes the information gleaned from a {@code <persistence-unit/>} element in a {@code persistence.xml} file
* whether parsed directly by Hibernate or passed to us by an EE container as a
* {@link javax.persistence.spi.PersistenceUnitInfo}.
*
* Easier to consolidate both views into a single contract and extract information through that shared contract.
*
* @author Steve Ebersole
*/
public class ParsedPersistenceXmlDescriptor implements org.hibernate.ejb.boot.spi.PersistenceUnitDescriptor {
private final URL persistenceUnitRootUrl;
private String name;
private Object nonJtaDataSource;
private Object jtaDataSource;
private String providerClassName;
private PersistenceUnitTransactionType transactionType;
private boolean useQuotedIdentifiers = false;
private boolean excludeUnlistedClasses = false;
private ValidationMode validationMode;
private SharedCacheMode sharedCacheMode;
private Properties properties = new Properties();
private List<String> classes = new ArrayList<String>();
private List<String> mappingFiles = new ArrayList<String>();
private List<URL> jarFileUrls = new ArrayList<URL>();
public ParsedPersistenceXmlDescriptor(URL persistenceUnitRootUrl) {
this.persistenceUnitRootUrl = persistenceUnitRootUrl;
}
@Override
public URL getPersistenceUnitRootUrl() {
return persistenceUnitRootUrl;
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public Object getNonJtaDataSource() {
return nonJtaDataSource;
}
public void setNonJtaDataSource(Object nonJtaDataSource) {
this.nonJtaDataSource = nonJtaDataSource;
}
@Override
public Object getJtaDataSource() {
return jtaDataSource;
}
public void setJtaDataSource(Object jtaDataSource) {
this.jtaDataSource = jtaDataSource;
}
@Override
public String getProviderClassName() {
return providerClassName;
}
public void setProviderClassName(String providerClassName) {
this.providerClassName = providerClassName;
}
@Override
public PersistenceUnitTransactionType getTransactionType() {
return transactionType;
}
public void setTransactionType(PersistenceUnitTransactionType transactionType) {
this.transactionType = transactionType;
}
@Override
public boolean isUseQuotedIdentifiers() {
return useQuotedIdentifiers;
}
public void setUseQuotedIdentifiers(boolean useQuotedIdentifiers) {
this.useQuotedIdentifiers = useQuotedIdentifiers;
}
@Override
public Properties getProperties() {
return properties;
}
@Override
public boolean isExcludeUnlistedClasses() {
return excludeUnlistedClasses;
}
public void setExcludeUnlistedClasses(boolean excludeUnlistedClasses) {
this.excludeUnlistedClasses = excludeUnlistedClasses;
}
@Override
public ValidationMode getValidationMode() {
return validationMode;
}
public void setValidationMode(String validationMode) {
this.validationMode = ValidationMode.valueOf( validationMode );
}
@Override
public SharedCacheMode getSharedCacheMode() {
return sharedCacheMode;
}
public void setSharedCacheMode(String sharedCacheMode) {
this.sharedCacheMode = SharedCacheMode.valueOf( sharedCacheMode );
}
@Override
public List<String> getManagedClassNames() {
return classes;
}
public void addClasses(String... classes) {
addClasses( Arrays.asList( classes ) );
}
public void addClasses(List<String> classes) {
this.classes.addAll( classes );
}
@Override
public List<String> getMappingFileNames() {
return mappingFiles;
}
public void addMappingFiles(String... mappingFiles) {
addMappingFiles( Arrays.asList( mappingFiles ) );
}
public void addMappingFiles(List<String> mappingFiles) {
this.mappingFiles.addAll( mappingFiles );
}
@Override
public List<URL> getJarFileUrls() {
return jarFileUrls;
}
public void addJarFileUrl(URL jarFileUrl) {
jarFileUrls.add( jarFileUrl );
}
@Override
public void pushClassTransformer(List<String> entityClassNames) {
// todo : log a message that this is currently not supported...
}
}

View File

@ -0,0 +1,121 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.boot.internal;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;
import java.net.URL;
import java.util.List;
import java.util.Properties;
import org.hibernate.ejb.boot.spi.PersistenceUnitDescriptor;
import org.hibernate.ejb.instrument.InterceptFieldClassFileTransformer;
/**
* @author Steve Ebersole
*/
public class PersistenceUnitInfoDescriptor implements PersistenceUnitDescriptor {
private final PersistenceUnitInfo persistenceUnitInfo;
public PersistenceUnitInfoDescriptor(PersistenceUnitInfo persistenceUnitInfo) {
this.persistenceUnitInfo = persistenceUnitInfo;
}
@Override
public URL getPersistenceUnitRootUrl() {
return persistenceUnitInfo.getPersistenceUnitRootUrl();
}
@Override
public String getName() {
return persistenceUnitInfo.getPersistenceUnitName();
}
@Override
public Object getNonJtaDataSource() {
return persistenceUnitInfo.getNonJtaDataSource();
}
@Override
public Object getJtaDataSource() {
return persistenceUnitInfo.getJtaDataSource();
}
@Override
public String getProviderClassName() {
return persistenceUnitInfo.getPersistenceProviderClassName();
}
@Override
public PersistenceUnitTransactionType getTransactionType() {
return persistenceUnitInfo.getTransactionType();
}
@Override
public boolean isUseQuotedIdentifiers() {
return false;
}
@Override
public Properties getProperties() {
return persistenceUnitInfo.getProperties();
}
@Override
public boolean isExcludeUnlistedClasses() {
return persistenceUnitInfo.excludeUnlistedClasses();
}
@Override
public ValidationMode getValidationMode() {
return persistenceUnitInfo.getValidationMode();
}
@Override
public SharedCacheMode getSharedCacheMode() {
return persistenceUnitInfo.getSharedCacheMode();
}
@Override
public List<String> getManagedClassNames() {
return persistenceUnitInfo.getManagedClassNames();
}
@Override
public List<String> getMappingFileNames() {
return persistenceUnitInfo.getMappingFileNames();
}
@Override
public List<URL> getJarFileUrls() {
return persistenceUnitInfo.getJarFileUrls();
}
@Override
public void pushClassTransformer(List<String> entityClassNames) {
persistenceUnitInfo.addTransformer( new InterceptFieldClassFileTransformer( entityClassNames ) );
}
}

View File

@ -0,0 +1,479 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.boot.internal;
import javax.persistence.PersistenceException;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.jboss.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.hibernate.ejb.AvailableSettings;
import org.hibernate.ejb.internal.EntityManagerMessageLogger;
import org.hibernate.ejb.packaging.JarVisitorFactory;
import org.hibernate.ejb.util.ConfigurationHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.source.XsdException;
import org.hibernate.service.classloading.internal.ClassLoaderServiceImpl;
import org.hibernate.service.classloading.spi.ClassLoaderService;
/**
* Used by Hibernate to parse {@code persistence.xml} files in SE environments.
*
* @author Steve Ebersole
*/
public class PersistenceXmlParser {
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(
EntityManagerMessageLogger.class,
PersistenceXmlParser.class.getName()
);
private final ClassLoaderService classLoaderService;
private final PersistenceUnitTransactionType defaultTransactionType;
public static List<ParsedPersistenceXmlDescriptor> locatePersistenceUnits(Map integration) {
final PersistenceXmlParser parser = new PersistenceXmlParser(
ClassLoaderServiceImpl.fromConfigSettings( integration ),
PersistenceUnitTransactionType.RESOURCE_LOCAL
);
return parser.doResolve( integration );
}
public PersistenceXmlParser(ClassLoaderService classLoaderService, PersistenceUnitTransactionType defaultTransactionType) {
this.classLoaderService = classLoaderService;
this.defaultTransactionType = defaultTransactionType;
}
public List<ParsedPersistenceXmlDescriptor> doResolve(Map integration) {
final List<ParsedPersistenceXmlDescriptor> persistenceUnits = new ArrayList<ParsedPersistenceXmlDescriptor>();
final List<URL> xmlUrls = classLoaderService.locateResources( "META-INF/persistence.xml" );
if ( xmlUrls.isEmpty() ) {
LOG.unableToFindPersistenceXmlInClasspath();
}
else {
for ( URL xmlUrl : xmlUrls ) {
persistenceUnits.addAll( parsePersistenceXml( xmlUrl, integration ) );
}
}
return persistenceUnits;
}
private List<ParsedPersistenceXmlDescriptor> parsePersistenceXml(URL xmlUrl, Map integration) {
// todo : if implementing a "xml binding service" this should be part of it, binding persistence.xml : HHH-6145
final Document doc = loadUrl( xmlUrl );
final Element top = doc.getDocumentElement();
final List<ParsedPersistenceXmlDescriptor> persistenceUnits = new ArrayList<ParsedPersistenceXmlDescriptor>();
final NodeList children = top.getChildNodes();
for ( int i = 0; i < children.getLength() ; i++ ) {
if ( children.item( i ).getNodeType() == Node.ELEMENT_NODE ) {
final Element element = (Element) children.item( i );
final String tag = element.getTagName();
if ( tag.equals( "persistence-unit" ) ) {
final URL puRootUrl = JarVisitorFactory.getJarURLFromURLEntry( xmlUrl, "/META-INF/persistence.xml" );
ParsedPersistenceXmlDescriptor persistenceUnit = new ParsedPersistenceXmlDescriptor( puRootUrl );
bindPersistenceUnit( persistenceUnit, element );
// per JPA spec, any settings passed in to PersistenceProvider bootstrap methods should override
// values found in persistence.xml
if ( integration.containsKey( AvailableSettings.PROVIDER ) ) {
persistenceUnit.setProviderClassName( (String) integration.get( AvailableSettings.PROVIDER ) );
}
if ( integration.containsKey( AvailableSettings.TRANSACTION_TYPE ) ) {
String transactionType = (String) integration.get( AvailableSettings.TRANSACTION_TYPE );
persistenceUnit.setTransactionType( parseTransactionType( transactionType ) );
}
if ( integration.containsKey( AvailableSettings.JTA_DATASOURCE ) ) {
persistenceUnit.setJtaDataSource( integration.get( AvailableSettings.JTA_DATASOURCE ) );
}
if ( integration.containsKey( AvailableSettings.NON_JTA_DATASOURCE ) ) {
persistenceUnit.setNonJtaDataSource( integration.get( AvailableSettings.NON_JTA_DATASOURCE ) );
}
decodeTransactionType( persistenceUnit );
Properties properties = persistenceUnit.getProperties();
ConfigurationHelper.overrideProperties( properties, integration );
persistenceUnits.add( persistenceUnit );
}
}
}
return persistenceUnits;
}
private void decodeTransactionType(ParsedPersistenceXmlDescriptor persistenceUnit) {
// if transaction type is set already
// use that value
// else
// if JTA DS
// use JTA
// else if NOT JTA DS
// use RESOURCE_LOCAL
// else
// use defaultTransactionType
if ( persistenceUnit.getTransactionType() != null ) {
return;
}
if ( persistenceUnit.getJtaDataSource() != null ) {
persistenceUnit.setTransactionType( PersistenceUnitTransactionType.JTA );
}
else if ( persistenceUnit.getNonJtaDataSource() != null ) {
persistenceUnit.setTransactionType( PersistenceUnitTransactionType.RESOURCE_LOCAL );
}
else {
persistenceUnit.setTransactionType( defaultTransactionType );
}
}
private void bindPersistenceUnit(ParsedPersistenceXmlDescriptor persistenceUnit, Element persistenceUnitElement) {
final String name = persistenceUnitElement.getAttribute( "name" );
if ( StringHelper.isNotEmpty( name ) ) {
LOG.tracef( "Persistence unit name from persistence.xml : %s", name );
persistenceUnit.setName( name );
}
final PersistenceUnitTransactionType transactionType = parseTransactionType(
persistenceUnitElement.getAttribute( "transaction-type" )
);
if ( transactionType != null ) {
persistenceUnit.setTransactionType( transactionType );
}
NodeList children = persistenceUnitElement.getChildNodes();
for ( int i = 0; i < children.getLength() ; i++ ) {
if ( children.item( i ).getNodeType() == Node.ELEMENT_NODE ) {
Element element = (Element) children.item( i );
String tag = element.getTagName();
if ( tag.equals( "non-jta-data-source" ) ) {
persistenceUnit.setNonJtaDataSource( extractContent( element ) );
}
else if ( tag.equals( "jta-data-source" ) ) {
persistenceUnit.setJtaDataSource( extractContent( element ) );
}
else if ( tag.equals( "provider" ) ) {
persistenceUnit.setProviderClassName( extractContent( element ) );
}
else if ( tag.equals( "class" ) ) {
persistenceUnit.addClasses( extractContent( element ) );
}
else if ( tag.equals( "mapping-file" ) ) {
persistenceUnit.addMappingFiles( extractContent( element ) );
}
else if ( tag.equals( "jar-file" ) ) {
persistenceUnit.addJarFileUrl( JarVisitorFactory.getURLFromPath( extractContent( element ) ) );
}
else if ( tag.equals( "exclude-unlisted-classes" ) ) {
persistenceUnit.setExcludeUnlistedClasses( true );
}
else if ( tag.equals( "delimited-identifiers" ) ) {
persistenceUnit.setUseQuotedIdentifiers( true );
}
else if ( tag.equals( "validation-mode" ) ) {
persistenceUnit.setValidationMode( extractContent( element ) );
}
else if ( tag.equals( "shared-cache-mode" ) ) {
persistenceUnit.setSharedCacheMode( extractContent( element ) );
}
else if ( tag.equals( "properties" ) ) {
NodeList props = element.getChildNodes();
for ( int j = 0; j < props.getLength() ; j++ ) {
if ( props.item( j ).getNodeType() == Node.ELEMENT_NODE ) {
Element propElement = (Element) props.item( j );
if ( !"property".equals( propElement.getTagName() ) ) {
continue;
}
String propName = propElement.getAttribute( "name" ).trim();
String propValue = propElement.getAttribute( "value" ).trim();
if ( StringHelper.isEmpty( propValue ) ) {
//fall back to the natural (Hibernate) way of description
propValue = extractContent( propElement, "" );
}
persistenceUnit.getProperties().put( propName, propValue );
}
}
}
}
}
}
private static String extractContent(Element element) {
return extractContent( element, null );
}
private static String extractContent(Element element, String defaultStr) {
if ( element == null ) {
return defaultStr;
}
NodeList children = element.getChildNodes();
StringBuilder result = new StringBuilder("");
for ( int i = 0; i < children.getLength() ; i++ ) {
if ( children.item( i ).getNodeType() == Node.TEXT_NODE ||
children.item( i ).getNodeType() == Node.CDATA_SECTION_NODE ) {
result.append( children.item( i ).getNodeValue() );
}
}
return result.toString().trim();
}
private static PersistenceUnitTransactionType parseTransactionType(String value) {
if ( StringHelper.isEmpty( value ) ) {
return null;
}
else if ( value.equalsIgnoreCase( "JTA" ) ) {
return PersistenceUnitTransactionType.JTA;
}
else if ( value.equalsIgnoreCase( "RESOURCE_LOCAL" ) ) {
return PersistenceUnitTransactionType.RESOURCE_LOCAL;
}
else {
throw new PersistenceException( "Unknown persistence unit transaction type : " + value );
}
}
private Document loadUrl(URL xmlUrl) {
final String resourceName = xmlUrl.toExternalForm();
try {
URLConnection conn = xmlUrl.openConnection();
conn.setUseCaches( false ); //avoid JAR locking on Windows and Tomcat
try {
InputStream inputStream = conn.getInputStream();
try {
final InputSource inputSource = new InputSource( inputStream );
try {
DocumentBuilder documentBuilder = documentBuilderFactory().newDocumentBuilder();
try {
Document document = documentBuilder.parse( inputSource );
validate( document );
return document;
}
catch (SAXException e) {
throw new PersistenceException( "Unexpected error parsing [" + resourceName + "]", e );
}
catch (IOException e) {
throw new PersistenceException( "Unexpected error parsing [" + resourceName + "]", e );
}
}
catch (ParserConfigurationException e) {
throw new PersistenceException( "Unable to generate javax.xml.parsers.DocumentBuilder instance", e );
}
}
finally {
try {
inputStream.close();
}
catch (Exception ignored) {
}
}
}
catch (IOException e) {
throw new PersistenceException( "Unable to obtain input stream from [" + resourceName + "]", e );
}
}
catch (IOException e) {
throw new PersistenceException( "Unable to access [" + resourceName + "]", e );
}
}
private void validate(Document document) {
// todo : add ability to disable validation...
final Validator validator;
final String version = document.getDocumentElement().getAttribute( "version" );
if ( "2.1".equals( version ) ) {
validator = v21Schema().newValidator();
}
else if ( "2.0".equals( version ) ) {
validator = v2Schema().newValidator();
}
else if ( "1.0".equals( version ) ) {
validator = v1Schema().newValidator();
}
else {
throw new PersistenceException( "Unrecognized persistence.xml version [" + version + "]" );
}
List<SAXException> errors = new ArrayList<SAXException>();
validator.setErrorHandler( new ErrorHandlerImpl( errors ) );
try {
validator.validate( new DOMSource( document ) );
}
catch (SAXException e) {
errors.add( e );
}
catch (IOException e) {
throw new PersistenceException( "Unable to validate persistence.xml", e );
}
if ( errors.size() != 0 ) {
//report all errors in the exception
StringBuilder errorMessage = new StringBuilder( );
for ( SAXException error : errors ) {
errorMessage.append( extractInfo( error ) ).append( '\n' );
}
throw new PersistenceException( "Invalid persistence.xml.\n" + errorMessage.toString() );
}
}
private DocumentBuilderFactory documentBuilderFactory;
private DocumentBuilderFactory documentBuilderFactory() {
if ( documentBuilderFactory == null ) {
documentBuilderFactory = buildDocumentBuilderFactory();
}
return documentBuilderFactory;
}
private DocumentBuilderFactory buildDocumentBuilderFactory() {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware( true );
return documentBuilderFactory;
}
private Schema v21Schema;
private Schema v21Schema() {
if ( v21Schema == null ) {
v21Schema = resolveLocalSchema( "org/hibernate/ejb/persistence_2_1.xsd" );
}
return v21Schema;
}
private Schema v2Schema;
private Schema v2Schema() {
if ( v2Schema == null ) {
v2Schema = resolveLocalSchema( "org/hibernate/ejb/persistence_2_0.xsd" );
}
return v2Schema;
}
private Schema v1Schema;
private Schema v1Schema() {
if ( v1Schema == null ) {
v1Schema = resolveLocalSchema( "org/hibernate/ejb/persistence_1_0.xsd" );
}
return v1Schema;
}
private Schema resolveLocalSchema(String schemaName) {
// These XSD resources should be available on the Hibernate ClassLoader
final URL url = classLoaderService.locateResource( schemaName );
if ( url == null ) {
throw new XsdException( "Unable to locate schema [" + schemaName + "] via classpath", schemaName );
}
try {
InputStream schemaStream = url.openStream();
try {
StreamSource source = new StreamSource( url.openStream() );
SchemaFactory schemaFactory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );
return schemaFactory.newSchema( source );
}
catch ( SAXException e ) {
throw new XsdException( "Unable to load schema [" + schemaName + "]", e, schemaName );
}
catch ( IOException e ) {
throw new XsdException( "Unable to load schema [" + schemaName + "]", e, schemaName );
}
finally {
try {
schemaStream.close();
}
catch ( IOException e ) {
LOG.debugf( "Problem closing schema stream [%s]", e.toString() );
}
}
}
catch ( IOException e ) {
throw new XsdException( "Stream error handling schema url [" + url.toExternalForm() + "]", schemaName );
}
}
public static class ErrorHandlerImpl implements ErrorHandler {
private List<SAXException> errors;
ErrorHandlerImpl(List<SAXException> errors) {
this.errors = errors;
}
public void error(SAXParseException error) {
errors.add( error );
}
public void fatalError(SAXParseException error) {
errors.add( error );
}
public void warning(SAXParseException warn) {
LOG.trace( extractInfo( warn ) );
}
}
private static String extractInfo(SAXException error) {
if ( error instanceof SAXParseException ) {
return "Error parsing XML [line : " + ( (SAXParseException) error ).getLineNumber()
+ ", column : " + ( (SAXParseException) error ).getColumnNumber()
+ "] : " + error.getMessage();
}
else {
return "Error parsing XML : " + error.getMessage();
}
}
}

View File

@ -0,0 +1,69 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.boot.internal;
import javax.persistence.spi.PersistenceUnitTransactionType;
import org.hibernate.Interceptor;
import org.hibernate.SessionFactoryObserver;
import org.hibernate.ejb.boot.spi.Settings;
/**
* @author Steve Ebersole
*/
public class SettingsImpl implements Settings {
private PersistenceUnitTransactionType transactionType;
private boolean releaseResourcesOnCloseEnabled;
private Class<? extends Interceptor> sessionInterceptorClass;
@Override
public PersistenceUnitTransactionType getTransactionType() {
return transactionType;
}
public SettingsImpl setTransactionType(PersistenceUnitTransactionType transactionType) {
this.transactionType = transactionType;
return this;
}
@Override
public boolean isReleaseResourcesOnCloseEnabled() {
return releaseResourcesOnCloseEnabled;
}
public SettingsImpl setReleaseResourcesOnCloseEnabled(boolean releaseResourcesOnCloseEnabled) {
this.releaseResourcesOnCloseEnabled = releaseResourcesOnCloseEnabled;
return this;
}
@Override
public Class<? extends Interceptor> getSessionInterceptorClass() {
return sessionInterceptorClass;
}
public SettingsImpl setSessionInterceptorClass(Class<? extends Interceptor> sessionInterceptorClass) {
this.sessionInterceptorClass = sessionInterceptorClass;
return this;
}
}

View File

@ -0,0 +1,66 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.boot.spi;
import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.ClassTransformer;
import org.hibernate.service.ServiceRegistryBuilder;
/**
* Ultimately the goal of this contract is to build {@link EntityManagerFactory} instances, which is done through
* the {@link #buildEntityManagerFactory()} method. But we also expose metadata about the semi-parsed persistence unit
* (as well as integration settings) that determine how the {@link EntityManagerFactory} will be built.
*
* @author Steve Ebersole
*/
public interface EntityManagerFactoryBuilder {
/**
* Build {@link EntityManagerFactory} instance
*
* @return The built {@link EntityManagerFactory}
*/
public EntityManagerFactory buildEntityManagerFactory();
/**
* Get the (read-only) view of in-effect settings that would be used when {@link #buildEntityManagerFactory()}
* is called.
*
* @return The in-effect settings.
*/
public Settings getSettings();
/**
* Get the ServiceRegistryBuilder that backs this EntityManagerFactoryBuilderImpl instance. The builder can be mutated
* if need be to add additional services ({@link ServiceRegistryBuilder#addService}) or additional
* service-initiators ({@link ServiceRegistryBuilder#addInitiator}).
*
* Note: {@link ServiceRegistryBuilder} also exposes the ability to add (which can also over-write) settings via
* the {@link ServiceRegistryBuilder#applySetting} and {@link ServiceRegistryBuilder#applySettings} methods,
* but use of those methods from here is discouraged as it will not effect {@link #getSettings()}
*
* @return The service registry builder.
*/
public ServiceRegistryBuilder getServiceRegistryBuilder();
}

View File

@ -0,0 +1,35 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.boot.spi;
import java.util.List;
import org.hibernate.integrator.spi.Integrator;
/**
* @author Steve Ebersole
*/
public interface IntegratorProvider {
public List<Integrator> getIntegrators();
}

View File

@ -0,0 +1,67 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.boot.spi;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.spi.PersistenceUnitTransactionType;
import java.net.URL;
import java.util.List;
import java.util.Properties;
import java.util.Set;
/**
* @author Steve Ebersole
*/
public interface PersistenceUnitDescriptor {
URL getPersistenceUnitRootUrl();
String getName();
Object getNonJtaDataSource();
Object getJtaDataSource();
String getProviderClassName();
PersistenceUnitTransactionType getTransactionType();
boolean isUseQuotedIdentifiers();
Properties getProperties();
boolean isExcludeUnlistedClasses();
ValidationMode getValidationMode();
SharedCacheMode getSharedCacheMode();
List<String> getManagedClassNames();
List<String> getMappingFileNames();
List<URL> getJarFileUrls();
public void pushClassTransformer(List<String> entityClassNames);
}

View File

@ -0,0 +1,99 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.boot.spi;
import java.util.Map;
import org.hibernate.ejb.AvailableSettings;
import org.hibernate.ejb.HibernatePersistence;
import org.hibernate.ejb.boot.internal.HibernatePersistenceProvider;
/**
* Helper for handling checks to see whether Hibernate is the requested
* {@link javax.persistence.spi.PersistenceProvider}
*
* @author Steve Ebersole
*/
public class ProviderChecker {
private static String[] HIBERNATE_PROVIDER_NAMES = new String[] {
HibernatePersistenceProvider.class.getName(),
HibernatePersistence.class.getName()
};
/**
* Does the descriptor and/or integration request Hibernate as the
* {@link javax.persistence.spi.PersistenceProvider}? Note that in the case of no requested provider being named
* we assume we are the provider (the calls got to us somehow...)
*
* @param persistenceUnit The {@code <persistence-unit/>} descriptor.
* @param integration The integration values.
*
* @return {@code true} if Hibernate should be the provider; {@code false} otherwise.
*/
public static boolean isProvider(PersistenceUnitDescriptor persistenceUnit, Map integration) {
// See if we (Hibernate) are the persistence provider
final String requestedProviderName = extractRequestedProviderName( persistenceUnit, integration );
// NOTE : if no requested name, we assume we are the provider (the calls got to us somehow...)
return requestedProviderName == null || hibernateProviderNamesContain( requestedProviderName );
}
/**
* Is the requested provider name one of the recognized Hibernate provider names?
*
* @param requestedProviderName The requested provider name to check against the recognized Hibernate names.
*
* @return {@code true} if Hibernate should be the provider; {@code false} otherwise.
*/
public static boolean hibernateProviderNamesContain(String requestedProviderName) {
for ( String hibernateProviderName : HIBERNATE_PROVIDER_NAMES ) {
if ( requestedProviderName.equals( hibernateProviderName ) ) {
return true;
}
}
return false;
}
/**
* Extract the requested persistence provider name using the algorithm Hibernate uses. Namely, a provider named
* in the 'integration' map (under the key '{@value AvailableSettings#PROVIDER}') is preferred, as per-spec, over
* value specified in persistence unit.
*
* @param persistenceUnit The {@code <persistence-unit/>} descriptor.
* @param integration The integration values.
*
* @return The extracted provider name, or {@code null} if none found.
*/
public static String extractRequestedProviderName(PersistenceUnitDescriptor persistenceUnit, Map integration) {
String providerName = integration == null ? null : (String) integration.get( AvailableSettings.PROVIDER );
if ( providerName == null ) {
providerName = persistenceUnit.getProviderClassName();
}
if ( providerName != null ) {
providerName = providerName.trim();
}
return providerName;
}
}

View File

@ -0,0 +1,47 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.boot.spi;
import javax.persistence.spi.PersistenceUnitTransactionType;
import org.hibernate.Interceptor;
/**
* @author Steve Ebersole
*/
public interface Settings {
public PersistenceUnitTransactionType getTransactionType();
/**
* Should resources held by {@link javax.persistence.EntityManager} instance be released immediately on close?
* <p/>
* The other option is to release them as part of an after-transaction callback.
*
* @return {@code true}/{@code false}
*/
public boolean isReleaseResourcesOnCloseEnabled();
public Class<? extends Interceptor> getSessionInterceptorClass();
}

View File

@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.Converter;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;
@ -143,10 +144,11 @@ public class NativeScanner implements Scanner {
}
private boolean isValidForClasses(Set<Class<? extends Annotation>> annotationsToLookFor) {
return annotationsToLookFor.size() != 3
return annotationsToLookFor.size() != 4
|| !annotationsToLookFor.contains( Entity.class )
|| !annotationsToLookFor.contains( MappedSuperclass.class )
|| !annotationsToLookFor.contains( Embeddable.class );
|| !annotationsToLookFor.contains( Embeddable.class )
|| !annotationsToLookFor.contains( Converter.class );
}
/**

View File

@ -0,0 +1,55 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.test.boot;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.ejb.boot.internal.HibernatePersistenceProvider;
import org.hibernate.ejb.test.jee.OrmVersionTest;
import org.junit.Test;
/**
* @author Steve Ebersole
*/
public class NewBootProcessTest {
@Test
public void basicNewBootProcessTest() {
Map settings = new HashMap();
HibernatePersistenceProvider persistenceProvider = new HibernatePersistenceProvider();
persistenceProvider.createContainerEntityManagerFactory(
new OrmVersionTest.PersistenceUnitInfoImpl( "my-test" ) {
@Override
public URL getPersistenceUnitRootUrl() {
// just get any known url...
return HibernatePersistenceProvider.class.getResource( "/org/hibernate/ejb/persistence_1_0.xsd" );
}
},
settings
);
}
}

View File

@ -28,6 +28,7 @@ import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Converter;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.EntityManagerFactory;
@ -63,6 +64,7 @@ public class ScannerTest extends PackagingTestCase {
annotationsToLookFor.add( Entity.class );
annotationsToLookFor.add( MappedSuperclass.class );
annotationsToLookFor.add( Embeddable.class );
annotationsToLookFor.add( Converter.class );
final Set<Class<?>> classes = scanner.getClassesInJar( defaultPar.toURL(), annotationsToLookFor );
assertEquals( 3, classes.size() );