HHH-9488 - Move scanning from HEM to core

This commit is contained in:
Steve Ebersole 2014-11-07 15:36:44 -06:00
parent d9fc06b7db
commit c7f58ab57e
59 changed files with 1485 additions and 957 deletions

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.archive.internal; package org.hibernate.boot.archive.internal;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -31,7 +31,7 @@ import java.net.URL;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.hibernate.jpa.boot.archive.spi.ArchiveException; import org.hibernate.boot.archive.spi.ArchiveException;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;

View File

@ -21,13 +21,12 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.internal; package org.hibernate.boot.archive.internal;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.InputStream; import java.io.InputStream;
import org.hibernate.jpa.boot.spi.InputStreamAccess; import org.hibernate.boot.archive.spi.InputStreamAccess;
import org.hibernate.jpa.boot.spi.NamedInputStream;
/** /**
* An InputStreamAccess implementation based on a byte array * An InputStreamAccess implementation based on a byte array
@ -52,9 +51,4 @@ public class ByteArrayInputStreamAccess implements InputStreamAccess {
public InputStream accessInputStream() { public InputStream accessInputStream() {
return new ByteArrayInputStream( bytes ); return new ByteArrayInputStream( bytes );
} }
@Override
public NamedInputStream asNamedInputStream() {
return new NamedInputStream( getStreamName(), accessInputStream() );
}
} }

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.archive.internal; package org.hibernate.boot.archive.internal;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -31,16 +31,14 @@ import java.util.Enumeration;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import org.hibernate.jpa.boot.archive.spi.AbstractArchiveDescriptor; import org.hibernate.boot.archive.spi.AbstractArchiveDescriptor;
import org.hibernate.jpa.boot.archive.spi.ArchiveContext; import org.hibernate.boot.archive.spi.ArchiveContext;
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory; import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory;
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry; import org.hibernate.boot.archive.spi.ArchiveEntry;
import org.hibernate.jpa.boot.archive.spi.ArchiveException; import org.hibernate.boot.archive.spi.ArchiveException;
import org.hibernate.jpa.boot.internal.FileInputStreamAccess; import org.hibernate.boot.archive.spi.InputStreamAccess;
import org.hibernate.jpa.boot.spi.InputStreamAccess;
import org.hibernate.jpa.internal.EntityManagerMessageLogger;
import org.jboss.logging.Logger; import static org.hibernate.internal.log.UrlMessageBundle.URL_LOGGER;
/** /**
* Descriptor for exploded (directory) archives * Descriptor for exploded (directory) archives
@ -48,11 +46,6 @@ import org.jboss.logging.Logger;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class ExplodedArchiveDescriptor extends AbstractArchiveDescriptor { public class ExplodedArchiveDescriptor extends AbstractArchiveDescriptor {
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(
EntityManagerMessageLogger.class,
ExplodedArchiveDescriptor.class.getName()
);
/** /**
* Constructs an ExplodedArchiveDescriptor * Constructs an ExplodedArchiveDescriptor
* *
@ -96,16 +89,16 @@ public class ExplodedArchiveDescriptor extends AbstractArchiveDescriptor {
} }
} }
catch (URISyntaxException e) { catch (URISyntaxException e) {
LOG.malformedUrl( getArchiveUrl(), e ); URL_LOGGER.logMalformedUrl( getArchiveUrl(), e );
return null; return null;
} }
if ( !archiveUrlDirectory.exists() ) { if ( !archiveUrlDirectory.exists() ) {
LOG.explodedJarDoesNotExist( getArchiveUrl() ); URL_LOGGER.logFileDoesNotExist( getArchiveUrl() );
return null; return null;
} }
if ( !archiveUrlDirectory.isDirectory() ) { if ( !archiveUrlDirectory.isDirectory() ) {
LOG.explodedJarNotDirectory( getArchiveUrl() ); URL_LOGGER.logFileIsNotDirectory( getArchiveUrl() );
return null; return null;
} }

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.internal; package org.hibernate.boot.archive.internal;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.File; import java.io.File;
@ -30,9 +30,8 @@ import java.io.FileNotFoundException;
import java.io.InputStream; import java.io.InputStream;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.jpa.boot.archive.spi.ArchiveException; import org.hibernate.boot.archive.spi.ArchiveException;
import org.hibernate.jpa.boot.spi.InputStreamAccess; import org.hibernate.boot.archive.spi.InputStreamAccess;
import org.hibernate.jpa.boot.spi.NamedInputStream;
/** /**
* An InputStreamAccess implementation based on a File reference * An InputStreamAccess implementation based on a File reference
@ -69,9 +68,4 @@ public class FileInputStreamAccess implements InputStreamAccess {
); );
} }
} }
@Override
public NamedInputStream asNamedInputStream() {
return new NamedInputStream( getStreamName(), accessInputStream() );
}
} }

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.archive.internal; package org.hibernate.boot.archive.internal;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.IOException; import java.io.IOException;
@ -33,28 +33,22 @@ import java.util.jar.JarFile;
import java.util.jar.JarInputStream; import java.util.jar.JarInputStream;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import org.hibernate.jpa.boot.archive.spi.AbstractArchiveDescriptor; import org.hibernate.boot.archive.spi.AbstractArchiveDescriptor;
import org.hibernate.jpa.boot.archive.spi.ArchiveContext; import org.hibernate.boot.archive.spi.ArchiveContext;
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory; import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory;
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry; import org.hibernate.boot.archive.spi.ArchiveEntry;
import org.hibernate.jpa.boot.archive.spi.ArchiveEntryHandler; import org.hibernate.boot.archive.spi.ArchiveEntryHandler;
import org.hibernate.jpa.boot.archive.spi.ArchiveException; import org.hibernate.boot.archive.spi.ArchiveException;
import org.hibernate.jpa.boot.spi.InputStreamAccess; import org.hibernate.boot.archive.spi.InputStreamAccess;
import org.hibernate.jpa.internal.EntityManagerMessageLogger;
import org.jboss.logging.Logger; import static org.hibernate.internal.log.UrlMessageBundle.URL_LOGGER;
/** /**
* An ArchiveDescriptor implementation leveraging the {@link JarFile} API for processing. * An ArchiveDescriptor implementation leveraging the {@link java.util.jar.JarFile} API for processing.
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class JarFileBasedArchiveDescriptor extends AbstractArchiveDescriptor { public class JarFileBasedArchiveDescriptor extends AbstractArchiveDescriptor {
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(
EntityManagerMessageLogger.class,
JarFileBasedArchiveDescriptor.class.getName()
);
/** /**
* Constructs a JarFileBasedArchiveDescriptor * Constructs a JarFileBasedArchiveDescriptor
* *
@ -103,8 +97,7 @@ public class JarFileBasedArchiveDescriptor extends AbstractArchiveDescriptor {
final String name = extractName( subZipEntry ); final String name = extractName( subZipEntry );
final String relativeName = extractRelativeName( subZipEntry ); final String relativeName = extractRelativeName( subZipEntry );
final InputStreamAccess inputStreamAccess final InputStreamAccess inputStreamAccess = buildByteBasedInputStreamAccess( name, jarInputStream );
= buildByteBasedInputStreamAccess( name, jarInputStream );
final ArchiveEntry entry = new ArchiveEntry() { final ArchiveEntry entry = new ArchiveEntry() {
@Override @Override
@ -190,10 +183,10 @@ public class JarFileBasedArchiveDescriptor extends AbstractArchiveDescriptor {
} }
} }
catch (IOException e) { catch (IOException e) {
LOG.unableToFindFile( getArchiveUrl(), e ); URL_LOGGER.logUnableToFindFileByUrl( getArchiveUrl(), e );
} }
catch (URISyntaxException e) { catch (URISyntaxException e) {
LOG.malformedUrlWarning( getArchiveUrl(), e ); URL_LOGGER.logMalformedUrl( getArchiveUrl(), e );
} }
return null; return null;
} }

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.archive.internal; package org.hibernate.boot.archive.internal;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
@ -29,15 +29,14 @@ import java.util.jar.JarEntry;
import java.util.jar.JarInputStream; import java.util.jar.JarInputStream;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import org.hibernate.jpa.boot.archive.spi.AbstractArchiveDescriptor; import org.hibernate.boot.archive.spi.AbstractArchiveDescriptor;
import org.hibernate.jpa.boot.archive.spi.ArchiveContext; import org.hibernate.boot.archive.spi.ArchiveContext;
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory; import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory;
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry; import org.hibernate.boot.archive.spi.ArchiveEntry;
import org.hibernate.jpa.boot.archive.spi.ArchiveException; import org.hibernate.boot.archive.spi.ArchiveException;
import org.hibernate.jpa.boot.spi.InputStreamAccess; import org.hibernate.boot.archive.spi.InputStreamAccess;
import org.hibernate.jpa.internal.EntityManagerMessageLogger;
import org.jboss.logging.Logger; import static org.hibernate.internal.log.UrlMessageBundle.URL_LOGGER;
/** /**
* An ArchiveDescriptor implementation that works on archives accessible through a {@link java.util.jar.JarInputStream}. * An ArchiveDescriptor implementation that works on archives accessible through a {@link java.util.jar.JarInputStream}.
@ -47,10 +46,6 @@ import org.jboss.logging.Logger;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class JarInputStreamBasedArchiveDescriptor extends AbstractArchiveDescriptor { public class JarInputStreamBasedArchiveDescriptor extends AbstractArchiveDescriptor {
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(
EntityManagerMessageLogger.class,
JarInputStreamBasedArchiveDescriptor.class.getName()
);
/** /**
* Constructs a JarInputStreamBasedArchiveDescriptor * Constructs a JarInputStreamBasedArchiveDescriptor
@ -74,7 +69,7 @@ public class JarInputStreamBasedArchiveDescriptor extends AbstractArchiveDescrip
} }
catch (Exception e) { catch (Exception e) {
//really should catch IOException but Eclipse is buggy and raise NPE... //really should catch IOException but Eclipse is buggy and raise NPE...
LOG.unableToFindFile( getArchiveUrl(), e ); URL_LOGGER.logUnableToFindFileByUrl( getArchiveUrl(), e );
return; return;
} }
@ -102,8 +97,7 @@ public class JarInputStreamBasedArchiveDescriptor extends AbstractArchiveDescrip
while (subZipEntry != null) { while (subZipEntry != null) {
if ( ! subZipEntry.isDirectory() ) { if ( ! subZipEntry.isDirectory() ) {
final String subName = extractName( subZipEntry ); final String subName = extractName( subZipEntry );
final InputStreamAccess inputStreamAccess final InputStreamAccess inputStreamAccess = buildByteBasedInputStreamAccess( subName, subJarInputStream );
= buildByteBasedInputStreamAccess( subName, subJarInputStream );
final ArchiveEntry entry = new ArchiveEntry() { final ArchiveEntry entry = new ArchiveEntry() {
@Override @Override

View File

@ -21,14 +21,14 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.archive.internal; package org.hibernate.boot.archive.internal;
import java.net.URL; import java.net.URL;
import org.hibernate.annotations.common.AssertionFailure; import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.jpa.boot.archive.spi.ArchiveContext; import org.hibernate.boot.archive.spi.ArchiveContext;
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptor; import org.hibernate.boot.archive.spi.ArchiveDescriptor;
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory; import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory;
/** /**
* An ArchiveDescriptor implementation for handling archives whose url reported a JAR protocol (i.e., jar://). * An ArchiveDescriptor implementation for handling archives whose url reported a JAR protocol (i.e., jar://).

View File

@ -21,15 +21,15 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.archive.internal; package org.hibernate.boot.archive.internal;
import java.io.File; import java.io.File;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptor; import org.hibernate.boot.archive.spi.ArchiveDescriptor;
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory; import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory;
/** /**
* Standard implementation of ArchiveDescriptorFactory * Standard implementation of ArchiveDescriptorFactory

View File

@ -21,14 +21,13 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.internal; package org.hibernate.boot.archive.internal;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.jpa.boot.spi.InputStreamAccess; import org.hibernate.boot.archive.spi.InputStreamAccess;
import org.hibernate.jpa.boot.spi.NamedInputStream;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
@ -54,9 +53,4 @@ public class UrlInputStreamAccess implements InputStreamAccess {
throw new HibernateException( "Could not open url stream : " + url.toExternalForm() ); throw new HibernateException( "Could not open url stream : " + url.toExternalForm() );
} }
} }
@Override
public NamedInputStream asNamedInputStream() {
return new NamedInputStream( getStreamName(), accessInputStream() );
}
} }

View File

@ -1,4 +1,4 @@
/** /**
* The internals of archive scanning support * The internals of archive scanning support
*/ */
package org.hibernate.jpa.boot.archive.internal; package org.hibernate.boot.archive.internal;

