HHH-8088 - Redesign Scanner contract
This commit is contained in:
parent
a1afa0ce35
commit
eeca84460e
|
@ -26,10 +26,12 @@ package org.hibernate.ejb.packaging;
|
|||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link org.hibernate.jpa.packaging.spi.NamedInputStream} instead
|
||||
* @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.packaging.spi.NamedInputStream {
|
||||
public class NamedInputStream extends org.hibernate.jpa.boot.spi.NamedInputStream {
|
||||
public NamedInputStream(String name, InputStream stream) {
|
||||
super( name, stream );
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
package org.hibernate.ejb.packaging;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link org.hibernate.jpa.packaging.spi.Scanner} instead
|
||||
* @deprecated Use {@link org.hibernate.jpa.boot.scan.spi.Scanner} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public interface Scanner extends org.hibernate.jpa.packaging.spi.Scanner {
|
||||
public interface Scanner extends org.hibernate.jpa.boot.scan.spi.Scanner {
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
|
||||
* 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 Middleware LLC.
|
||||
* 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
|
||||
|
@ -19,29 +21,26 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.packaging.internal;
|
||||
package org.hibernate.jpa.boot.archive.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.jpa.internal.EntityManagerMessageLogger;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveException;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
* @author Brett Meyer
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JarVisitorFactory {
|
||||
|
||||
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(EntityManagerMessageLogger.class,
|
||||
JarVisitorFactory.class.getName());
|
||||
public class ArchiveHelper {
|
||||
private static final Logger log = Logger.getLogger( ArchiveHelper.class );
|
||||
|
||||
/**
|
||||
* Get the JAR URL of the JAR containing the given entry
|
||||
|
@ -51,7 +50,6 @@ public class JarVisitorFactory {
|
|||
* @param entry file known to be in the JAR
|
||||
* @return the JAR URL
|
||||
* @throws IllegalArgumentException if none URL is found
|
||||
* TODO move to a ScannerHelper service?
|
||||
*/
|
||||
public static URL getJarURLFromURLEntry(URL url, String entry) throws IllegalArgumentException {
|
||||
URL jarUrl;
|
||||
|
@ -106,7 +104,7 @@ public class JarVisitorFactory {
|
|||
"Unable to determine JAR Url from " + url + ". Cause: " + e.getMessage()
|
||||
);
|
||||
}
|
||||
LOG.trace("JAR URL from URL Entry: " + url + " >> " + jarUrl);
|
||||
log.trace("JAR URL from URL Entry: " + url + " >> " + jarUrl);
|
||||
return jarUrl;
|
||||
}
|
||||
|
||||
|
@ -114,7 +112,6 @@ public class JarVisitorFactory {
|
|||
* get the URL from a given path string
|
||||
*
|
||||
* @throws IllegalArgumentException is something goes wrong
|
||||
* TODO move to a ScannerHelper service?
|
||||
*/
|
||||
public static URL getURLFromPath(String jarPath) {
|
||||
URL jarUrl;
|
||||
|
@ -134,70 +131,40 @@ public class JarVisitorFactory {
|
|||
return jarUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JarVisitor to the jar <code>jarPath</code> applying the given filters
|
||||
*
|
||||
* Method used in a non-managed environment
|
||||
*
|
||||
* @throws IllegalArgumentException if the jarPath is incorrect
|
||||
*/
|
||||
public static JarVisitor getVisitor(String jarPath, Filter[] filters) throws IllegalArgumentException {
|
||||
File file = new File( jarPath );
|
||||
if ( file.isFile() ) {
|
||||
return new InputStreamZippedJarVisitor( jarPath, filters );
|
||||
public static String unqualifiedJarFileName(URL jarUrl) {
|
||||
// todo : weak algorithm subject to AOOBE
|
||||
String fileName = jarUrl.getFile();
|
||||
int exclamation = fileName.lastIndexOf( "!" );
|
||||
if (exclamation != -1) {
|
||||
fileName = fileName.substring( 0, exclamation );
|
||||
}
|
||||
else {
|
||||
return new ExplodedJarVisitor( jarPath, filters );
|
||||
|
||||
int slash = fileName.lastIndexOf( "/" );
|
||||
if ( slash != -1 ) {
|
||||
fileName = fileName.substring(
|
||||
fileName.lastIndexOf( "/" ) + 1,
|
||||
fileName.length()
|
||||
);
|
||||
}
|
||||
|
||||
if ( fileName.length() > 4 && fileName.endsWith( "ar" ) && fileName.charAt( fileName.length() - 4 ) == '.' ) {
|
||||
fileName = fileName.substring( 0, fileName.length() - 4 );
|
||||
}
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public static byte[] getBytesFromInputStreamSafely(InputStream inputStream) {
|
||||
try {
|
||||
return getBytesFromInputStream( inputStream );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new ArchiveException( "Unable to extract bytes from InputStream", e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JarVisitor on the given JAR URL applying the given filters
|
||||
*
|
||||
* @throws IllegalArgumentException if the URL is malformed
|
||||
*/
|
||||
public static JarVisitor getVisitor(URL jarUrl, Filter[] filters) throws IllegalArgumentException {
|
||||
return getVisitor( jarUrl, filters, "" );
|
||||
}
|
||||
|
||||
public static JarVisitor getVisitor(URL jarUrl, Filter[] filters, String entry) throws IllegalArgumentException {
|
||||
String protocol = jarUrl.getProtocol();
|
||||
if ( "jar".equals( protocol ) ) {
|
||||
return new JarProtocolVisitor( jarUrl, filters, entry );
|
||||
}
|
||||
else if ( StringHelper.isEmpty( protocol ) || "file".equals( protocol ) || "vfszip".equals( protocol ) || "vfsfile".equals( protocol ) ) {
|
||||
File file;
|
||||
try {
|
||||
final String filePart = jarUrl.getFile();
|
||||
if ( filePart != null && filePart.indexOf( ' ' ) != -1 ) {
|
||||
//unescaped (from the container), keep as is
|
||||
file = new File( jarUrl.getFile() );
|
||||
}
|
||||
else {
|
||||
file = new File( jarUrl.toURI().getSchemeSpecificPart() );
|
||||
}
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to visit JAR " + jarUrl + ". Cause: " + e.getMessage(), e
|
||||
);
|
||||
}
|
||||
|
||||
if ( file.isDirectory() ) {
|
||||
return new ExplodedJarVisitor( jarUrl, filters, entry );
|
||||
}
|
||||
else {
|
||||
return new FileZippedJarVisitor( jarUrl, filters, entry );
|
||||
}
|
||||
}
|
||||
else {
|
||||
//let's assume the url can return the jar as a zip stream
|
||||
return new InputStreamZippedJarVisitor( jarUrl, filters, entry );
|
||||
}
|
||||
}
|
||||
|
||||
// Optimized by HHH-7835
|
||||
public static byte[] getBytesFromInputStream(InputStream inputStream) throws IOException {
|
||||
// Optimized by HHH-7835
|
||||
int size;
|
||||
List<byte[]> data = new LinkedList<byte[]>();
|
||||
int bufferSize = 4096;
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* 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.archive.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.jpa.boot.archive.spi.AbstractArchiveDescriptor;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveException;
|
||||
import org.hibernate.jpa.boot.internal.FileInputStreamAccess;
|
||||
import org.hibernate.jpa.boot.spi.InputStreamAccess;
|
||||
import org.hibernate.jpa.internal.EntityManagerMessageLogger;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ExplodedArchiveDescriptor extends AbstractArchiveDescriptor {
|
||||
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(
|
||||
EntityManagerMessageLogger.class,
|
||||
ExplodedArchiveDescriptor.class.getName()
|
||||
);
|
||||
|
||||
public ExplodedArchiveDescriptor(
|
||||
ArchiveDescriptorFactory archiveDescriptorFactory,
|
||||
URL archiveUrl,
|
||||
String entryBasePrefix) {
|
||||
super( archiveDescriptorFactory, archiveUrl, entryBasePrefix );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitArchive(ArchiveContext context) {
|
||||
final File rootDirectory = resolveRootDirectory();
|
||||
if ( rootDirectory == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( rootDirectory.isDirectory() ) {
|
||||
processDirectory( rootDirectory, null, context );
|
||||
}
|
||||
else {
|
||||
//assume zipped file
|
||||
processZippedRoot( rootDirectory, context );
|
||||
}
|
||||
}
|
||||
|
||||
private File resolveRootDirectory() {
|
||||
final File archiveUrlDirectory;
|
||||
try {
|
||||
final String filePart = getArchiveUrl().getFile();
|
||||
if ( filePart != null && filePart.indexOf( ' ' ) != -1 ) {
|
||||
//unescaped (from the container), keep as is
|
||||
archiveUrlDirectory = new File( filePart );
|
||||
}
|
||||
else {
|
||||
archiveUrlDirectory = new File( getArchiveUrl().toURI().getSchemeSpecificPart() );
|
||||
}
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
LOG.malformedUrl( getArchiveUrl(), e );
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( !archiveUrlDirectory.exists() ) {
|
||||
LOG.explodedJarDoesNotExist( getArchiveUrl() );
|
||||
return null;
|
||||
}
|
||||
if ( !archiveUrlDirectory.isDirectory() ) {
|
||||
LOG.explodedJarNotDirectory( getArchiveUrl() );
|
||||
return null;
|
||||
}
|
||||
|
||||
final String entryBase = getEntryBasePrefix();
|
||||
if ( entryBase != null && entryBase.length() > 0 && ! "/".equals( entryBase ) ) {
|
||||
return new File( archiveUrlDirectory, entryBase );
|
||||
}
|
||||
else {
|
||||
return archiveUrlDirectory;
|
||||
}
|
||||
}
|
||||
|
||||
private void processDirectory(
|
||||
File directory,
|
||||
String path,
|
||||
ArchiveContext context) {
|
||||
if ( directory == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
final File[] files = directory.listFiles();
|
||||
if ( files == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
path = path == null ? "" : path + "/";
|
||||
for ( final File localFile : files ) {
|
||||
if ( !localFile.exists() ) {
|
||||
// should never happen conceptually, but...
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( localFile.isDirectory() ) {
|
||||
processDirectory( localFile, path + localFile.getName(), context );
|
||||
continue;
|
||||
}
|
||||
|
||||
final String name = localFile.getAbsolutePath();
|
||||
final String relativeName = path + localFile.getName();
|
||||
final InputStreamAccess inputStreamAccess = new FileInputStreamAccess( name, localFile );
|
||||
|
||||
final ArchiveEntry entry = new ArchiveEntry() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameWithinArchive() {
|
||||
return relativeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStreamAccess getStreamAccess() {
|
||||
return inputStreamAccess;
|
||||
}
|
||||
};
|
||||
|
||||
context.obtainArchiveEntryHandler( entry ).handleEntry( entry, context );
|
||||
}
|
||||
}
|
||||
|
||||
private void processZippedRoot(File rootFile, ArchiveContext context) {
|
||||
try {
|
||||
final JarFile jarFile = new JarFile(rootFile);
|
||||
final Enumeration<? extends ZipEntry> entries = jarFile.entries();
|
||||
while ( entries.hasMoreElements() ) {
|
||||
final ZipEntry zipEntry = entries.nextElement();
|
||||
if ( zipEntry.isDirectory() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String name = extractName( zipEntry );
|
||||
final String relativeName = extractRelativeName( zipEntry );
|
||||
final InputStreamAccess inputStreamAccess;
|
||||
try {
|
||||
inputStreamAccess = buildByteBasedInputStreamAccess( name, jarFile.getInputStream( zipEntry ) );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new ArchiveException(
|
||||
String.format(
|
||||
"Unable to access stream from jar file [%s] for entry [%s]",
|
||||
jarFile.getName(),
|
||||
zipEntry.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
final ArchiveEntry entry = new ArchiveEntry() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameWithinArchive() {
|
||||
return relativeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStreamAccess getStreamAccess() {
|
||||
return inputStreamAccess;
|
||||
}
|
||||
};
|
||||
context.obtainArchiveEntryHandler( entry ).handleEntry( entry, context );
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new ArchiveException( "Error accessing jar file [" + rootFile.getAbsolutePath() + "]", e );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* 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.archive.internal;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarInputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.jpa.boot.archive.spi.AbstractArchiveDescriptor;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
|
||||
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.archive.spi.ArchiveException;
|
||||
import org.hibernate.jpa.internal.EntityManagerMessageLogger;
|
||||
import org.hibernate.jpa.boot.spi.InputStreamAccess;
|
||||
|
||||
/**
|
||||
* An ArchiveDescriptor implementation leveraging the {@link JarFile} API for processing.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JarFileBasedArchiveDescriptor extends AbstractArchiveDescriptor {
|
||||
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(
|
||||
EntityManagerMessageLogger.class,
|
||||
JarFileBasedArchiveDescriptor.class.getName()
|
||||
);
|
||||
|
||||
public JarFileBasedArchiveDescriptor(
|
||||
ArchiveDescriptorFactory archiveDescriptorFactory,
|
||||
URL archiveUrl,
|
||||
String entry) {
|
||||
super( archiveDescriptorFactory, archiveUrl, entry );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitArchive(ArchiveContext context) {
|
||||
final JarFile jarFile = resolveJarFileReference();
|
||||
if ( jarFile == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Enumeration<? extends ZipEntry> zipEntries = jarFile.entries();
|
||||
while ( zipEntries.hasMoreElements() ) {
|
||||
final ZipEntry zipEntry = zipEntries.nextElement();
|
||||
final String entryName = extractName( zipEntry );
|
||||
|
||||
if ( getEntryBasePrefix() != null && ! entryName.startsWith( getEntryBasePrefix() ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( zipEntry.isDirectory() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( entryName.equals( getEntryBasePrefix() ) ) {
|
||||
// exact match, might be a nested jar entry (ie from jar:file:..../foo.ear!/bar.jar)
|
||||
//
|
||||
// This algorithm assumes that the zipped file is only the URL root (including entry), not
|
||||
// just any random entry
|
||||
try {
|
||||
InputStream is = new BufferedInputStream( jarFile.getInputStream( zipEntry ) );
|
||||
try {
|
||||
final JarInputStream jarInputStream = new JarInputStream( is );
|
||||
ZipEntry subZipEntry = jarInputStream.getNextEntry();
|
||||
while ( subZipEntry != null ) {
|
||||
if ( ! subZipEntry.isDirectory() ) {
|
||||
|
||||
final String name = extractName( subZipEntry );
|
||||
final String relativeName = extractRelativeName( subZipEntry );
|
||||
final InputStreamAccess inputStreamAccess
|
||||
= buildByteBasedInputStreamAccess( name, jarInputStream );
|
||||
|
||||
final ArchiveEntry entry = new ArchiveEntry() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameWithinArchive() {
|
||||
return relativeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStreamAccess getStreamAccess() {
|
||||
return inputStreamAccess;
|
||||
}
|
||||
};
|
||||
|
||||
final ArchiveEntryHandler entryHandler = context.obtainArchiveEntryHandler( entry );
|
||||
entryHandler.handleEntry( entry, context );
|
||||
}
|
||||
|
||||
subZipEntry = jarInputStream.getNextEntry();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new ArchiveException( "Error accessing JarFile entry [" + zipEntry.getName() + "]", e );
|
||||
}
|
||||
}
|
||||
else {
|
||||
final String name = extractName( zipEntry );
|
||||
final String relativeName = extractRelativeName( zipEntry );
|
||||
final InputStreamAccess inputStreamAccess;
|
||||
try {
|
||||
inputStreamAccess = buildByteBasedInputStreamAccess( name, jarFile.getInputStream( zipEntry ) );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new ArchiveException(
|
||||
String.format(
|
||||
"Unable to access stream from jar file [%s] for entry [%s]",
|
||||
jarFile.getName(),
|
||||
zipEntry.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
final ArchiveEntry entry = new ArchiveEntry() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameWithinArchive() {
|
||||
return relativeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStreamAccess getStreamAccess() {
|
||||
return inputStreamAccess;
|
||||
}
|
||||
};
|
||||
|
||||
final ArchiveEntryHandler entryHandler = context.obtainArchiveEntryHandler( entry );
|
||||
entryHandler.handleEntry( entry, context );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JarFile resolveJarFileReference() {
|
||||
try {
|
||||
String filePart = getArchiveUrl().getFile();
|
||||
if ( filePart != null && filePart.indexOf( ' ' ) != -1 ) {
|
||||
// unescaped (from the container), keep as is
|
||||
return new JarFile( getArchiveUrl().getFile() );
|
||||
}
|
||||
else {
|
||||
return new JarFile( getArchiveUrl().toURI().getSchemeSpecificPart() );
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.unableToFindFile( getArchiveUrl(), e );
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
LOG.malformedUrlWarning( getArchiveUrl(), e );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* 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.archive.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarInputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.jpa.boot.archive.spi.AbstractArchiveDescriptor;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveException;
|
||||
import org.hibernate.jpa.boot.spi.InputStreamAccess;
|
||||
import org.hibernate.jpa.internal.EntityManagerMessageLogger;
|
||||
|
||||
/**
|
||||
* An ArchiveDescriptor implementation that works on archives accessible through a {@link java.util.jar.JarInputStream}.
|
||||
* NOTE : This is less efficient implementation than {@link JarFileBasedArchiveDescriptor}
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JarInputStreamBasedArchiveDescriptor extends AbstractArchiveDescriptor {
|
||||
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(
|
||||
EntityManagerMessageLogger.class,
|
||||
JarInputStreamBasedArchiveDescriptor.class.getName()
|
||||
);
|
||||
|
||||
public JarInputStreamBasedArchiveDescriptor(
|
||||
ArchiveDescriptorFactory archiveDescriptorFactory,
|
||||
URL url,
|
||||
String entry) {
|
||||
super( archiveDescriptorFactory, url, entry );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitArchive(ArchiveContext context) {
|
||||
final JarInputStream jarInputStream;
|
||||
try {
|
||||
jarInputStream = new JarInputStream( getArchiveUrl().openStream() );
|
||||
}
|
||||
catch (Exception e) {
|
||||
//really should catch IOException but Eclipse is buggy and raise NPE...
|
||||
LOG.unableToFindFile( getArchiveUrl(), e );
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
JarEntry jarEntry;
|
||||
while ( ( jarEntry = jarInputStream.getNextJarEntry() ) != null ) {
|
||||
String jarEntryName = jarEntry.getName();
|
||||
if ( getEntryBasePrefix() != null && ! jarEntryName.startsWith( getEntryBasePrefix() ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( jarEntry.isDirectory() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( jarEntryName.equals( getEntryBasePrefix() ) ) {
|
||||
// exact match, might be a nested jar entry (ie from jar:file:..../foo.ear!/bar.jar)
|
||||
//
|
||||
// This algorithm assumes that the zipped file is only the URL root (including entry), not
|
||||
// just any random entry
|
||||
try {
|
||||
final JarInputStream subJarInputStream = new JarInputStream( jarInputStream );
|
||||
try {
|
||||
ZipEntry subZipEntry = jarInputStream.getNextEntry();
|
||||
while (subZipEntry != null) {
|
||||
if ( ! subZipEntry.isDirectory() ) {
|
||||
final String subName = extractName( subZipEntry );
|
||||
final InputStreamAccess inputStreamAccess
|
||||
= buildByteBasedInputStreamAccess( subName, subJarInputStream );
|
||||
|
||||
final ArchiveEntry entry = new ArchiveEntry() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return subName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameWithinArchive() {
|
||||
return subName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStreamAccess getStreamAccess() {
|
||||
return inputStreamAccess;
|
||||
}
|
||||
};
|
||||
|
||||
context.obtainArchiveEntryHandler( entry ).handleEntry( entry, context );
|
||||
}
|
||||
subZipEntry = jarInputStream.getNextJarEntry();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
subJarInputStream.close();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new ArchiveException( "Error accessing nested jar", e );
|
||||
}
|
||||
}
|
||||
else {
|
||||
final String entryName = extractName( jarEntry );
|
||||
final InputStreamAccess inputStreamAccess
|
||||
= buildByteBasedInputStreamAccess( entryName, jarInputStream );
|
||||
|
||||
final String relativeName = extractRelativeName( jarEntry );
|
||||
|
||||
final ArchiveEntry entry = new ArchiveEntry() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return entryName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameWithinArchive() {
|
||||
return relativeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStreamAccess getStreamAccess() {
|
||||
return inputStreamAccess;
|
||||
}
|
||||
};
|
||||
|
||||
context.obtainArchiveEntryHandler( entry ).handleEntry( entry, context );
|
||||
}
|
||||
}
|
||||
|
||||
jarInputStream.close();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
throw new ArchiveException(
|
||||
String.format( "Error accessing JarInputStream [%s]", getArchiveUrl() ),
|
||||
ioe
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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.archive.internal;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import org.hibernate.annotations.common.AssertionFailure;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptor;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory;
|
||||
|
||||
/**
|
||||
* An ArchiveDescriptor implementation for handling archives whose url reported a JAR protocol (i.e., jar://).
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JarProtocolArchiveDescriptor implements ArchiveDescriptor {
|
||||
private final ArchiveDescriptor delegateDescriptor;
|
||||
|
||||
public JarProtocolArchiveDescriptor(
|
||||
ArchiveDescriptorFactory archiveDescriptorFactory,
|
||||
URL url,
|
||||
String incomingEntry) {
|
||||
if ( incomingEntry != null && incomingEntry.length() > 0 ) {
|
||||
throw new IllegalArgumentException( "jar:jar: not supported: " + url );
|
||||
}
|
||||
|
||||
final String urlFile = url.getFile();
|
||||
final int subEntryIndex = urlFile.lastIndexOf( "!" );
|
||||
if ( subEntryIndex == -1 ) {
|
||||
throw new AssertionFailure( "JAR URL does not contain '!/' :" + url );
|
||||
}
|
||||
|
||||
final String subEntry;
|
||||
if ( subEntryIndex + 1 >= urlFile.length() ) {
|
||||
subEntry = "";
|
||||
}
|
||||
else {
|
||||
subEntry = urlFile.substring( subEntryIndex + 1 );
|
||||
}
|
||||
|
||||
URL fileUrl = archiveDescriptorFactory.getJarURLFromURLEntry( url, subEntry );
|
||||
delegateDescriptor = archiveDescriptorFactory.buildArchiveDescriptor( fileUrl, subEntry );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitArchive(ArchiveContext context) {
|
||||
delegateDescriptor.visitArchive( context );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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.archive.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptor;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardArchiveDescriptorFactory implements ArchiveDescriptorFactory {
|
||||
public static final StandardArchiveDescriptorFactory INSTANCE = new StandardArchiveDescriptorFactory();
|
||||
|
||||
@Override
|
||||
public ArchiveDescriptor buildArchiveDescriptor(URL url) {
|
||||
return buildArchiveDescriptor( url, "" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArchiveDescriptor buildArchiveDescriptor(URL url, String entry) {
|
||||
final String protocol = url.getProtocol();
|
||||
if ( "jar".equals( protocol ) ) {
|
||||
return new JarProtocolArchiveDescriptor( this, url, entry );
|
||||
}
|
||||
else if ( StringHelper.isEmpty( protocol )
|
||||
|| "file".equals( protocol )
|
||||
|| "vfszip".equals( protocol )
|
||||
|| "vfsfile".equals( protocol ) ) {
|
||||
final File file;
|
||||
try {
|
||||
final String filePart = url.getFile();
|
||||
if ( filePart != null && filePart.indexOf( ' ' ) != -1 ) {
|
||||
//unescaped (from the container), keep as is
|
||||
file = new File( url.getFile() );
|
||||
}
|
||||
else {
|
||||
file = new File( url.toURI().getSchemeSpecificPart() );
|
||||
}
|
||||
|
||||
if ( ! file.exists() ) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"File [%s] referenced by given URL [%s] does not exist",
|
||||
filePart,
|
||||
url.toExternalForm()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to visit JAR " + url + ". Cause: " + e.getMessage(), e
|
||||
);
|
||||
}
|
||||
|
||||
if ( file.isDirectory() ) {
|
||||
return new ExplodedArchiveDescriptor( this, url, entry );
|
||||
}
|
||||
else {
|
||||
return new JarFileBasedArchiveDescriptor( this, url, entry );
|
||||
}
|
||||
}
|
||||
else {
|
||||
//let's assume the url can return the jar as a zip stream
|
||||
return new JarInputStreamBasedArchiveDescriptor( this, url, entry );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getJarURLFromURLEntry(URL url, String entry) throws IllegalArgumentException {
|
||||
return ArchiveHelper.getJarURLFromURLEntry( url, entry );
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getURLFromPath(String jarPath) {
|
||||
return ArchiveHelper.getURLFromPath( jarPath );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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.archive.spi;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.jpa.boot.internal.ByteArrayInputStreamAccess;
|
||||
import org.hibernate.jpa.boot.archive.internal.ArchiveHelper;
|
||||
import org.hibernate.jpa.boot.spi.InputStreamAccess;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractArchiveDescriptor implements ArchiveDescriptor {
|
||||
private final ArchiveDescriptorFactory archiveDescriptorFactory;
|
||||
private final URL archiveUrl;
|
||||
private final String entryBasePrefix;
|
||||
|
||||
protected AbstractArchiveDescriptor(
|
||||
ArchiveDescriptorFactory archiveDescriptorFactory,
|
||||
URL archiveUrl,
|
||||
String entryBasePrefix) {
|
||||
this.archiveDescriptorFactory = archiveDescriptorFactory;
|
||||
this.archiveUrl = archiveUrl;
|
||||
this.entryBasePrefix = normalizeEntryBasePrefix( entryBasePrefix );
|
||||
}
|
||||
|
||||
private static String normalizeEntryBasePrefix(String entryBasePrefix) {
|
||||
if ( StringHelper.isEmpty( entryBasePrefix ) || entryBasePrefix.length() == 1 ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return entryBasePrefix.startsWith( "/" ) ? entryBasePrefix.substring( 1 ) : entryBasePrefix;
|
||||
}
|
||||
|
||||
protected ArchiveDescriptorFactory getArchiveDescriptorFactory() {
|
||||
return archiveDescriptorFactory;
|
||||
}
|
||||
|
||||
protected URL getArchiveUrl() {
|
||||
return archiveUrl;
|
||||
}
|
||||
|
||||
protected String getEntryBasePrefix() {
|
||||
return entryBasePrefix;
|
||||
}
|
||||
|
||||
protected String extractRelativeName(ZipEntry zipEntry) {
|
||||
final String entryName = extractName( zipEntry );
|
||||
return entryBasePrefix == null ? entryName : entryName.substring( entryBasePrefix.length() );
|
||||
}
|
||||
|
||||
protected String extractName(ZipEntry zipEntry) {
|
||||
return normalizePathName( zipEntry.getName() );
|
||||
}
|
||||
|
||||
protected String normalizePathName(String pathName) {
|
||||
return pathName.startsWith( "/" ) ? pathName.substring( 1 ) : pathName;
|
||||
}
|
||||
|
||||
protected InputStreamAccess buildByteBasedInputStreamAccess(final String name, InputStream inputStream) {
|
||||
// because of how jar InputStreams work we need to extract the bytes immediately. However, we
|
||||
// do delay the creation of the ByteArrayInputStreams until needed
|
||||
final byte[] bytes = ArchiveHelper.getBytesFromInputStreamSafely( inputStream );
|
||||
return new ByteArrayInputStreamAccess( name, bytes );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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.archive.spi;
|
||||
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ArchiveContext {
|
||||
public PersistenceUnitDescriptor getPersistenceUnitDescriptor();
|
||||
|
||||
public boolean isRootUrl();
|
||||
|
||||
public ArchiveEntryHandler obtainArchiveEntryHandler(ArchiveEntry entry);
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
|
||||
* 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 Middleware LLC.
|
||||
* 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
|
||||
|
@ -19,22 +21,14 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.packaging.internal;
|
||||
|
||||
package org.hibernate.jpa.boot.archive.spi;
|
||||
|
||||
/**
|
||||
* Filter used when searching elements in a JAR
|
||||
* Contract for visiting an archive, which might be a jar, a zip, an exploded directory, etc.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public abstract class Filter {
|
||||
private boolean retrieveStream;
|
||||
|
||||
protected Filter(boolean retrieveStream) {
|
||||
this.retrieveStream = retrieveStream;
|
||||
}
|
||||
|
||||
public boolean getStream() {
|
||||
return retrieveStream;
|
||||
}
|
||||
public interface ArchiveDescriptor {
|
||||
public void visitArchive(ArchiveContext archiveContext);
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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.archive.spi;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Contract for building ArchiveDescriptor instances.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ArchiveDescriptorFactory {
|
||||
public ArchiveDescriptor buildArchiveDescriptor(URL url);
|
||||
public ArchiveDescriptor buildArchiveDescriptor(URL jarUrl, String entry);
|
||||
|
||||
public URL getJarURLFromURLEntry(URL url, String entry) throws IllegalArgumentException;
|
||||
public URL getURLFromPath(String jarPath);
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
|
||||
* 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 Middleware LLC.
|
||||
* 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
|
||||
|
@ -19,28 +21,35 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.packaging.internal;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
package org.hibernate.jpa.boot.archive.spi;
|
||||
|
||||
import org.hibernate.jpa.boot.spi.InputStreamAccess;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
* Represent an entry in the archive.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface JarVisitor {
|
||||
public interface ArchiveEntry {
|
||||
/**
|
||||
* Get the unqualified Jar name (ie wo path and wo extension)
|
||||
* Get the entry's name
|
||||
*
|
||||
* @return the unqualified jar name.
|
||||
* @return
|
||||
*/
|
||||
String getUnqualifiedJarName();
|
||||
|
||||
Filter[] getFilters();
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* Return the matching entries for each filter in the same order the filter where passed
|
||||
* Get the relative name of the entry within the archive. Typically what we are looking for here is
|
||||
* the ClassLoader resource lookup name.
|
||||
*
|
||||
* @return array of Set of JarVisitor.Entry
|
||||
* @throws java.io.IOException if something went wrong
|
||||
* @return
|
||||
*/
|
||||
Set[] getMatchingEntries() throws IOException;
|
||||
public String getNameWithinArchive();
|
||||
|
||||
/**
|
||||
* Get access to the stream for the entry
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public InputStreamAccess getStreamAccess();
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
|
||||
* 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 Middleware LLC.
|
||||
* 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
|
||||
|
@ -19,25 +21,13 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.packaging.internal;
|
||||
|
||||
package org.hibernate.jpa.boot.archive.spi;
|
||||
|
||||
/**
|
||||
* Filter use to match a file by its name
|
||||
* Handler for archive entries, based on the classified type of the entry
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class FileFilter extends Filter {
|
||||
|
||||
/**
|
||||
* @param retrieveStream Give back an open stream to the matching element or not
|
||||
*/
|
||||
public FileFilter(boolean retrieveStream) {
|
||||
super( retrieveStream );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the fully qualified file name match
|
||||
*/
|
||||
public abstract boolean accept(String name);
|
||||
}
|
||||
public interface ArchiveEntryHandler {
|
||||
public void handleEntry(ArchiveEntry entry, ArchiveContext context);
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
|
||||
* 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 Middleware LLC.
|
||||
* 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
|
||||
|
@ -19,20 +21,19 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.packaging.internal;
|
||||
package org.hibernate.jpa.boot.archive.spi;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* Filter on class elements
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
* @see JavaElementFilter
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class ClassFilter extends JavaElementFilter {
|
||||
/**
|
||||
* @see JavaElementFilter#JavaElementFilter(boolean, Class[])
|
||||
*/
|
||||
protected ClassFilter(boolean retrieveStream, Class[] annotations) {
|
||||
super( retrieveStream, annotations );
|
||||
public class ArchiveException extends HibernateException {
|
||||
public ArchiveException(String message) {
|
||||
super( message );
|
||||
}
|
||||
|
||||
public ArchiveException(String message, Throwable root) {
|
||||
super( message, root );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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.internal;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.hibernate.jpa.boot.spi.InputStreamAccess;
|
||||
import org.hibernate.jpa.boot.spi.NamedInputStream;
|
||||
|
||||
/**
|
||||
* An InputStreamAccess implementation based on a byte array
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ByteArrayInputStreamAccess implements InputStreamAccess {
|
||||
private final String name;
|
||||
private final byte[] bytes;
|
||||
|
||||
public ByteArrayInputStreamAccess(String name, byte[] bytes) {
|
||||
this.name = name;
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStreamName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream accessInputStream() {
|
||||
return new ByteArrayInputStream( bytes );
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamedInputStream asNamedInputStream() {
|
||||
return new NamedInputStream( getStreamName(), accessInputStream() );
|
||||
}
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
|
||||
* 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 Middleware LLC.
|
||||
* 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
|
||||
|
@ -19,43 +21,47 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.packaging.internal;
|
||||
import java.io.InputStream;
|
||||
package org.hibernate.jpa.boot.internal;
|
||||
|
||||
import org.hibernate.jpa.boot.spi.ClassDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.InputStreamAccess;
|
||||
|
||||
/**
|
||||
* Represent a JAR entry
|
||||
* Contains a name and an optional Input stream to the entry
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class Entry {
|
||||
private String name;
|
||||
private InputStream is;
|
||||
public class ClassDescriptorImpl implements ClassDescriptor {
|
||||
private final String name;
|
||||
private final InputStreamAccess streamAccess;
|
||||
|
||||
public Entry(String name, InputStream is) {
|
||||
public ClassDescriptorImpl(String name, InputStreamAccess streamAccess) {
|
||||
this.name = name;
|
||||
this.is = is;
|
||||
this.streamAccess = streamAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return is;
|
||||
@Override
|
||||
public InputStreamAccess getStreamAccess() {
|
||||
return streamAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) return true;
|
||||
if ( o == null || getClass() != o.getClass() ) return false;
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Entry entry = (Entry) o;
|
||||
|
||||
if ( !name.equals( entry.name ) ) return false;
|
||||
|
||||
return true;
|
||||
ClassDescriptorImpl that = (ClassDescriptorImpl) o;
|
||||
return name.equals( that.name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
|
@ -23,12 +23,17 @@
|
|||
*/
|
||||
package org.hibernate.jpa.boot.internal;
|
||||
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||
import javax.sql.DataSource;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -42,18 +47,17 @@ import java.util.Properties;
|
|||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||
import javax.sql.DataSource;
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
import org.jboss.jandex.DotName;
|
||||
import org.jboss.jandex.Index;
|
||||
import org.jboss.jandex.IndexView;
|
||||
import org.jboss.jandex.Indexer;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.InvalidMappingException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.MappingNotFoundException;
|
||||
import org.hibernate.SessionFactory;
|
||||
|
@ -81,14 +85,21 @@ import org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder;
|
|||
import org.hibernate.jpa.boot.spi.IntegratorProvider;
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
import org.hibernate.jpa.event.spi.JpaIntegrator;
|
||||
import org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator;
|
||||
import org.hibernate.jpa.internal.EntityManagerFactoryImpl;
|
||||
import org.hibernate.jpa.internal.EntityManagerMessageLogger;
|
||||
import org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator;
|
||||
import org.hibernate.jpa.internal.util.LogHelper;
|
||||
import org.hibernate.jpa.internal.util.PersistenceUnitTransactionTypeHelper;
|
||||
import org.hibernate.jpa.packaging.internal.NativeScanner;
|
||||
import org.hibernate.jpa.packaging.spi.NamedInputStream;
|
||||
import org.hibernate.jpa.packaging.spi.Scanner;
|
||||
import org.hibernate.jpa.boot.scan.internal.StandardScanOptions;
|
||||
import org.hibernate.jpa.boot.scan.internal.StandardScanner;
|
||||
import org.hibernate.jpa.boot.spi.ClassDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.InputStreamAccess;
|
||||
import org.hibernate.jpa.boot.spi.MappingFileDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.NamedInputStream;
|
||||
import org.hibernate.jpa.boot.spi.PackageDescriptor;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanOptions;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanResult;
|
||||
import org.hibernate.jpa.boot.scan.spi.Scanner;
|
||||
import org.hibernate.jpa.spi.IdentifierGeneratorStrategyProvider;
|
||||
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||
import org.hibernate.metamodel.source.annotations.JandexHelper;
|
||||
|
@ -97,14 +108,6 @@ import org.hibernate.secure.internal.JACCConfiguration;
|
|||
import org.hibernate.service.ConfigLoader;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
import org.jboss.jandex.CompositeIndex;
|
||||
import org.jboss.jandex.DotName;
|
||||
import org.jboss.jandex.Index;
|
||||
import org.jboss.jandex.IndexView;
|
||||
import org.jboss.jandex.Indexer;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -199,13 +202,14 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Next we do a preliminary pass at metadata processing, which involves:
|
||||
// 1) scanning
|
||||
ScanResult scanResult = scan( bootstrapServiceRegistry );
|
||||
final ScanResult scanResult = scan( bootstrapServiceRegistry );
|
||||
final DeploymentResources deploymentResources = buildDeploymentResources( scanResult, bootstrapServiceRegistry );
|
||||
// 2) building a Jandex index
|
||||
Set<String> collectedManagedClassNames = collectManagedClassNames( scanResult );
|
||||
IndexView jandexIndex = locateOrBuildJandexIndex( collectedManagedClassNames, scanResult.getPackageNames(), bootstrapServiceRegistry );
|
||||
final IndexView jandexIndex = locateOrBuildJandexIndex( deploymentResources );
|
||||
// 3) building "metadata sources" to keep for later to use in building the SessionFactory
|
||||
metadataSources = prepareMetadataSources( jandexIndex, collectedManagedClassNames, scanResult, bootstrapServiceRegistry );
|
||||
metadataSources = prepareMetadataSources( jandexIndex, deploymentResources, bootstrapServiceRegistry );
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
withValidatorFactory( configurationValues.get( AvailableSettings.VALIDATION_FACTORY ) );
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -217,6 +221,122 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
}
|
||||
}
|
||||
|
||||
private static interface DeploymentResources {
|
||||
public Iterable<ClassDescriptor> getClassDescriptors();
|
||||
public Iterable<PackageDescriptor> getPackageDescriptors();
|
||||
public Iterable<MappingFileDescriptor> getMappingFileDescriptors();
|
||||
}
|
||||
|
||||
private DeploymentResources buildDeploymentResources(
|
||||
ScanResult scanResult,
|
||||
BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||
|
||||
// mapping files ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
final ArrayList<MappingFileDescriptor> mappingFileDescriptors = new ArrayList<MappingFileDescriptor>();
|
||||
|
||||
final Set<String> nonLocatedMappingFileNames = new HashSet<String>();
|
||||
final List<String> explicitMappingFileNames = persistenceUnit.getMappingFileNames();
|
||||
if ( explicitMappingFileNames != null ) {
|
||||
nonLocatedMappingFileNames.addAll( explicitMappingFileNames );
|
||||
}
|
||||
|
||||
for ( MappingFileDescriptor mappingFileDescriptor : scanResult.getLocatedMappingFiles() ) {
|
||||
mappingFileDescriptors.add( mappingFileDescriptor );
|
||||
nonLocatedMappingFileNames.remove( mappingFileDescriptor.getName() );
|
||||
}
|
||||
|
||||
for ( String name : nonLocatedMappingFileNames ) {
|
||||
MappingFileDescriptor descriptor = buildMappingFileDescriptor( name, bootstrapServiceRegistry );
|
||||
mappingFileDescriptors.add( descriptor );
|
||||
}
|
||||
|
||||
|
||||
// classes and packages ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
final HashMap<String, ClassDescriptor> classDescriptorMap = new HashMap<String, ClassDescriptor>();
|
||||
final HashMap<String, PackageDescriptor> packageDescriptorMap = new HashMap<String, PackageDescriptor>();
|
||||
|
||||
for ( ClassDescriptor classDescriptor : scanResult.getLocatedClasses() ) {
|
||||
classDescriptorMap.put( classDescriptor.getName(), classDescriptor );
|
||||
}
|
||||
|
||||
for ( PackageDescriptor packageDescriptor : scanResult.getLocatedPackages() ) {
|
||||
packageDescriptorMap.put( packageDescriptor.getName(), packageDescriptor );
|
||||
}
|
||||
|
||||
final List<String> explicitClassNames = persistenceUnit.getManagedClassNames();
|
||||
if ( explicitClassNames != null ) {
|
||||
for ( String explicitClassName : explicitClassNames ) {
|
||||
// IMPL NOTE : explicitClassNames can contain class or package names!!!
|
||||
if ( classDescriptorMap.containsKey( explicitClassName ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( packageDescriptorMap.containsKey( explicitClassName ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// try it as a class name first...
|
||||
final String classFileName = explicitClassName.replace( '.', '/' ) + ".class";
|
||||
final URL classFileUrl = bootstrapServiceRegistry.getService( ClassLoaderService.class )
|
||||
.locateResource( classFileName );
|
||||
if ( classFileUrl != null ) {
|
||||
classDescriptorMap.put(
|
||||
explicitClassName,
|
||||
new ClassDescriptorImpl( explicitClassName, new UrlInputStreamAccess( classFileUrl ) )
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// otherwise, try it as a package name
|
||||
final String packageInfoFileName = explicitClassName.replace( '.', '/' ) + "/package-info.class";
|
||||
final URL packageInfoFileUrl = bootstrapServiceRegistry.getService( ClassLoaderService.class )
|
||||
.locateResource( packageInfoFileName );
|
||||
if ( packageInfoFileUrl != null ) {
|
||||
packageDescriptorMap.put(
|
||||
explicitClassName,
|
||||
new PackageDescriptorImpl( explicitClassName, new UrlInputStreamAccess( packageInfoFileUrl ) )
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG.debugf(
|
||||
"Unable to resolve class [%s] named in persistence unit [%s]",
|
||||
explicitClassName,
|
||||
persistenceUnit.getName()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return new DeploymentResources() {
|
||||
@Override
|
||||
public Iterable<ClassDescriptor> getClassDescriptors() {
|
||||
return classDescriptorMap.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<PackageDescriptor> getPackageDescriptors() {
|
||||
return packageDescriptorMap.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<MappingFileDescriptor> getMappingFileDescriptors() {
|
||||
return mappingFileDescriptors;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private MappingFileDescriptor buildMappingFileDescriptor(
|
||||
String name,
|
||||
BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||
final URL url = bootstrapServiceRegistry.getService( ClassLoaderService.class ).locateResource( name );
|
||||
if ( url == null ) {
|
||||
throw persistenceException( "Unable to resolve named mapping-file [" + name + "]" );
|
||||
}
|
||||
|
||||
return new MappingFileDescriptorImpl( name, new UrlInputStreamAccess( url ) );
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// temporary!
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -233,13 +353,13 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
@SuppressWarnings("unchecked")
|
||||
private MetadataSources prepareMetadataSources(
|
||||
IndexView jandexIndex,
|
||||
Set<String> collectedManagedClassNames,
|
||||
ScanResult scanResult,
|
||||
DeploymentResources deploymentResources,
|
||||
BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||
// todo : this needs to tie into the metamodel branch...
|
||||
MetadataSources metadataSources = new MetadataSources();
|
||||
|
||||
for ( String className : collectedManagedClassNames ) {
|
||||
for ( ClassDescriptor classDescriptor : deploymentResources.getClassDescriptors() ) {
|
||||
final String className = classDescriptor.getName();
|
||||
final ClassInfo classInfo = jandexIndex.getClassByName( DotName.createSimple( className ) );
|
||||
if ( classInfo == null ) {
|
||||
// Not really sure what this means. Most likely it is explicitly listed in the persistence unit,
|
||||
|
@ -266,15 +386,19 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
}
|
||||
}
|
||||
|
||||
metadataSources.packageNames.addAll( scanResult.getPackageNames() );
|
||||
for ( PackageDescriptor packageDescriptor : deploymentResources.getPackageDescriptors() ) {
|
||||
metadataSources.packageNames.add( packageDescriptor.getName() );
|
||||
}
|
||||
|
||||
metadataSources.namedMappingFileInputStreams.addAll( scanResult.getHbmFiles() );
|
||||
for ( MappingFileDescriptor mappingFileDescriptor : deploymentResources.getMappingFileDescriptors() ) {
|
||||
metadataSources.namedMappingFileInputStreams.add( mappingFileDescriptor.getStreamAccess().asNamedInputStream() );
|
||||
}
|
||||
|
||||
metadataSources.mappingFileResources.addAll( scanResult.getMappingFiles() );
|
||||
final String explicitHbmXmls = (String) configurationValues.remove( AvailableSettings.HBXML_FILES );
|
||||
if ( explicitHbmXmls != null ) {
|
||||
metadataSources.mappingFileResources.addAll( Arrays.asList( StringHelper.split( ", ", explicitHbmXmls ) ) );
|
||||
}
|
||||
|
||||
final List<String> explicitOrmXml = (List<String>) configurationValues.remove( AvailableSettings.XML_FILE_NAMES );
|
||||
if ( explicitOrmXml != null ) {
|
||||
metadataSources.mappingFileResources.addAll( explicitOrmXml );
|
||||
|
@ -283,41 +407,26 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
return metadataSources;
|
||||
}
|
||||
|
||||
private Set<String> collectManagedClassNames(ScanResult scanResult) {
|
||||
Set<String> collectedNames = new HashSet<String>();
|
||||
if ( persistenceUnit.getManagedClassNames() != null ) {
|
||||
collectedNames.addAll( persistenceUnit.getManagedClassNames() );
|
||||
}
|
||||
collectedNames.addAll( scanResult.getManagedClassNames() );
|
||||
return collectedNames;
|
||||
}
|
||||
|
||||
private IndexView locateOrBuildJandexIndex(
|
||||
Set<String> collectedManagedClassNames,
|
||||
List<String> packageNames,
|
||||
BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||
private IndexView locateOrBuildJandexIndex(DeploymentResources deploymentResources) {
|
||||
// for now create a whole new Index to work with, eventually we need to:
|
||||
// 1) accept an Index as an incoming config value
|
||||
// 2) pass that Index along to the metamodel code...
|
||||
//
|
||||
// (1) is mocked up here, but JBoss AS does not currently pass in any Index to use...
|
||||
IndexView jandexIndex = (IndexView) configurationValues.get( JANDEX_INDEX );
|
||||
if ( jandexIndex == null ) {
|
||||
jandexIndex = buildJandexIndex( collectedManagedClassNames, packageNames, bootstrapServiceRegistry );
|
||||
jandexIndex = buildJandexIndex( deploymentResources );
|
||||
}
|
||||
return jandexIndex;
|
||||
}
|
||||
|
||||
private IndexView buildJandexIndex(Set<String> classNamesSource, List<String> packageNames, BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||
private IndexView buildJandexIndex(DeploymentResources deploymentResources) {
|
||||
Indexer indexer = new Indexer();
|
||||
|
||||
for ( String className : classNamesSource ) {
|
||||
indexResource( className.replace( '.', '/' ) + ".class", indexer, bootstrapServiceRegistry );
|
||||
for ( ClassDescriptor classDescriptor : deploymentResources.getClassDescriptors() ) {
|
||||
indexStream( indexer, classDescriptor.getStreamAccess() );
|
||||
}
|
||||
|
||||
// add package-info from the configured packages
|
||||
for ( String packageName : packageNames ) {
|
||||
indexResource( packageName.replace( '.', '/' ) + "/package-info.class", indexer, bootstrapServiceRegistry );
|
||||
for ( PackageDescriptor packageDescriptor : deploymentResources.getPackageDescriptors() ) {
|
||||
indexStream( indexer, packageDescriptor.getStreamAccess() );
|
||||
}
|
||||
|
||||
// for now we just skip entities defined in (1) orm.xml files and (2) hbm.xml files. this part really needs
|
||||
|
@ -325,16 +434,25 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
|
||||
// for now, we also need to wrap this in a CompositeIndex until Jandex is updated to use a common interface
|
||||
// between the 2...
|
||||
return CompositeIndex.create( indexer.complete() );
|
||||
return indexer.complete();
|
||||
}
|
||||
|
||||
private void indexResource(String resourceName, Indexer indexer, BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||
InputStream stream = bootstrapServiceRegistry.getService( ClassLoaderService.class ).locateResourceStream( resourceName );
|
||||
private void indexStream(Indexer indexer, InputStreamAccess streamAccess) {
|
||||
try {
|
||||
indexer.index( stream );
|
||||
InputStream stream = streamAccess.accessInputStream();
|
||||
try {
|
||||
indexer.index( stream );
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
stream.close();
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
throw persistenceException( "Unable to open input stream for resource " + resourceName, e );
|
||||
throw persistenceException( "Unable to index from stream " + streamAccess.getStreamName(), e );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -586,37 +704,24 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ScanResult scan(BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||
Scanner scanner = locateOrBuildScanner( bootstrapServiceRegistry );
|
||||
ScanningContext scanningContext = new ScanningContext();
|
||||
final Scanner scanner = locateOrBuildScanner( bootstrapServiceRegistry );
|
||||
final ScanOptions scanOptions = determineScanOptions();
|
||||
|
||||
final ScanResult scanResult = new ScanResult();
|
||||
if ( persistenceUnit.getMappingFileNames() != null ) {
|
||||
scanResult.getMappingFiles().addAll( persistenceUnit.getMappingFileNames() );
|
||||
}
|
||||
return scanner.scan( persistenceUnit, scanOptions );
|
||||
}
|
||||
|
||||
// dunno, but the old code did it...
|
||||
scanningContext.setSearchOrm( ! scanResult.getMappingFiles().contains( META_INF_ORM_XML ) );
|
||||
|
||||
if ( persistenceUnit.getJarFileUrls() != null ) {
|
||||
prepareAutoDetectionSettings( scanningContext, false );
|
||||
for ( URL jar : persistenceUnit.getJarFileUrls() ) {
|
||||
scanningContext.setUrl( jar );
|
||||
scanInContext( scanner, scanningContext, scanResult );
|
||||
}
|
||||
}
|
||||
|
||||
prepareAutoDetectionSettings( scanningContext, persistenceUnit.isExcludeUnlistedClasses() );
|
||||
scanningContext.setUrl( persistenceUnit.getPersistenceUnitRootUrl() );
|
||||
scanInContext( scanner, scanningContext, scanResult );
|
||||
|
||||
return scanResult;
|
||||
private ScanOptions determineScanOptions() {
|
||||
return new StandardScanOptions(
|
||||
(String) configurationValues.get( AvailableSettings.AUTODETECTION ),
|
||||
persistenceUnit.isExcludeUnlistedClasses()
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Scanner locateOrBuildScanner(BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||
final Object value = configurationValues.remove( AvailableSettings.SCANNER );
|
||||
if ( value == null ) {
|
||||
return new NativeScanner();
|
||||
return new StandardScanner();
|
||||
}
|
||||
|
||||
if ( Scanner.class.isInstance( value ) ) {
|
||||
|
@ -650,91 +755,6 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
}
|
||||
}
|
||||
|
||||
private void prepareAutoDetectionSettings(ScanningContext context, boolean excludeUnlistedClasses) {
|
||||
final String detectionSetting = (String) configurationValues.get( AvailableSettings.AUTODETECTION );
|
||||
|
||||
if ( detectionSetting == null ) {
|
||||
if ( excludeUnlistedClasses ) {
|
||||
context.setDetectClasses( false );
|
||||
context.setDetectHbmFiles( false );
|
||||
}
|
||||
else {
|
||||
context.setDetectClasses( true );
|
||||
context.setDetectHbmFiles( true );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( String token : StringHelper.split( ", ", detectionSetting ) ) {
|
||||
if ( "class".equalsIgnoreCase( token ) ) {
|
||||
context.setDetectClasses( true );
|
||||
}
|
||||
if ( "hbm".equalsIgnoreCase( token ) ) {
|
||||
context.setDetectClasses( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scanInContext(
|
||||
Scanner scanner,
|
||||
ScanningContext scanningContext,
|
||||
ScanResult scanResult) {
|
||||
if ( scanningContext.getUrl() == null ) {
|
||||
// not sure i like just ignoring this being null, but this is exactly what the old code does...
|
||||
LOG.containerProvidingNullPersistenceUnitRootUrl();
|
||||
return;
|
||||
}
|
||||
if ( scanningContext.getUrl().getProtocol().equalsIgnoreCase( "bundle" ) ) {
|
||||
// TODO: Is there a way to scan the root bundle URL in OSGi containers?
|
||||
// Although the URL provides a stream handler that works for finding
|
||||
// resources in a specific Bundle, the root one does not work.
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if ( scanningContext.isDetectClasses() ) {
|
||||
Set<Package> matchingPackages = scanner.getPackagesInJar( scanningContext.url, new HashSet<Class<? extends Annotation>>(0) );
|
||||
for ( Package pkg : matchingPackages ) {
|
||||
scanResult.getPackageNames().add( pkg.getName() );
|
||||
}
|
||||
|
||||
Set<Class<? extends Annotation>> annotationsToLookFor = new HashSet<Class<? extends Annotation>>();
|
||||
annotationsToLookFor.add( Entity.class );
|
||||
annotationsToLookFor.add( MappedSuperclass.class );
|
||||
annotationsToLookFor.add( Embeddable.class );
|
||||
annotationsToLookFor.add( Converter.class );
|
||||
Set<Class<?>> matchingClasses = scanner.getClassesInJar( scanningContext.url, annotationsToLookFor );
|
||||
for ( Class<?> clazz : matchingClasses ) {
|
||||
scanResult.getManagedClassNames().add( clazz.getName() );
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> patterns = new HashSet<String>();
|
||||
if ( scanningContext.isSearchOrm() ) {
|
||||
patterns.add( META_INF_ORM_XML );
|
||||
}
|
||||
if ( scanningContext.isDetectHbmFiles() ) {
|
||||
patterns.add( "**/*.hbm.xml" );
|
||||
}
|
||||
if ( ! scanResult.getMappingFiles().isEmpty() ) {
|
||||
patterns.addAll( scanResult.getMappingFiles() );
|
||||
}
|
||||
if ( patterns.size() != 0 ) {
|
||||
Set<NamedInputStream> files = scanner.getFilesInJar( scanningContext.getUrl(), patterns );
|
||||
for ( NamedInputStream file : files ) {
|
||||
scanResult.getHbmFiles().add( file );
|
||||
scanResult.getMappingFiles().remove( file.getName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (PersistenceException e ) {
|
||||
throw e;
|
||||
}
|
||||
catch ( RuntimeException e ) {
|
||||
throw persistenceException( "error trying to scan url: " + scanningContext.getUrl().toString(), e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityManagerFactoryBuilder withValidatorFactory(Object validatorFactory) {
|
||||
this.validatorFactory = validatorFactory;
|
||||
|
@ -1094,14 +1114,28 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
//addInputStream has the responsibility to close the stream
|
||||
cfg.addInputStream( new BufferedInputStream( namedInputStream.getStream() ) );
|
||||
}
|
||||
catch (MappingException me) {
|
||||
//try our best to give the file name
|
||||
if ( StringHelper.isEmpty( namedInputStream.getName() ) ) {
|
||||
throw me;
|
||||
catch ( InvalidMappingException e ) {
|
||||
// try our best to give the file name
|
||||
if ( StringHelper.isNotEmpty( namedInputStream.getName() ) ) {
|
||||
throw new InvalidMappingException(
|
||||
"Error while parsing file: " + namedInputStream.getName(),
|
||||
e.getType(),
|
||||
e.getPath(),
|
||||
e
|
||||
);
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
catch (MappingException me) {
|
||||
// try our best to give the file name
|
||||
if ( StringHelper.isNotEmpty( namedInputStream.getName() ) ) {
|
||||
throw new MappingException("Error while parsing file: " + namedInputStream.getName(), me );
|
||||
}
|
||||
else {
|
||||
throw me;
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( String packageName : metadataSources.packageNames ) {
|
||||
|
@ -1176,68 +1210,6 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
}
|
||||
}
|
||||
|
||||
public static class ScanningContext {
|
||||
private URL url;
|
||||
private boolean detectClasses;
|
||||
private boolean detectHbmFiles;
|
||||
private boolean searchOrm;
|
||||
|
||||
public URL getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(URL url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public boolean isDetectClasses() {
|
||||
return detectClasses;
|
||||
}
|
||||
|
||||
public void setDetectClasses(boolean detectClasses) {
|
||||
this.detectClasses = detectClasses;
|
||||
}
|
||||
|
||||
public boolean isDetectHbmFiles() {
|
||||
return detectHbmFiles;
|
||||
}
|
||||
|
||||
public void setDetectHbmFiles(boolean detectHbmFiles) {
|
||||
this.detectHbmFiles = detectHbmFiles;
|
||||
}
|
||||
|
||||
public boolean isSearchOrm() {
|
||||
return searchOrm;
|
||||
}
|
||||
|
||||
public void setSearchOrm(boolean searchOrm) {
|
||||
this.searchOrm = searchOrm;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ScanResult {
|
||||
private final List<String> managedClassNames = new ArrayList<String>();
|
||||
private final List<String> packageNames = new ArrayList<String>();
|
||||
private final List<NamedInputStream> hbmFiles = new ArrayList<NamedInputStream>();
|
||||
private final List<String> mappingFiles = new ArrayList<String>();
|
||||
|
||||
public List<String> getManagedClassNames() {
|
||||
return managedClassNames;
|
||||
}
|
||||
|
||||
public List<String> getPackageNames() {
|
||||
return packageNames;
|
||||
}
|
||||
|
||||
public List<NamedInputStream> getHbmFiles() {
|
||||
return hbmFiles;
|
||||
}
|
||||
|
||||
public List<String> getMappingFiles() {
|
||||
return mappingFiles;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MetadataSources {
|
||||
private final List<String> annotatedMappingClassNames = new ArrayList<String>();
|
||||
private final List<ConverterDescriptor> converterDescriptors = new ArrayList<ConverterDescriptor>();
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.internal;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveException;
|
||||
import org.hibernate.jpa.boot.spi.InputStreamAccess;
|
||||
import org.hibernate.jpa.boot.spi.NamedInputStream;
|
||||
|
||||
/**
|
||||
* An InputStreamAccess implementation based on a File reference
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class FileInputStreamAccess implements InputStreamAccess {
|
||||
private final String name;
|
||||
private final File file;
|
||||
|
||||
public FileInputStreamAccess(String name, File file) {
|
||||
this.name = name;
|
||||
this.file = file;
|
||||
if ( ! file.exists() ) {
|
||||
throw new HibernateException( "File must exist : " + file.getAbsolutePath() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStreamName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream accessInputStream() {
|
||||
try {
|
||||
return new BufferedInputStream( new FileInputStream( file ) );
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
// should never ever ever happen, but...
|
||||
throw new ArchiveException(
|
||||
"File believed to exist based on File.exists threw error when passed to FileInputStream ctor",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamedInputStream asNamedInputStream() {
|
||||
return new NamedInputStream( getStreamName(), accessInputStream() );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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.internal;
|
||||
|
||||
import org.hibernate.jpa.boot.spi.InputStreamAccess;
|
||||
import org.hibernate.jpa.boot.spi.MappingFileDescriptor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class MappingFileDescriptorImpl implements MappingFileDescriptor {
|
||||
private final String name;
|
||||
private final InputStreamAccess streamAccess;
|
||||
|
||||
public MappingFileDescriptorImpl(String name, InputStreamAccess streamAccess) {
|
||||
this.name = name;
|
||||
this.streamAccess = streamAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStreamAccess getStreamAccess() {
|
||||
return streamAccess;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean equals(Object o) {
|
||||
// if ( this == o ) {
|
||||
// return true;
|
||||
// }
|
||||
// if ( o == null || getClass() != o.getClass() ) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// MappingFileDescriptorImpl that = (MappingFileDescriptorImpl) o;
|
||||
//
|
||||
// return name.equals( that.name )
|
||||
// && streamAccess.getStreamName().equals( that.streamAccess.getStreamName() );
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int hashCode() {
|
||||
// int result = name.hashCode();
|
||||
// result = 31 * result + streamAccess.getStreamName().hashCode();
|
||||
// return result;
|
||||
// }
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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.internal;
|
||||
|
||||
import org.hibernate.jpa.boot.spi.InputStreamAccess;
|
||||
import org.hibernate.jpa.boot.spi.PackageDescriptor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class PackageDescriptorImpl implements PackageDescriptor {
|
||||
private final String name;
|
||||
private final InputStreamAccess streamAccess;
|
||||
|
||||
public PackageDescriptorImpl(String name, InputStreamAccess streamAccess) {
|
||||
this.name = name;
|
||||
this.streamAccess = streamAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStreamAccess getStreamAccess() {
|
||||
return streamAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PackageDescriptorImpl that = (PackageDescriptorImpl) o;
|
||||
return name.equals( that.name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
}
|
|
@ -54,8 +54,8 @@ import org.xml.sax.SAXException;
|
|||
import org.xml.sax.SAXParseException;
|
||||
|
||||
import org.hibernate.jpa.AvailableSettings;
|
||||
import org.hibernate.jpa.boot.archive.internal.ArchiveHelper;
|
||||
import org.hibernate.jpa.internal.EntityManagerMessageLogger;
|
||||
import org.hibernate.jpa.packaging.internal.JarVisitorFactory;
|
||||
import org.hibernate.jpa.internal.util.ConfigurationHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.metamodel.source.XsdException;
|
||||
|
@ -121,7 +121,7 @@ public class PersistenceXmlParser {
|
|||
final Element element = (Element) children.item( i );
|
||||
final String tag = element.getTagName();
|
||||
if ( tag.equals( "persistence-unit" ) ) {
|
||||
final URL puRootUrl = JarVisitorFactory.getJarURLFromURLEntry( xmlUrl, "/META-INF/persistence.xml" );
|
||||
final URL puRootUrl = ArchiveHelper.getJarURLFromURLEntry( xmlUrl, "/META-INF/persistence.xml" );
|
||||
ParsedPersistenceXmlDescriptor persistenceUnit = new ParsedPersistenceXmlDescriptor( puRootUrl );
|
||||
bindPersistenceUnit( persistenceUnit, element );
|
||||
|
||||
|
@ -214,7 +214,7 @@ public class PersistenceXmlParser {
|
|||
persistenceUnit.addMappingFiles( extractContent( element ) );
|
||||
}
|
||||
else if ( tag.equals( "jar-file" ) ) {
|
||||
persistenceUnit.addJarFileUrl( JarVisitorFactory.getURLFromPath( extractContent( element ) ) );
|
||||
persistenceUnit.addJarFileUrl( ArchiveHelper.getURLFromPath( extractContent( element ) ) );
|
||||
}
|
||||
else if ( tag.equals( "exclude-unlisted-classes" ) ) {
|
||||
persistenceUnit.setExcludeUnlistedClasses( true );
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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.internal;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.jpa.boot.spi.InputStreamAccess;
|
||||
import org.hibernate.jpa.boot.spi.NamedInputStream;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class UrlInputStreamAccess implements InputStreamAccess {
|
||||
private final URL url;
|
||||
|
||||
public UrlInputStreamAccess(URL url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStreamName() {
|
||||
return url.toExternalForm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream accessInputStream() {
|
||||
try {
|
||||
return url.openStream();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new HibernateException( "Could not open url stream : " + url.toExternalForm() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamedInputStream asNamedInputStream() {
|
||||
return new NamedInputStream( getStreamName(), accessInputStream() );
|
||||
}
|
||||
}
|
|
@ -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.internal;
|
||||
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanOptions;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardScanOptions implements ScanOptions {
|
||||
private final boolean detectClassesInRoot;
|
||||
private final boolean detectClassesInNonRoot;
|
||||
private final boolean detectHibernateMappingFiles;
|
||||
|
||||
public StandardScanOptions() {
|
||||
this( "hbm,class", false );
|
||||
}
|
||||
|
||||
public StandardScanOptions(String explicitDetectionSetting, boolean persistenceUnitExcludeUnlistedClassesValue) {
|
||||
if ( explicitDetectionSetting == null ) {
|
||||
detectHibernateMappingFiles = true;
|
||||
detectClassesInRoot = ! persistenceUnitExcludeUnlistedClassesValue;
|
||||
detectClassesInNonRoot = true;
|
||||
}
|
||||
else {
|
||||
detectHibernateMappingFiles = explicitDetectionSetting.contains( "hbm" );
|
||||
detectClassesInRoot = explicitDetectionSetting.contains( "class" );
|
||||
detectClassesInNonRoot = detectClassesInRoot;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDetectUnlistedClassesInRoot() {
|
||||
return detectClassesInRoot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDetectUnlistedClassesInNonRoot() {
|
||||
return detectClassesInNonRoot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDetectHibernateMappingFiles() {
|
||||
return detectHibernateMappingFiles;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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.internal;
|
||||
|
||||
import org.hibernate.jpa.boot.archive.internal.StandardArchiveDescriptorFactory;
|
||||
import org.hibernate.jpa.boot.scan.spi.AbstractScannerImpl;
|
||||
|
||||
/**
|
||||
* Standard implementation of the Scanner contract, supporting typical archive walking support where
|
||||
* the urls we are processing can be treated using normal file handling.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class StandardScanner extends AbstractScannerImpl {
|
||||
public StandardScanner() {
|
||||
super( StandardArchiveDescriptorFactory.INSTANCE );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
* 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, false, 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;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ArchiveDescriptorInfo {
|
||||
private final ArchiveDescriptor archiveDescriptor;
|
||||
private final boolean isRoot;
|
||||
private final ScanOptions scanOptions;
|
||||
|
||||
private 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* 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 javax.persistence.Converter;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javassist.bytecode.AnnotationsAttribute;
|
||||
import javassist.bytecode.ClassFile;
|
||||
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntryHandler;
|
||||
import org.hibernate.jpa.boot.archive.spi.ArchiveException;
|
||||
import org.hibernate.jpa.boot.internal.ClassDescriptorImpl;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanOptions;
|
||||
import org.hibernate.jpa.boot.spi.ClassDescriptor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ClassFileArchiveEntryHandler implements ArchiveEntryHandler {
|
||||
private final ScanOptions scanOptions;
|
||||
private final Callback callback;
|
||||
|
||||
public static interface Callback {
|
||||
public void locatedClass(ClassDescriptor classDescriptor);
|
||||
}
|
||||
|
||||
public ClassFileArchiveEntryHandler(ScanOptions scanOptions, Callback callback) {
|
||||
this.scanOptions = scanOptions;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEntry(ArchiveEntry entry, ArchiveContext context) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
notifyMatchedClass( classDescriptor );
|
||||
}
|
||||
|
||||
private ClassFile toClassFile(ArchiveEntry entry) {
|
||||
final InputStream inputStream = entry.getStreamAccess().accessInputStream();
|
||||
final DataInputStream dataInputStream = new DataInputStream( inputStream );
|
||||
try {
|
||||
return new ClassFile( dataInputStream );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new ArchiveException( "Could not build ClassFile" );
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
dataInputStream.close();
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
}
|
||||
|
||||
try {
|
||||
inputStream.close();
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SimplifiableIfStatement")
|
||||
private boolean containsClassAnnotationsOfInterest(ClassFile cf) {
|
||||
final AnnotationsAttribute visibleAnnotations = (AnnotationsAttribute) cf.getAttribute( AnnotationsAttribute.visibleTag );
|
||||
if ( visibleAnnotations == null ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return visibleAnnotations.getAnnotation( Entity.class.getName() ) != null
|
||||
|| visibleAnnotations.getAnnotation( MappedSuperclass.class.getName() ) != null
|
||||
|| visibleAnnotations.getAnnotation( Embeddable.class.getName() ) != null
|
||||
|| visibleAnnotations.getAnnotation( Converter.class.getName() ) != null;
|
||||
}
|
||||
|
||||
protected ClassDescriptor toClassDescriptor(ClassFile classFile, ArchiveEntry entry) {
|
||||
return new ClassDescriptorImpl( classFile.getName(), entry.getStreamAccess() );
|
||||
}
|
||||
|
||||
protected final void notifyMatchedClass(ClassDescriptor classDescriptor) {
|
||||
callback.locatedClass( classDescriptor );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NonClassFileArchiveEntryHandler implements ArchiveEntryHandler {
|
||||
private final ScanOptions scanOptions;
|
||||
private final Callback callback;
|
||||
|
||||
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.getName().endsWith( "hbm.xml" ) ) {
|
||||
return scanOptions.canDetectHibernateMappingFiles();
|
||||
}
|
||||
|
||||
// todo : should really do this case-insensitively
|
||||
if ( entry.getName().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() );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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.PackageDescriptorImpl;
|
||||
import org.hibernate.jpa.boot.spi.PackageDescriptor;
|
||||
|
||||
import static java.io.File.separatorChar;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class PackageInfoArchiveEntryHandler implements ArchiveEntryHandler {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
||||
private final ScanOptions scanOptions;
|
||||
private final Callback callback;
|
||||
|
||||
public static interface Callback {
|
||||
public void locatedPackage(PackageDescriptor packageDescriptor);
|
||||
}
|
||||
|
||||
public PackageInfoArchiveEntryHandler(ScanOptions scanOptions, Callback callback) {
|
||||
this.scanOptions = scanOptions;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEntry(ArchiveEntry entry, ArchiveContext context) {
|
||||
if ( entry.getNameWithinArchive().equals( "package-info.class" ) ) {
|
||||
// the old code skipped package-info in the root package/dir...
|
||||
return;
|
||||
}
|
||||
notifyMatchedPackage( toPackageDescriptor( entry ) );
|
||||
}
|
||||
|
||||
protected PackageDescriptor toPackageDescriptor(ArchiveEntry entry) {
|
||||
final String packageInfoFilePath = entry.getNameWithinArchive();
|
||||
final String packageName = packageInfoFilePath.substring( 0, packageInfoFilePath.lastIndexOf( '/' ) )
|
||||
.replace( separatorChar, '.' );
|
||||
|
||||
return new PackageDescriptorImpl( packageName, entry.getStreamAccess() );
|
||||
}
|
||||
|
||||
protected final void notifyMatchedPackage(PackageDescriptor packageDescriptor) {
|
||||
callback.locatedPackage( packageDescriptor );
|
||||
}
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
|
||||
* 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 Middleware LLC.
|
||||
* 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
|
||||
|
@ -19,20 +21,14 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.packaging.internal;
|
||||
|
||||
package org.hibernate.jpa.boot.scan.spi;
|
||||
|
||||
/**
|
||||
* Filter on pachage element
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
* @see JavaElementFilter
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class PackageFilter extends JavaElementFilter {
|
||||
/**
|
||||
* @see JavaElementFilter#JavaElementFilter(boolean, Class[])
|
||||
*/
|
||||
protected PackageFilter(boolean retrieveStream, Class[] annotations) {
|
||||
super( retrieveStream, annotations );
|
||||
}
|
||||
public interface ScanOptions {
|
||||
public boolean canDetectUnlistedClassesInRoot();
|
||||
public boolean canDetectUnlistedClassesInNonRoot();
|
||||
|
||||
public boolean canDetectHibernateMappingFiles();
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.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
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ScanResult {
|
||||
public Set<PackageDescriptor> getLocatedPackages();
|
||||
public Set<ClassDescriptor> getLocatedClasses();
|
||||
public Set<MappingFileDescriptor> getLocatedMappingFiles();
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.boot.scan.spi;
|
||||
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
|
||||
/**
|
||||
* Defines the contract for Hibernate to be able to scan for classes, packages and resources inside a
|
||||
* persistence unit.
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface Scanner {
|
||||
/**
|
||||
* Perform the scanning against the described persistence unit using the defined options, and return the scan
|
||||
* results.
|
||||
*
|
||||
* @param persistenceUnit THe description of the persistence unit.
|
||||
* @param options The scan options
|
||||
*
|
||||
* @return The scan results.
|
||||
*/
|
||||
public ScanResult scan(PersistenceUnitDescriptor persistenceUnit, ScanOptions options);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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.spi;
|
||||
|
||||
/**
|
||||
* Defines the result of scanning a persistence unit for classes.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ClassDescriptor {
|
||||
public String getName();
|
||||
public InputStreamAccess getStreamAccess();
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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.spi;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Contract for building InputStreams, especially in on-demand situations
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface InputStreamAccess {
|
||||
/**
|
||||
* Get the name of the resource backing the stream
|
||||
*
|
||||
* @return The backing resource name
|
||||
*/
|
||||
public String getStreamName();
|
||||
|
||||
/**
|
||||
* Get access to the stream. Can be called multiple times, a different stream instance should be returned each time.
|
||||
*
|
||||
* @return The stream
|
||||
*/
|
||||
public InputStream accessInputStream();
|
||||
|
||||
/**
|
||||
* @deprecated Needed until we can remove NamedInputStream
|
||||
*/
|
||||
public NamedInputStream asNamedInputStream();
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.spi;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface MappingFileDescriptor {
|
||||
public String getName();
|
||||
public InputStreamAccess getStreamAccess();
|
||||
}
|
|
@ -21,34 +21,33 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.packaging.spi;
|
||||
package org.hibernate.jpa.boot.spi;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@Deprecated
|
||||
public class NamedInputStream {
|
||||
private final String name;
|
||||
private final InputStream stream;
|
||||
|
||||
public NamedInputStream(String name, InputStream stream) {
|
||||
this.name = name;
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
private String name;
|
||||
private InputStream stream;
|
||||
|
||||
public InputStream getStream() {
|
||||
return stream;
|
||||
}
|
||||
|
||||
public void setStream(InputStream stream) {
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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.spi;
|
||||
|
||||
/**
|
||||
* Defines the result of scanning a persistence unit for packages.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface PackageDescriptor {
|
||||
public String getName();
|
||||
public InputStreamAccess getStreamAccess();
|
||||
}
|
|
@ -1,262 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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.packaging.internal;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javassist.bytecode.AnnotationsAttribute;
|
||||
import javassist.bytecode.ClassFile;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.jpa.internal.EntityManagerMessageLogger;
|
||||
|
||||
/**
|
||||
* Parse a JAR of any form (zip file, exploded directory, ...)
|
||||
* apply a set of filters (File filter, Class filter, Package filter)
|
||||
* and return the appropriate matching sets of elements
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public abstract class AbstractJarVisitor implements JarVisitor {
|
||||
|
||||
//TODO shortcut when filters are null or empty
|
||||
|
||||
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(EntityManagerMessageLogger.class,
|
||||
AbstractJarVisitor.class.getName());
|
||||
|
||||
protected String unqualifiedJarName;
|
||||
protected URL jarUrl;
|
||||
protected boolean done = false;
|
||||
private List<Filter> filters = new ArrayList<Filter>();
|
||||
private Set<FileFilter> fileFilters = new HashSet<FileFilter>();
|
||||
private Set<JavaElementFilter> classFilters = new HashSet<JavaElementFilter>();
|
||||
private Set<JavaElementFilter> packageFilters = new HashSet<JavaElementFilter>();
|
||||
private Set[] entries;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Build a jar visitor from its jar string path
|
||||
*/
|
||||
private AbstractJarVisitor(String jarPath) {
|
||||
this.jarUrl = JarVisitorFactory.getURLFromPath( jarPath );
|
||||
unqualify();
|
||||
}
|
||||
|
||||
protected AbstractJarVisitor(String fileName, Filter[] filters) {
|
||||
this( fileName );
|
||||
initFilters( filters );
|
||||
}
|
||||
|
||||
private void initFilters(Filter[] filters) {
|
||||
for ( Filter filter : filters ) {
|
||||
if ( filter instanceof FileFilter ) {
|
||||
fileFilters.add( (FileFilter) filter );
|
||||
}
|
||||
else if ( filter instanceof ClassFilter ) {
|
||||
classFilters.add( (ClassFilter) filter );
|
||||
}
|
||||
else if ( filter instanceof PackageFilter ) {
|
||||
packageFilters.add( (PackageFilter) filter );
|
||||
}
|
||||
else {
|
||||
throw new AssertionError( "Unknown filter type: " + filter.getClass().getName() );
|
||||
}
|
||||
this.filters.add( filter );
|
||||
}
|
||||
int size = this.filters.size();
|
||||
this.entries = new Set[ size ];
|
||||
for ( int index = 0; index < size ; index++ ) {
|
||||
this.entries[index] = new HashSet<Entry>();
|
||||
}
|
||||
}
|
||||
|
||||
protected AbstractJarVisitor(URL url, Filter[] filters) {
|
||||
this( url );
|
||||
initFilters( filters );
|
||||
}
|
||||
|
||||
private AbstractJarVisitor(URL url) {
|
||||
jarUrl = url;
|
||||
unqualify();
|
||||
}
|
||||
|
||||
protected void unqualify() {
|
||||
//FIXME weak algorithm subject to AOOBE
|
||||
String fileName = jarUrl.getFile();
|
||||
int exclamation = fileName.lastIndexOf( "!" );
|
||||
if (exclamation != -1) fileName = fileName.substring( 0, exclamation );
|
||||
int slash = fileName.lastIndexOf( "/" );
|
||||
if ( slash != -1 ) {
|
||||
fileName = fileName.substring(
|
||||
fileName.lastIndexOf( "/" ) + 1,
|
||||
fileName.length()
|
||||
);
|
||||
}
|
||||
if ( fileName.length() > 4 && fileName.endsWith( "ar" ) && fileName.charAt( fileName.length() - 4 ) == '.' ) {
|
||||
fileName = fileName.substring( 0, fileName.length() - 4 );
|
||||
}
|
||||
unqualifiedJarName = fileName;
|
||||
LOG.debugf("Searching mapped entities in jar/par: %s", jarUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unqualified Jar name (ie wo path and wo extension)
|
||||
*/
|
||||
public String getUnqualifiedJarName() {
|
||||
return unqualifiedJarName;
|
||||
}
|
||||
|
||||
public Filter[] getFilters() {
|
||||
return filters.toArray( new Filter[ filters.size() ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the matching entries for each filter in the same order the filter where passed
|
||||
*
|
||||
* @return array of Set of JarVisitor.Entry
|
||||
* @throws IOException if something went wrong
|
||||
*/
|
||||
public Set[] getMatchingEntries() throws IOException {
|
||||
if ( !done ) {
|
||||
//avoid url access and so on
|
||||
if ( filters.size() > 0 ) doProcessElements();
|
||||
done = true;
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
protected abstract void doProcessElements() throws IOException;
|
||||
|
||||
//TODO avoid 2 input stream when not needed
|
||||
protected final void addElement(String entryName, InputStream is, InputStream secondIs) throws IOException {
|
||||
int entryNameLength = entryName.length();
|
||||
if ( entryName.endsWith( "package-info.class" ) ) {
|
||||
String name;
|
||||
if ( entryNameLength == "package-info.class".length() ) {
|
||||
name = "";
|
||||
}
|
||||
else {
|
||||
name = entryName.substring( 0, entryNameLength - ".package-info.class".length() ).replace( '/', '.' );
|
||||
}
|
||||
executeJavaElementFilter( name, packageFilters, is, secondIs );
|
||||
}
|
||||
else if ( entryName.endsWith( ".class" ) ) {
|
||||
String name = entryName.substring( 0, entryNameLength - ".class".length() ).replace( '/', '.' );
|
||||
LOG.debugf("Filtering: %s", name);
|
||||
executeJavaElementFilter( name, classFilters, is, secondIs );
|
||||
}
|
||||
else {
|
||||
String name = entryName;
|
||||
boolean accepted = false;
|
||||
for ( FileFilter filter : fileFilters ) {
|
||||
if ( filter.accept( name ) ) {
|
||||
accepted = true;
|
||||
InputStream localIs;
|
||||
if ( filter.getStream() ) {
|
||||
localIs = secondIs;
|
||||
}
|
||||
else {
|
||||
localIs = null;
|
||||
secondIs.close();
|
||||
}
|
||||
is.close();
|
||||
LOG.debugf("File Filter matched for %s", name);
|
||||
Entry entry = new Entry( name, localIs );
|
||||
int index = this.filters.indexOf( filter );
|
||||
this.entries[index].add( entry );
|
||||
}
|
||||
}
|
||||
if (!accepted) {
|
||||
//not accepted free resources
|
||||
is.close();
|
||||
secondIs.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void executeJavaElementFilter(
|
||||
String name, Set<JavaElementFilter> filters, InputStream is, InputStream secondIs
|
||||
) throws IOException {
|
||||
boolean accepted = false;
|
||||
for ( JavaElementFilter filter : filters ) {
|
||||
if ( filter.accept( name ) ) {
|
||||
//FIXME cannot currently have a class filtered twice but matching once
|
||||
// need to copy the is
|
||||
boolean match = checkAnnotationMatching( is, filter );
|
||||
if ( match ) {
|
||||
accepted = true;
|
||||
InputStream localIs;
|
||||
if ( filter.getStream() ) {
|
||||
localIs = secondIs;
|
||||
}
|
||||
else {
|
||||
localIs = null;
|
||||
secondIs.close();
|
||||
}
|
||||
LOG.debugf("Java element filter matched for %s", name);
|
||||
Entry entry = new Entry( name, localIs );
|
||||
int index = this.filters.indexOf( filter );
|
||||
this.entries[index].add( entry );
|
||||
break; //we matched
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!accepted) {
|
||||
is.close();
|
||||
secondIs.close();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkAnnotationMatching(InputStream is, JavaElementFilter filter) throws IOException {
|
||||
if ( filter.getAnnotations().length == 0 ) {
|
||||
is.close();
|
||||
return true;
|
||||
}
|
||||
DataInputStream dstream = new DataInputStream( is );
|
||||
ClassFile cf = null;
|
||||
|
||||
try {
|
||||
cf = new ClassFile( dstream );
|
||||
}
|
||||
finally {
|
||||
dstream.close();
|
||||
is.close();
|
||||
}
|
||||
boolean match = false;
|
||||
AnnotationsAttribute visible = (AnnotationsAttribute) cf.getAttribute( AnnotationsAttribute.visibleTag );
|
||||
if ( visible != null ) {
|
||||
for ( Class annotation : filter.getAnnotations() ) {
|
||||
match = visible.getAnnotation( annotation.getName() ) != null;
|
||||
if ( match ) break;
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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.packaging.internal;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.jpa.internal.EntityManagerMessageLogger;
|
||||
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class ExplodedJarVisitor extends AbstractJarVisitor {
|
||||
|
||||
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(EntityManagerMessageLogger.class,
|
||||
ExplodedJarVisitor.class.getName());
|
||||
|
||||
private String entry;
|
||||
|
||||
public ExplodedJarVisitor(URL url, Filter[] filters, String entry) {
|
||||
super( url, filters );
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
public ExplodedJarVisitor(String fileName, Filter[] filters) {
|
||||
super( fileName, filters );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doProcessElements() throws IOException {
|
||||
File jarFile;
|
||||
try {
|
||||
String filePart = jarUrl.getFile();
|
||||
if ( filePart != null && filePart.indexOf( ' ' ) != -1 ) {
|
||||
//unescaped (from the container), keep as is
|
||||
jarFile = new File( jarUrl.getFile() );
|
||||
}
|
||||
else {
|
||||
jarFile = new File( jarUrl.toURI().getSchemeSpecificPart() );
|
||||
}
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
LOG.malformedUrl(jarUrl, e);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !jarFile.exists() ) {
|
||||
LOG.explodedJarDoesNotExist(jarUrl);
|
||||
return;
|
||||
}
|
||||
if ( !jarFile.isDirectory() ) {
|
||||
LOG.explodedJarNotDirectory(jarUrl);
|
||||
return;
|
||||
}
|
||||
File rootFile;
|
||||
if (entry != null && entry.length() > 0 && ! "/".equals( entry ) ) {
|
||||
rootFile = new File(jarFile, entry);
|
||||
}
|
||||
else {
|
||||
rootFile = jarFile;
|
||||
}
|
||||
if ( rootFile.isDirectory() ) {
|
||||
getClassNamesInTree( rootFile, null );
|
||||
}
|
||||
else {
|
||||
//assume zipped file
|
||||
processZippedRoot(rootFile);
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME shameful copy of FileZippedJarVisitor.doProcess()
|
||||
//TODO long term fix is to introduce a process interface (closure like) to addElements and then share the code
|
||||
private void processZippedRoot(File rootFile) throws IOException {
|
||||
JarFile jarFile = new JarFile(rootFile);
|
||||
Enumeration<? extends ZipEntry> entries = jarFile.entries();
|
||||
while ( entries.hasMoreElements() ) {
|
||||
ZipEntry zipEntry = entries.nextElement();
|
||||
String name = zipEntry.getName();
|
||||
if ( !zipEntry.isDirectory() ) {
|
||||
//build relative name
|
||||
if ( name.startsWith( "/" ) ) name = name.substring( 1 );
|
||||
addElement(
|
||||
name,
|
||||
new BufferedInputStream( jarFile.getInputStream( zipEntry ) ),
|
||||
new BufferedInputStream( jarFile.getInputStream( zipEntry ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getClassNamesInTree(File jarFile, String header) throws IOException {
|
||||
File[] files = jarFile.listFiles();
|
||||
header = header == null ? "" : header + "/";
|
||||
for ( File localFile : files ) {
|
||||
if ( !localFile.isDirectory() ) {
|
||||
String entryName = localFile.getName();
|
||||
addElement(
|
||||
header + entryName,
|
||||
new BufferedInputStream( new FileInputStream( localFile ) ),
|
||||
new BufferedInputStream( new FileInputStream( localFile ) )
|
||||
);
|
||||
|
||||
}
|
||||
else {
|
||||
getClassNamesInTree( localFile, header + localFile.getName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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.packaging.internal;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarInputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.jpa.internal.EntityManagerMessageLogger;
|
||||
|
||||
/**
|
||||
* Work on a JAR that can be accessed through a File
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class FileZippedJarVisitor extends AbstractJarVisitor {
|
||||
|
||||
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(EntityManagerMessageLogger.class,
|
||||
FileZippedJarVisitor.class.getName());
|
||||
|
||||
private String entry;
|
||||
|
||||
public FileZippedJarVisitor(String fileName, Filter[] filters) {
|
||||
super( fileName, filters );
|
||||
}
|
||||
|
||||
public FileZippedJarVisitor(URL url, Filter[] filters, String entry) {
|
||||
super( url, filters );
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doProcessElements() throws IOException {
|
||||
JarFile jarFile;
|
||||
try {
|
||||
String filePart = jarUrl.getFile();
|
||||
if ( filePart != null && filePart.indexOf( ' ' ) != -1 ) {
|
||||
//unescaped (from the container), keep as is
|
||||
jarFile = new JarFile( jarUrl.getFile() );
|
||||
}
|
||||
else {
|
||||
jarFile = new JarFile( jarUrl.toURI().getSchemeSpecificPart() );
|
||||
}
|
||||
}
|
||||
catch (IOException ze) {
|
||||
LOG.unableToFindFile(jarUrl, ze);
|
||||
return;
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
LOG.malformedUrlWarning(jarUrl, e);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( entry != null && entry.length() == 1 ) entry = null; //no entry
|
||||
if ( entry != null && entry.startsWith( "/" ) ) entry = entry.substring( 1 ); //remove '/' header
|
||||
|
||||
Enumeration<? extends ZipEntry> entries = jarFile.entries();
|
||||
while ( entries.hasMoreElements() ) {
|
||||
ZipEntry zipEntry = entries.nextElement();
|
||||
String name = zipEntry.getName();
|
||||
if ( entry != null && ! name.startsWith( entry ) ) continue; //filter it out
|
||||
if ( !zipEntry.isDirectory() ) {
|
||||
if ( name.equals( entry ) ) {
|
||||
//exact match, might be a nested jar entry (ie from jar:file:..../foo.ear!/bar.jar)
|
||||
/*
|
||||
* This algorithm assumes that the zipped file is only the URL root (including entry), not just any random entry
|
||||
*/
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = new BufferedInputStream( jarFile.getInputStream( zipEntry ) );
|
||||
JarInputStream jis = new JarInputStream( is );
|
||||
ZipEntry subZipEntry = jis.getNextEntry();
|
||||
while (subZipEntry != null) {
|
||||
if ( ! subZipEntry.isDirectory() ) {
|
||||
//FIXME copy sucks
|
||||
byte[] entryBytes = JarVisitorFactory.getBytesFromInputStream( jis );
|
||||
String subname = subZipEntry.getName();
|
||||
if ( subname.startsWith( "/" ) ) subname = subname.substring( 1 );
|
||||
addElement(
|
||||
subname,
|
||||
new ByteArrayInputStream(entryBytes),
|
||||
new ByteArrayInputStream(entryBytes)
|
||||
);
|
||||
}
|
||||
subZipEntry = jis.getNextEntry();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if ( is != null) is.close();
|
||||
}
|
||||
}
|
||||
else {
|
||||
//build relative name
|
||||
if (entry != null) name = name.substring( entry.length() );
|
||||
if ( name.startsWith( "/" ) ) name = name.substring( 1 );
|
||||
addElement(
|
||||
name,
|
||||
new BufferedInputStream( jarFile.getInputStream( zipEntry ) ),
|
||||
new BufferedInputStream( jarFile.getInputStream( zipEntry ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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.packaging.internal;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarInputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.jpa.internal.EntityManagerMessageLogger;
|
||||
|
||||
|
||||
/**
|
||||
* Work on a JAR that can only be accessed through a inputstream
|
||||
* This is less efficient than the {@link FileZippedJarVisitor}
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class InputStreamZippedJarVisitor extends AbstractJarVisitor {
|
||||
|
||||
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(EntityManagerMessageLogger.class,
|
||||
InputStreamZippedJarVisitor.class.getName());
|
||||
|
||||
private String entry;
|
||||
|
||||
public InputStreamZippedJarVisitor(URL url, Filter[] filters, String entry) {
|
||||
super( url, filters );
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
public InputStreamZippedJarVisitor(String fileName, Filter[] filters) {
|
||||
super( fileName, filters );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doProcessElements() throws IOException {
|
||||
JarInputStream jis;
|
||||
try {
|
||||
jis = new JarInputStream( jarUrl.openStream() );
|
||||
}
|
||||
catch (Exception ze) {
|
||||
//really should catch IOException but Eclipse is buggy and raise NPE...
|
||||
LOG.unableToFindFile(jarUrl, ze);
|
||||
return;
|
||||
}
|
||||
if ( entry != null && entry.length() == 1 ) entry = null; //no entry
|
||||
if ( entry != null && entry.startsWith( "/" ) ) entry = entry.substring( 1 ); //remove '/' header
|
||||
|
||||
JarEntry jarEntry;
|
||||
while ( ( jarEntry = jis.getNextJarEntry() ) != null ) {
|
||||
String name = jarEntry.getName();
|
||||
if ( entry != null && ! name.startsWith( entry ) ) continue; //filter it out
|
||||
if ( !jarEntry.isDirectory() ) {
|
||||
if ( name.equals( entry ) ) {
|
||||
//exact match, might be a nested jar entry (ie from jar:file:..../foo.ear!/bar.jar)
|
||||
/*
|
||||
* This algorithm assumes that the zipped file is only the URL root (including entry), not just any random entry
|
||||
*/
|
||||
JarInputStream subJis = null;
|
||||
try {
|
||||
subJis = new JarInputStream( jis );
|
||||
ZipEntry subZipEntry = jis.getNextEntry();
|
||||
while (subZipEntry != null) {
|
||||
if ( ! subZipEntry.isDirectory() ) {
|
||||
//FIXME copy sucks
|
||||
byte[] entryBytes = JarVisitorFactory.getBytesFromInputStream( jis );
|
||||
String subname = subZipEntry.getName();
|
||||
if ( subname.startsWith( "/" ) ) subname = subname.substring( 1 );
|
||||
addElement(
|
||||
subname,
|
||||
new ByteArrayInputStream(entryBytes),
|
||||
new ByteArrayInputStream(entryBytes)
|
||||
);
|
||||
}
|
||||
subZipEntry = jis.getNextJarEntry();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (subJis != null) subJis.close();
|
||||
}
|
||||
}
|
||||
else {
|
||||
byte[] entryBytes = JarVisitorFactory.getBytesFromInputStream( jis );
|
||||
//build relative name
|
||||
if (entry != null) name = name.substring( entry.length() );
|
||||
if ( name.startsWith( "/" ) ) name = name.substring( 1 );
|
||||
//this is bad cause we actually read everything instead of walking it lazily
|
||||
addElement(
|
||||
name,
|
||||
new ByteArrayInputStream( entryBytes ),
|
||||
new ByteArrayInputStream( entryBytes )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
jis.close();
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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.packaging.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.annotations.common.AssertionFailure;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class JarProtocolVisitor implements JarVisitor {
|
||||
private JarVisitor delegate;
|
||||
private URL jarUrl;
|
||||
private Filter[] filters;
|
||||
|
||||
public JarProtocolVisitor(URL url, Filter[] filters, String entry) {
|
||||
this.jarUrl = url;
|
||||
this.filters = filters;
|
||||
if (entry != null && entry.length() > 0) throw new IllegalArgumentException( "jar:jar: not supported: " + jarUrl );
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
String file = jarUrl.getFile();
|
||||
String entry;
|
||||
int subEntryIndex = file.lastIndexOf( "!" );
|
||||
if (subEntryIndex == -1) throw new AssertionFailure("JAR URL does not contain '!/' :" + jarUrl);
|
||||
if ( subEntryIndex + 1 >= file.length() ) {
|
||||
entry = "";
|
||||
}
|
||||
else {
|
||||
entry = file.substring( subEntryIndex + 1 );
|
||||
}
|
||||
URL fileUrl = JarVisitorFactory.getJarURLFromURLEntry( jarUrl, entry );
|
||||
delegate = JarVisitorFactory.getVisitor( fileUrl, filters, entry );
|
||||
|
||||
}
|
||||
|
||||
public String getUnqualifiedJarName() {
|
||||
return delegate.getUnqualifiedJarName();
|
||||
}
|
||||
|
||||
public Filter[] getFilters() {
|
||||
return delegate.getFilters();
|
||||
}
|
||||
|
||||
public Set[] getMatchingEntries() throws IOException {
|
||||
return delegate.getMatchingEntries();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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.packaging.internal;
|
||||
|
||||
|
||||
/**
|
||||
* Filter a Java element (class or package per fully qualified name and annotation existence)
|
||||
* At least 1 annotation has to annotate the element and the accept method must match
|
||||
* If none annotations are passed, only the accept method must pass.
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public abstract class JavaElementFilter extends Filter {
|
||||
private Class[] annotations;
|
||||
|
||||
/**
|
||||
* @param retrieveStream Give back an open stream to the matching element or not
|
||||
* @param annotations Array of annotations that must be present to match (1 of them should annotate the element
|
||||
*/
|
||||
protected JavaElementFilter(boolean retrieveStream, Class[] annotations) {
|
||||
super( retrieveStream );
|
||||
this.annotations = annotations == null ? new Class[]{} : annotations;
|
||||
}
|
||||
|
||||
public Class[] getAnnotations() {
|
||||
return annotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the fully qualified name match
|
||||
*/
|
||||
public abstract boolean accept(String javaElementName);
|
||||
}
|
|
@ -1,248 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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.packaging.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Converter;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.jpa.packaging.spi.NamedInputStream;
|
||||
import org.hibernate.jpa.packaging.spi.Scanner;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class NativeScanner implements Scanner {
|
||||
|
||||
private static final String META_INF_ORM_XML = "META-INF/orm.xml";
|
||||
|
||||
private Map<URL, StateJarVisitor> visitors = new HashMap<URL, StateJarVisitor>();
|
||||
private static final int PACKAGE_FILTER_INDEX = 0;
|
||||
private static final int CLASS_FILTER_INDEX = 1;
|
||||
private static final int FILE_FILTER_INDEX = 2;
|
||||
|
||||
/**
|
||||
* This implementation does not honor the list of annotations and return everything.
|
||||
* Must strictly be used by HEM
|
||||
*/
|
||||
public Set<Package> getPackagesInJar(URL jarToScan, Set<Class<? extends Annotation>> annotationsToLookFor) {
|
||||
if ( annotationsToLookFor.size() > 0 ) {
|
||||
throw new AssertionFailure( "Improper use of NativeScanner: must not filter packages" );
|
||||
}
|
||||
|
||||
JarVisitor jarVisitor = getVisitor( jarToScan );
|
||||
final Set<Entry> packageEntries;
|
||||
try {
|
||||
packageEntries = ( Set<Entry> ) jarVisitor.getMatchingEntries()[PACKAGE_FILTER_INDEX];
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
throw new RuntimeException( "Error while reading " + jarToScan.toString(), e );
|
||||
}
|
||||
Set<Package> packages = new HashSet<Package>( packageEntries.size() );
|
||||
for ( Entry entry : packageEntries ) {
|
||||
try {
|
||||
packages.add( ReflectHelper.classForName( entry.getName() + ".package-info" ).getPackage() );
|
||||
}
|
||||
catch ( ClassNotFoundException e ) {
|
||||
//should never happen, if it happens, simply ignore the flawed package
|
||||
}
|
||||
}
|
||||
return packages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JarVisitor with some assumptions wrt the scanning
|
||||
* This helps do one scan instead of several
|
||||
*/
|
||||
private JarVisitor getVisitor(URL jar) {
|
||||
StateJarVisitor stateJarVisitor = visitors.get( jar );
|
||||
|
||||
if ( stateJarVisitor == null ) {
|
||||
|
||||
Filter[] filters = new Filter[3];
|
||||
filters[PACKAGE_FILTER_INDEX] = new PackageFilter( false, null ) {
|
||||
public boolean accept(String javaElementName) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
filters[CLASS_FILTER_INDEX] = new ClassFilter(
|
||||
false, new Class[] {
|
||||
Entity.class,
|
||||
MappedSuperclass.class,
|
||||
Embeddable.class
|
||||
}
|
||||
) {
|
||||
public boolean accept(String javaElementName) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
filters[FILE_FILTER_INDEX] = new FileFilter( true ) {
|
||||
public boolean accept(String javaElementName) {
|
||||
return javaElementName.endsWith( "hbm.xml" )
|
||||
|| javaElementName.endsWith( META_INF_ORM_XML );
|
||||
}
|
||||
};
|
||||
|
||||
stateJarVisitor = new StateJarVisitor( JarVisitorFactory.getVisitor( jar, filters ) );
|
||||
visitors.put( jar, stateJarVisitor );
|
||||
}
|
||||
return stateJarVisitor.visitor;
|
||||
}
|
||||
|
||||
public Set<Class<?>> getClassesInJar(URL jarToScan, Set<Class<? extends Annotation>> annotationsToLookFor) {
|
||||
if ( isValidForClasses( annotationsToLookFor ) ) {
|
||||
throw new AssertionFailure(
|
||||
"Improper use of NativeScanner: "
|
||||
+ "must not filter classes by other annotations than Entity, MappedSuperclass, embeddable"
|
||||
);
|
||||
}
|
||||
JarVisitor jarVisitor = getVisitor( jarToScan );
|
||||
final Set<Entry> classesEntry;
|
||||
try {
|
||||
classesEntry = ( Set<Entry> ) jarVisitor.getMatchingEntries()[CLASS_FILTER_INDEX];
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
throw new RuntimeException( "Error while reading " + jarToScan.toString(), e );
|
||||
}
|
||||
Set<Class<?>> classes = new HashSet<Class<?>>( classesEntry.size() );
|
||||
for ( Entry entry : classesEntry ) {
|
||||
try {
|
||||
classes.add( ReflectHelper.classForName( entry.getName() ) );
|
||||
}
|
||||
catch ( ClassNotFoundException e ) {
|
||||
//should never happen, if it happens, simply ignore the flawed package
|
||||
}
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
private boolean isValidForClasses(Set<Class<? extends Annotation>> annotationsToLookFor) {
|
||||
return annotationsToLookFor.size() != 4
|
||||
|| !annotationsToLookFor.contains( Entity.class )
|
||||
|| !annotationsToLookFor.contains( MappedSuperclass.class )
|
||||
|| !annotationsToLookFor.contains( Embeddable.class )
|
||||
|| !annotationsToLookFor.contains( Converter.class );
|
||||
}
|
||||
|
||||
/**
|
||||
* support for patterns is primitive:
|
||||
* - **\/*.hbm.xml
|
||||
* Other patterns will not be found
|
||||
*/
|
||||
public Set<NamedInputStream> getFilesInJar(URL jarToScan, Set<String> filePatterns) {
|
||||
StringBuilder sb = new StringBuilder("URL: ").append( jarToScan )
|
||||
.append( "\n" );
|
||||
for (String pattern : filePatterns) {
|
||||
sb.append( " " ).append( pattern ).append( "\n" );
|
||||
}
|
||||
JarVisitor jarVisitor = getVisitor( jarToScan );
|
||||
|
||||
//state visitor available
|
||||
final StateJarVisitor stateVisitor = visitors.get( jarToScan );
|
||||
if ( stateVisitor.hasReadFiles ) {
|
||||
throw new AssertionFailure( "Cannot read files twice on NativeScanner" );
|
||||
}
|
||||
stateVisitor.hasReadFiles = true;
|
||||
|
||||
Set<String> endWiths = new HashSet<String>();
|
||||
Set<String> exacts = new HashSet<String>();
|
||||
for ( String pattern : filePatterns ) {
|
||||
if ( pattern.startsWith( "**/*" ) ) {
|
||||
final String patternTail = pattern.substring( 4, pattern.length() );
|
||||
if ( !patternTail.equals( ".hbm.xml" ) ) {
|
||||
throw new AssertionFailure(
|
||||
"Improper use of NativeScanner: "
|
||||
+ "must not filter files via pattern other than .hbm.xml"
|
||||
);
|
||||
}
|
||||
endWiths.add( patternTail );
|
||||
}
|
||||
else {
|
||||
exacts.add( pattern );
|
||||
}
|
||||
}
|
||||
|
||||
final Set<Entry> fileEntries;
|
||||
try {
|
||||
fileEntries = ( Set<Entry> ) jarVisitor.getMatchingEntries()[FILE_FILTER_INDEX];
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
throw new RuntimeException( "Error while reading " + jarToScan.toString(), e );
|
||||
}
|
||||
Set<NamedInputStream> files = new HashSet<NamedInputStream>( fileEntries.size() );
|
||||
Set<Entry> leftOver = new HashSet<Entry>( fileEntries );
|
||||
for ( Entry entry : fileEntries ) {
|
||||
boolean done = false;
|
||||
for ( String exact : exacts ) {
|
||||
if ( entry.getName().equals( exact ) ) {
|
||||
files.add( new NamedInputStream( entry.getName(), entry.getInputStream() ) );
|
||||
leftOver.remove( entry );
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
if (done) continue;
|
||||
for ( String endWithPattern : endWiths ) {
|
||||
if ( entry.getName().endsWith( endWithPattern ) ) {
|
||||
files.add( new NamedInputStream( entry.getName(), entry.getInputStream() ) );
|
||||
leftOver.remove( entry );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for ( Entry entry : leftOver ) {
|
||||
try {
|
||||
entry.getInputStream().close();
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
//swallow as we don't care about these files
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
public Set<NamedInputStream> getFilesInClasspath(Set<String> filePatterns) {
|
||||
throw new AssertionFailure( "Not implemented" );
|
||||
}
|
||||
|
||||
public String getUnqualifiedJarName(URL jarToScan) {
|
||||
JarVisitor jarVisitor = getVisitor( jarToScan );
|
||||
return jarVisitor.getUnqualifiedJarName();
|
||||
}
|
||||
|
||||
private static class StateJarVisitor {
|
||||
StateJarVisitor(JarVisitor visitor) {
|
||||
this.visitor = visitor;
|
||||
}
|
||||
JarVisitor visitor;
|
||||
boolean hasReadFiles = false;
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.packaging.spi;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.net.URL;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public interface Scanner {
|
||||
/**
|
||||
* return all packages in the jar matching one of these annotations
|
||||
* if annotationsToLookFor is empty, return all packages
|
||||
*/
|
||||
Set<Package> getPackagesInJar(URL jartoScan, Set<Class<? extends Annotation>> annotationsToLookFor);
|
||||
|
||||
/**
|
||||
* return all classes in the jar matching one of these annotations
|
||||
* if annotationsToLookFor is empty, return all classes
|
||||
*/
|
||||
Set<Class<?>> getClassesInJar(URL jartoScan, Set<Class<? extends Annotation>> annotationsToLookFor);
|
||||
|
||||
/**
|
||||
* return all files in the jar matching one of these file names
|
||||
* if filePatterns is empty, return all files
|
||||
* eg **\/*.hbm.xml, META-INF/orm.xml
|
||||
*/
|
||||
Set<NamedInputStream> getFilesInJar(URL jartoScan, Set<String> filePatterns);
|
||||
|
||||
|
||||
/**
|
||||
* Return all files in the classpath (ie PU visibility) matching one of these file names
|
||||
* if filePatterns is empty, return all files
|
||||
* the use case is really exact file name.
|
||||
*
|
||||
* NOT USED by HEM at the moment. We use exact file search via getResourceAsStream for now.
|
||||
*/
|
||||
Set<NamedInputStream> getFilesInClasspath(Set<String> filePatterns);
|
||||
|
||||
/**
|
||||
* return the unqualified JAR name ie customer-model.jar or store.war
|
||||
*/
|
||||
String getUnqualifiedJarName(URL jarUrl);
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package org.hibernate.jpa.test;
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import static java.io.File.separatorChar;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class TestHelper {
|
||||
private static URL RESOLVED_TEST_ROOT_URL;
|
||||
|
||||
public static URL determineTestRootUrl() {
|
||||
if ( RESOLVED_TEST_ROOT_URL == null ) {
|
||||
RESOLVED_TEST_ROOT_URL = resolveRootUrl( TestHelper.class );
|
||||
}
|
||||
return RESOLVED_TEST_ROOT_URL;
|
||||
}
|
||||
|
||||
public static URL resolveRootUrl(Class knownClass) {
|
||||
final String knownClassFileName = '/' + knownClass.getName().replace( '.', separatorChar ) + ".class";
|
||||
final URL knownClassFileUrl = TestHelper.class.getResource( knownClassFileName );
|
||||
final String knownClassFileUrlString = knownClassFileUrl.toExternalForm();
|
||||
|
||||
// to start, strip off the class file name
|
||||
String rootUrlString = knownClassFileUrlString.substring( 0, knownClassFileUrlString.lastIndexOf( separatorChar ) );
|
||||
|
||||
// then strip off each package dir
|
||||
final String packageName = knownClass.getPackage().getName();
|
||||
for ( String packageNamePart : packageName.split( "\\." ) ) {
|
||||
rootUrlString = rootUrlString.substring( 0, rootUrlString.lastIndexOf( separatorChar ) );
|
||||
}
|
||||
|
||||
try {
|
||||
return new URL( rootUrlString );
|
||||
}
|
||||
catch (MalformedURLException e) {
|
||||
throw new RuntimeException( "Could not convert class base url as string to URL ref", e );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +1,17 @@
|
|||
package org.hibernate.jpa.test.packaging;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.net.URL;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.jpa.packaging.internal.NativeScanner;
|
||||
import org.hibernate.jpa.packaging.spi.NamedInputStream;
|
||||
import org.hibernate.jpa.packaging.spi.Scanner;
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
import org.hibernate.jpa.boot.scan.internal.StandardScanner;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanOptions;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanResult;
|
||||
import org.hibernate.jpa.boot.scan.spi.Scanner;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class CustomScanner implements Scanner {
|
||||
public static boolean isUsed = false;
|
||||
private Scanner scanner = new NativeScanner();
|
||||
private Scanner delegate = new StandardScanner();
|
||||
|
||||
public static boolean isUsed() {
|
||||
return isUsed;
|
||||
|
@ -23,28 +21,9 @@ public class CustomScanner implements Scanner {
|
|||
isUsed = false;
|
||||
}
|
||||
|
||||
public Set<Package> getPackagesInJar(URL jartoScan, Set<Class<? extends Annotation>> annotationsToLookFor) {
|
||||
@Override
|
||||
public ScanResult scan(PersistenceUnitDescriptor persistenceUnit, ScanOptions options) {
|
||||
isUsed = true;
|
||||
return scanner.getPackagesInJar( jartoScan, annotationsToLookFor );
|
||||
}
|
||||
|
||||
public Set<Class<?>> getClassesInJar(URL jartoScan, Set<Class<? extends Annotation>> annotationsToLookFor) {
|
||||
isUsed = true;
|
||||
return scanner.getClassesInJar( jartoScan, annotationsToLookFor );
|
||||
}
|
||||
|
||||
public Set<NamedInputStream> getFilesInJar(URL jartoScan, Set<String> filePatterns) {
|
||||
isUsed = true;
|
||||
return scanner.getFilesInJar( jartoScan, filePatterns );
|
||||
}
|
||||
|
||||
public Set<NamedInputStream> getFilesInClasspath(Set<String> filePatterns) {
|
||||
isUsed = true;
|
||||
return scanner.getFilesInClasspath( filePatterns );
|
||||
}
|
||||
|
||||
public String getUnqualifiedJarName(URL jarUrl) {
|
||||
isUsed = true;
|
||||
return scanner.getUnqualifiedJarName( jarUrl );
|
||||
return delegate.scan( persistenceUnit, options );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,12 +23,6 @@
|
|||
*/
|
||||
package org.hibernate.jpa.test.packaging;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
@ -38,29 +32,32 @@ import java.net.URL;
|
|||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.URLStreamHandlerFactory;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.jpa.packaging.internal.ClassFilter;
|
||||
import org.hibernate.jpa.packaging.internal.Entry;
|
||||
import org.hibernate.jpa.packaging.internal.ExplodedJarVisitor;
|
||||
import org.hibernate.jpa.packaging.internal.FileFilter;
|
||||
import org.hibernate.jpa.packaging.internal.FileZippedJarVisitor;
|
||||
import org.hibernate.jpa.packaging.internal.Filter;
|
||||
import org.hibernate.jpa.packaging.internal.InputStreamZippedJarVisitor;
|
||||
import org.hibernate.jpa.packaging.internal.JarProtocolVisitor;
|
||||
import org.hibernate.jpa.packaging.internal.JarVisitor;
|
||||
import org.hibernate.jpa.packaging.internal.JarVisitorFactory;
|
||||
import org.hibernate.jpa.packaging.internal.PackageFilter;
|
||||
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.explodedpar.Carpet;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.RequiresDialect;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
|
@ -72,7 +69,7 @@ import org.junit.Test;
|
|||
public class JarVisitorTest extends PackagingTestCase {
|
||||
@Test
|
||||
public void testHttp() throws Exception {
|
||||
URL url = JarVisitorFactory.getJarURLFromURLEntry(
|
||||
URL url = ArchiveHelper.getJarURLFromURLEntry(
|
||||
new URL(
|
||||
"jar:http://www.ibiblio.org/maven/hibernate/jars/hibernate-annotations-3.0beta1.jar!/META-INF/persistence.xml"
|
||||
),
|
||||
|
@ -86,10 +83,18 @@ public class JarVisitorTest extends PackagingTestCase {
|
|||
//fail silently
|
||||
return;
|
||||
}
|
||||
JarVisitor visitor = JarVisitorFactory.getVisitor( url, getFilters() );
|
||||
assertEquals( 0, visitor.getMatchingEntries()[0].size() );
|
||||
assertEquals( 0, visitor.getMatchingEntries()[1].size() );
|
||||
assertEquals( 0, visitor.getMatchingEntries()[2].size() );
|
||||
ArchiveDescriptor archiveDescriptor = StandardArchiveDescriptorFactory.INSTANCE.buildArchiveDescriptor( url );
|
||||
AbstractScannerImpl.ResultCollector resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() );
|
||||
archiveDescriptor.visitArchive(
|
||||
new AbstractScannerImpl.ArchiveContextImpl(
|
||||
new PersistenceUnitDescriptorAdapter(),
|
||||
true,
|
||||
resultCollector
|
||||
)
|
||||
);
|
||||
assertEquals( 0, resultCollector.getClassDescriptorSet().size() );
|
||||
assertEquals( 0, resultCollector.getPackageDescriptorSet().size() );
|
||||
assertEquals( 0, resultCollector.getMappingFileSet().size() );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -97,20 +102,40 @@ public class JarVisitorTest extends PackagingTestCase {
|
|||
File defaultPar = buildDefaultPar();
|
||||
addPackageToClasspath( defaultPar );
|
||||
|
||||
Filter[] filters = getFilters();
|
||||
JarVisitor jarVisitor = new InputStreamZippedJarVisitor( defaultPar.toURL(), filters, "" );
|
||||
assertEquals( "defaultpar", jarVisitor.getUnqualifiedJarName() );
|
||||
Set entries = jarVisitor.getMatchingEntries()[1];
|
||||
assertEquals( 3, entries.size() );
|
||||
Entry entry = new Entry( org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class.getName(), null );
|
||||
assertTrue( entries.contains( entry ) );
|
||||
entry = new Entry( Version.class.getName(), null );
|
||||
assertTrue( entries.contains( entry ) );
|
||||
assertNull( ( ( Entry ) entries.iterator().next() ).getInputStream() );
|
||||
assertEquals( 2, jarVisitor.getMatchingEntries()[2].size() );
|
||||
for ( Entry localEntry : ( Set<Entry> ) jarVisitor.getMatchingEntries()[2] ) {
|
||||
assertNotNull( localEntry.getInputStream() );
|
||||
localEntry.getInputStream().close();
|
||||
ArchiveDescriptor archiveDescriptor = new JarInputStreamBasedArchiveDescriptor(
|
||||
StandardArchiveDescriptorFactory.INSTANCE,
|
||||
defaultPar.toURL(),
|
||||
""
|
||||
);
|
||||
|
||||
AbstractScannerImpl.ResultCollector resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() );
|
||||
archiveDescriptor.visitArchive(
|
||||
new AbstractScannerImpl.ArchiveContextImpl(
|
||||
new PersistenceUnitDescriptorAdapter(),
|
||||
true,
|
||||
resultCollector
|
||||
)
|
||||
);
|
||||
|
||||
validateResults( resultCollector, org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class, Version.class );
|
||||
}
|
||||
|
||||
private void validateResults(AbstractScannerImpl.ResultCollector resultCollector, Class... expectedClasses) throws IOException {
|
||||
assertEquals( 3, resultCollector.getClassDescriptorSet().size() );
|
||||
for ( Class expectedClass : expectedClasses ) {
|
||||
assertTrue(
|
||||
resultCollector.getClassDescriptorSet().contains(
|
||||
new ClassDescriptorImpl( expectedClass.getName(), null )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
assertEquals( 2, resultCollector.getMappingFileSet().size() );
|
||||
for ( MappingFileDescriptor mappingFileDescriptor : resultCollector.getMappingFileSet() ) {
|
||||
assertNotNull( mappingFileDescriptor.getStreamAccess() );
|
||||
final InputStream stream = mappingFileDescriptor.getStreamAccess().accessInputStream();
|
||||
assertNotNull( stream );
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,41 +147,39 @@ public class JarVisitorTest extends PackagingTestCase {
|
|||
addPackageToClasspath( nestedEar );
|
||||
|
||||
String jarFileName = nestedEar.toURL().toExternalForm() + "!/defaultpar.par";
|
||||
Filter[] filters = getFilters();
|
||||
JarVisitor jarVisitor = new JarProtocolVisitor( new URL( jarFileName ), filters, "" );
|
||||
//TODO should we fix the name here to reach defaultpar rather than nestedjar ??
|
||||
//assertEquals( "defaultpar", jarVisitor.getUnqualifiedJarName() );
|
||||
Set entries = jarVisitor.getMatchingEntries()[1];
|
||||
assertEquals( 3, entries.size() );
|
||||
Entry entry = new Entry( org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class.getName(), null );
|
||||
assertTrue( entries.contains( entry ) );
|
||||
entry = new Entry( Version.class.getName(), null );
|
||||
assertTrue( entries.contains( entry ) );
|
||||
assertNull( ( ( Entry ) entries.iterator().next() ).getInputStream() );
|
||||
assertEquals( 2, jarVisitor.getMatchingEntries()[2].size() );
|
||||
for ( Entry localEntry : ( Set<Entry> ) jarVisitor.getMatchingEntries()[2] ) {
|
||||
assertNotNull( localEntry.getInputStream() );
|
||||
localEntry.getInputStream().close();
|
||||
}
|
||||
|
||||
JarProtocolArchiveDescriptor archiveDescriptor = new JarProtocolArchiveDescriptor(
|
||||
StandardArchiveDescriptorFactory.INSTANCE,
|
||||
new URL( jarFileName ),
|
||||
""
|
||||
);
|
||||
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 );
|
||||
|
||||
jarFileName = nestedEarDir.toURL().toExternalForm() + "!/defaultpar.par";
|
||||
//JarVisitor jarVisitor = new ZippedJarVisitor( jarFileName, true, true );
|
||||
filters = getFilters();
|
||||
jarVisitor = new JarProtocolVisitor( new URL( jarFileName ), filters, "" );
|
||||
//TODO should we fix the name here to reach defaultpar rather than nestedjar ??
|
||||
//assertEquals( "defaultpar", jarVisitor.getUnqualifiedJarName() );
|
||||
entries = jarVisitor.getMatchingEntries()[1];
|
||||
assertEquals( 3, entries.size() );
|
||||
entry = new Entry( org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class.getName(), null );
|
||||
assertTrue( entries.contains( entry ) );
|
||||
entry = new Entry( Version.class.getName(), null );
|
||||
assertTrue( entries.contains( entry ) );
|
||||
assertNull( ( ( Entry ) entries.iterator().next() ).getInputStream() );
|
||||
assertEquals( 2, jarVisitor.getMatchingEntries()[2].size() );
|
||||
for ( Entry localEntry : ( Set<Entry> ) jarVisitor.getMatchingEntries()[2] ) {
|
||||
assertNotNull( localEntry.getInputStream() );
|
||||
localEntry.getInputStream().close();
|
||||
}
|
||||
archiveDescriptor = new JarProtocolArchiveDescriptor(
|
||||
StandardArchiveDescriptorFactory.INSTANCE,
|
||||
new URL( jarFileName ),
|
||||
""
|
||||
);
|
||||
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
|
||||
|
@ -165,21 +188,26 @@ public class JarVisitorTest extends PackagingTestCase {
|
|||
addPackageToClasspath( war );
|
||||
|
||||
String jarFileName = war.toURL().toExternalForm() + "!/WEB-INF/classes";
|
||||
Filter[] filters = getFilters();
|
||||
JarVisitor jarVisitor = new JarProtocolVisitor( new URL( jarFileName ), filters, "" );
|
||||
assertEquals( "war", jarVisitor.getUnqualifiedJarName() );
|
||||
Set entries = jarVisitor.getMatchingEntries()[1];
|
||||
assertEquals( 3, entries.size() );
|
||||
Entry entry = new Entry( org.hibernate.jpa.test.pack.war.ApplicationServer.class.getName(), null );
|
||||
assertTrue( entries.contains( entry ) );
|
||||
entry = new Entry( org.hibernate.jpa.test.pack.war.Version.class.getName(), null );
|
||||
assertTrue( entries.contains( entry ) );
|
||||
assertNull( ( ( Entry ) entries.iterator().next() ).getInputStream() );
|
||||
assertEquals( 2, jarVisitor.getMatchingEntries()[2].size() );
|
||||
for ( Entry localEntry : ( Set<Entry> ) jarVisitor.getMatchingEntries()[2] ) {
|
||||
assertNotNull( localEntry.getInputStream() );
|
||||
localEntry.getInputStream().close();
|
||||
}
|
||||
JarProtocolArchiveDescriptor archiveDescriptor = new JarProtocolArchiveDescriptor(
|
||||
StandardArchiveDescriptorFactory.INSTANCE,
|
||||
new URL( jarFileName ),
|
||||
""
|
||||
);
|
||||
|
||||
AbstractScannerImpl.ResultCollector resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() );
|
||||
archiveDescriptor.visitArchive(
|
||||
new AbstractScannerImpl.ArchiveContextImpl(
|
||||
new PersistenceUnitDescriptorAdapter(),
|
||||
true,
|
||||
resultCollector
|
||||
)
|
||||
);
|
||||
|
||||
validateResults(
|
||||
resultCollector,
|
||||
org.hibernate.jpa.test.pack.war.ApplicationServer.class,
|
||||
org.hibernate.jpa.test.pack.war.Version.class
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -187,21 +215,21 @@ public class JarVisitorTest extends PackagingTestCase {
|
|||
File defaultPar = buildDefaultPar();
|
||||
addPackageToClasspath( defaultPar );
|
||||
|
||||
Filter[] filters = getFilters();
|
||||
JarVisitor jarVisitor = new FileZippedJarVisitor( defaultPar.toURL(), filters, "" );
|
||||
assertEquals( "defaultpar", jarVisitor.getUnqualifiedJarName() );
|
||||
Set entries = jarVisitor.getMatchingEntries()[1];
|
||||
assertEquals( 3, entries.size() );
|
||||
Entry entry = new Entry( org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class.getName(), null );
|
||||
assertTrue( entries.contains( entry ) );
|
||||
entry = new Entry( Version.class.getName(), null );
|
||||
assertTrue( entries.contains( entry ) );
|
||||
assertNull( ( ( Entry ) entries.iterator().next() ).getInputStream() );
|
||||
assertEquals( 2, jarVisitor.getMatchingEntries()[2].size() );
|
||||
for ( Entry localEntry : ( Set<Entry> ) jarVisitor.getMatchingEntries()[2] ) {
|
||||
assertNotNull( localEntry.getInputStream() );
|
||||
localEntry.getInputStream().close();
|
||||
}
|
||||
JarFileBasedArchiveDescriptor archiveDescriptor = new JarFileBasedArchiveDescriptor(
|
||||
StandardArchiveDescriptorFactory.INSTANCE,
|
||||
defaultPar.toURL(),
|
||||
""
|
||||
);
|
||||
AbstractScannerImpl.ResultCollector resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() );
|
||||
archiveDescriptor.visitArchive(
|
||||
new AbstractScannerImpl.ArchiveContextImpl(
|
||||
new PersistenceUnitDescriptorAdapter(),
|
||||
true,
|
||||
resultCollector
|
||||
)
|
||||
);
|
||||
|
||||
validateResults( resultCollector, org.hibernate.jpa.test.pack.defaultpar.ApplicationServer.class, Version.class );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -209,32 +237,50 @@ public class JarVisitorTest extends PackagingTestCase {
|
|||
File explodedPar = buildExplodedPar();
|
||||
addPackageToClasspath( explodedPar );
|
||||
|
||||
Filter[] filters = getFilters();
|
||||
String dirPath = explodedPar.toURL().toExternalForm();
|
||||
// TODO - shouldn't ExplodedJarVisitor take care of a trailing slash?
|
||||
if ( dirPath.endsWith( "/" ) ) {
|
||||
dirPath = dirPath.substring( 0, dirPath.length() - 1 );
|
||||
}
|
||||
JarVisitor jarVisitor = new ExplodedJarVisitor( dirPath, filters );
|
||||
assertEquals( "explodedpar", jarVisitor.getUnqualifiedJarName() );
|
||||
Set[] entries = jarVisitor.getMatchingEntries();
|
||||
assertEquals( 1, entries[1].size() );
|
||||
assertEquals( 1, entries[0].size() );
|
||||
assertEquals( 1, entries[2].size() );
|
||||
|
||||
Entry entry = new Entry( Carpet.class.getName(), null );
|
||||
assertTrue( entries[1].contains( entry ) );
|
||||
for ( Entry localEntry : ( Set<Entry> ) jarVisitor.getMatchingEntries()[2] ) {
|
||||
assertNotNull( localEntry.getInputStream() );
|
||||
localEntry.getInputStream().close();
|
||||
ExplodedArchiveDescriptor archiveDescriptor = new ExplodedArchiveDescriptor(
|
||||
StandardArchiveDescriptorFactory.INSTANCE,
|
||||
ArchiveHelper.getURLFromPath( dirPath ),
|
||||
""
|
||||
);
|
||||
AbstractScannerImpl.ResultCollector resultCollector = new AbstractScannerImpl.ResultCollector( new StandardScanOptions() );
|
||||
archiveDescriptor.visitArchive(
|
||||
new AbstractScannerImpl.ArchiveContextImpl(
|
||||
new PersistenceUnitDescriptorAdapter(),
|
||||
true,
|
||||
resultCollector
|
||||
)
|
||||
);
|
||||
|
||||
assertEquals( 1, resultCollector.getClassDescriptorSet().size() );
|
||||
assertEquals( 1, resultCollector.getPackageDescriptorSet().size() );
|
||||
assertEquals( 1, resultCollector.getMappingFileSet().size() );
|
||||
|
||||
assertTrue(
|
||||
resultCollector.getClassDescriptorSet().contains(
|
||||
new ClassDescriptorImpl( Carpet.class.getName(), null )
|
||||
)
|
||||
);
|
||||
|
||||
for ( MappingFileDescriptor mappingFileDescriptor : resultCollector.getMappingFileSet() ) {
|
||||
assertNotNull( mappingFileDescriptor.getStreamAccess() );
|
||||
final InputStream stream = mappingFileDescriptor.getStreamAccess().accessInputStream();
|
||||
assertNotNull( stream );
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-6806")
|
||||
public void testJarVisitorFactory() throws Exception{
|
||||
|
||||
addPackageToClasspath( buildExplodedPar(), buildDefaultPar() );
|
||||
public void testJarVisitorFactory() throws Exception {
|
||||
final File explodedPar = buildExplodedPar();
|
||||
final File defaultPar = buildDefaultPar();
|
||||
addPackageToClasspath( explodedPar, defaultPar );
|
||||
|
||||
//setting URL to accept vfs based protocol
|
||||
URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() {
|
||||
|
@ -250,21 +296,21 @@ public class JarVisitorTest extends PackagingTestCase {
|
|||
}
|
||||
});
|
||||
|
||||
URL jarUrl = new URL ("file:./target/packages/defaultpar.par");
|
||||
JarVisitor jarVisitor = JarVisitorFactory.getVisitor(jarUrl, getFilters(), null);
|
||||
assertEquals(FileZippedJarVisitor.class.getName(), jarVisitor.getClass().getName());
|
||||
URL jarUrl = defaultPar.toURL();
|
||||
ArchiveDescriptor descriptor = StandardArchiveDescriptorFactory.INSTANCE.buildArchiveDescriptor( jarUrl );
|
||||
assertEquals( JarFileBasedArchiveDescriptor.class.getName(), descriptor.getClass().getName() );
|
||||
|
||||
jarUrl = new URL ("file:./target/packages/explodedpar");
|
||||
jarVisitor = JarVisitorFactory.getVisitor(jarUrl, getFilters(), null);
|
||||
assertEquals(ExplodedJarVisitor.class.getName(), jarVisitor.getClass().getName());
|
||||
jarUrl = explodedPar.toURL();
|
||||
descriptor = StandardArchiveDescriptorFactory.INSTANCE.buildArchiveDescriptor( jarUrl );
|
||||
assertEquals( ExplodedArchiveDescriptor.class.getName(), descriptor.getClass().getName() );
|
||||
|
||||
jarUrl = new URL ("vfszip:./target/packages/defaultpar.par");
|
||||
jarVisitor = JarVisitorFactory.getVisitor(jarUrl, getFilters(), null);
|
||||
assertEquals(FileZippedJarVisitor.class.getName(), jarVisitor.getClass().getName());
|
||||
jarUrl = new URL( defaultPar.toURL().toExternalForm().replace( "file:", "vfszip:" ) );
|
||||
descriptor = StandardArchiveDescriptorFactory.INSTANCE.buildArchiveDescriptor( jarUrl );
|
||||
assertEquals( JarFileBasedArchiveDescriptor.class.getName(), descriptor.getClass().getName());
|
||||
|
||||
jarUrl = new URL ("vfsfile:./target/packages/explodedpar");
|
||||
jarVisitor = JarVisitorFactory.getVisitor(jarUrl, getFilters(), null);
|
||||
assertEquals(ExplodedJarVisitor.class.getName(), jarVisitor.getClass().getName());
|
||||
jarUrl = new URL( explodedPar.toURL().toExternalForm().replace( "file:", "vfsfile:" ) );
|
||||
descriptor = StandardArchiveDescriptorFactory.INSTANCE.buildArchiveDescriptor( jarUrl );
|
||||
assertEquals( ExplodedArchiveDescriptor.class.getName(), descriptor.getClass().getName() );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -315,36 +361,29 @@ public class JarVisitorTest extends PackagingTestCase {
|
|||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-7835")
|
||||
public void testGetBytesFromInputStream() {
|
||||
try {
|
||||
File file = buildLargeJar();
|
||||
public void testGetBytesFromInputStream() throws Exception {
|
||||
File file = buildLargeJar();
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
InputStream stream = new BufferedInputStream(
|
||||
new FileInputStream( file ) );
|
||||
int oldLength = getBytesFromInputStream( stream ).length;
|
||||
stream.close();
|
||||
long oldTime = System.currentTimeMillis() - start;
|
||||
long start = System.currentTimeMillis();
|
||||
InputStream stream = new BufferedInputStream(
|
||||
new FileInputStream( file ) );
|
||||
int oldLength = getBytesFromInputStream( stream ).length;
|
||||
stream.close();
|
||||
long oldTime = System.currentTimeMillis() - start;
|
||||
|
||||
start = System.currentTimeMillis();
|
||||
stream = new BufferedInputStream( new FileInputStream( file ) );
|
||||
int newLength = JarVisitorFactory.getBytesFromInputStream(
|
||||
stream ).length;
|
||||
stream.close();
|
||||
long newTime = System.currentTimeMillis() - start;
|
||||
start = System.currentTimeMillis();
|
||||
stream = new BufferedInputStream( new FileInputStream( file ) );
|
||||
int newLength = ArchiveHelper.getBytesFromInputStream( stream ).length;
|
||||
stream.close();
|
||||
long newTime = System.currentTimeMillis() - start;
|
||||
|
||||
assertEquals( oldLength, newLength );
|
||||
assertTrue( oldTime > newTime );
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
fail( e.getMessage() );
|
||||
}
|
||||
assertEquals( oldLength, newLength );
|
||||
assertTrue( oldTime > newTime );
|
||||
}
|
||||
|
||||
// This is the old getBytesFromInputStream from JarVisitorFactory before
|
||||
// it was changed by HHH-7835. Use it as a regression test.
|
||||
private byte[] getBytesFromInputStream(
|
||||
InputStream inputStream) throws IOException {
|
||||
private byte[] getBytesFromInputStream(InputStream inputStream) throws IOException {
|
||||
int size;
|
||||
|
||||
byte[] entryBytes = new byte[0];
|
||||
|
@ -363,46 +402,16 @@ public class JarVisitorTest extends PackagingTestCase {
|
|||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-7835")
|
||||
public void testGetBytesFromZeroInputStream() {
|
||||
try {
|
||||
// Ensure that JarVisitorFactory#getBytesFromInputStream
|
||||
// can handle 0 length streams gracefully.
|
||||
InputStream emptyStream = new BufferedInputStream(
|
||||
new FileInputStream( new File(
|
||||
"src/test/resources/org/hibernate/jpa/test/packaging/empty.txt" ) ) );
|
||||
int length = JarVisitorFactory.getBytesFromInputStream(
|
||||
emptyStream ).length;
|
||||
assertEquals( length, 0 );
|
||||
emptyStream.close();
|
||||
public void testGetBytesFromZeroInputStream() throws Exception {
|
||||
// Ensure that JarVisitorFactory#getBytesFromInputStream
|
||||
// can handle 0 length streams gracefully.
|
||||
URL emptyTxtUrl = getClass().getResource( "/org/hibernate/jpa/test/packaging/empty.txt" );
|
||||
if ( emptyTxtUrl == null ) {
|
||||
throw new RuntimeException( "Bah!" );
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
fail( e.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
private Filter[] getFilters() {
|
||||
return new Filter[] {
|
||||
new PackageFilter( false, null ) {
|
||||
public boolean accept(String javaElementName) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
new ClassFilter(
|
||||
false, new Class[] {
|
||||
Entity.class,
|
||||
MappedSuperclass.class,
|
||||
Embeddable.class
|
||||
}
|
||||
) {
|
||||
public boolean accept(String javaElementName) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
new FileFilter( true ) {
|
||||
public boolean accept(String javaElementName) {
|
||||
return javaElementName.endsWith( "hbm.xml" ) || javaElementName.endsWith( "META-INF/orm.xml" );
|
||||
}
|
||||
}
|
||||
};
|
||||
InputStream emptyStream = new BufferedInputStream( emptyTxtUrl.openStream() );
|
||||
int length = ArchiveHelper.getBytesFromInputStream( emptyStream ).length;
|
||||
assertEquals( length, 0 );
|
||||
emptyStream.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.hibernate.jpa.test.Cat;
|
|||
import org.hibernate.jpa.test.Distributor;
|
||||
import org.hibernate.jpa.test.Item;
|
||||
import org.hibernate.jpa.test.Kitten;
|
||||
import org.hibernate.jpa.test.TestHelper;
|
||||
import org.hibernate.jpa.test.pack.cfgxmlpar.Morito;
|
||||
import org.hibernate.jpa.test.pack.defaultpar.ApplicationServer;
|
||||
import org.hibernate.jpa.test.pack.defaultpar.IncrementListener;
|
||||
|
@ -204,6 +205,10 @@ public abstract class PackagingTestCase extends BaseCoreFunctionalTestCase {
|
|||
}
|
||||
|
||||
protected File buildExplicitPar() {
|
||||
// explicitpar/persistence.xml references externaljar.jar so build that from here.
|
||||
// this is the reason for tests failing after clean at least on my (Steve) local system
|
||||
buildExternalJar();
|
||||
|
||||
String fileName = "explicitpar.par";
|
||||
JavaArchive archive = ShrinkWrap.create( JavaArchive.class, fileName );
|
||||
archive.addClasses(
|
||||
|
@ -342,8 +347,10 @@ public abstract class PackagingTestCase extends BaseCoreFunctionalTestCase {
|
|||
// Build a large jar by adding a lorem ipsum file repeatedly.
|
||||
for ( int i = 0; i < 100; i++ ) {
|
||||
ArchivePath path = ArchivePaths.create( "META-INF/file" + i );
|
||||
archive.addAsResource( new File( "src/test/resources/org/hibernate/jpa/test/packaging/loremipsum.txt" ),
|
||||
path );
|
||||
archive.addAsResource(
|
||||
"org/hibernate/jpa/test/packaging/loremipsum.txt",
|
||||
path
|
||||
);
|
||||
}
|
||||
|
||||
File testPackage = new File( packageTargetDir, fileName );
|
||||
|
|
|
@ -23,31 +23,32 @@
|
|||
*/
|
||||
package org.hibernate.jpa.test.packaging;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Converter;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
import org.junit.Test;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.hibernate.jpa.AvailableSettings;
|
||||
import org.hibernate.jpa.packaging.internal.NativeScanner;
|
||||
|
||||
import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
import org.hibernate.jpa.boot.scan.internal.StandardScanOptions;
|
||||
import org.hibernate.jpa.boot.scan.internal.StandardScanner;
|
||||
import org.hibernate.jpa.boot.spi.ClassDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.MappingFileDescriptor;
|
||||
import org.hibernate.jpa.boot.spi.NamedInputStream;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanOptions;
|
||||
import org.hibernate.jpa.boot.scan.spi.ScanResult;
|
||||
import org.hibernate.jpa.boot.scan.spi.Scanner;
|
||||
import org.hibernate.jpa.test.pack.defaultpar.ApplicationServer;
|
||||
import org.hibernate.jpa.packaging.spi.NamedInputStream;
|
||||
import org.hibernate.jpa.packaging.spi.Scanner;
|
||||
import org.hibernate.jpa.test.pack.defaultpar.Version;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
|
@ -59,32 +60,39 @@ public class ScannerTest extends PackagingTestCase {
|
|||
File defaultPar = buildDefaultPar();
|
||||
addPackageToClasspath( defaultPar );
|
||||
|
||||
Scanner scanner = new NativeScanner();
|
||||
assertEquals( "defaultpar", scanner.getUnqualifiedJarName( defaultPar.toURL() ) );
|
||||
PersistenceUnitDescriptor descriptor = new ParsedPersistenceXmlDescriptor( defaultPar.toURL() );
|
||||
ScanOptions options = new StandardScanOptions( "hbm,class", descriptor.isExcludeUnlistedClasses() );
|
||||
Scanner scanner = new StandardScanner();
|
||||
ScanResult scanResult = scanner.scan( descriptor, options );
|
||||
|
||||
Set<Class<? extends Annotation>> annotationsToLookFor = new HashSet<Class<? extends Annotation>>( 3 );
|
||||
annotationsToLookFor.add( Entity.class );
|
||||
annotationsToLookFor.add( MappedSuperclass.class );
|
||||
annotationsToLookFor.add( Embeddable.class );
|
||||
annotationsToLookFor.add( Converter.class );
|
||||
final Set<Class<?>> classes = scanner.getClassesInJar( defaultPar.toURL(), annotationsToLookFor );
|
||||
assertEquals( 3, scanResult.getLocatedClasses().size() );
|
||||
assertClassesContained( scanResult, ApplicationServer.class );
|
||||
assertClassesContained( scanResult, Version.class );
|
||||
|
||||
assertEquals( 3, classes.size() );
|
||||
assertTrue( classes.contains( ApplicationServer.class ) );
|
||||
assertTrue( classes.contains( Version.class ) );
|
||||
|
||||
Set<String> filePatterns = new HashSet<String>( 2 );
|
||||
filePatterns.add( "**/*.hbm.xml" );
|
||||
filePatterns.add( "META-INF/orm.xml" );
|
||||
final Set<NamedInputStream> files = scanner.getFilesInJar( defaultPar.toURL(), filePatterns );
|
||||
|
||||
assertEquals( 2, files.size() );
|
||||
for ( NamedInputStream file : files ) {
|
||||
assertNotNull( file.getStream() );
|
||||
file.getStream().close();
|
||||
assertEquals( 2, scanResult.getLocatedMappingFiles().size() );
|
||||
for ( MappingFileDescriptor mappingFileDescriptor : scanResult.getLocatedMappingFiles() ) {
|
||||
assertNotNull( mappingFileDescriptor.getName() );
|
||||
assertNotNull( mappingFileDescriptor.getStreamAccess() );
|
||||
InputStream stream = mappingFileDescriptor.getStreamAccess().accessInputStream();
|
||||
assertNotNull( stream );
|
||||
stream.close();
|
||||
NamedInputStream namedInputStream = mappingFileDescriptor.getStreamAccess().asNamedInputStream();
|
||||
assertNotNull( namedInputStream );
|
||||
stream = namedInputStream.getStream();
|
||||
assertNotNull( stream );
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void assertClassesContained(ScanResult scanResult, Class classToCheckFor) {
|
||||
for ( ClassDescriptor classDescriptor : scanResult.getLocatedClasses() ) {
|
||||
if ( classDescriptor.getName().equals( classToCheckFor.getName() ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
fail( "ScanResult did not contain expected Class : " + classToCheckFor.getName() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomScanner() throws Exception {
|
||||
File defaultPar = buildDefaultPar();
|
||||
|
|
Loading…
Reference in New Issue