mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-07 19:58:16 +00:00
HHH-9143 - Build baseline Jandex as part of scanning
This commit is contained in:
parent
9db6596a15
commit
4b443069fd
@ -454,12 +454,29 @@ public interface AvailableSettings {
|
||||
String FLUSH_MODE = "org.hibernate.flushMode";
|
||||
|
||||
/**
|
||||
* Pass an implementation of {@link org.hibernate.ejb.packaging.Scanner}:
|
||||
* - preferably an actual instance
|
||||
* - or a class name with a no-arg constructor
|
||||
* Pass an implementation of {@link org.hibernate.jpa.boot.scan.spi.Scanner}
|
||||
* (or the deprecated {@link org.hibernate.ejb.packaging.Scanner}). Accepts
|
||||
* either:<ul>
|
||||
* <li>an actual instance</li>
|
||||
* <li>a reference to a Class that implements Scanner</li>
|
||||
* <li>a fully qualified name of a Class that implements Scanner</li>
|
||||
* </ul>
|
||||
*/
|
||||
String SCANNER = "hibernate.ejb.resource_scanner";
|
||||
|
||||
/**
|
||||
* Pass {@link org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory} to use
|
||||
* in the scanning process. Accepts either:<ul>
|
||||
* <li>an ArchiveDescriptorFactory instance</li>
|
||||
* <li>a reference to a Class that implements ArchiveDescriptorFactory</li>
|
||||
* <li>a fully qualified name of a Class that implements ArchiveDescriptorFactory</li>
|
||||
* </ul>
|
||||
*
|
||||
* @see #SCANNER
|
||||
* @see org.hibernate.jpa.boot.scan.spi.Scanner
|
||||
*/
|
||||
String SCANNER_ARCHIVE_DELEGATE = "hibernate.jpa.scanner_archive_delegate";
|
||||
|
||||
/**
|
||||
* List of classes names
|
||||
* Internal use only
|
||||
|
@ -64,8 +64,11 @@
|
||||
import org.hibernate.internal.util.ValueHolder;
|
||||
import org.hibernate.jaxb.spi.cfg.JaxbHibernateConfiguration;
|
||||
import org.hibernate.jpa.AvailableSettings;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory;
|
||||
import org.hibernate.jpa.boot.scan.internal.StandardJpaScanEnvironmentImpl;
|
||||
import org.hibernate.jpa.boot.scan.internal.StandardScanOptions;
|
||||
import org.hibernate.jpa.boot.scan.internal.StandardScanner;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanEnvironment;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanOptions;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanResult;
|
||||
import org.hibernate.jpa.boot.scan.spi.Scanner;
|
||||
@ -691,28 +694,37 @@ private void configure(StandardServiceRegistry ssr, MergedSettings mergedSetting
|
||||
@SuppressWarnings("unchecked")
|
||||
private ScanResult scanDeployment(BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||
IndexView jandexIndex = (IndexView) configurationValues.remove( JANDEX_INDEX );
|
||||
Indexer indexer = null;
|
||||
if ( jandexIndex != null ) {
|
||||
indexer = new Indexer();
|
||||
Indexer jandexIndexer = null;
|
||||
if ( jandexIndex == null ) {
|
||||
// If we don't have a Jandex index passed to us, we need to build one.
|
||||
jandexIndexer = new Indexer();
|
||||
}
|
||||
|
||||
final Scanner scanner = locateOrBuildScanner( bootstrapServiceRegistry );
|
||||
final ScanOptions scanOptions = determineScanOptions( indexer );
|
||||
final ScanEnvironment environment = new StandardJpaScanEnvironmentImpl( persistenceUnit );
|
||||
final ScanOptions options = determineScanOptions( jandexIndexer, jandexIndex );
|
||||
final ScanResult result = scanner.scan( environment, options );
|
||||
|
||||
ScanResult scanResult = scanner.scan( persistenceUnit, scanOptions );
|
||||
|
||||
if ( indexer != null ) {
|
||||
jandexIndex = indexer.complete();
|
||||
configurationValues.put( JANDEX_INDEX, jandexIndex );
|
||||
if ( jandexIndexer != null ) {
|
||||
jandexIndex = jandexIndexer.complete();
|
||||
// if the indexer indexed anything use that index
|
||||
//
|
||||
// IMPL NOTE : (unfortunately?) Jandex has no way to see if an Indexer
|
||||
// actually indexed anything. But, it also manages package-info.class
|
||||
// as any other class, so this check should be fine
|
||||
if ( !jandexIndex.getKnownClasses().isEmpty() ) {
|
||||
configurationValues.put( JANDEX_INDEX, jandexIndex );
|
||||
}
|
||||
}
|
||||
return scanResult;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Scanner locateOrBuildScanner(BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||
final Object value = configurationValues.remove( AvailableSettings.SCANNER );
|
||||
if ( value == null ) {
|
||||
return new StandardScanner();
|
||||
return createStandardScanner( bootstrapServiceRegistry );
|
||||
}
|
||||
|
||||
if ( Scanner.class.isInstance( value ) ) {
|
||||
@ -746,11 +758,56 @@ private Scanner locateOrBuildScanner(BootstrapServiceRegistry bootstrapServiceRe
|
||||
}
|
||||
}
|
||||
|
||||
private ScanOptions determineScanOptions(Indexer indexer) {
|
||||
@SuppressWarnings("unchecked")
|
||||
private Scanner createStandardScanner(BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||
final Object value = configurationValues.remove( AvailableSettings.SCANNER_ARCHIVE_DELEGATE );
|
||||
if ( value == null ) {
|
||||
return new StandardScanner();
|
||||
}
|
||||
|
||||
if ( ArchiveDescriptorFactory.class.isInstance( value ) ) {
|
||||
return new StandardScanner( (ArchiveDescriptorFactory) value );
|
||||
}
|
||||
|
||||
final Class<? extends ArchiveDescriptorFactory> delegateClass;
|
||||
if ( Class.class.isInstance( value ) ) {
|
||||
try {
|
||||
delegateClass = (Class<? extends ArchiveDescriptorFactory>) value;
|
||||
}
|
||||
catch ( ClassCastException e ) {
|
||||
throw persistenceException(
|
||||
"Expecting ArchiveDescriptorFactory implementation, but found " + ((Class) value).getName()
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
final String delegateClassName = value.toString();
|
||||
try {
|
||||
delegateClass = bootstrapServiceRegistry.getService( ClassLoaderService.class ).classForName( delegateClassName );
|
||||
}
|
||||
catch ( ClassCastException e ) {
|
||||
throw persistenceException(
|
||||
"Expecting ArchiveDescriptorFactory implementation, but found " + delegateClassName
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
final ArchiveDescriptorFactory delegate = delegateClass.newInstance();
|
||||
return new StandardScanner( delegate );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw persistenceException( "Unable to instantiate ArchiveDescriptorFactory class: " + delegateClass, e );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ScanOptions determineScanOptions(Indexer indexer, IndexView jandexIndex) {
|
||||
return new StandardScanOptions(
|
||||
indexer,
|
||||
jandexIndex,
|
||||
(String) configurationValues.get( AvailableSettings.AUTODETECTION ),
|
||||
persistenceUnit.isExcludeUnlistedClasses(),
|
||||
indexer
|
||||
persistenceUnit.isExcludeUnlistedClasses()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, 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.jpa.boot.scan.internal;
|
||||
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntryHandler;
|
||||
import org.hibernate.jpa.boot.scan.spi.ArchiveEntryHandlers;
|
||||
import org.hibernate.jpa.boot.scan.spi.ClassFileArchiveEntryHandler;
|
||||
import org.hibernate.jpa.boot.scan.spi.NonClassFileArchiveEntryHandler;
|
||||
import org.hibernate.jpa.boot.scan.spi.PackageInfoArchiveEntryHandler;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ResultCoordinator implements ArchiveEntryHandlers {
|
||||
private final ClassFileArchiveEntryHandler classEntryHandler;
|
||||
private final PackageInfoArchiveEntryHandler packageEntryHandler;
|
||||
private final ArchiveEntryHandler fileEntryHandler;
|
||||
|
||||
public ResultCoordinator(ScanResultCollector resultCollector) {
|
||||
this.classEntryHandler = new ClassFileArchiveEntryHandler( resultCollector );
|
||||
this.packageEntryHandler = new PackageInfoArchiveEntryHandler( resultCollector );
|
||||
this.fileEntryHandler = new NonClassFileArchiveEntryHandler( resultCollector );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArchiveEntryHandler getClassFileHandler() {
|
||||
return classEntryHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArchiveEntryHandler getPackageInfoHandler() {
|
||||
return packageEntryHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArchiveEntryHandler getFileHandler() {
|
||||
return fileEntryHandler;
|
||||
}
|
||||
}
|
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, 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.jpa.boot.scan.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanEnvironment;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanOptions;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanResult;
|
||||
import org.hibernate.jpa.boot.spi.ClassDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.MappingFileDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.PackageDescriptor;
|
||||
import org.hibernate.metamodel.source.internal.annotations.util.JPADotNames;
|
||||
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
import org.jboss.jandex.DotName;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ScanResultCollector {
|
||||
private static final Logger log = Logger.getLogger( ScanResultCollector.class );
|
||||
|
||||
private final ScanEnvironment environment;
|
||||
private final ScanOptions options;
|
||||
|
||||
private final Set<ClassDescriptor> discoveredClasses;
|
||||
private final Set<PackageDescriptor> discoveredPackages;
|
||||
private final Set<MappingFileDescriptor> discoveredMappingFiles;
|
||||
|
||||
public ScanResultCollector(ScanEnvironment environment, ScanOptions options) {
|
||||
this.environment = environment;
|
||||
this.options = options;
|
||||
|
||||
if ( options.getJandexIndexer() == null && options.getJandexView() == null ) {
|
||||
throw new IllegalArgumentException( "Indexer and IndexView cannot both be null" );
|
||||
}
|
||||
|
||||
if ( environment.getExplicitlyListedClassNames() == null ) {
|
||||
throw new IllegalArgumentException( "ScanEnvironment#getExplicitlyListedClassNames should not return null" );
|
||||
}
|
||||
|
||||
if ( environment.getExplicitlyListedMappingFiles() == null ) {
|
||||
throw new IllegalArgumentException( "ScanEnvironment#getExplicitlyListedMappingFiles should not return null" );
|
||||
}
|
||||
|
||||
this.discoveredPackages = new HashSet<PackageDescriptor>();
|
||||
this.discoveredClasses = new HashSet<ClassDescriptor>();
|
||||
this.discoveredMappingFiles = new HashSet<MappingFileDescriptor>();
|
||||
}
|
||||
|
||||
public void handleClass(ClassDescriptor classDescriptor, boolean rootUrl) {
|
||||
// Always make sure the Jandex entry is created.
|
||||
final ClassInfo classInfo;
|
||||
if ( options.getJandexIndexer() != null ) {
|
||||
classInfo = indexStream( classDescriptor );
|
||||
}
|
||||
else {
|
||||
classInfo = options.getJandexView().getClassByName( DotName.createSimple( classDescriptor.getName() ) );
|
||||
}
|
||||
|
||||
if ( classInfo == null ) {
|
||||
log.debugf(
|
||||
"Could not locate class [%s] in Jandex; this will most likely lead to problems later",
|
||||
classDescriptor.getName()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// see if "discovery" of this entry is allowed
|
||||
|
||||
if ( !isListedOrDetectable( classInfo.name().toString(), rootUrl ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !containsClassAnnotationsOfInterest( classInfo ) ) {
|
||||
// not strictly needed, but helps cut down on the size of discoveredClasses
|
||||
return;
|
||||
}
|
||||
|
||||
discoveredClasses.add( classDescriptor );
|
||||
}
|
||||
|
||||
@SuppressWarnings("SimplifiableIfStatement")
|
||||
protected boolean isListedOrDetectable(String name, boolean rootUrl) {
|
||||
// IMPL NOTE : protect the calls to getExplicitlyListedClassNames unless needed,
|
||||
// since it can take time with lots of listed classes.
|
||||
if ( rootUrl ) {
|
||||
// the entry comes from the root url, allow it if either:
|
||||
// 1) we are allowed to discover classes/packages in the root url
|
||||
// 2) the entry was explicitly listed
|
||||
return options.canDetectUnlistedClassesInRoot()
|
||||
|| environment.getExplicitlyListedClassNames().contains( name );
|
||||
}
|
||||
else {
|
||||
// the entry comes from a non-root url, allow it if either:
|
||||
// 1) we are allowed to discover classes/packages in non-root urls
|
||||
// 2) the entry was explicitly listed
|
||||
return options.canDetectUnlistedClassesInNonRoot()
|
||||
|| environment.getExplicitlyListedClassNames().contains( name );
|
||||
}
|
||||
}
|
||||
|
||||
private ClassInfo indexStream(ClassDescriptor classDescriptor) {
|
||||
InputStream stream = classDescriptor.getStreamAccess().accessInputStream();
|
||||
try {
|
||||
return options.getJandexIndexer().index( stream );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new PersistenceException(
|
||||
"Could not add class [" + classDescriptor.getName() + "] to Jandex Indexer",
|
||||
e
|
||||
);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
stream.close();
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SimplifiableIfStatement")
|
||||
private boolean containsClassAnnotationsOfInterest(ClassInfo classInfo) {
|
||||
if ( classInfo.annotations() == null ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return classInfo.annotations().containsKey( JPADotNames.ENTITY )
|
||||
|| classInfo.annotations().containsKey( JPADotNames.MAPPED_SUPERCLASS )
|
||||
|| classInfo.annotations().containsKey( JPADotNames.EMBEDDABLE )
|
||||
|| classInfo.annotations().containsKey( JPADotNames.CONVERTER );
|
||||
}
|
||||
|
||||
public void handlePackage(PackageDescriptor packageDescriptor, boolean rootUrl) {
|
||||
// Always make sure the Jandex entry is created.
|
||||
if ( options.getJandexIndexer() != null ) {
|
||||
indexStream( packageDescriptor );
|
||||
}
|
||||
|
||||
if ( !isListedOrDetectable( packageDescriptor.getName(), rootUrl ) ) {
|
||||
// not strictly needed, but helps cut down on the size of discoveredPackages
|
||||
return;
|
||||
}
|
||||
|
||||
discoveredPackages.add( packageDescriptor );
|
||||
}
|
||||
|
||||
private ClassInfo indexStream(PackageDescriptor packageDescriptor) {
|
||||
InputStream stream = packageDescriptor.getStreamAccess().accessInputStream();
|
||||
try {
|
||||
return options.getJandexIndexer().index( stream );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new PersistenceException(
|
||||
"Could not add package [" + packageDescriptor.getName() + "] to Jandex Indexer",
|
||||
e
|
||||
);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
stream.close();
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleMappingFile(MappingFileDescriptor mappingFileDescriptor, boolean rootUrl) {
|
||||
if ( acceptAsMappingFile( mappingFileDescriptor, rootUrl ) ) {
|
||||
discoveredMappingFiles.add( mappingFileDescriptor );
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SimplifiableIfStatement")
|
||||
private boolean acceptAsMappingFile(MappingFileDescriptor mappingFileDescriptor, boolean rootUrl) {
|
||||
if ( mappingFileDescriptor.getName().endsWith( "hbm.xml" ) ) {
|
||||
return options.canDetectHibernateMappingFiles();
|
||||
}
|
||||
|
||||
if ( mappingFileDescriptor.getName().endsWith( "META-INF/orm.xml" ) ) {
|
||||
if ( environment.getExplicitlyListedMappingFiles().contains( "META-INF/orm.xml" ) ) {
|
||||
// if the user explicitly listed META-INF/orm.xml, only except the root one
|
||||
//
|
||||
// not sure why exactly, but this is what the old code does
|
||||
return rootUrl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return environment.getExplicitlyListedMappingFiles().contains( mappingFileDescriptor.getName() );
|
||||
}
|
||||
|
||||
public ScanResult toScanResult() {
|
||||
return new ScanResultImpl(
|
||||
Collections.unmodifiableSet( discoveredPackages ),
|
||||
Collections.unmodifiableSet( discoveredClasses ),
|
||||
Collections.unmodifiableSet( discoveredMappingFiles )
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, 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.jpa.boot.scan.internal;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanResult;
|
||||
import org.hibernate.jpa.boot.spi.ClassDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.MappingFileDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.PackageDescriptor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ScanResultImpl implements ScanResult {
|
||||
private final Set<PackageDescriptor> packageDescriptorSet;
|
||||
private final Set<ClassDescriptor> classDescriptorSet;
|
||||
private final Set<MappingFileDescriptor> mappingFileSet;
|
||||
|
||||
public ScanResultImpl(
|
||||
Set<PackageDescriptor> packageDescriptorSet,
|
||||
Set<ClassDescriptor> classDescriptorSet,
|
||||
Set<MappingFileDescriptor> mappingFileSet) {
|
||||
this.packageDescriptorSet = packageDescriptorSet;
|
||||
this.classDescriptorSet = classDescriptorSet;
|
||||
this.mappingFileSet = mappingFileSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<PackageDescriptor> getLocatedPackages() {
|
||||
return packageDescriptorSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ClassDescriptor> getLocatedClasses() {
|
||||
return classDescriptorSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<MappingFileDescriptor> getLocatedMappingFiles() {
|
||||
return mappingFileSet;
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, 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.jpa.boot.scan.internal;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanEnvironment;
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
|
||||
/**
|
||||
* Implementation of ScanEnvironment leveraging a JPA deployment descriptor.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardJpaScanEnvironmentImpl implements ScanEnvironment {
|
||||
private final PersistenceUnitDescriptor persistenceUnitDescriptor;
|
||||
|
||||
private final List<String> explicitlyListedClassNames;
|
||||
private final List<String> explicitlyListedMappingFiles;
|
||||
|
||||
|
||||
public StandardJpaScanEnvironmentImpl(PersistenceUnitDescriptor persistenceUnitDescriptor) {
|
||||
this.persistenceUnitDescriptor = persistenceUnitDescriptor;
|
||||
|
||||
this.explicitlyListedClassNames = persistenceUnitDescriptor.getManagedClassNames() == null
|
||||
? Collections.<String>emptyList()
|
||||
: persistenceUnitDescriptor.getManagedClassNames();
|
||||
this.explicitlyListedMappingFiles = persistenceUnitDescriptor.getMappingFileNames() == null
|
||||
? Collections.<String>emptyList()
|
||||
: persistenceUnitDescriptor.getMappingFileNames();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getRootUrl() {
|
||||
return persistenceUnitDescriptor.getPersistenceUnitRootUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<URL> getNonRootUrls() {
|
||||
return persistenceUnitDescriptor.getJarFileUrls();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getExplicitlyListedClassNames() {
|
||||
return explicitlyListedClassNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getExplicitlyListedMappingFiles() {
|
||||
return explicitlyListedMappingFiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistenceUnitDescriptor getPersistenceUnitDescriptor() {
|
||||
return persistenceUnitDescriptor;
|
||||
}
|
||||
}
|
@ -25,30 +25,27 @@
|
||||
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanOptions;
|
||||
|
||||
import org.jboss.jandex.IndexView;
|
||||
import org.jboss.jandex.Indexer;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardScanOptions implements ScanOptions {
|
||||
private final Indexer jandexIndexer;
|
||||
private final IndexView jandexView;
|
||||
|
||||
private final boolean detectClassesInRoot;
|
||||
private final boolean detectClassesInNonRoot;
|
||||
private final boolean detectHibernateMappingFiles;
|
||||
private final Indexer jandexIndexer;
|
||||
|
||||
public StandardScanOptions() {
|
||||
this( "hbm,class", false );
|
||||
}
|
||||
public StandardScanOptions(
|
||||
Indexer jandexIndexer,
|
||||
IndexView jandexView,
|
||||
String explicitDetectionSetting,
|
||||
boolean persistenceUnitExcludeUnlistedClassesValue) {
|
||||
this( explicitDetectionSetting, persistenceUnitExcludeUnlistedClassesValue, null );
|
||||
}
|
||||
|
||||
public StandardScanOptions(
|
||||
String explicitDetectionSetting,
|
||||
boolean persistenceUnitExcludeUnlistedClassesValue,
|
||||
Indexer jandexIndexer) {
|
||||
this.jandexIndexer = jandexIndexer;
|
||||
this.jandexView = jandexView;
|
||||
if ( explicitDetectionSetting == null ) {
|
||||
this.detectHibernateMappingFiles = true;
|
||||
this.detectClassesInRoot = ! persistenceUnitExcludeUnlistedClassesValue;
|
||||
@ -59,7 +56,32 @@ public StandardScanOptions(
|
||||
this.detectClassesInRoot = explicitDetectionSetting.contains( "class" );
|
||||
this.detectClassesInNonRoot = this.detectClassesInRoot;
|
||||
}
|
||||
this.jandexIndexer = jandexIndexer;
|
||||
}
|
||||
|
||||
/**
|
||||
* INTENDED FOR TESTING ONLY
|
||||
*/
|
||||
public StandardScanOptions() {
|
||||
this( "hbm,class", false );
|
||||
}
|
||||
|
||||
/**
|
||||
* INTENDED FOR TESTING ONLY
|
||||
*/
|
||||
public StandardScanOptions(
|
||||
String explicitDetectionSetting,
|
||||
boolean persistenceUnitExcludeUnlistedClassesValue) {
|
||||
this( new Indexer(), null, explicitDetectionSetting, persistenceUnitExcludeUnlistedClassesValue );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Indexer getJandexIndexer() {
|
||||
return jandexIndexer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexView getJandexView() {
|
||||
return jandexView;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -76,9 +98,4 @@ public boolean canDetectUnlistedClassesInNonRoot() {
|
||||
public boolean canDetectHibernateMappingFiles() {
|
||||
return detectHibernateMappingFiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Indexer getJandexIndexer() {
|
||||
return jandexIndexer;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
package org.hibernate.jpa.boot.scan.internal;
|
||||
|
||||
import org.hibernate.jpa.boot.archive.internal.StandardArchiveDescriptorFactory;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory;
|
||||
import org.hibernate.jpa.boot.scan.spi.AbstractScannerImpl;
|
||||
|
||||
/**
|
||||
@ -35,6 +36,10 @@
|
||||
*/
|
||||
public class StandardScanner extends AbstractScannerImpl {
|
||||
public StandardScanner() {
|
||||
super( StandardArchiveDescriptorFactory.INSTANCE );
|
||||
this( StandardArchiveDescriptorFactory.INSTANCE );
|
||||
}
|
||||
|
||||
public StandardScanner(ArchiveDescriptorFactory value) {
|
||||
super( value );
|
||||
}
|
||||
}
|
||||
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, 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.jpa.boot.scan.spi;
|
||||
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntryHandler;
|
||||
|
||||
/**
|
||||
* Base class for commonality between handling class file entries and handling package-info file entries.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractJavaArtifactArchiveEntryHandler implements ArchiveEntryHandler {
|
||||
private final ScanOptions scanOptions;
|
||||
|
||||
protected AbstractJavaArtifactArchiveEntryHandler(ScanOptions scanOptions) {
|
||||
this.scanOptions = scanOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if the incoming name (class/package name) is either:<ul>
|
||||
* <li>explicitly listed in a {@code <class/>} entry within the {@code <persistence-unit/>}</li>
|
||||
* <li>whether the scan options indicate that we are allowed to detect this entry</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param context Information about the archive. Mainly whether it is the root of the PU
|
||||
* @param name The class/package name
|
||||
*
|
||||
* @return {@code true} if the named class/package is either detectable or explicitly listed; {@code false}
|
||||
* otherwise.
|
||||
*/
|
||||
protected boolean isListedOrDetectable(ArchiveContext context, String name) {
|
||||
// IMPL NOTE : protect the isExplicitlyListed call unless needed, since it can take time in a PU
|
||||
// with lots of listed classes. The other conditions are simple boolean flag checks.
|
||||
if ( context.isRootUrl() ) {
|
||||
return scanOptions.canDetectUnlistedClassesInRoot() || isExplicitlyListed( context, name );
|
||||
}
|
||||
else {
|
||||
return scanOptions.canDetectUnlistedClassesInNonRoot() || isExplicitlyListed( context, name );
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isExplicitlyListed(ArchiveContext context, String name) {
|
||||
return context.getPersistenceUnitDescriptor().getManagedClassNames().contains( name );
|
||||
}
|
||||
}
|
@ -23,29 +23,15 @@
|
||||
*/
|
||||
package org.hibernate.jpa.boot.scan.spi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptor;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntryHandler;
|
||||
import org.hibernate.jpa.boot.internal.ClassDescriptorImpl;
|
||||
import org.hibernate.jpa.boot.internal.MappingFileDescriptorImpl;
|
||||
import org.hibernate.jpa.boot.internal.PackageDescriptorImpl;
|
||||
import org.hibernate.jpa.boot.spi.ClassDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.MappingFileDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.PackageDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
import org.hibernate.jpa.boot.scan.internal.ResultCoordinator;
|
||||
import org.hibernate.jpa.boot.scan.internal.ScanResultCollector;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
@ -59,295 +45,62 @@ protected AbstractScannerImpl(ArchiveDescriptorFactory archiveDescriptorFactory)
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScanResult scan(PersistenceUnitDescriptor persistenceUnit, ScanOptions scanOptions) {
|
||||
final ResultCollector resultCollector = new ResultCollector( scanOptions );
|
||||
public ScanResult scan(ScanEnvironment environment, ScanOptions options) {
|
||||
final ScanResultCollector collector = new ScanResultCollector( environment, options );
|
||||
final ResultCoordinator resultCoordinator = new ResultCoordinator( collector );
|
||||
|
||||
if ( persistenceUnit.getJarFileUrls() != null ) {
|
||||
for ( URL url : persistenceUnit.getJarFileUrls() ) {
|
||||
final ArchiveDescriptor descriptor = buildArchiveDescriptor( url, false, scanOptions );
|
||||
final ArchiveContext context = buildArchiveContext( persistenceUnit, false, resultCollector );
|
||||
if ( environment.getNonRootUrls() != null ) {
|
||||
final ArchiveContext context = new ArchiveContextImpl( environment, false, resultCoordinator );
|
||||
for ( URL url : environment.getNonRootUrls() ) {
|
||||
final ArchiveDescriptor descriptor = buildArchiveDescriptor( url, false );
|
||||
descriptor.visitArchive( context );
|
||||
}
|
||||
}
|
||||
|
||||
if ( persistenceUnit.getPersistenceUnitRootUrl() != null ) {
|
||||
final ArchiveDescriptor descriptor = buildArchiveDescriptor( persistenceUnit.getPersistenceUnitRootUrl(), true, scanOptions );
|
||||
final ArchiveContext context = buildArchiveContext( persistenceUnit, true, resultCollector );
|
||||
if ( environment.getRootUrl() != null ) {
|
||||
final ArchiveContext context = new ArchiveContextImpl( environment, true, resultCoordinator );
|
||||
final ArchiveDescriptor descriptor = buildArchiveDescriptor( environment.getRootUrl(), true );
|
||||
descriptor.visitArchive( context );
|
||||
}
|
||||
|
||||
return ScanResultImpl.from( resultCollector );
|
||||
return collector.toScanResult();
|
||||
}
|
||||
|
||||
private ArchiveContext buildArchiveContext(
|
||||
PersistenceUnitDescriptor persistenceUnit,
|
||||
boolean isRoot,
|
||||
ArchiveEntryHandlers entryHandlers) {
|
||||
return new ArchiveContextImpl( persistenceUnit, isRoot, entryHandlers );
|
||||
}
|
||||
|
||||
protected static interface ArchiveEntryHandlers {
|
||||
public ArchiveEntryHandler getClassFileHandler();
|
||||
public ArchiveEntryHandler getPackageInfoHandler();
|
||||
public ArchiveEntryHandler getFileHandler();
|
||||
}
|
||||
|
||||
private ArchiveDescriptor buildArchiveDescriptor(URL url, boolean isRootUrl, ScanOptions scanOptions) {
|
||||
private ArchiveDescriptor buildArchiveDescriptor(URL url, boolean isRootUrl) {
|
||||
final ArchiveDescriptor descriptor;
|
||||
final ArchiveDescriptorInfo descriptorInfo = archiveDescriptorCache.get( url );
|
||||
if ( descriptorInfo == null ) {
|
||||
descriptor = archiveDescriptorFactory.buildArchiveDescriptor( url );
|
||||
archiveDescriptorCache.put(
|
||||
url,
|
||||
new ArchiveDescriptorInfo( descriptor, isRootUrl, scanOptions )
|
||||
new ArchiveDescriptorInfo( descriptor, isRootUrl )
|
||||
);
|
||||
}
|
||||
else {
|
||||
validateReuse( descriptorInfo, isRootUrl, scanOptions );
|
||||
validateReuse( descriptorInfo, isRootUrl );
|
||||
descriptor = descriptorInfo.archiveDescriptor;
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
public static class ResultCollector
|
||||
implements ArchiveEntryHandlers,
|
||||
PackageInfoArchiveEntryHandler.Callback,
|
||||
ClassFileArchiveEntryHandler.Callback,
|
||||
NonClassFileArchiveEntryHandler.Callback {
|
||||
private final ScanOptions scanOptions;
|
||||
|
||||
private final ClassFileArchiveEntryHandler classFileHandler;
|
||||
private final PackageInfoArchiveEntryHandler packageInfoHandler;
|
||||
private final NonClassFileArchiveEntryHandler fileHandler;
|
||||
|
||||
private final Set<PackageDescriptor> packageDescriptorSet = new HashSet<PackageDescriptor>();
|
||||
private final Set<ClassDescriptor> classDescriptorSet = new HashSet<ClassDescriptor>();
|
||||
private final Set<MappingFileDescriptor> mappingFileSet = new HashSet<MappingFileDescriptor>();
|
||||
|
||||
public ResultCollector(ScanOptions scanOptions) {
|
||||
this.scanOptions = scanOptions;
|
||||
|
||||
this.classFileHandler = new ClassFileArchiveEntryHandler( scanOptions, this );
|
||||
this.packageInfoHandler = new PackageInfoArchiveEntryHandler( scanOptions, this );
|
||||
this.fileHandler = new NonClassFileArchiveEntryHandler( scanOptions, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArchiveEntryHandler getClassFileHandler() {
|
||||
return classFileHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArchiveEntryHandler getPackageInfoHandler() {
|
||||
return packageInfoHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArchiveEntryHandler getFileHandler() {
|
||||
return fileHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void locatedPackage(PackageDescriptor packageDescriptor) {
|
||||
final PackageDescriptor keeper;
|
||||
|
||||
if ( PackageDescriptorImpl.class.isInstance( packageDescriptor ) ) {
|
||||
keeper = packageDescriptor;
|
||||
}
|
||||
else {
|
||||
// to make sure we have proper equals/hashcode
|
||||
keeper = new PackageDescriptorImpl(
|
||||
packageDescriptor.getName(),
|
||||
packageDescriptor.getStreamAccess()
|
||||
);
|
||||
}
|
||||
|
||||
if ( scanOptions.getJandexIndexer() != null ) {
|
||||
InputStream stream = keeper.getStreamAccess().accessInputStream();
|
||||
try {
|
||||
scanOptions.getJandexIndexer().index( stream );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new PersistenceException( "Could not add package-info to Jandex Indexer", e );
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
stream.close();
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
packageDescriptorSet.add( keeper );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void locatedClass(ClassDescriptor classDescriptor) {
|
||||
// to make sure we have proper equals/hashcode
|
||||
final ClassDescriptor keeper;
|
||||
|
||||
if ( ClassDescriptorImpl.class.isInstance( classDescriptor ) ) {
|
||||
keeper = classDescriptor;
|
||||
}
|
||||
else {
|
||||
keeper = new ClassDescriptorImpl(
|
||||
classDescriptor.getName(),
|
||||
classDescriptor.getStreamAccess()
|
||||
);
|
||||
}
|
||||
|
||||
if ( scanOptions.getJandexIndexer() != null ) {
|
||||
InputStream stream = keeper.getStreamAccess().accessInputStream();
|
||||
try {
|
||||
scanOptions.getJandexIndexer().index( stream );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new PersistenceException(
|
||||
"Could not add class [" + keeper.getName() + "] to Jandex Indexer",
|
||||
e
|
||||
);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
stream.close();
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
classDescriptorSet.add( keeper );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void locatedMappingFile(MappingFileDescriptor mappingFileDescriptor) {
|
||||
if ( MappingFileDescriptorImpl.class.isInstance( mappingFileDescriptor ) ) {
|
||||
mappingFileSet.add( mappingFileDescriptor );
|
||||
}
|
||||
else {
|
||||
// to make sure we have proper equals/hashcode
|
||||
mappingFileSet.add(
|
||||
new MappingFileDescriptorImpl(
|
||||
mappingFileDescriptor.getName(),
|
||||
mappingFileDescriptor.getStreamAccess()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<PackageDescriptor> getPackageDescriptorSet() {
|
||||
return packageDescriptorSet;
|
||||
}
|
||||
|
||||
public Set<ClassDescriptor> getClassDescriptorSet() {
|
||||
return classDescriptorSet;
|
||||
}
|
||||
|
||||
public Set<MappingFileDescriptor> getMappingFileSet() {
|
||||
return mappingFileSet;
|
||||
}
|
||||
}
|
||||
|
||||
// This needs to be protected and attributes/constructor visible in case
|
||||
// a custom scanner needs to override validateReuse.
|
||||
protected static class ArchiveDescriptorInfo {
|
||||
public final ArchiveDescriptor archiveDescriptor;
|
||||
public final boolean isRoot;
|
||||
public final ScanOptions scanOptions;
|
||||
|
||||
public ArchiveDescriptorInfo(
|
||||
ArchiveDescriptor archiveDescriptor,
|
||||
boolean isRoot,
|
||||
ScanOptions scanOptions) {
|
||||
public ArchiveDescriptorInfo(ArchiveDescriptor archiveDescriptor, boolean isRoot) {
|
||||
this.archiveDescriptor = archiveDescriptor;
|
||||
this.isRoot = isRoot;
|
||||
this.scanOptions = scanOptions;
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateReuse(ArchiveDescriptorInfo descriptor, boolean root, ScanOptions options) {
|
||||
@SuppressWarnings("UnusedParameters")
|
||||
protected void validateReuse(ArchiveDescriptorInfo descriptor, boolean root) {
|
||||
// is it really reasonable that a single url be processed multiple times?
|
||||
// for now, throw an exception, mainly because I am interested in situations where this might happen
|
||||
throw new IllegalStateException( "ArchiveDescriptor reused; can URLs be processed multiple times?" );
|
||||
}
|
||||
|
||||
public static class ArchiveContextImpl implements ArchiveContext {
|
||||
private final PersistenceUnitDescriptor persistenceUnitDescriptor;
|
||||
private final boolean isRootUrl;
|
||||
private final ArchiveEntryHandlers entryHandlers;
|
||||
|
||||
public ArchiveContextImpl(
|
||||
PersistenceUnitDescriptor persistenceUnitDescriptor,
|
||||
boolean isRootUrl,
|
||||
ArchiveEntryHandlers entryHandlers) {
|
||||
this.persistenceUnitDescriptor = persistenceUnitDescriptor;
|
||||
this.isRootUrl = isRootUrl;
|
||||
this.entryHandlers = entryHandlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistenceUnitDescriptor getPersistenceUnitDescriptor() {
|
||||
return persistenceUnitDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRootUrl() {
|
||||
return isRootUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArchiveEntryHandler obtainArchiveEntryHandler(ArchiveEntry entry) {
|
||||
final String nameWithinArchive = entry.getNameWithinArchive();
|
||||
|
||||
if ( nameWithinArchive.endsWith( "package-info.class" ) ) {
|
||||
return entryHandlers.getPackageInfoHandler();
|
||||
}
|
||||
else if ( nameWithinArchive.endsWith( ".class" ) ) {
|
||||
return entryHandlers.getClassFileHandler();
|
||||
}
|
||||
else {
|
||||
return entryHandlers.getFileHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ScanResultImpl implements ScanResult {
|
||||
private final Set<PackageDescriptor> packageDescriptorSet;
|
||||
private final Set<ClassDescriptor> classDescriptorSet;
|
||||
private final Set<MappingFileDescriptor> mappingFileSet;
|
||||
|
||||
private ScanResultImpl(
|
||||
Set<PackageDescriptor> packageDescriptorSet,
|
||||
Set<ClassDescriptor> classDescriptorSet,
|
||||
Set<MappingFileDescriptor> mappingFileSet) {
|
||||
this.packageDescriptorSet = packageDescriptorSet;
|
||||
this.classDescriptorSet = classDescriptorSet;
|
||||
this.mappingFileSet = mappingFileSet;
|
||||
}
|
||||
|
||||
private static ScanResult from(ResultCollector resultCollector) {
|
||||
return new ScanResultImpl(
|
||||
Collections.unmodifiableSet( resultCollector.packageDescriptorSet ),
|
||||
Collections.unmodifiableSet( resultCollector.classDescriptorSet ),
|
||||
Collections.unmodifiableSet( resultCollector.mappingFileSet )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<PackageDescriptor> getLocatedPackages() {
|
||||
return packageDescriptorSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ClassDescriptor> getLocatedClasses() {
|
||||
return classDescriptorSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<MappingFileDescriptor> getLocatedMappingFiles() {
|
||||
return mappingFileSet;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, 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.jpa.boot.scan.spi;
|
||||
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntryHandler;
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ArchiveContextImpl implements ArchiveContext {
|
||||
private final ScanEnvironment environment;
|
||||
private final boolean isRootUrl;
|
||||
private final ArchiveEntryHandlers entryHandlers;
|
||||
|
||||
public ArchiveContextImpl(
|
||||
ScanEnvironment environment,
|
||||
boolean isRootUrl,
|
||||
ArchiveEntryHandlers entryHandlers) {
|
||||
this.environment = environment;
|
||||
this.isRootUrl = isRootUrl;
|
||||
this.entryHandlers = entryHandlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public PersistenceUnitDescriptor getPersistenceUnitDescriptor() {
|
||||
return environment.getPersistenceUnitDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRootUrl() {
|
||||
return isRootUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArchiveEntryHandler obtainArchiveEntryHandler(ArchiveEntry entry) {
|
||||
final String nameWithinArchive = entry.getNameWithinArchive();
|
||||
|
||||
if ( nameWithinArchive.endsWith( "package-info.class" ) ) {
|
||||
return entryHandlers.getPackageInfoHandler();
|
||||
}
|
||||
else if ( nameWithinArchive.endsWith( ".class" ) ) {
|
||||
return entryHandlers.getClassFileHandler();
|
||||
}
|
||||
else {
|
||||
return entryHandlers.getFileHandler();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, 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.jpa.boot.scan.spi;
|
||||
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntryHandler;
|
||||
|
||||
/**
|
||||
* Composite of the various types of ArchiveEntryHandlers
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ArchiveEntryHandlers {
|
||||
public ArchiveEntryHandler getClassFileHandler();
|
||||
public ArchiveEntryHandler getPackageInfoHandler();
|
||||
public ArchiveEntryHandler getFileHandler();
|
||||
}
|
@ -26,18 +26,15 @@
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import javax.persistence.Converter;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
import javassist.bytecode.AnnotationsAttribute;
|
||||
import javassist.bytecode.ClassFile;
|
||||
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntryHandler;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveException;
|
||||
import org.hibernate.jpa.boot.internal.ClassDescriptorImpl;
|
||||
import org.hibernate.jpa.boot.scan.internal.ScanResultCollector;
|
||||
import org.hibernate.jpa.boot.spi.ClassDescriptor;
|
||||
|
||||
/**
|
||||
@ -45,37 +42,16 @@
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ClassFileArchiveEntryHandler extends AbstractJavaArtifactArchiveEntryHandler {
|
||||
private final Callback callback;
|
||||
public class ClassFileArchiveEntryHandler implements ArchiveEntryHandler {
|
||||
private final ScanResultCollector resultCollector;
|
||||
|
||||
/**
|
||||
* Contract for the thing interested in being notified about accepted class descriptors.
|
||||
*/
|
||||
public static interface Callback {
|
||||
public void locatedClass(ClassDescriptor classDescriptor);
|
||||
}
|
||||
|
||||
public ClassFileArchiveEntryHandler(ScanOptions scanOptions, Callback callback) {
|
||||
super( scanOptions );
|
||||
this.callback = callback;
|
||||
public ClassFileArchiveEntryHandler(ScanResultCollector resultCollector) {
|
||||
this.resultCollector = resultCollector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEntry(ArchiveEntry entry, ArchiveContext context) {
|
||||
final ClassFile classFile = toClassFile( entry );
|
||||
final ClassDescriptor classDescriptor = toClassDescriptor( classFile, entry );
|
||||
|
||||
if ( ! isListedOrDetectable( context, classDescriptor.getName() ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// we are only interested in classes with certain annotations, so see if the JavaTypeDescriptor
|
||||
// represents a class which contains any of those annotations
|
||||
if ( ! containsClassAnnotationsOfInterest( classFile ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
notifyMatchedClass( classDescriptor );
|
||||
resultCollector.handleClass( toClassDescriptor( toClassFile( entry ), entry ), context.isRootUrl() );
|
||||
}
|
||||
|
||||
private ClassFile toClassFile(ArchiveEntry entry) {
|
||||
@ -102,24 +78,7 @@ private ClassFile toClassFile(ArchiveEntry entry) {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SimplifiableIfStatement")
|
||||
private boolean containsClassAnnotationsOfInterest(ClassFile cf) {
|
||||
final AnnotationsAttribute visibleAnnotations = (AnnotationsAttribute) cf.getAttribute( AnnotationsAttribute.visibleTag );
|
||||
if ( visibleAnnotations == null ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return visibleAnnotations.getAnnotation( Entity.class.getName() ) != null
|
||||
|| visibleAnnotations.getAnnotation( MappedSuperclass.class.getName() ) != null
|
||||
|| visibleAnnotations.getAnnotation( Embeddable.class.getName() ) != null
|
||||
|| visibleAnnotations.getAnnotation( Converter.class.getName() ) != null;
|
||||
}
|
||||
|
||||
protected ClassDescriptor toClassDescriptor(ClassFile classFile, ArchiveEntry entry) {
|
||||
private ClassDescriptor toClassDescriptor(ClassFile classFile, ArchiveEntry entry) {
|
||||
return new ClassDescriptorImpl( classFile.getName(), entry.getStreamAccess() );
|
||||
}
|
||||
|
||||
protected final void notifyMatchedClass(ClassDescriptor classDescriptor) {
|
||||
callback.locatedClass( classDescriptor );
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntryHandler;
|
||||
import org.hibernate.jpa.boot.internal.MappingFileDescriptorImpl;
|
||||
import org.hibernate.jpa.boot.spi.MappingFileDescriptor;
|
||||
import org.hibernate.jpa.boot.scan.internal.ScanResultCollector;
|
||||
|
||||
/**
|
||||
* Defines handling and filtering for all non-class file (package-info is also a class file...) entries within an archive
|
||||
@ -35,54 +35,17 @@
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NonClassFileArchiveEntryHandler implements ArchiveEntryHandler {
|
||||
private final ScanOptions scanOptions;
|
||||
private final Callback callback;
|
||||
private final ScanResultCollector resultCollector;
|
||||
|
||||
/**
|
||||
* Contract for the thing interested in being notified about accepted mapping file descriptors.
|
||||
*/
|
||||
public static interface Callback {
|
||||
public void locatedMappingFile(MappingFileDescriptor mappingFileDescriptor);
|
||||
}
|
||||
|
||||
public NonClassFileArchiveEntryHandler(ScanOptions scanOptions, Callback callback) {
|
||||
this.scanOptions = scanOptions;
|
||||
this.callback = callback;
|
||||
public NonClassFileArchiveEntryHandler(ScanResultCollector resultCollector) {
|
||||
this.resultCollector = resultCollector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEntry(ArchiveEntry entry, ArchiveContext context) {
|
||||
if ( acceptAsMappingFile( entry, context) ) {
|
||||
notifyMatchedMappingFile( entry );
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SimplifiableIfStatement")
|
||||
private boolean acceptAsMappingFile(ArchiveEntry entry, ArchiveContext context) {
|
||||
if ( entry.getNameWithinArchive().endsWith( "hbm.xml" ) ) {
|
||||
return scanOptions.canDetectHibernateMappingFiles();
|
||||
}
|
||||
|
||||
// todo : should really do this case-insensitively
|
||||
// use getNameWithinArchive, not getName -- ensure paths are normalized (Windows, etc.)
|
||||
if ( entry.getNameWithinArchive().endsWith( "META-INF/orm.xml" ) ) {
|
||||
if ( context.getPersistenceUnitDescriptor().getMappingFileNames().contains( "META-INF/orm.xml" ) ) {
|
||||
// if the user explicitly listed META-INF/orm.xml, only except the root one
|
||||
//
|
||||
// not sure why exactly, but this is what the old code does
|
||||
return context.isRootUrl();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return context.getPersistenceUnitDescriptor().getMappingFileNames().contains( entry.getNameWithinArchive() );
|
||||
}
|
||||
|
||||
protected final void notifyMatchedMappingFile(ArchiveEntry entry) {
|
||||
callback.locatedMappingFile( toMappingFileDescriptor( entry ) );
|
||||
}
|
||||
|
||||
protected MappingFileDescriptor toMappingFileDescriptor(ArchiveEntry entry) {
|
||||
return new MappingFileDescriptorImpl( entry.getNameWithinArchive(), entry.getStreamAccess() );
|
||||
resultCollector.handleMappingFile(
|
||||
new MappingFileDescriptorImpl( entry.getNameWithinArchive(), entry.getStreamAccess() ),
|
||||
context.isRootUrl()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,9 @@
|
||||
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntryHandler;
|
||||
import org.hibernate.jpa.boot.internal.PackageDescriptorImpl;
|
||||
import org.hibernate.jpa.boot.scan.internal.ScanResultCollector;
|
||||
import org.hibernate.jpa.boot.spi.PackageDescriptor;
|
||||
|
||||
/**
|
||||
@ -33,19 +35,11 @@
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class PackageInfoArchiveEntryHandler extends AbstractJavaArtifactArchiveEntryHandler {
|
||||
private final Callback callback;
|
||||
public class PackageInfoArchiveEntryHandler implements ArchiveEntryHandler {
|
||||
private final ScanResultCollector resultCollector;
|
||||
|
||||
/**
|
||||
* Contract for the thing interested in being notified about accepted package-info descriptors.
|
||||
*/
|
||||
public static interface Callback {
|
||||
public void locatedPackage(PackageDescriptor packageDescriptor);
|
||||
}
|
||||
|
||||
public PackageInfoArchiveEntryHandler(ScanOptions scanOptions, Callback callback) {
|
||||
super( scanOptions );
|
||||
this.callback = callback;
|
||||
public PackageInfoArchiveEntryHandler(ScanResultCollector resultCollector) {
|
||||
this.resultCollector = resultCollector;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -55,12 +49,7 @@ public void handleEntry(ArchiveEntry entry, ArchiveContext context) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! isListedOrDetectable( context, entry.getName() ) ) {
|
||||
// the package is not explicitly listed, and we are not allowed to detect it.
|
||||
return;
|
||||
}
|
||||
|
||||
notifyMatchedPackage( toPackageDescriptor( entry ) );
|
||||
resultCollector.handlePackage( toPackageDescriptor( entry ), context.isRootUrl() );
|
||||
}
|
||||
|
||||
protected PackageDescriptor toPackageDescriptor(ArchiveEntry entry) {
|
||||
@ -70,8 +59,4 @@ protected PackageDescriptor toPackageDescriptor(ArchiveEntry entry) {
|
||||
|
||||
return new PackageDescriptorImpl( packageName, entry.getStreamAccess() );
|
||||
}
|
||||
|
||||
protected final void notifyMatchedPackage(PackageDescriptor packageDescriptor) {
|
||||
callback.locatedPackage( packageDescriptor );
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, 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.jpa.boot.scan.spi;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ScanEnvironment {
|
||||
public URL getRootUrl();
|
||||
public List<URL> getNonRootUrls();
|
||||
|
||||
public List<String> getExplicitlyListedClassNames();
|
||||
public List<String> getExplicitlyListedMappingFiles();
|
||||
|
||||
/**
|
||||
* @deprecated Added temporarily to support legacy
|
||||
* {@link org.hibernate.jpa.boot.archive.spi.ArchiveContext#getPersistenceUnitDescriptor()}
|
||||
* calls
|
||||
*/
|
||||
@Deprecated
|
||||
public PersistenceUnitDescriptor getPersistenceUnitDescriptor();
|
||||
}
|
@ -23,16 +23,58 @@
|
||||
*/
|
||||
package org.hibernate.jpa.boot.scan.spi;
|
||||
|
||||
import org.jboss.jandex.IndexView;
|
||||
import org.jboss.jandex.Indexer;
|
||||
|
||||
/**
|
||||
* Options for performing scanning
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ScanOptions {
|
||||
/**
|
||||
* The Jandex Indexer to use.
|
||||
* <p/>
|
||||
* Note that either this or {@link #getJandexView()} must return non-null.
|
||||
*
|
||||
* @return The Jandex Indexer to use
|
||||
*/
|
||||
public Indexer getJandexIndexer();
|
||||
|
||||
/**
|
||||
* The Jandex index to use.
|
||||
* <p/>
|
||||
* Note that either this or {@link #getJandexIndexer()} must return non-null.
|
||||
*
|
||||
* @return The Jandex index to use.
|
||||
*/
|
||||
public IndexView getJandexView();
|
||||
|
||||
/**
|
||||
* Is detection of managed classes from root url allowed? In strict JPA
|
||||
* sense, this would be controlled by the {@code <exclude-unlisted-classes/>}
|
||||
* element.
|
||||
*
|
||||
* @return Whether detection of classes from root url is allowed
|
||||
*/
|
||||
public boolean canDetectUnlistedClassesInRoot();
|
||||
|
||||
/**
|
||||
* Is detection of managed classes from non-root urls allowed? In strict JPA
|
||||
* sense, this would always be allowed.
|
||||
*
|
||||
* @return Whether detection of classes from non-root urls is allowed
|
||||
*/
|
||||
public boolean canDetectUnlistedClassesInNonRoot();
|
||||
|
||||
/**
|
||||
* Is detection of Hibernate Mapping files allowed?
|
||||
*
|
||||
* @return Whether detection of Mapping files is allowed.
|
||||
*
|
||||
* @deprecated With move to unified schema, this setting is now deprecated and will
|
||||
* be removed once support for reading {@code hbm.xml} files is fully removed.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean canDetectHibernateMappingFiles();
|
||||
|
||||
public Indexer getJandexIndexer();
|
||||
}
|
||||
|
@ -23,8 +23,6 @@
|
||||
*/
|
||||
package org.hibernate.jpa.boot.scan.spi;
|
||||
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
|
||||
/**
|
||||
* Defines the contract for Hibernate to be able to scan for classes, packages and resources inside a
|
||||
* persistence unit.
|
||||
@ -34,13 +32,11 @@
|
||||
*/
|
||||
public interface Scanner {
|
||||
/**
|
||||
* Perform the scanning against the described persistence unit using the defined options, and return the scan
|
||||
* results.
|
||||
* Perform the scanning against the described environment using the
|
||||
* defined options, and return the scan results.
|
||||
*
|
||||
* @param persistenceUnit THe description of the persistence unit.
|
||||
* @param options The scan options
|
||||
*
|
||||
* @return The scan results.
|
||||
* @param environment The scan environment
|
||||
* @param options The options to control the scanning
|
||||
*/
|
||||
public ScanResult scan(PersistenceUnitDescriptor persistenceUnit, ScanOptions options);
|
||||
public ScanResult scan(ScanEnvironment environment, ScanOptions options);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package org.hibernate.jpa.test.packaging;
|
||||
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
import org.hibernate.jpa.boot.scan.internal.StandardScanner;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanEnvironment;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanOptions;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanResult;
|
||||
import org.hibernate.jpa.boot.scan.spi.Scanner;
|
||||
@ -22,8 +22,8 @@ public static void resetUsed() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScanResult scan(PersistenceUnitDescriptor persistenceUnit, ScanOptions options) {
|
||||
public ScanResult scan(ScanEnvironment environment, ScanOptions options) {
|
||||
isUsed = true;
|
||||
return delegate.scan( persistenceUnit, options );
|
||||
return delegate.scan( environment, options );
|
||||
}
|
||||
}
|
||||
|
@ -32,32 +32,37 @@
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.URLStreamHandlerFactory;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.jpa.boot.archive.internal.ArchiveHelper;
|
||||
import org.hibernate.jpa.boot.archive.internal.ExplodedArchiveDescriptor;
|
||||
import org.hibernate.jpa.boot.archive.internal.JarFileBasedArchiveDescriptor;
|
||||
import org.hibernate.jpa.boot.archive.internal.JarInputStreamBasedArchiveDescriptor;
|
||||
import org.hibernate.jpa.boot.archive.internal.JarProtocolArchiveDescriptor;
|
||||
import org.hibernate.jpa.boot.archive.internal.StandardArchiveDescriptorFactory;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptor;
|
||||
import org.hibernate.jpa.boot.internal.ClassDescriptorImpl;
|
||||
import org.hibernate.jpa.boot.scan.internal.ResultCoordinator;
|
||||
import org.hibernate.jpa.boot.scan.internal.ScanResultCollector;
|
||||
import org.hibernate.jpa.boot.scan.internal.StandardScanOptions;
|
||||
import org.hibernate.jpa.boot.scan.spi.AbstractScannerImpl;
|
||||
import org.hibernate.jpa.boot.scan.internal.StandardScanner;
|
||||
import org.hibernate.jpa.boot.scan.spi.ArchiveContextImpl;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanEnvironment;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanResult;
|
||||
import org.hibernate.jpa.boot.spi.MappingFileDescriptor;
|
||||
import org.hibernate.jpa.test.PersistenceUnitDescriptorAdapter;
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
import org.hibernate.jpa.test.pack.defaultpar.Version;
|
||||
import org.hibernate.jpa.test.pack.explodedpar.Carpet;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.RequiresDialect;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
@ -69,7 +74,7 @@
|
||||
public class JarVisitorTest extends PackagingTestCase {
|
||||
@Test
|
||||
public void testHttp() throws Exception {
|
||||
URL url = ArchiveHelper.getJarURLFromURLEntry(
|
||||
final URL url = ArchiveHelper.getJarURLFromURLEntry(
|
||||
new URL(
|
||||
"jar:http://www.ibiblio.org/maven/hibernate/jars/hibernate-annotations-3.0beta1.jar!/META-INF/persistence.xml"
|
||||
),
|
||||
@ -83,18 +88,49 @@ public void testHttp() throws Exception {
|
||||
//fail silently
|
||||
return;
|
||||
}
|
||||
ArchiveDescriptor archiveDescriptor = StandardArchiveDescriptorFactory.INSTANCE.buildArchiveDescriptor( url );
|
||||
AbstractScannerImpl.ResultCollector resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() );
|
||||
archiveDescriptor.visitArchive(
|
||||
new AbstractScannerImpl.ArchiveContextImpl(
|
||||
new PersistenceUnitDescriptorAdapter(),
|
||||
true,
|
||||
resultCollector
|
||||
)
|
||||
);
|
||||
assertEquals( 0, resultCollector.getClassDescriptorSet().size() );
|
||||
assertEquals( 0, resultCollector.getPackageDescriptorSet().size() );
|
||||
assertEquals( 0, resultCollector.getMappingFileSet().size() );
|
||||
|
||||
ScanResult result = standardScan( url );
|
||||
assertEquals( 0, result.getLocatedClasses().size() );
|
||||
assertEquals( 0, result.getLocatedPackages().size() );
|
||||
assertEquals( 0, result.getLocatedMappingFiles().size() );
|
||||
}
|
||||
|
||||
private ScanResult standardScan(URL url) {
|
||||
ScanEnvironment env = new ScanEnvironmentImpl( url );
|
||||
return new StandardScanner().scan( env, new StandardScanOptions() );
|
||||
}
|
||||
|
||||
private static class ScanEnvironmentImpl implements ScanEnvironment {
|
||||
private final URL rootUrl;
|
||||
|
||||
private ScanEnvironmentImpl(URL rootUrl) {
|
||||
this.rootUrl = rootUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getRootUrl() {
|
||||
return rootUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<URL> getNonRootUrls() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getExplicitlyListedClassNames() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getExplicitlyListedMappingFiles() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistenceUnitDescriptor getPersistenceUnitDescriptor() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -102,36 +138,22 @@ public void testInputStreamZippedJar() throws Exception {
|
||||
File defaultPar = buildDefaultPar();
|
||||
addPackageToClasspath( defaultPar );
|
||||
|
||||
ArchiveDescriptor archiveDescriptor = new JarInputStreamBasedArchiveDescriptor(
|
||||
StandardArchiveDescriptorFactory.INSTANCE,
|
||||
defaultPar.toURL(),
|
||||
""
|
||||
);
|
||||
|
||||
AbstractScannerImpl.ResultCollector resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() );
|
||||
archiveDescriptor.visitArchive(
|
||||
new AbstractScannerImpl.ArchiveContextImpl(
|
||||
new PersistenceUnitDescriptorAdapter(),
|
||||
true,
|
||||
resultCollector
|
||||
)
|
||||
);
|
||||
|
||||
validateResults( resultCollector, org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class, Version.class );
|
||||
ScanResult result = standardScan( defaultPar.toURL() );
|
||||
validateResults( result, org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class, Version.class );
|
||||
}
|
||||
|
||||
private void validateResults(AbstractScannerImpl.ResultCollector resultCollector, Class... expectedClasses) throws IOException {
|
||||
assertEquals( 3, resultCollector.getClassDescriptorSet().size() );
|
||||
private void validateResults(ScanResult scanResult, Class... expectedClasses) throws IOException {
|
||||
assertEquals( 3, scanResult.getLocatedClasses().size() );
|
||||
for ( Class expectedClass : expectedClasses ) {
|
||||
assertTrue(
|
||||
resultCollector.getClassDescriptorSet().contains(
|
||||
scanResult.getLocatedClasses().contains(
|
||||
new ClassDescriptorImpl( expectedClass.getName(), null )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
assertEquals( 2, resultCollector.getMappingFileSet().size() );
|
||||
for ( MappingFileDescriptor mappingFileDescriptor : resultCollector.getMappingFileSet() ) {
|
||||
assertEquals( 2, scanResult.getLocatedMappingFiles().size() );
|
||||
for ( MappingFileDescriptor mappingFileDescriptor : scanResult.getLocatedMappingFiles() ) {
|
||||
assertNotNull( mappingFileDescriptor.getStreamAccess() );
|
||||
final InputStream stream = mappingFileDescriptor.getStreamAccess().accessInputStream();
|
||||
assertNotNull( stream );
|
||||
@ -147,39 +169,54 @@ public void testNestedJarProtocol() throws Exception {
|
||||
addPackageToClasspath( nestedEar );
|
||||
|
||||
String jarFileName = nestedEar.toURL().toExternalForm() + "!/defaultpar.par";
|
||||
URL rootUrl = new URL( jarFileName );
|
||||
|
||||
JarProtocolArchiveDescriptor archiveDescriptor = new JarProtocolArchiveDescriptor(
|
||||
StandardArchiveDescriptorFactory.INSTANCE,
|
||||
new URL( jarFileName ),
|
||||
rootUrl,
|
||||
""
|
||||
);
|
||||
AbstractScannerImpl.ResultCollector resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() );
|
||||
|
||||
ScanEnvironment environment = new ScanEnvironmentImpl( rootUrl );
|
||||
ScanResultCollector collector = new ScanResultCollector( environment, new StandardScanOptions() );
|
||||
|
||||
archiveDescriptor.visitArchive(
|
||||
new AbstractScannerImpl.ArchiveContextImpl(
|
||||
new PersistenceUnitDescriptorAdapter(),
|
||||
new ArchiveContextImpl(
|
||||
environment,
|
||||
true,
|
||||
resultCollector
|
||||
new ResultCoordinator( collector )
|
||||
)
|
||||
);
|
||||
|
||||
validateResults( resultCollector, org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class, Version.class );
|
||||
validateResults(
|
||||
collector.toScanResult(),
|
||||
org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class,
|
||||
Version.class
|
||||
);
|
||||
|
||||
jarFileName = nestedEarDir.toURL().toExternalForm() + "!/defaultpar.par";
|
||||
rootUrl = new URL( jarFileName );
|
||||
archiveDescriptor = new JarProtocolArchiveDescriptor(
|
||||
StandardArchiveDescriptorFactory.INSTANCE,
|
||||
new URL( jarFileName ),
|
||||
rootUrl,
|
||||
""
|
||||
);
|
||||
resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() );
|
||||
|
||||
environment = new ScanEnvironmentImpl( rootUrl );
|
||||
collector = new ScanResultCollector( environment, new StandardScanOptions() );
|
||||
|
||||
archiveDescriptor.visitArchive(
|
||||
new AbstractScannerImpl.ArchiveContextImpl(
|
||||
new PersistenceUnitDescriptorAdapter(),
|
||||
new ArchiveContextImpl(
|
||||
environment,
|
||||
true,
|
||||
resultCollector
|
||||
new ResultCoordinator( collector )
|
||||
)
|
||||
);
|
||||
|
||||
validateResults( resultCollector, org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class, Version.class );
|
||||
validateResults(
|
||||
collector.toScanResult(),
|
||||
org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class,
|
||||
Version.class
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -188,23 +225,27 @@ public void testJarProtocol() throws Exception {
|
||||
addPackageToClasspath( war );
|
||||
|
||||
String jarFileName = war.toURL().toExternalForm() + "!/WEB-INF/classes";
|
||||
URL rootUrl = new URL( jarFileName );
|
||||
|
||||
JarProtocolArchiveDescriptor archiveDescriptor = new JarProtocolArchiveDescriptor(
|
||||
StandardArchiveDescriptorFactory.INSTANCE,
|
||||
new URL( jarFileName ),
|
||||
rootUrl,
|
||||
""
|
||||
);
|
||||
|
||||
AbstractScannerImpl.ResultCollector resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() );
|
||||
final ScanEnvironment environment = new ScanEnvironmentImpl( rootUrl );
|
||||
final ScanResultCollector collector = new ScanResultCollector( environment, new StandardScanOptions() );
|
||||
|
||||
archiveDescriptor.visitArchive(
|
||||
new AbstractScannerImpl.ArchiveContextImpl(
|
||||
new PersistenceUnitDescriptorAdapter(),
|
||||
new ArchiveContextImpl(
|
||||
environment,
|
||||
true,
|
||||
resultCollector
|
||||
new ResultCoordinator( collector )
|
||||
)
|
||||
);
|
||||
|
||||
validateResults(
|
||||
resultCollector,
|
||||
collector.toScanResult(),
|
||||
org.hibernate.jpa.test.pack.war.ApplicationServer.class,
|
||||
org.hibernate.jpa.test.pack.war.Version.class
|
||||
);
|
||||
@ -215,21 +256,12 @@ public void testZippedJar() throws Exception {
|
||||
File defaultPar = buildDefaultPar();
|
||||
addPackageToClasspath( defaultPar );
|
||||
|
||||
JarFileBasedArchiveDescriptor archiveDescriptor = new JarFileBasedArchiveDescriptor(
|
||||
StandardArchiveDescriptorFactory.INSTANCE,
|
||||
defaultPar.toURL(),
|
||||
""
|
||||
ScanResult result = standardScan( defaultPar.toURL() );
|
||||
validateResults(
|
||||
result,
|
||||
org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class,
|
||||
Version.class
|
||||
);
|
||||
AbstractScannerImpl.ResultCollector resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() );
|
||||
archiveDescriptor.visitArchive(
|
||||
new AbstractScannerImpl.ArchiveContextImpl(
|
||||
new PersistenceUnitDescriptorAdapter(),
|
||||
true,
|
||||
resultCollector
|
||||
)
|
||||
);
|
||||
|
||||
validateResults( resultCollector, org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class, Version.class );
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -243,31 +275,18 @@ public void testExplodedJar() throws Exception {
|
||||
dirPath = dirPath.substring( 0, dirPath.length() - 1 );
|
||||
}
|
||||
|
||||
ExplodedArchiveDescriptor archiveDescriptor = new ExplodedArchiveDescriptor(
|
||||
StandardArchiveDescriptorFactory.INSTANCE,
|
||||
ArchiveHelper.getURLFromPath( dirPath ),
|
||||
""
|
||||
);
|
||||
AbstractScannerImpl.ResultCollector resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() );
|
||||
archiveDescriptor.visitArchive(
|
||||
new AbstractScannerImpl.ArchiveContextImpl(
|
||||
new PersistenceUnitDescriptorAdapter(),
|
||||
true,
|
||||
resultCollector
|
||||
)
|
||||
);
|
||||
|
||||
assertEquals( 1, resultCollector.getClassDescriptorSet().size() );
|
||||
assertEquals( 1, resultCollector.getPackageDescriptorSet().size() );
|
||||
assertEquals( 1, resultCollector.getMappingFileSet().size() );
|
||||
ScanResult result = standardScan( ArchiveHelper.getURLFromPath( dirPath ) );
|
||||
assertEquals( 1, result.getLocatedClasses().size() );
|
||||
assertEquals( 1, result.getLocatedPackages().size() );
|
||||
assertEquals( 1, result.getLocatedMappingFiles().size() );
|
||||
|
||||
assertTrue(
|
||||
resultCollector.getClassDescriptorSet().contains(
|
||||
result.getLocatedClasses().contains(
|
||||
new ClassDescriptorImpl( Carpet.class.getName(), null )
|
||||
)
|
||||
);
|
||||
|
||||
for ( MappingFileDescriptor mappingFileDescriptor : resultCollector.getMappingFileSet() ) {
|
||||
for ( MappingFileDescriptor mappingFileDescriptor : result.getLocatedMappingFiles() ) {
|
||||
assertNotNull( mappingFileDescriptor.getStreamAccess() );
|
||||
final InputStream stream = mappingFileDescriptor.getStreamAccess().accessInputStream();
|
||||
assertNotNull( stream );
|
||||
|
@ -45,6 +45,7 @@
|
||||
import org.hibernate.jpa.test.Distributor;
|
||||
import org.hibernate.jpa.test.Item;
|
||||
import org.hibernate.jpa.test.Kitten;
|
||||
import org.hibernate.jpa.test.LastUpdateListener;
|
||||
import org.hibernate.jpa.test.pack.cfgxmlpar.Morito;
|
||||
import org.hibernate.jpa.test.pack.defaultpar.ApplicationServer;
|
||||
import org.hibernate.jpa.test.pack.defaultpar.IncrementListener;
|
||||
@ -289,7 +290,11 @@ protected File buildCfgXmlPar() {
|
||||
JavaArchive archive = ShrinkWrap.create( JavaArchive.class,fileName );
|
||||
archive.addClasses(
|
||||
Morito.class,
|
||||
Item.class
|
||||
Item.class,
|
||||
Distributor.class,
|
||||
Cat.class,
|
||||
Kitten.class,
|
||||
LastUpdateListener.class
|
||||
);
|
||||
|
||||
ArchivePath path = ArchivePaths.create( "META-INF/persistence.xml" );
|
||||
|
@ -31,13 +31,15 @@
|
||||
|
||||
import org.hibernate.jpa.AvailableSettings;
|
||||
import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
import org.hibernate.jpa.boot.scan.internal.StandardJpaScanEnvironmentImpl;
|
||||
import org.hibernate.jpa.boot.scan.internal.StandardScanOptions;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanEnvironment;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanOptions;
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
import org.hibernate.jpa.boot.scan.internal.StandardScanner;
|
||||
import org.hibernate.jpa.boot.spi.ClassDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.MappingFileDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.NamedInputStream;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanOptions;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanResult;
|
||||
import org.hibernate.jpa.boot.scan.spi.Scanner;
|
||||
import org.hibernate.jpa.test.pack.defaultpar.ApplicationServer;
|
||||
@ -61,9 +63,10 @@ public void testNativeScanner() throws Exception {
|
||||
addPackageToClasspath( defaultPar );
|
||||
|
||||
PersistenceUnitDescriptor descriptor = new ParsedPersistenceXmlDescriptor( defaultPar.toURL() );
|
||||
ScanEnvironment env = new StandardJpaScanEnvironmentImpl( descriptor );
|
||||
ScanOptions options = new StandardScanOptions( "hbm,class", descriptor.isExcludeUnlistedClasses() );
|
||||
Scanner scanner = new StandardScanner();
|
||||
ScanResult scanResult = scanner.scan( descriptor, options );
|
||||
ScanResult scanResult = scanner.scan( env, options );
|
||||
|
||||
assertEquals( 3, scanResult.getLocatedClasses().size() );
|
||||
assertClassesContained( scanResult, ApplicationServer.class );
|
||||
|
Loading…
x
Reference in New Issue
Block a user