View File

@ -21,10 +21,10 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.internal; package org.hibernate.boot.archive.scan.internal;
import org.hibernate.jpa.boot.spi.ClassDescriptor; import org.hibernate.boot.archive.scan.spi.ClassDescriptor;
import org.hibernate.jpa.boot.spi.InputStreamAccess; import org.hibernate.boot.archive.spi.InputStreamAccess;
/** /**
* @author Steve Ebersole * @author Steve Ebersole

View File

@ -21,10 +21,10 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.internal; package org.hibernate.boot.archive.scan.internal;
import org.hibernate.jpa.boot.spi.InputStreamAccess; import org.hibernate.boot.archive.spi.InputStreamAccess;
import org.hibernate.jpa.boot.spi.MappingFileDescriptor; import org.hibernate.boot.archive.scan.spi.MappingFileDescriptor;
/** /**
* @author Steve Ebersole * @author Steve Ebersole

View File

@ -21,10 +21,10 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.internal; package org.hibernate.boot.archive.scan.internal;
import org.hibernate.jpa.boot.spi.InputStreamAccess; import org.hibernate.boot.archive.spi.InputStreamAccess;
import org.hibernate.jpa.boot.spi.PackageDescriptor; import org.hibernate.boot.archive.scan.spi.PackageDescriptor;
/** /**
* @author Steve Ebersole * @author Steve Ebersole

View File

@ -0,0 +1,171 @@
/*
* 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.boot.archive.scan.internal;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.boot.archive.scan.spi.ClassDescriptor;
import org.hibernate.boot.archive.scan.spi.MappingFileDescriptor;
import org.hibernate.boot.archive.scan.spi.PackageDescriptor;
import org.hibernate.boot.archive.scan.spi.ScanEnvironment;
import org.hibernate.boot.archive.scan.spi.ScanOptions;
import org.hibernate.boot.archive.scan.spi.ScanParameters;
import org.hibernate.boot.archive.scan.spi.ScanResult;
import org.jboss.jandex.ClassInfo;
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 ScanParameters scanParameters;
private final Set<ClassDescriptor> discoveredClasses;
private final Set<PackageDescriptor> discoveredPackages;
private final Set<MappingFileDescriptor> discoveredMappingFiles;
public ScanResultCollector(ScanEnvironment environment, ScanOptions options, ScanParameters parameters) {
this.environment = environment;
this.options = options;
this.scanParameters = parameters;
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) {
// see if "discovery" of this entry is allowed
// final ClassInfo classInfo = scanParameters.getJandexInitializer().handle( classDescriptor );
//
// if ( !isListedOrDetectable( classInfo.name().toString(), rootUrl ) ) {
// return;
// }
//
// if ( !containsClassAnnotationsOfInterest( classInfo ) ) {
// // not strictly needed, but helps cut down on the size of discoveredClasses
// return;
// }
if ( !isListedOrDetectable( classDescriptor.getName(), rootUrl ) ) {
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 );
}
}
// @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) {
// final ClassInfo classInfo = scanParameters.getJandexInitializer().handle( packageDescriptor );
if ( !isListedOrDetectable( packageDescriptor.getName(), rootUrl ) ) {
// not strictly needed, but helps cut down on the size of discoveredPackages
return;
}
discoveredPackages.add( packageDescriptor );
}
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 )
);
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.boot.archive.scan.internal;
import java.util.Set;
import org.hibernate.boot.archive.scan.spi.ClassDescriptor;
import org.hibernate.boot.archive.scan.spi.MappingFileDescriptor;
import org.hibernate.boot.archive.scan.spi.PackageDescriptor;
import org.hibernate.boot.archive.scan.spi.ScanResult;
/**
* @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;
}
}

View File

@ -21,9 +21,9 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.scan.internal; package org.hibernate.boot.archive.scan.internal;
import org.hibernate.jpa.boot.scan.spi.ScanOptions; import org.hibernate.boot.archive.scan.spi.ScanOptions;
/** /**
* @author Steve Ebersole * @author Steve Ebersole

View File

@ -21,10 +21,11 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.scan.internal; package org.hibernate.boot.archive.scan.internal;
import org.hibernate.jpa.boot.archive.internal.StandardArchiveDescriptorFactory; import org.hibernate.boot.archive.internal.StandardArchiveDescriptorFactory;
import org.hibernate.jpa.boot.scan.spi.AbstractScannerImpl; import org.hibernate.boot.archive.scan.spi.AbstractScannerImpl;
import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory;
/** /**
* Standard implementation of the Scanner contract, supporting typical archive walking support where * Standard implementation of the Scanner contract, supporting typical archive walking support where
@ -35,6 +36,10 @@ import org.hibernate.jpa.boot.scan.spi.AbstractScannerImpl;
*/ */
public class StandardScanner extends AbstractScannerImpl { public class StandardScanner extends AbstractScannerImpl {
public StandardScanner() { public StandardScanner() {
super( StandardArchiveDescriptorFactory.INSTANCE ); this( StandardArchiveDescriptorFactory.INSTANCE );
}
public StandardScanner(ArchiveDescriptorFactory value) {
super( value );
} }
} }

View File

@ -0,0 +1,142 @@
/*
* 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.boot.archive.scan.spi;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.boot.archive.scan.internal.ScanResultCollector;
import org.hibernate.boot.archive.spi.ArchiveContext;
import org.hibernate.boot.archive.spi.ArchiveDescriptor;
import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory;
import org.hibernate.boot.archive.spi.ArchiveEntry;
import org.hibernate.boot.archive.spi.ArchiveEntryHandler;
/**
* @author Steve Ebersole
*/
public abstract class AbstractScannerImpl implements Scanner {
private final ArchiveDescriptorFactory archiveDescriptorFactory;
private final Map<URL, ArchiveDescriptorInfo> archiveDescriptorCache = new HashMap<URL, ArchiveDescriptorInfo>();
protected AbstractScannerImpl(ArchiveDescriptorFactory archiveDescriptorFactory) {
this.archiveDescriptorFactory = archiveDescriptorFactory;
}
@Override
public ScanResult scan(ScanEnvironment environment, ScanOptions options, ScanParameters parameters) {
final ScanResultCollector collector = new ScanResultCollector( environment, options, parameters );
if ( environment.getNonRootUrls() != null ) {
final ArchiveContext context = new ArchiveContextImpl( false, collector );
for ( URL url : environment.getNonRootUrls() ) {
final ArchiveDescriptor descriptor = buildArchiveDescriptor( url, false );
descriptor.visitArchive( context );
}
}
if ( environment.getRootUrl() != null ) {
final ArchiveContext context = new ArchiveContextImpl( true, collector );
final ArchiveDescriptor descriptor = buildArchiveDescriptor( environment.getRootUrl(), true );
descriptor.visitArchive( context );
}
return collector.toScanResult();
}
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 )
);
}
else {
validateReuse( descriptorInfo, isRootUrl );
descriptor = descriptorInfo.archiveDescriptor;
}
return descriptor;
}
// 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 ArchiveDescriptorInfo(ArchiveDescriptor archiveDescriptor, boolean isRoot) {
this.archiveDescriptor = archiveDescriptor;
this.isRoot = isRoot;
}
}
@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 boolean isRootUrl;
private final ClassFileArchiveEntryHandler classEntryHandler;
private final PackageInfoArchiveEntryHandler packageEntryHandler;
private final ArchiveEntryHandler fileEntryHandler;
public ArchiveContextImpl(boolean isRootUrl, ScanResultCollector scanResultCollector) {
this.isRootUrl = isRootUrl;
this.classEntryHandler = new ClassFileArchiveEntryHandler( scanResultCollector );
this.packageEntryHandler = new PackageInfoArchiveEntryHandler( scanResultCollector );
this.fileEntryHandler = new NonClassFileArchiveEntryHandler( scanResultCollector );
}
@Override
public boolean isRootUrl() {
return isRootUrl;
}
@Override
public ArchiveEntryHandler obtainArchiveEntryHandler(ArchiveEntry entry) {
final String nameWithinArchive = entry.getNameWithinArchive();
if ( nameWithinArchive.endsWith( "package-info.class" ) ) {
return packageEntryHandler;
}
else if ( nameWithinArchive.endsWith( ".class" ) ) {
return classEntryHandler;
}
else {
return fileEntryHandler;
}
}
}
}

View File

