From e4c1db1e8f11c00d005539ca9208dd73946800eb Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Sat, 23 Mar 2013 13:55:48 -0500 Subject: [PATCH] HHH-8088 - Redesign Scanner contract --- ...stractJavaArtifactArchiveEntryHandler.java | 67 +++++++++++++++++++ .../spi/ClassFileArchiveEntryHandler.java | 29 +++----- .../spi/NonClassFileArchiveEntryHandler.java | 9 ++- .../spi/PackageInfoArchiveEntryHandler.java | 18 +++-- 4 files changed, 98 insertions(+), 25 deletions(-) create mode 100644 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/AbstractJavaArtifactArchiveEntryHandler.java diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/AbstractJavaArtifactArchiveEntryHandler.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/AbstractJavaArtifactArchiveEntryHandler.java new file mode 100644 index 0000000000..c8547ebf14 --- /dev/null +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/AbstractJavaArtifactArchiveEntryHandler.java @@ -0,0 +1,67 @@ +/* + * 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: + * + * @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 ); + } +} diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/ClassFileArchiveEntryHandler.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/ClassFileArchiveEntryHandler.java index 0bfcad0fc4..33c61005b7 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/ClassFileArchiveEntryHandler.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/ClassFileArchiveEntryHandler.java @@ -36,25 +36,27 @@ import javassist.bytecode.ClassFile; import org.hibernate.jpa.boot.archive.spi.ArchiveContext; import org.hibernate.jpa.boot.archive.spi.ArchiveEntry; -import org.hibernate.jpa.boot.archive.spi.ArchiveEntryHandler; import org.hibernate.jpa.boot.archive.spi.ArchiveException; import org.hibernate.jpa.boot.internal.ClassDescriptorImpl; -import org.hibernate.jpa.boot.scan.spi.ScanOptions; import org.hibernate.jpa.boot.spi.ClassDescriptor; /** -* @author Steve Ebersole -*/ -public class ClassFileArchiveEntryHandler implements ArchiveEntryHandler { - private final ScanOptions scanOptions; + * Defines handling and filtering for class file entries within an archive + * + * @author Steve Ebersole + */ +public class ClassFileArchiveEntryHandler extends AbstractJavaArtifactArchiveEntryHandler { private final Callback callback; + /** + * Contract for the thing interested in being notified about accepted class descriptors. + */ public static interface Callback { public void locatedClass(ClassDescriptor classDescriptor); } public ClassFileArchiveEntryHandler(ScanOptions scanOptions, Callback callback) { - this.scanOptions = scanOptions; + super( scanOptions ); this.callback = callback; } @@ -63,17 +65,8 @@ public class ClassFileArchiveEntryHandler implements ArchiveEntryHandler { final ClassFile classFile = toClassFile( entry ); final ClassDescriptor classDescriptor = toClassDescriptor( classFile, entry ); - if ( ! context.getPersistenceUnitDescriptor().getManagedClassNames().contains( classDescriptor.getName() ) ) { - if ( context.isRootUrl() ) { - if ( ! scanOptions.canDetectUnlistedClassesInRoot() ) { - return; - } - } - else { - if ( ! scanOptions.canDetectUnlistedClassesInNonRoot() ) { - return; - } - } + if ( ! isListedOrDetectable( context, classDescriptor.getName() ) ) { + return; } // we are only interested in classes with certain annotations, so see if the ClassDescriptor diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/NonClassFileArchiveEntryHandler.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/NonClassFileArchiveEntryHandler.java index a3aa33a437..5e6fccb2fb 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/NonClassFileArchiveEntryHandler.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/NonClassFileArchiveEntryHandler.java @@ -30,12 +30,17 @@ import org.hibernate.jpa.boot.internal.MappingFileDescriptorImpl; import org.hibernate.jpa.boot.spi.MappingFileDescriptor; /** -* @author Steve Ebersole -*/ + * 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); } diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/PackageInfoArchiveEntryHandler.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/PackageInfoArchiveEntryHandler.java index bacd9d3f1b..d824ef015e 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/PackageInfoArchiveEntryHandler.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/PackageInfoArchiveEntryHandler.java @@ -25,26 +25,28 @@ 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.PackageDescriptorImpl; import org.hibernate.jpa.boot.spi.PackageDescriptor; import static java.io.File.separatorChar; /** + * Defines handling and filtering for package-info file entries within an archive + * * @author Steve Ebersole */ -public class PackageInfoArchiveEntryHandler implements ArchiveEntryHandler { - @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) - private final ScanOptions scanOptions; +public class PackageInfoArchiveEntryHandler extends AbstractJavaArtifactArchiveEntryHandler { private final Callback callback; + /** + * Contract for the thing interested in being notified about accepted package-info descriptors. + */ public static interface Callback { public void locatedPackage(PackageDescriptor packageDescriptor); } public PackageInfoArchiveEntryHandler(ScanOptions scanOptions, Callback callback) { - this.scanOptions = scanOptions; + super( scanOptions ); this.callback = callback; } @@ -54,6 +56,12 @@ public class PackageInfoArchiveEntryHandler implements ArchiveEntryHandler { // the old code skipped package-info in the root package/dir... return; } + + if ( ! isListedOrDetectable( context, entry.getName() ) ) { + // the package is not explicitly listed, and we are not allowed to detect it. + return; + } + notifyMatchedPackage( toPackageDescriptor( entry ) ); }