@ -21,14 +21,27 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.spi; package org.hibernate.boot.archive.scan.spi;
import org.hibernate.boot.archive.spi.InputStreamAccess;
/** /**
* Defines the result of scanning a persistence unit for classes. * Descriptor for a class file.
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface ClassDescriptor { public interface ClassDescriptor {
/**
* Retrieves the class name, not the file name.
*
* @return The name (FQN) of the class
*/
public String getName(); public String getName();
/**
* Retrieves access to the InputStream for the class file.
*
* @return Access to the InputStream for the class file.
*/
public InputStreamAccess getStreamAccess(); public InputStreamAccess getStreamAccess();
} }

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.scan.spi; package org.hibernate.boot.archive.scan.spi;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
@ -34,30 +34,23 @@ import javax.persistence.MappedSuperclass;
import javassist.bytecode.AnnotationsAttribute; import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ClassFile; import javassist.bytecode.ClassFile;
import org.hibernate.jpa.boot.archive.spi.ArchiveContext; import org.hibernate.boot.archive.scan.internal.ClassDescriptorImpl;
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry; import org.hibernate.boot.archive.scan.internal.ScanResultCollector;
import org.hibernate.jpa.boot.archive.spi.ArchiveException; import org.hibernate.boot.archive.spi.ArchiveContext;
import org.hibernate.jpa.boot.internal.ClassDescriptorImpl; import org.hibernate.boot.archive.spi.ArchiveEntry;
import org.hibernate.jpa.boot.spi.ClassDescriptor; import org.hibernate.boot.archive.spi.ArchiveEntryHandler;
import org.hibernate.boot.archive.spi.ArchiveException;
/** /**
* Defines handling and filtering for class file entries within an archive * Defines handling and filtering for class file entries within an archive
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class ClassFileArchiveEntryHandler extends AbstractJavaArtifactArchiveEntryHandler { public class ClassFileArchiveEntryHandler implements ArchiveEntryHandler {
private final Callback callback; private final ScanResultCollector resultCollector;
/** public ClassFileArchiveEntryHandler(ScanResultCollector resultCollector) {
* Contract for the thing interested in being notified about accepted class descriptors. this.resultCollector = resultCollector;
*/
public static interface Callback {
public void locatedClass(ClassDescriptor classDescriptor);
}
public ClassFileArchiveEntryHandler(ScanOptions scanOptions, Callback callback) {
super( scanOptions );
this.callback = callback;
} }
@Override @Override
@ -65,17 +58,14 @@ public class ClassFileArchiveEntryHandler extends AbstractJavaArtifactArchiveEnt
final ClassFile classFile = toClassFile( entry ); final ClassFile classFile = toClassFile( entry );
final ClassDescriptor classDescriptor = toClassDescriptor( classFile, entry ); final ClassDescriptor classDescriptor = toClassDescriptor( classFile, entry );
if ( ! isListedOrDetectable( context, classDescriptor.getName() ) ) { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return; // temporary until HHH-9489 is addressed
}
// we are only interested in classes with certain annotations, so see if the ClassDescriptor
// represents a class which contains any of those annotations
if ( ! containsClassAnnotationsOfInterest( classFile ) ) { if ( ! containsClassAnnotationsOfInterest( classFile ) ) {
return; return;
} }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
notifyMatchedClass( classDescriptor ); resultCollector.handleClass( toClassDescriptor( toClassFile( entry ), entry ), context.isRootUrl() );
} }
private ClassFile toClassFile(ArchiveEntry entry) { private ClassFile toClassFile(ArchiveEntry entry) {
@ -102,6 +92,7 @@ public class ClassFileArchiveEntryHandler extends AbstractJavaArtifactArchiveEnt
} }
} }
@SuppressWarnings("SimplifiableIfStatement") @SuppressWarnings("SimplifiableIfStatement")
private boolean containsClassAnnotationsOfInterest(ClassFile cf) { private boolean containsClassAnnotationsOfInterest(ClassFile cf) {
final AnnotationsAttribute visibleAnnotations = (AnnotationsAttribute) cf.getAttribute( AnnotationsAttribute.visibleTag ); final AnnotationsAttribute visibleAnnotations = (AnnotationsAttribute) cf.getAttribute( AnnotationsAttribute.visibleTag );
@ -115,11 +106,7 @@ public class ClassFileArchiveEntryHandler extends AbstractJavaArtifactArchiveEnt
|| visibleAnnotations.getAnnotation( Converter.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() ); return new ClassDescriptorImpl( classFile.getName(), entry.getStreamAccess() );
} }
protected final void notifyMatchedClass(ClassDescriptor classDescriptor) {
callback.locatedClass( classDescriptor );
}
} }

View File

@ -1,7 +1,7 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as * Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution * indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are * statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc. * distributed under license by Red Hat Inc.
@ -21,14 +21,19 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.scan.spi; package org.hibernate.boot.archive.scan.spi;
import org.jboss.jandex.ClassInfo;
/** /**
* Helper for preparing Jandex for later use..
*
* Not currently used. See https://hibernate.atlassian.net/browse/HHH-9489
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface ScanOptions { public interface JandexInitializer {
public boolean canDetectUnlistedClassesInRoot(); ClassInfo handle(PackageDescriptor packageDescriptor);
public boolean canDetectUnlistedClassesInNonRoot();
public boolean canDetectHibernateMappingFiles(); ClassInfo handle(ClassDescriptor classDescriptor);
} }

View File

@ -0,0 +1,49 @@
/*
* 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.boot.archive.scan.spi;
import org.hibernate.boot.archive.spi.InputStreamAccess;
/**
* Descriptor for a mapping (XML) file.
*
* @author Steve Ebersole
*/
public interface MappingFileDescriptor {
/**
* The mapping file name. This is its name within the archive, the
* expectation being that most times this will equate to a "classpath
* lookup resource name".
*
* @return The mapping file resource name.
*/
public String getName();
/**
* Retrieves access to the InputStream for the mapping file.
*
* @return Access to the InputStream for the mapping file.
*/
public InputStreamAccess getStreamAccess();
}

View File

@ -0,0 +1,51 @@
/*
* 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.boot.archive.scan.spi;
import org.hibernate.boot.archive.scan.internal.MappingFileDescriptorImpl;
import org.hibernate.boot.archive.scan.internal.ScanResultCollector;
import org.hibernate.boot.archive.spi.ArchiveContext;
import org.hibernate.boot.archive.spi.ArchiveEntry;
import org.hibernate.boot.archive.spi.ArchiveEntryHandler;
/**
* Defines handling and filtering for all non-class file (package-info is also a class file...) entries within an archive
*
* @author Steve Ebersole
*/
public class NonClassFileArchiveEntryHandler implements ArchiveEntryHandler {
private final ScanResultCollector resultCollector;
public NonClassFileArchiveEntryHandler(ScanResultCollector resultCollector) {
this.resultCollector = resultCollector;
}
@Override
public void handleEntry(ArchiveEntry entry, ArchiveContext context) {
resultCollector.handleMappingFile(
new MappingFileDescriptorImpl( entry.getNameWithinArchive(), entry.getStreamAccess() ),
context.isRootUrl()
);
}
}

View File

@ -21,12 +21,27 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.spi; package org.hibernate.boot.archive.scan.spi;
import org.hibernate.boot.archive.spi.InputStreamAccess;
/** /**
* Descriptor for a package (as indicated by a package-info.class file).
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface MappingFileDescriptor { public interface PackageDescriptor {
/**
* Retrieves the package name.
*
* @return The package name
*/
public String getName(); public String getName();
/**
* Retrieves access to the InputStream for the {@code package-info.class} file.
*
* @return Access to the InputStream for the {@code package-info.class} file.
*/
public InputStreamAccess getStreamAccess(); public InputStreamAccess getStreamAccess();
} }

View File

@ -21,31 +21,24 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.scan.spi; package org.hibernate.boot.archive.scan.spi;
import org.hibernate.jpa.boot.archive.spi.ArchiveContext; import org.hibernate.boot.archive.scan.internal.PackageDescriptorImpl;
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry; import org.hibernate.boot.archive.scan.internal.ScanResultCollector;
import org.hibernate.jpa.boot.internal.PackageDescriptorImpl; import org.hibernate.boot.archive.spi.ArchiveContext;
import org.hibernate.jpa.boot.spi.PackageDescriptor; import org.hibernate.boot.archive.spi.ArchiveEntry;
import org.hibernate.boot.archive.spi.ArchiveEntryHandler;
/** /**
* Defines handling and filtering for package-info file entries within an archive * Defines handling and filtering for package-info file entries within an archive
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class PackageInfoArchiveEntryHandler extends AbstractJavaArtifactArchiveEntryHandler { public class PackageInfoArchiveEntryHandler implements ArchiveEntryHandler {
private final Callback callback; private final ScanResultCollector resultCollector;
/** public PackageInfoArchiveEntryHandler(ScanResultCollector resultCollector) {
* Contract for the thing interested in being notified about accepted package-info descriptors. this.resultCollector = resultCollector;
*/
public static interface Callback {
public void locatedPackage(PackageDescriptor packageDescriptor);
}
public PackageInfoArchiveEntryHandler(ScanOptions scanOptions, Callback callback) {
super( scanOptions );
this.callback = callback;
} }
@Override @Override
@ -55,12 +48,7 @@ public class PackageInfoArchiveEntryHandler extends AbstractJavaArtifactArchiveE
return; return;
} }
if ( ! isListedOrDetectable( context, entry.getName() ) ) { resultCollector.handlePackage( toPackageDescriptor( entry ), context.isRootUrl() );
// the package is not explicitly listed, and we are not allowed to detect it.
return;
}
notifyMatchedPackage( toPackageDescriptor( entry ) );
} }
protected PackageDescriptor toPackageDescriptor(ArchiveEntry entry) { protected PackageDescriptor toPackageDescriptor(ArchiveEntry entry) {
@ -70,8 +58,4 @@ public class PackageInfoArchiveEntryHandler extends AbstractJavaArtifactArchiveE
return new PackageDescriptorImpl( packageName, entry.getStreamAccess() ); return new PackageDescriptorImpl( packageName, entry.getStreamAccess() );
} }
protected final void notifyMatchedPackage(PackageDescriptor packageDescriptor) {
callback.locatedPackage( packageDescriptor );
}
} }

View File

@ -0,0 +1,81 @@
/*
* 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.boot.archive.scan.spi;
import java.net.URL;
import java.util.List;
/**
* Describes the environment in which the scan will occur.
* <p/>
* Note that much of this comes from the PU in JPA sense. This is
* intended as an abstraction over the PU in JPA cases, as well as a
* delegate allowing usage in non-JPA cases. With the planned move
* to unify the cfg.xml and persistence.xml schemas (like we are doing
* with hbm.xml and orm.xml) this becomes less needed (at least parts
* of it).
* <p/>
* After unification, I think the biggest difference is that we will
* not need to pass ScanEnvironment into the MetadataSources/MetadataBuilder
* while for the time being we will need to.
*
* @author Steve Ebersole
*/
public interface ScanEnvironment {
/**
* Returns the root URL for scanning. Can be {@code null}, indicating that
* no root URL scanning should be done (aka, if maybe a root URL is not known).
*
* @return The root URL
*
* @see ScanOptions#canDetectUnlistedClassesInRoot()
*/
public URL getRootUrl();
/**
* Returns any non-root URLs for scanning. Can be null/empty to indicate
* that no non-root URL scanning should be done.
*
* @return The non-root URLs
*
* @see ScanOptions#canDetectUnlistedClassesInNonRoot()
*/
public List<URL> getNonRootUrls();
/**
* Returns any classes which are explicitly listed as part of the
* "persistence unit".
*
* @return The explicitly listed classes
*/
public List<String> getExplicitlyListedClassNames();
/**
* Returns the mapping files which are explicitly listed as part of the
* "persistence unit".
*
* @return The explicitly listed mapping files.
*/
public List<String> getExplicitlyListedMappingFiles();
}

View File

@ -0,0 +1,59 @@
/*
* 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.boot.archive.scan.spi;
/**
* Options for performing scanning
*
* @author Steve Ebersole
*/
public interface ScanOptions {
/**
* 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();
}

View File

@ -1,7 +1,7 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as * Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution * indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are * statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc. * distributed under license by Red Hat Inc.
@ -21,14 +21,14 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.spi; package org.hibernate.boot.archive.scan.spi;
/** /**
* Defines the result of scanning a persistence unit for packages. * A "parameter object" passed to {@link Scanner#scan} to help support future
* changes in terms of needing to pass additional stuff to scanning.
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface PackageDescriptor { public interface ScanParameters {
public String getName(); public JandexInitializer getJandexInitializer();
public InputStreamAccess getStreamAccess();
} }

View File

@ -21,21 +21,34 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.scan.spi; package org.hibernate.boot.archive.scan.spi;
import java.util.Set; import java.util.Set;
import org.hibernate.jpa.boot.spi.ClassDescriptor;
import org.hibernate.jpa.boot.spi.MappingFileDescriptor;
import org.hibernate.jpa.boot.spi.PackageDescriptor;
/** /**
* Defines the result of scanning * Defines the result of scanning
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface ScanResult { public interface ScanResult {
/**
* Returns descriptors for all packages discovered as part of the scan
*
* @return Descriptors for discovered packages
*/
public Set<PackageDescriptor> getLocatedPackages(); public Set<PackageDescriptor> getLocatedPackages();
/**
* Returns descriptors for all classes discovered as part of the scan
*
* @return Descriptors for discovered classes
*/
public Set<ClassDescriptor> getLocatedClasses(); public Set<ClassDescriptor> getLocatedClasses();
/**
* Returns descriptors for all mapping files discovered as part of the scan
*
* @return Descriptors for discovered mapping files
*/
public Set<MappingFileDescriptor> getLocatedMappingFiles(); public Set<MappingFileDescriptor> getLocatedMappingFiles();
} }

View File

@ -21,26 +21,31 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.scan.spi; package org.hibernate.boot.archive.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 * Defines the contract for Hibernate to be able to scan for classes, packages and resources inside a
* persistence unit. * persistence unit.
* <p/>
* Constructors are expected in one of 2 forms:<ul>
* <li>no-arg</li>
* <li>single arg, of type {@link org.hibernate.boot.archive.spi.ArchiveDescriptorFactory}</li>
* </ul>
* <p/>
* If a ArchiveDescriptorFactory is specified in the configuration, but the Scanner
* to be used does not accept a ArchiveDescriptorFactory an exception will be thrown.
* *
* @author Emmanuel Bernard * @author Emmanuel Bernard
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface Scanner { public interface Scanner {
/** /**
* Perform the scanning against the described persistence unit using the defined options, and return the scan * Perform the scanning against the described environment using the
* results. * defined options, and return the scan results.
* *
* @param persistenceUnit THe description of the persistence unit. * @param environment The scan environment.
* @param options The scan options * @param options The options to control the scanning.
* * @param params The parameters for scanning
* @return The scan results.
*/ */
public ScanResult scan(PersistenceUnitDescriptor persistenceUnit, ScanOptions options); public ScanResult scan(ScanEnvironment environment, ScanOptions options, ScanParameters params);
} }

View File

@ -21,16 +21,15 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.archive.spi; package org.hibernate.boot.archive.spi;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import org.hibernate.boot.archive.internal.ByteArrayInputStreamAccess;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.jpa.boot.archive.internal.ArchiveHelper; import org.hibernate.boot.archive.internal.ArchiveHelper;
import org.hibernate.jpa.boot.internal.ByteArrayInputStreamAccess;
import org.hibernate.jpa.boot.spi.InputStreamAccess;
/** /**
* Base support for ArchiveDescriptor implementors. * Base support for ArchiveDescriptor implementors.
@ -74,7 +73,9 @@ public abstract class AbstractArchiveDescriptor implements ArchiveDescriptor {
protected String extractRelativeName(ZipEntry zipEntry) { protected String extractRelativeName(ZipEntry zipEntry) {
final String entryName = extractName( zipEntry ); final String entryName = extractName( zipEntry );
return entryBasePrefix != null && entryName.contains( entryBasePrefix ) ? entryName.substring( entryBasePrefix.length() ) : entryName; return entryBasePrefix != null && entryName.contains( entryBasePrefix )
? entryName.substring( entryBasePrefix.length() )
: entryName;
} }
protected String extractName(ZipEntry zipEntry) { protected String extractName(ZipEntry zipEntry) {

View File

@ -1,7 +1,7 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as * Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution * indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are * statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc. * distributed under license by Red Hat Inc.
@ -21,33 +21,28 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.spi; package org.hibernate.boot.archive.spi;
import java.io.InputStream; import java.net.URL;
import org.hibernate.boot.archive.internal.ArchiveHelper;
/** /**
* Bundles together a stream and the name that was used to locate it. The name is often useful for logging.
*
* @deprecated Use {@link org.hibernate.jpa.boot.spi.InputStreamAccess} instead.
*
* @author Emmanuel Bernard
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@Deprecated public abstract class AbstractArchiveDescriptorFactory implements ArchiveDescriptorFactory {
public class NamedInputStream { @Override
private final String name; public ArchiveDescriptor buildArchiveDescriptor(URL url) {
private final InputStream stream; return buildArchiveDescriptor( url, "" );
public NamedInputStream(String name, InputStream stream) {
this.name = name;
this.stream = stream;
} }
public InputStream getStream() { @Override
return stream; public URL getJarURLFromURLEntry(URL url, String entry) throws IllegalArgumentException {
return ArchiveHelper.getJarURLFromURLEntry( url, entry );
} }
public String getName() { @Override
return name; public URL getURLFromPath(String jarPath) {
return ArchiveHelper.getURLFromPath( jarPath );
} }
} }

View File

@ -21,23 +21,14 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.archive.spi; package org.hibernate.boot.archive.spi;
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
/** /**
* Describes the context for visiting the entries within an archive * Describes the context for visiting the entries within an archive
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface ArchiveContext { public interface ArchiveContext {
/**
* The persistence-unit descriptor which led to this archive being scanned.
*
* @return The persistence-unit descriptor
*/
public PersistenceUnitDescriptor getPersistenceUnitDescriptor();
/** /**
* Is the archive described (and being visited) the root url for the persistence-unit? * Is the archive described (and being visited) the root url for the persistence-unit?
* *

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.archive.spi; package org.hibernate.boot.archive.spi;
/** /**
* Contract for visiting an archive, which might be a jar, a zip, an exploded directory, etc. * Contract for visiting an archive, which might be a jar, a zip, an exploded directory, etc.

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.archive.spi; package org.hibernate.boot.archive.spi;
import java.net.URL; import java.net.URL;

View File

@ -21,9 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.archive.spi; package org.hibernate.boot.archive.spi;
import org.hibernate.jpa.boot.spi.InputStreamAccess;
/** /**
* Represent an entry in the archive. * Represent an entry in the archive.

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.archive.spi; package org.hibernate.boot.archive.spi;
/** /**
* Handler for archive entries, based on the classified type of the entry * Handler for archive entries, based on the classified type of the entry

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.archive.spi; package org.hibernate.boot.archive.spi;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.jpa.boot.spi; package org.hibernate.boot.archive.spi;
import java.io.InputStream; import java.io.InputStream;
@ -44,9 +44,4 @@ public interface InputStreamAccess {
* @return The stream * @return The stream
*/ */
public InputStream accessInputStream(); public InputStream accessInputStream();
/**
* @deprecated Needed until we can remove NamedInputStream
*/
public NamedInputStream asNamedInputStream();
} }

View File

@ -12,4 +12,4 @@
* <li>etc</li> * <li>etc</li>
* </ul> * </ul>
*/ */
package org.hibernate.jpa.boot.archive.spi; package org.hibernate.boot.archive.spi;

View File

@ -724,4 +724,46 @@ public interface AvailableSettings {
String AUTO_SESSION_EVENTS_LISTENER = "hibernate.session.events.auto"; String AUTO_SESSION_EVENTS_LISTENER = "hibernate.session.events.auto";
/**
* The deprecated name. Use {@link #SCANNER} or {@link #SCANNER_ARCHIVE_INTERPRETER} instead.
*/
String SCANNER_DEPRECATED = "hibernate.ejb.resource_scanner";
/**
* Pass an implementation of {@link org.hibernate.boot.archive.scan.spi.Scanner}.
* Accepts either:<ul>
* <li>an actual instance</li>
* <li>a reference to a Class that implements Scanner</li>
* <li>a fully qualified name (String) of a Class that implements Scanner</li>
* </ul>
*/
String SCANNER = "hibernate.archive.scanner";
/**
* Pass {@link org.hibernate.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 (String) of a Class that implements ArchiveDescriptorFactory</li>
* </ul>
* <p/>
* See information on {@link org.hibernate.boot.archive.scan.spi.Scanner}
* about expected constructor forms.
*
* @see #SCANNER
* @see org.hibernate.boot.archive.scan.spi.Scanner
* @see org.hibernate.boot.archive.scan.spi.AbstractScannerImpl
*/
String SCANNER_ARCHIVE_INTERPRETER = "hibernate.archive.interpreter";
/**
* Identifies a comma-separate list of values indicating the types of
* things we should auto-detect during scanning. Allowable values include:<ul>
* <li>"class" - discover classes - .class files are discovered as managed classes</li>
* <li>"hbm" - discover hbm mapping files - hbm.xml files are discovered as mapping files</li>
* </ul>
*/
String SCANNER_DISCOVERY = "hibernate.archive.autodetection";
} }

View File

@ -0,0 +1,57 @@
/*
* 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.internal.log;
import org.jboss.logging.Logger;
import org.jboss.logging.annotations.LogMessage;
import org.jboss.logging.annotations.Message;
import org.jboss.logging.annotations.MessageLogger;
import org.jboss.logging.annotations.ValidIdRange;
import static org.jboss.logging.Logger.Level.INFO;
/**
* Class to consolidate logging about usage of deprecated features.
*
* @author Steve Ebersole
*/
@MessageLogger( projectCode = "HHH" )
@ValidIdRange( min = 90000001, max = 90001000 )
public interface DeprecationLogger {
public static final DeprecationLogger DEPRECATION_LOGGER = Logger.getMessageLogger(
DeprecationLogger.class,
"org.hibernate.orm.deprecation"
);
/**
* Log about usage of deprecated Scanner setting
*/
@LogMessage( level = INFO )
@Message(
value = "Found usage of deprecated setting for specifying Scanner [hibernate.ejb.resource_scanner]; " +
"use [hibernate.archive.scanner] instead",
id = 90000001
)
public void logDeprecatedScannerSetting();
}

View File

@ -0,0 +1,110 @@
/*
* 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.internal.log;
import java.net.URISyntaxException;
import java.net.URL;
import org.jboss.logging.Logger;
import org.jboss.logging.annotations.Cause;
import org.jboss.logging.annotations.LogMessage;
import org.jboss.logging.annotations.Message;
import org.jboss.logging.annotations.MessageLogger;
import org.jboss.logging.annotations.ValidIdRange;
import static org.jboss.logging.Logger.Level.WARN;
/**
* Acts as the {@link org.jboss.logging.annotations.MessageLogger} and
* {@link org.jboss.logging.annotations.MessageBundle} for messages related to
* processing URLs.
*
* @author Steve Ebersole
*/
@MessageLogger( projectCode = "HHH" )
@ValidIdRange( min = 10000001, max = 10001000 )
public interface UrlMessageBundle {
public static final UrlMessageBundle URL_LOGGER = Logger.getMessageLogger(
UrlMessageBundle.class,
"org.hibernate.orm.url"
);
/**
* Logs a warning about a malformed URL, caused by a {@link java.net.URISyntaxException}
*
* @param jarUrl The URL that lead to the {@link java.net.URISyntaxException}
* @param e The underlying URISyntaxException
*/
@LogMessage( level = WARN )
@Message( value = "Malformed URL: %s", id = 10000001 )
void logMalformedUrl(URL jarUrl, @Cause URISyntaxException e);
/**
* Logs a warning about not being able to find a file by a specified URL. This is different
* from {@link #logFileDoesNotExist}.
*
* @param url The URL is supposed to identify the file which we cannot locate
* @param e The underlying URISyntaxException
*/
@LogMessage( level = WARN )
@Message( value = "File or directory named by URL [%s] could not be found. URL will be ignored", id = 10000002 )
void logUnableToFindFileByUrl(URL url, @Cause Exception e);
/**
* Logs a warning that the File (file/directory) to which the URL resolved
* reported that it did not exist.
*
* @param url The URL that named the file/directory
*
* @see java.io.File#exists()
*/
@LogMessage( level = WARN )
@Message( value = "File or directory named by URL [%s] did not exist. URL will be ignored", id = 10000003 )
void logFileDoesNotExist(URL url);
/**
* Logs a warning indicating that the URL resolved to a File that we were expecting
* to be a directory, but {@link java.io.File#isDirectory()} reported it was not.
*
* @param url The URL that named the file/directory
*
* @see java.io.File#isDirectory()
*/
@LogMessage( level = WARN )
@Message( value = "Expecting resource named by URL [%s] to be a directory, but it was not. URL will be ignored", id = 10000004 )
void logFileIsNotDirectory(URL url);
/**
* Access to the exception message used when a URL references names a file that does not exist.
* <p/>
* TODO : detail when this is a warning {@link #logFileDoesNotExist} versus an exception...
*
* @param filePart The "file part" that we gleaned from the URL
* @param url The given URL
*
* @return The message
*/
@Message( value = "File [%s] referenced by given URL [%s] does not exist", id = 10000005 )
String fileDoesNotExist(String filePart, URL url);
}

View File

@ -1,38 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, 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.packaging;
import java.io.InputStream;
/**
* @deprecated Doubly deprecated actually :) Moved to {@link org.hibernate.jpa.boot.spi.NamedInputStream}
* due to package renaming (org.hibernate.ejb -> org.hibernate.jpa). But also, the role fulfilled by this class
* was moved to the new {@link org.hibernate.jpa.boot.spi.InputStreamAccess} contract.
*/
@Deprecated
public class NamedInputStream extends org.hibernate.jpa.boot.spi.NamedInputStream {
public NamedInputStream(String name, InputStream stream) {
super( name, stream );
}
}

View File

@ -24,8 +24,8 @@
package org.hibernate.ejb.packaging; package org.hibernate.ejb.packaging;
/** /**
* @deprecated Use {@link org.hibernate.jpa.boot.scan.spi.Scanner} instead * @deprecated Use {@link org.hibernate.boot.archive.scan.spi.Scanner} instead
*/ */
@Deprecated @Deprecated
public interface Scanner extends org.hibernate.jpa.boot.scan.spi.Scanner { public interface Scanner extends org.hibernate.boot.archive.scan.spi.Scanner {
} }

View File

@ -371,8 +371,11 @@ public interface AvailableSettings {
/** /**
* JAR autodetection artifacts class, hbm * JAR autodetection artifacts class, hbm
*
* @deprecated Use {@link org.hibernate.cfg.AvailableSettings#SCANNER_DISCOVERY} instead
*/ */
String AUTODETECTION = "hibernate.archive.autodetection"; @Deprecated
String AUTODETECTION = org.hibernate.cfg.AvailableSettings.SCANNER_DISCOVERY;
/** /**
* cfg.xml configuration file used * cfg.xml configuration file used
@ -459,11 +462,11 @@ public interface AvailableSettings {
String FLUSH_MODE = "org.hibernate.flushMode"; String FLUSH_MODE = "org.hibernate.flushMode";
/** /**
* Pass an implementation of {@link org.hibernate.ejb.packaging.Scanner}: * @deprecated Prefer {@link org.hibernate.cfg.AvailableSettings#SCANNER} instead
* - preferably an actual instance
* - or a class name with a no-arg constructor
*/ */
String SCANNER = "hibernate.ejb.resource_scanner"; @Deprecated
@SuppressWarnings("UnusedDeclaration")
String SCANNER = org.hibernate.cfg.AvailableSettings.SCANNER_DEPRECATED;
/** /**
* List of classes names * List of classes names

View File

@ -28,6 +28,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -55,6 +56,14 @@ import org.hibernate.MappingException;
import org.hibernate.MappingNotFoundException; import org.hibernate.MappingNotFoundException;
import org.hibernate.SessionFactory; import org.hibernate.SessionFactory;
import org.hibernate.SessionFactoryObserver; import org.hibernate.SessionFactoryObserver;
import org.hibernate.boot.archive.internal.StandardArchiveDescriptorFactory;
import org.hibernate.boot.archive.internal.UrlInputStreamAccess;
import org.hibernate.boot.archive.scan.internal.ClassDescriptorImpl;
import org.hibernate.boot.archive.scan.internal.MappingFileDescriptorImpl;
import org.hibernate.boot.archive.scan.internal.PackageDescriptorImpl;
import org.hibernate.boot.archive.scan.spi.JandexInitializer;
import org.hibernate.boot.archive.scan.spi.ScanParameters;
import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory;
import org.hibernate.boot.registry.BootstrapServiceRegistry; import org.hibernate.boot.registry.BootstrapServiceRegistry;
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
@ -76,18 +85,17 @@ import org.hibernate.internal.jaxb.cfg.JaxbHibernateConfiguration;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.ValueHolder; import org.hibernate.internal.util.ValueHolder;
import org.hibernate.jpa.AvailableSettings; import org.hibernate.jpa.AvailableSettings;
import org.hibernate.jpa.boot.scan.internal.StandardScanOptions; import org.hibernate.boot.archive.scan.internal.StandardScanOptions;
import org.hibernate.jpa.boot.scan.internal.StandardScanner; import org.hibernate.boot.archive.scan.internal.StandardScanner;
import org.hibernate.jpa.boot.scan.spi.ScanOptions; import org.hibernate.boot.archive.scan.spi.ScanOptions;
import org.hibernate.jpa.boot.scan.spi.ScanResult; import org.hibernate.boot.archive.scan.spi.ScanResult;
import org.hibernate.jpa.boot.scan.spi.Scanner; import org.hibernate.boot.archive.scan.spi.Scanner;
import org.hibernate.jpa.boot.spi.ClassDescriptor; import org.hibernate.boot.archive.scan.spi.ClassDescriptor;
import org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder; import org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder;
import org.hibernate.jpa.boot.spi.InputStreamAccess; import org.hibernate.boot.archive.spi.InputStreamAccess;
import org.hibernate.jpa.boot.spi.IntegratorProvider; import org.hibernate.jpa.boot.spi.IntegratorProvider;
import org.hibernate.jpa.boot.spi.MappingFileDescriptor; import org.hibernate.boot.archive.scan.spi.MappingFileDescriptor;
import org.hibernate.jpa.boot.spi.NamedInputStream; import org.hibernate.boot.archive.scan.spi.PackageDescriptor;
import org.hibernate.jpa.boot.spi.PackageDescriptor;
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor; import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
import org.hibernate.jpa.boot.spi.StrategyRegistrationProviderList; import org.hibernate.jpa.boot.spi.StrategyRegistrationProviderList;
import org.hibernate.jpa.boot.spi.TypeContributorList; import org.hibernate.jpa.boot.spi.TypeContributorList;
@ -115,6 +123,8 @@ import org.jboss.jandex.IndexView;
import org.jboss.jandex.Indexer; import org.jboss.jandex.Indexer;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@ -410,7 +420,7 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
} }
for ( MappingFileDescriptor mappingFileDescriptor : deploymentResources.getMappingFileDescriptors() ) { for ( MappingFileDescriptor mappingFileDescriptor : deploymentResources.getMappingFileDescriptors() ) {
metadataSources.namedMappingFileInputStreams.add( mappingFileDescriptor.getStreamAccess().asNamedInputStream() ); metadataSources.mappingFileInputStreamAccessList.add( mappingFileDescriptor.getStreamAccess() );
} }
final String explicitHbmXmls = (String) configurationValues.remove( AvailableSettings.HBXML_FILES ); final String explicitHbmXmls = (String) configurationValues.remove( AvailableSettings.HBXML_FILES );
@ -749,51 +759,137 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
final Scanner scanner = locateOrBuildScanner( bootstrapServiceRegistry ); final Scanner scanner = locateOrBuildScanner( bootstrapServiceRegistry );
final ScanOptions scanOptions = determineScanOptions(); final ScanOptions scanOptions = determineScanOptions();
return scanner.scan( persistenceUnit, scanOptions ); return scanner.scan(
new StandardJpaScanEnvironmentImpl( persistenceUnit ),
scanOptions,
new ScanParameters() {
@Override
public JandexInitializer getJandexInitializer() {
return null;
}
}
);
} }
private ScanOptions determineScanOptions() { private ScanOptions determineScanOptions() {
return new StandardScanOptions( return new StandardScanOptions(
(String) configurationValues.get( AvailableSettings.AUTODETECTION ), (String) configurationValues.get( org.hibernate.cfg.AvailableSettings.SCANNER_DISCOVERY ),
persistenceUnit.isExcludeUnlistedClasses() persistenceUnit.isExcludeUnlistedClasses()
); );
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Scanner locateOrBuildScanner(BootstrapServiceRegistry bootstrapServiceRegistry) { private Scanner locateOrBuildScanner(BootstrapServiceRegistry bootstrapServiceRegistry) {
final Object value = configurationValues.remove( AvailableSettings.SCANNER ); Object scannerSetting = configurationValues.remove( org.hibernate.cfg.AvailableSettings.SCANNER );
if ( value == null ) { if ( scannerSetting == null ) {
return new StandardScanner(); scannerSetting = configurationValues.remove( org.hibernate.cfg.AvailableSettings.SCANNER_DEPRECATED );
} if ( scannerSetting != null ) {
DEPRECATION_LOGGER.logDeprecatedScannerSetting();
if ( Scanner.class.isInstance( value ) ) {
return (Scanner) value;
}
Class<? extends Scanner> scannerClass;
if ( Class.class.isInstance( value ) ) {
try {
scannerClass = (Class<? extends Scanner>) value;
} }
catch ( ClassCastException e ) { }
throw persistenceException( "Expecting Scanner implementation, but found " + ((Class) value).getName() );
final StrategySelector strategySelector = bootstrapServiceRegistry.getService( StrategySelector.class );
ArchiveDescriptorFactory archiveDescriptorFactory = strategySelector.resolveStrategy(
ArchiveDescriptorFactory.class,
configurationValues.remove( org.hibernate.cfg.AvailableSettings.SCANNER_ARCHIVE_INTERPRETER )
);
if ( scannerSetting == null ) {
// No custom Scanner specified, use the StandardScanner
if ( archiveDescriptorFactory == null ) {
return new StandardScanner();
}
else {
return new StandardScanner( archiveDescriptorFactory );
} }
} }
else { else {
final String scannerClassName = value.toString(); if ( Scanner.class.isInstance( scannerSetting ) ) {
try { if ( archiveDescriptorFactory != null ) {
scannerClass = bootstrapServiceRegistry.getService( ClassLoaderService.class ).classForName( scannerClassName ); throw new IllegalStateException(
"A Scanner instance and an ArchiveDescriptorFactory were both specified; please " +
"specify one or the other, or if you need to supply both, name a Scanner class " +
"to use (assuming it has a constructor accepting a ArchiveDescriptorFactory). " +
"Alternatively, just pass the ArchiveDescriptorFactory during your own " +
"Scanner constructor assuming it is statically known."
);
}
return (Scanner) scannerSetting;
} }
catch ( ClassCastException e ) {
throw persistenceException( "Expecting Scanner implementation, but found " + scannerClassName );
}
}
try { final Class<? extends Scanner> scannerImplClass;
return scannerClass.newInstance(); if ( Class.class.isInstance( scannerSetting ) ) {
} scannerImplClass = (Class<? extends Scanner>) scannerSetting;
catch ( Exception e ) { }
throw persistenceException( "Unable to instantiate Scanner class: " + scannerClass, e ); else {
final String scannerClassName = scannerSetting.toString();
scannerImplClass = bootstrapServiceRegistry.getService( ClassLoaderService.class ).classForName(
scannerClassName
);
}
final Class[] SINGLE_ARG = new Class[] { ArchiveDescriptorFactory.class };
if ( archiveDescriptorFactory != null ) {
// find the single-arg constructor - its an error if none exists
try {
final Constructor<? extends Scanner> constructor = scannerImplClass.getConstructor( SINGLE_ARG );
try {
return constructor.newInstance( archiveDescriptorFactory );
}
catch (Exception e) {
throw new IllegalStateException(
"Error trying to instantiate custom specified Scanner [" +
scannerImplClass.getName() + "]",
e
);
}
}
catch (NoSuchMethodException e) {
throw new IllegalArgumentException(
"Configuration named a custom Scanner and a custom ArchiveDescriptorFactory, but " +
"Scanner impl did not define a constructor accepting ArchiveDescriptorFactory"
);
}
}
else {
// could be either ctor form...
// find the single-arg constructor - its an error if none exists
try {
final Constructor<? extends Scanner> constructor = scannerImplClass.getConstructor( SINGLE_ARG );
try {
return constructor.newInstance( StandardArchiveDescriptorFactory.INSTANCE );
}
catch (Exception e) {
throw new IllegalStateException(
"Error trying to instantiate custom specified Scanner [" +
scannerImplClass.getName() + "]",
e
);
}
}
catch (NoSuchMethodException e) {
try {
final Constructor<? extends Scanner> constructor = scannerImplClass.getConstructor();
try {
return constructor.newInstance();
}
catch (Exception e2) {
throw new IllegalStateException(
"Error trying to instantiate custom specified Scanner [" +
scannerImplClass.getName() + "]",
e2
);
}
}
catch (NoSuchMethodException ignore) {
throw new IllegalArgumentException(
"Configuration named a custom Scanner, but we were unable to locate " +
"an appropriate constructor"
);
}
}
}
} }
} }
@ -1198,16 +1294,17 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
LOG.exceptionHeaderNotFound( getExceptionHeader(), META_INF_ORM_XML ); LOG.exceptionHeaderNotFound( getExceptionHeader(), META_INF_ORM_XML );
} }
} }
for ( NamedInputStream namedInputStream : metadataSources.namedMappingFileInputStreams ) {
for ( InputStreamAccess streamAccess : metadataSources.mappingFileInputStreamAccessList ) {
try { try {
//addInputStream has the responsibility to close the stream //addInputStream has the responsibility to close the stream
cfg.addInputStream( new BufferedInputStream( namedInputStream.getStream() ) ); cfg.addInputStream( new BufferedInputStream( streamAccess.accessInputStream() ) );
} }
catch ( InvalidMappingException e ) { catch ( InvalidMappingException e ) {
// try our best to give the file name // try our best to give the file name
if ( StringHelper.isNotEmpty( namedInputStream.getName() ) ) { if ( StringHelper.isNotEmpty( streamAccess.getStreamName() ) ) {
throw new InvalidMappingException( throw new InvalidMappingException(
"Error while parsing file: " + namedInputStream.getName(), "Error while parsing file: " + streamAccess.getStreamName(),
e.getType(), e.getType(),
e.getPath(), e.getPath(),
e e
@ -1219,8 +1316,8 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
} }
catch (MappingException me) { catch (MappingException me) {
// try our best to give the file name // try our best to give the file name
if ( StringHelper.isNotEmpty( namedInputStream.getName() ) ) { if ( StringHelper.isNotEmpty( streamAccess.getStreamName() ) ) {
throw new MappingException("Error while parsing file: " + namedInputStream.getName(), me ); throw new MappingException("Error while parsing file: " + streamAccess.getStreamName(), me );
} }
else { else {
throw me; throw me;
@ -1312,7 +1409,7 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
public static class MetadataSources { public static class MetadataSources {
private final List<String> annotatedMappingClassNames = new ArrayList<String>(); private final List<String> annotatedMappingClassNames = new ArrayList<String>();
private final List<ConverterDescriptor> converterDescriptors = new ArrayList<ConverterDescriptor>(); private final List<ConverterDescriptor> converterDescriptors = new ArrayList<ConverterDescriptor>();
private final List<NamedInputStream> namedMappingFileInputStreams = new ArrayList<NamedInputStream>(); private final List<InputStreamAccess> mappingFileInputStreamAccessList = new ArrayList<InputStreamAccess>();
private final List<String> mappingFileResources = new ArrayList<String>(); private final List<String> mappingFileResources = new ArrayList<String>();
private final List<String> packageNames = new ArrayList<String>(); private final List<String> packageNames = new ArrayList<String>();
@ -1324,8 +1421,8 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
return converterDescriptors; return converterDescriptors;
} }
public List<NamedInputStream> getNamedMappingFileInputStreams() { public List<InputStreamAccess> getMappingFileInputStreamAccessList() {
return namedMappingFileInputStreams; return mappingFileInputStreamAccessList;
} }
public List<String> getPackageNames() { public List<String> getPackageNames() {

View File

@ -47,7 +47,7 @@ import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.jpa.AvailableSettings; import org.hibernate.jpa.AvailableSettings;
import org.hibernate.jpa.boot.archive.internal.ArchiveHelper; import org.hibernate.boot.archive.internal.ArchiveHelper;
import org.hibernate.jpa.internal.EntityManagerMessageLogger; import org.hibernate.jpa.internal.EntityManagerMessageLogger;
import org.hibernate.jpa.internal.util.ConfigurationHelper; import org.hibernate.jpa.internal.util.ConfigurationHelper;
import org.hibernate.internal.util.xml.XsdException; import org.hibernate.internal.util.xml.XsdException;

View File

@ -0,0 +1,75 @@
/*
* 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.internal;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
import org.hibernate.boot.archive.scan.spi.ScanEnvironment;
/**
* 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;
}
}

View File

@ -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 );
}
}

View File

@ -1,304 +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 java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
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;
/**
* @author Steve Ebersole
*/
public abstract class AbstractScannerImpl implements Scanner {
private final ArchiveDescriptorFactory archiveDescriptorFactory;
private final Map<URL, ArchiveDescriptorInfo> archiveDescriptorCache = new HashMap<URL, ArchiveDescriptorInfo>();
protected AbstractScannerImpl(ArchiveDescriptorFactory archiveDescriptorFactory) {
this.archiveDescriptorFactory = archiveDescriptorFactory;
}
@Override
public ScanResult scan(PersistenceUnitDescriptor persistenceUnit, ScanOptions scanOptions) {
final ResultCollector resultCollector = new ResultCollector( scanOptions );
if ( persistenceUnit.getJarFileUrls() != null ) {
for ( URL url : persistenceUnit.getJarFileUrls() ) {
final ArchiveDescriptor descriptor = buildArchiveDescriptor( url, false, scanOptions );
final ArchiveContext context = buildArchiveContext( persistenceUnit, false, resultCollector );
descriptor.visitArchive( context );
}
}
if ( persistenceUnit.getPersistenceUnitRootUrl() != null ) {
final ArchiveDescriptor descriptor = buildArchiveDescriptor( persistenceUnit.getPersistenceUnitRootUrl(), true, scanOptions );
final ArchiveContext context = buildArchiveContext( persistenceUnit, true, resultCollector );
descriptor.visitArchive( context );
}
return ScanResultImpl.from( resultCollector );
}
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) {
final ArchiveDescriptor descriptor;
final ArchiveDescriptorInfo descriptorInfo = archiveDescriptorCache.get( url );
if ( descriptorInfo == null ) {
descriptor = archiveDescriptorFactory.buildArchiveDescriptor( url );
archiveDescriptorCache.put(
url,
new ArchiveDescriptorInfo( descriptor, isRootUrl, scanOptions )
);
}
else {
validateReuse( descriptorInfo, isRootUrl, scanOptions );
descriptor = descriptorInfo.archiveDescriptor;
}
return descriptor;
}
public static class ResultCollector
implements ArchiveEntryHandlers,
PackageInfoArchiveEntryHandler.Callback,
ClassFileArchiveEntryHandler.Callback,
NonClassFileArchiveEntryHandler.Callback {
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.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) {
if ( PackageDescriptorImpl.class.isInstance( packageDescriptor ) ) {
packageDescriptorSet.add( packageDescriptor );
}
else {
// to make sure we have proper equals/hashcode
packageDescriptorSet.add(
new PackageDescriptorImpl(
packageDescriptor.getName(),
packageDescriptor.getStreamAccess()
)
);
}
}
@Override
public void locatedClass(ClassDescriptor classDescriptor) {
if ( ClassDescriptorImpl.class.isInstance( classDescriptor ) ) {
classDescriptorSet.add( classDescriptor );
}
else {
// to make sure we have proper equals/hashcode
classDescriptorSet.add(
new ClassDescriptorImpl(
classDescriptor.getName(),
classDescriptor.getStreamAccess()
)
);
}
}
@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) {
this.archiveDescriptor = archiveDescriptor;
this.isRoot = isRoot;
this.scanOptions = scanOptions;
}
}
protected void validateReuse(ArchiveDescriptorInfo descriptor, boolean root, ScanOptions options) {
// 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;
}
}
}

View File

@ -1,88 +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.ArchiveEntry;
import org.hibernate.jpa.boot.archive.spi.ArchiveEntryHandler;
import org.hibernate.jpa.boot.internal.MappingFileDescriptorImpl;
import org.hibernate.jpa.boot.spi.MappingFileDescriptor;
/**
* Defines handling and filtering for all non-class file (package-info is also a class file...) entries within an archive
*
* @author Steve Ebersole
*/
public class NonClassFileArchiveEntryHandler implements ArchiveEntryHandler {
private final ScanOptions scanOptions;
private final Callback callback;
/**
* 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;
}
@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() );
}
}

View File

@ -1,10 +1,11 @@
package org.hibernate.jpa.test.packaging; package org.hibernate.jpa.test.packaging;
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor; import org.hibernate.boot.archive.scan.internal.StandardScanner;
import org.hibernate.jpa.boot.scan.internal.StandardScanner; import org.hibernate.boot.archive.scan.spi.ScanEnvironment;
import org.hibernate.jpa.boot.scan.spi.ScanOptions; import org.hibernate.boot.archive.scan.spi.ScanOptions;
import org.hibernate.jpa.boot.scan.spi.ScanResult; import org.hibernate.boot.archive.scan.spi.ScanParameters;
import org.hibernate.jpa.boot.scan.spi.Scanner; import org.hibernate.boot.archive.scan.spi.ScanResult;
import org.hibernate.boot.archive.scan.spi.Scanner;
/** /**
* @author Emmanuel Bernard * @author Emmanuel Bernard
@ -22,8 +23,12 @@ public class CustomScanner implements Scanner {
} }
@Override @Override
public ScanResult scan(PersistenceUnitDescriptor persistenceUnit, ScanOptions options) { public ScanResult scan(
ScanEnvironment environment,
ScanOptions options,
ScanParameters parameters) {
isUsed = true; isUsed = true;
return delegate.scan( persistenceUnit, options ); return delegate.scan( environment, options, parameters );
} }
} }

View File

@ -32,32 +32,36 @@ import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.net.URLStreamHandler; import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory; import java.net.URLStreamHandlerFactory;
import java.util.Collections;
import java.util.List;
import org.hibernate.boot.archive.internal.ArchiveHelper;
import org.hibernate.boot.archive.internal.ExplodedArchiveDescriptor;
import org.hibernate.boot.archive.internal.JarFileBasedArchiveDescriptor;
import org.hibernate.boot.archive.internal.JarProtocolArchiveDescriptor;
import org.hibernate.boot.archive.internal.StandardArchiveDescriptorFactory;
import org.hibernate.boot.archive.scan.internal.ClassDescriptorImpl;
import org.hibernate.boot.archive.scan.internal.ScanResultCollector;
import org.hibernate.boot.archive.scan.internal.StandardScanOptions;
import org.hibernate.boot.archive.scan.internal.StandardScanner;
import org.hibernate.boot.archive.scan.spi.AbstractScannerImpl;
import org.hibernate.boot.archive.scan.spi.JandexInitializer;
import org.hibernate.boot.archive.scan.spi.MappingFileDescriptor;
import org.hibernate.boot.archive.scan.spi.ScanEnvironment;
import org.hibernate.boot.archive.scan.spi.ScanParameters;
import org.hibernate.boot.archive.scan.spi.ScanResult;
import org.hibernate.boot.archive.spi.ArchiveDescriptor;
import org.hibernate.dialect.H2Dialect; 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.ArchiveDescriptor;
import org.hibernate.jpa.boot.internal.ClassDescriptorImpl;
import org.hibernate.jpa.boot.scan.internal.StandardScanOptions;
import org.hibernate.jpa.boot.scan.spi.AbstractScannerImpl;
import org.hibernate.jpa.boot.spi.MappingFileDescriptor;
import org.hibernate.jpa.test.PersistenceUnitDescriptorAdapter;
import org.hibernate.jpa.test.pack.defaultpar.Version; import org.hibernate.jpa.test.pack.defaultpar.Version;
import org.hibernate.jpa.test.pack.explodedpar.Carpet; import org.hibernate.jpa.test.pack.explodedpar.Carpet;
import org.junit.Test;
import org.hibernate.testing.RequiresDialect; import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/** /**
* @author Emmanuel Bernard * @author Emmanuel Bernard
@ -69,7 +73,7 @@ import static org.junit.Assert.fail;
public class JarVisitorTest extends PackagingTestCase { public class JarVisitorTest extends PackagingTestCase {
@Test @Test
public void testHttp() throws Exception { public void testHttp() throws Exception {
URL url = ArchiveHelper.getJarURLFromURLEntry( final URL url = ArchiveHelper.getJarURLFromURLEntry(
new URL( new URL(
"jar:http://www.ibiblio.org/maven/hibernate/jars/hibernate-annotations-3.0beta1.jar!/META-INF/persistence.xml" "jar:http://www.ibiblio.org/maven/hibernate/jars/hibernate-annotations-3.0beta1.jar!/META-INF/persistence.xml"
), ),
@ -83,18 +87,55 @@ public class JarVisitorTest extends PackagingTestCase {
//fail silently //fail silently
return; return;
} }
ArchiveDescriptor archiveDescriptor = StandardArchiveDescriptorFactory.INSTANCE.buildArchiveDescriptor( url );
AbstractScannerImpl.ResultCollector resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() ); ScanResult result = standardScan( url );
archiveDescriptor.visitArchive( assertEquals( 0, result.getLocatedClasses().size() );
new AbstractScannerImpl.ArchiveContextImpl( assertEquals( 0, result.getLocatedPackages().size() );
new PersistenceUnitDescriptorAdapter(), assertEquals( 0, result.getLocatedMappingFiles().size() );
true, }
resultCollector
) private ScanResult standardScan(URL url) {
ScanEnvironment env = new ScanEnvironmentImpl( url );
return new StandardScanner().scan(
env,
new StandardScanOptions(),
new ScanParameters() {
// private final JandexInitManager jandexInitManager = new JandexInitManager();
@Override
public JandexInitializer getJandexInitializer() {
// return jandexInitManager;
return null;
}
}
); );
assertEquals( 0, resultCollector.getClassDescriptorSet().size() ); }
assertEquals( 0, resultCollector.getPackageDescriptorSet().size() );
assertEquals( 0, resultCollector.getMappingFileSet().size() ); 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();
}
} }
@Test @Test
@ -102,36 +143,22 @@ public class JarVisitorTest extends PackagingTestCase {
File defaultPar = buildDefaultPar(); File defaultPar = buildDefaultPar();
addPackageToClasspath( defaultPar ); addPackageToClasspath( defaultPar );
ArchiveDescriptor archiveDescriptor = new JarInputStreamBasedArchiveDescriptor( ScanResult result = standardScan( defaultPar.toURL() );
StandardArchiveDescriptorFactory.INSTANCE, validateResults( result, org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class, Version.class );
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 );
} }
private void validateResults(AbstractScannerImpl.ResultCollector resultCollector, Class... expectedClasses) throws IOException { private void validateResults(ScanResult scanResult, Class... expectedClasses) throws IOException {
assertEquals( 3, resultCollector.getClassDescriptorSet().size() ); assertEquals( 3, scanResult.getLocatedClasses().size() );
for ( Class expectedClass : expectedClasses ) { for ( Class expectedClass : expectedClasses ) {
assertTrue( assertTrue(
resultCollector.getClassDescriptorSet().contains( scanResult.getLocatedClasses().contains(
new ClassDescriptorImpl( expectedClass.getName(), null ) new ClassDescriptorImpl( expectedClass.getName(), null )
) )
); );
} }
assertEquals( 2, resultCollector.getMappingFileSet().size() ); assertEquals( 2, scanResult.getLocatedMappingFiles().size() );
for ( MappingFileDescriptor mappingFileDescriptor : resultCollector.getMappingFileSet() ) { for ( MappingFileDescriptor mappingFileDescriptor : scanResult.getLocatedMappingFiles() ) {
assertNotNull( mappingFileDescriptor.getStreamAccess() ); assertNotNull( mappingFileDescriptor.getStreamAccess() );
final InputStream stream = mappingFileDescriptor.getStreamAccess().accessInputStream(); final InputStream stream = mappingFileDescriptor.getStreamAccess().accessInputStream();
assertNotNull( stream ); assertNotNull( stream );
@ -147,39 +174,68 @@ public class JarVisitorTest extends PackagingTestCase {
addPackageToClasspath( nestedEar ); addPackageToClasspath( nestedEar );
String jarFileName = nestedEar.toURL().toExternalForm() + "!/defaultpar.par"; String jarFileName = nestedEar.toURL().toExternalForm() + "!/defaultpar.par";
URL rootUrl = new URL( jarFileName );
JarProtocolArchiveDescriptor archiveDescriptor = new JarProtocolArchiveDescriptor( JarProtocolArchiveDescriptor archiveDescriptor = new JarProtocolArchiveDescriptor(
StandardArchiveDescriptorFactory.INSTANCE, StandardArchiveDescriptorFactory.INSTANCE,
new URL( jarFileName ), rootUrl,
"" ""
); );
AbstractScannerImpl.ResultCollector resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() );
archiveDescriptor.visitArchive( ScanEnvironment environment = new ScanEnvironmentImpl( rootUrl );
new AbstractScannerImpl.ArchiveContextImpl( ScanResultCollector collector = new ScanResultCollector(
new PersistenceUnitDescriptorAdapter(), environment,
true, new StandardScanOptions(),
resultCollector new ScanParameters() {
) // private final JandexInitManager jandexInitManager = new JandexInitManager();
@Override
public JandexInitializer getJandexInitializer() {
// return jandexInitManager;
return null;
}
}
); );
validateResults( resultCollector, org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class, Version.class ); archiveDescriptor.visitArchive(
new AbstractScannerImpl.ArchiveContextImpl( true, collector )
);
validateResults(
collector.toScanResult(),
org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class,
Version.class
);
jarFileName = nestedEarDir.toURL().toExternalForm() + "!/defaultpar.par"; jarFileName = nestedEarDir.toURL().toExternalForm() + "!/defaultpar.par";
rootUrl = new URL( jarFileName );
archiveDescriptor = new JarProtocolArchiveDescriptor( archiveDescriptor = new JarProtocolArchiveDescriptor(
StandardArchiveDescriptorFactory.INSTANCE, StandardArchiveDescriptorFactory.INSTANCE,
new URL( jarFileName ), rootUrl,
"" ""
); );
resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() );
archiveDescriptor.visitArchive( environment = new ScanEnvironmentImpl( rootUrl );
new AbstractScannerImpl.ArchiveContextImpl( collector = new ScanResultCollector(
new PersistenceUnitDescriptorAdapter(), environment,
true, new StandardScanOptions(),
resultCollector new ScanParameters() {
) // private final JandexInitManager jandexInitManager = new JandexInitManager();
@Override
public JandexInitializer getJandexInitializer() {
// return jandexInitManager;
return null;
}
}
); );
validateResults( resultCollector, org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class, Version.class ); archiveDescriptor.visitArchive(
new AbstractScannerImpl.ArchiveContextImpl( true, collector )
);
validateResults(
collector.toScanResult(),
org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class,
Version.class
);
} }
@Test @Test
@ -188,23 +244,34 @@ public class JarVisitorTest extends PackagingTestCase {
addPackageToClasspath( war ); addPackageToClasspath( war );
String jarFileName = war.toURL().toExternalForm() + "!/WEB-INF/classes"; String jarFileName = war.toURL().toExternalForm() + "!/WEB-INF/classes";
URL rootUrl = new URL( jarFileName );
JarProtocolArchiveDescriptor archiveDescriptor = new JarProtocolArchiveDescriptor( JarProtocolArchiveDescriptor archiveDescriptor = new JarProtocolArchiveDescriptor(
StandardArchiveDescriptorFactory.INSTANCE, 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(),
new ScanParameters() {
// private final JandexInitManager jandexInitManager = new JandexInitManager();
@Override
public JandexInitializer getJandexInitializer() {
// return jandexInitManager;
return null;
}
}
);
archiveDescriptor.visitArchive( archiveDescriptor.visitArchive(
new AbstractScannerImpl.ArchiveContextImpl( new AbstractScannerImpl.ArchiveContextImpl( true, collector )
new PersistenceUnitDescriptorAdapter(),
true,
resultCollector
)
); );
validateResults( validateResults(
resultCollector, collector.toScanResult(),
org.hibernate.jpa.test.pack.war.ApplicationServer.class, org.hibernate.jpa.test.pack.war.ApplicationServer.class,
org.hibernate.jpa.test.pack.war.Version.class org.hibernate.jpa.test.pack.war.Version.class
); );
@ -215,21 +282,12 @@ public class JarVisitorTest extends PackagingTestCase {
File defaultPar = buildDefaultPar(); File defaultPar = buildDefaultPar();
addPackageToClasspath( defaultPar ); addPackageToClasspath( defaultPar );
JarFileBasedArchiveDescriptor archiveDescriptor = new JarFileBasedArchiveDescriptor( ScanResult result = standardScan( defaultPar.toURL() );
StandardArchiveDescriptorFactory.INSTANCE, validateResults(
defaultPar.toURL(), 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 @Test
@ -243,59 +301,46 @@ public class JarVisitorTest extends PackagingTestCase {
dirPath = dirPath.substring( 0, dirPath.length() - 1 ); dirPath = dirPath.substring( 0, dirPath.length() - 1 );
} }
ExplodedArchiveDescriptor archiveDescriptor = new ExplodedArchiveDescriptor( ScanResult result = standardScan( ArchiveHelper.getURLFromPath( dirPath ) );
StandardArchiveDescriptorFactory.INSTANCE, assertEquals( 1, result.getLocatedClasses().size() );
ArchiveHelper.getURLFromPath( dirPath ), assertEquals( 1, result.getLocatedPackages().size() );
"" assertEquals( 1, result.getLocatedMappingFiles().size() );
);
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() );
assertTrue( assertTrue(
resultCollector.getClassDescriptorSet().contains( result.getLocatedClasses().contains(
new ClassDescriptorImpl( Carpet.class.getName(), null ) new ClassDescriptorImpl( Carpet.class.getName(), null )
) )
); );
for ( MappingFileDescriptor mappingFileDescriptor : resultCollector.getMappingFileSet() ) { for ( MappingFileDescriptor mappingFileDescriptor : result.getLocatedMappingFiles() ) {
assertNotNull( mappingFileDescriptor.getStreamAccess() ); assertNotNull( mappingFileDescriptor.getStreamAccess() );
final InputStream stream = mappingFileDescriptor.getStreamAccess().accessInputStream(); final InputStream stream = mappingFileDescriptor.getStreamAccess().accessInputStream();
assertNotNull( stream ); assertNotNull( stream );
stream.close(); stream.close();
} }
} }
@Test @Test
@TestForIssue(jiraKey = "HHH-6806") @TestForIssue(jiraKey = "HHH-6806")
public void testJarVisitorFactory() throws Exception { public void testJarVisitorFactory() throws Exception {
final File explodedPar = buildExplodedPar(); final File explodedPar = buildExplodedPar();
final File defaultPar = buildDefaultPar(); final File defaultPar = buildDefaultPar();
addPackageToClasspath( explodedPar, defaultPar ); addPackageToClasspath( explodedPar, defaultPar );
//setting URL to accept vfs based protocol //setting URL to accept vfs based protocol
URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() { URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() {
public URLStreamHandler createURLStreamHandler(String protocol) { public URLStreamHandler createURLStreamHandler(String protocol) {
if("vfszip".equals(protocol) || "vfsfile".equals(protocol) ) if("vfszip".equals(protocol) || "vfsfile".equals(protocol) )
return new URLStreamHandler() { return new URLStreamHandler() {
protected URLConnection openConnection(URL u) protected URLConnection openConnection(URL u)
throws IOException { throws IOException {
return null; return null;
} }
}; };
return null; return null;
} }
}); });
URL jarUrl = defaultPar.toURL(); URL jarUrl = defaultPar.toURL();
ArchiveDescriptor descriptor = StandardArchiveDescriptorFactory.INSTANCE.buildArchiveDescriptor( jarUrl ); ArchiveDescriptor descriptor = StandardArchiveDescriptorFactory.INSTANCE.buildArchiveDescriptor( jarUrl );
assertEquals( JarFileBasedArchiveDescriptor.class.getName(), descriptor.getClass().getName() ); assertEquals( JarFileBasedArchiveDescriptor.class.getName(), descriptor.getClass().getName() );
@ -358,7 +403,7 @@ public class JarVisitorTest extends PackagingTestCase {
// Entry entry = new Entry( Carpet.class.getName(), null ); // Entry entry = new Entry( Carpet.class.getName(), null );
// assertTrue( entries[1].contains( entry ) ); // assertTrue( entries[1].contains( entry ) );
} }
@Test @Test
@TestForIssue(jiraKey = "HHH-7835") @TestForIssue(jiraKey = "HHH-7835")
public void testGetBytesFromInputStream() throws Exception { public void testGetBytesFromInputStream() throws Exception {

View File

@ -29,17 +29,20 @@ import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import org.hibernate.jpa.AvailableSettings; import org.hibernate.boot.archive.scan.spi.JandexInitializer;
import org.hibernate.boot.archive.scan.spi.ScanEnvironment;
import org.hibernate.boot.archive.scan.spi.ScanParameters;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor; import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
import org.hibernate.jpa.boot.internal.StandardJpaScanEnvironmentImpl;
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor; import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
import org.hibernate.jpa.boot.scan.internal.StandardScanOptions; import org.hibernate.boot.archive.scan.internal.StandardScanOptions;
import org.hibernate.jpa.boot.scan.internal.StandardScanner; import org.hibernate.boot.archive.scan.internal.StandardScanner;
import org.hibernate.jpa.boot.spi.ClassDescriptor; import org.hibernate.boot.archive.scan.spi.ClassDescriptor;
import org.hibernate.jpa.boot.spi.MappingFileDescriptor; import org.hibernate.boot.archive.scan.spi.MappingFileDescriptor;
import org.hibernate.jpa.boot.spi.NamedInputStream; import org.hibernate.boot.archive.scan.spi.ScanOptions;
import org.hibernate.jpa.boot.scan.spi.ScanOptions; import org.hibernate.boot.archive.scan.spi.ScanResult;
import org.hibernate.jpa.boot.scan.spi.ScanResult; import org.hibernate.boot.archive.scan.spi.Scanner;
import org.hibernate.jpa.boot.scan.spi.Scanner;
import org.hibernate.jpa.test.pack.defaultpar.ApplicationServer; import org.hibernate.jpa.test.pack.defaultpar.ApplicationServer;
import org.hibernate.jpa.test.pack.defaultpar.Version; import org.hibernate.jpa.test.pack.defaultpar.Version;
@ -61,9 +64,21 @@ public class ScannerTest extends PackagingTestCase {
addPackageToClasspath( defaultPar ); addPackageToClasspath( defaultPar );
PersistenceUnitDescriptor descriptor = new ParsedPersistenceXmlDescriptor( defaultPar.toURL() ); PersistenceUnitDescriptor descriptor = new ParsedPersistenceXmlDescriptor( defaultPar.toURL() );
ScanEnvironment env = new StandardJpaScanEnvironmentImpl( descriptor );
ScanOptions options = new StandardScanOptions( "hbm,class", descriptor.isExcludeUnlistedClasses() ); ScanOptions options = new StandardScanOptions( "hbm,class", descriptor.isExcludeUnlistedClasses() );
Scanner scanner = new StandardScanner(); Scanner scanner = new StandardScanner();
ScanResult scanResult = scanner.scan( descriptor, options ); ScanResult scanResult = scanner.scan(
env,
options,
new ScanParameters() {
// private final JandexInitManager jandexInitManager = new JandexInitManager();
@Override
public JandexInitializer getJandexInitializer() {
// return jandexInitManager;
return null;
}
}
);
assertEquals( 3, scanResult.getLocatedClasses().size() ); assertEquals( 3, scanResult.getLocatedClasses().size() );
assertClassesContained( scanResult, ApplicationServer.class ); assertClassesContained( scanResult, ApplicationServer.class );
@ -76,11 +91,6 @@ public class ScannerTest extends PackagingTestCase {
InputStream stream = mappingFileDescriptor.getStreamAccess().accessInputStream(); InputStream stream = mappingFileDescriptor.getStreamAccess().accessInputStream();
assertNotNull( stream ); assertNotNull( stream );
stream.close(); stream.close();
NamedInputStream namedInputStream = mappingFileDescriptor.getStreamAccess().asNamedInputStream();
assertNotNull( namedInputStream );
stream = namedInputStream.getStream();
assertNotNull( stream );
stream.close();
} }
} }

View File

@ -27,11 +27,10 @@ import javax.persistence.PersistenceException;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jpa.boot.archive.spi.ArchiveContext; import org.hibernate.boot.archive.spi.ArchiveContext;
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptor; import org.hibernate.boot.archive.spi.ArchiveDescriptor;
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry; import org.hibernate.boot.archive.spi.ArchiveEntry;
import org.hibernate.jpa.boot.spi.InputStreamAccess; import org.hibernate.boot.archive.spi.InputStreamAccess;
import org.hibernate.jpa.boot.spi.NamedInputStream;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;
import org.osgi.framework.wiring.BundleWiring; import org.osgi.framework.wiring.BundleWiring;
@ -77,11 +76,6 @@ public class OsgiArchiveDescriptor implements ArchiveDescriptor {
public InputStream accessInputStream() { public InputStream accessInputStream() {
return openInputStream(); return openInputStream();
} }
@Override
public NamedInputStream asNamedInputStream() {
return new NamedInputStream( resource, openInputStream() );
}
private InputStream openInputStream() { private InputStream openInputStream() {
try { try {

View File

@ -22,8 +22,8 @@ package org.hibernate.osgi;
import java.net.URL; import java.net.URL;
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptor; import org.hibernate.boot.archive.spi.ArchiveDescriptor;
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory; import org.hibernate.boot.archive.spi.ArchiveDescriptorFactory;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;

View File

@ -85,7 +85,7 @@ public class OsgiPersistenceProvider extends HibernatePersistenceProvider {
final Map settings = generateSettings( properties ); final Map settings = generateSettings( properties );
// TODO: This needs tested. // TODO: This needs tested.
settings.put( org.hibernate.jpa.AvailableSettings.SCANNER, new OsgiScanner( requestingBundle ) ); settings.put( org.hibernate.cfg.AvailableSettings.SCANNER, new OsgiScanner( requestingBundle ) );
// TODO: This is temporary -- for PersistenceXmlParser's use of // TODO: This is temporary -- for PersistenceXmlParser's use of
// ClassLoaderServiceImpl#fromConfigSettings // ClassLoaderServiceImpl#fromConfigSettings
settings.put( AvailableSettings.ENVIRONMENT_CLASSLOADER, osgiClassLoader ); settings.put( AvailableSettings.ENVIRONMENT_CLASSLOADER, osgiClassLoader );
@ -103,7 +103,7 @@ public class OsgiPersistenceProvider extends HibernatePersistenceProvider {
// OSGi ClassLoaders must implement BundleReference // OSGi ClassLoaders must implement BundleReference
settings.put( settings.put(
org.hibernate.jpa.AvailableSettings.SCANNER, org.hibernate.cfg.AvailableSettings.SCANNER,
new OsgiScanner( ( (BundleReference) info.getClassLoader() ).getBundle() ) new OsgiScanner( ( (BundleReference) info.getClassLoader() ).getBundle() )
); );

View File

@ -20,7 +20,7 @@
*/ */
package org.hibernate.osgi; package org.hibernate.osgi;
import org.hibernate.jpa.boot.scan.spi.AbstractScannerImpl; import org.hibernate.boot.archive.scan.spi.AbstractScannerImpl;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;