[hibernate-commits] Hibernate SVN: r14273 - in entitymanager/trunk: src/java/org/hibernate/ejb and 15 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Jan 15 14:25:10 EST 2008


Author: epbernard
Date: 2008-01-15 14:25:10 -0500 (Tue, 15 Jan 2008)
New Revision: 14273

Added:
   entitymanager/trunk/src/java/org/hibernate/ejb/packaging/AbstractJarVisitor.java
   entitymanager/trunk/src/java/org/hibernate/ejb/packaging/ClassFilter.java
   entitymanager/trunk/src/java/org/hibernate/ejb/packaging/Entry.java
   entitymanager/trunk/src/java/org/hibernate/ejb/packaging/FileFilter.java
   entitymanager/trunk/src/java/org/hibernate/ejb/packaging/Filter.java
   entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarProtocolVisitor.java
   entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitor.java
   entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitorFactory.java
   entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JavaElementFilter.java
   entitymanager/trunk/src/java/org/hibernate/ejb/packaging/PackageFilter.java
   entitymanager/trunk/src/test-resources/war/
   entitymanager/trunk/src/test-resources/war/WEB-INF/
   entitymanager/trunk/src/test-resources/war/WEB-INF/classes/
   entitymanager/trunk/src/test-resources/war/WEB-INF/classes/META-INF/
   entitymanager/trunk/src/test-resources/war/WEB-INF/classes/META-INF/orm.xml
   entitymanager/trunk/src/test-resources/war/WEB-INF/classes/META-INF/persistence.xml
   entitymanager/trunk/src/test-resources/war/WEB-INF/classes/org/
   entitymanager/trunk/src/test-resources/war/WEB-INF/classes/org/hibernate/
   entitymanager/trunk/src/test-resources/war/WEB-INF/classes/org/hibernate/ejb/
   entitymanager/trunk/src/test-resources/war/WEB-INF/classes/org/hibernate/ejb/test/
   entitymanager/trunk/src/test-resources/war/WEB-INF/classes/org/hibernate/ejb/test/pack/
   entitymanager/trunk/src/test-resources/war/WEB-INF/classes/org/hibernate/ejb/test/pack/war/
   entitymanager/trunk/src/test-resources/war/WEB-INF/classes/org/hibernate/ejb/test/pack/war/Mouse.hbm.xml
   entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/
   entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/ApplicationServer.java
   entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/IncrementListener.java
   entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Lighter.java
   entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Money.java
   entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Mouse.java
   entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/OtherIncrementListener.java
   entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Version.java
   entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/package-info.java
Removed:
   entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitor.java
Modified:
   entitymanager/trunk/build.xml
   entitymanager/trunk/src/java/org/hibernate/ejb/Ejb3Configuration.java
   entitymanager/trunk/src/java/org/hibernate/ejb/packaging/ExplodedJarVisitor.java
   entitymanager/trunk/src/java/org/hibernate/ejb/packaging/FileZippedJarVisitor.java
   entitymanager/trunk/src/java/org/hibernate/ejb/packaging/InputStreamZippedJarVisitor.java
   entitymanager/trunk/src/test/org/hibernate/ejb/test/packaging/JarVisitorTest.java
Log:
EJB-326 Support for jar:<url>!/{entry} especially when {entry} is WEB-INF/classes like in WARs

Modified: entitymanager/trunk/build.xml
===================================================================
--- entitymanager/trunk/build.xml	2008-01-10 10:11:13 UTC (rev 14272)
+++ entitymanager/trunk/build.xml	2008-01-15 19:25:10 UTC (rev 14273)
@@ -133,12 +133,21 @@
     <target name="packjar">
         <property name="extension" value="jar"/>
 		<property name="packagename" value="${jarname}"/>
-		<!-- property name="jarname"/ -->
+        <property name="headerdirectory" value="."/>
+        <!-- property name="jarname"/ -->
         <mkdir dir="${build.testresources.dir}"/>
+        <mkdir dir="${build.temp.dir}/${headerdirectory}"/>
+        <copy todir="${build.temp.dir}/${headerdirectory}">
+            <fileset dir="${classes.dir}" >
+                <include name="**/test/pack/${packagename}/**.*"/>
+            </fileset>
+        </copy>
         <jar destfile="${build.testresources.dir}/${jarname}.${extension}">
-            <!-- fileset dir="${build.temp.dir}"/ -->
-            <fileset dir="${classes.dir}">
+            <!-- fileset dir="${classes.dir}" >
                 <include name="**/test/pack/${packagename}/**.*"/>
+            </fileset -->
+            <fileset dir="${build.temp.dir}">
+                <include name="**/*.*"/>
             </fileset>
             <fileset dir="${testresources.dir}/${jarname}">
                 <include name="**/*.*"/>
@@ -160,7 +169,7 @@
                 <include name="**/*.*"/>
             </fileset>
         </copy>
-        <delete dir="${build.temp.dir}"/>
+        <!-- delete dir="${build.temp.dir}"/ -->
     </target>
 
     <target name="test-resources" description="Prepare all needed jars and pars">
@@ -194,7 +203,13 @@
             <param name="jarname" value="overridenpar"/>
         </antcall>
 
-		<antcall target="packexploded" inheritall="true">
+        <antcall target="packjar" inheritall="true">
+            <param name="extension" value="war"/>
+            <param name="jarname" value="war"/>
+            <param name="headerdirectory" value="WEB-INF/classes"/>
+        </antcall>
+
+        <antcall target="packexploded" inheritall="true">
             <param name="extension" value="par"/>
             <param name="jarname" value="explodedpar"/>
         </antcall>

Modified: entitymanager/trunk/src/java/org/hibernate/ejb/Ejb3Configuration.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/Ejb3Configuration.java	2008-01-10 10:11:13 UTC (rev 14272)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/Ejb3Configuration.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -58,6 +58,12 @@
 import org.hibernate.ejb.packaging.NamedInputStream;
 import org.hibernate.ejb.packaging.PersistenceMetadata;
 import org.hibernate.ejb.packaging.PersistenceXmlLoader;
+import org.hibernate.ejb.packaging.Filter;
+import org.hibernate.ejb.packaging.JarVisitorFactory;
+import org.hibernate.ejb.packaging.Entry;
+import org.hibernate.ejb.packaging.FileFilter;
+import org.hibernate.ejb.packaging.PackageFilter;
+import org.hibernate.ejb.packaging.ClassFilter;
 import org.hibernate.ejb.transaction.JoinableCMTTransactionFactory;
 import org.hibernate.ejb.util.ConfigurationHelper;
 import org.hibernate.ejb.util.LogHelper;
@@ -236,9 +242,9 @@
 						else if ( persistenceUnitName == null || metadata.getName().equals( persistenceUnitName ) ) {
 							if (visitor == null) visitor = getMainJarVisitor( url, metadata, integration );
 							addMetadataFromVisitor( visitor, metadata );
-							JarVisitor.Filter[] otherXmlFilter = getFilters( metadata, integration, false );
+							Filter[] otherXmlFilter = getFilters( metadata, integration, false );
 							for ( String jarFile : metadata.getJarFiles() ) {
-								visitor = JarVisitor.getVisitor( jarFile, otherXmlFilter );
+								visitor = JarVisitorFactory.getVisitor( jarFile, otherXmlFilter );
 								addMetadataFromVisitor( visitor, metadata );
 							}
 							return configure( metadata, integration );
@@ -260,9 +266,9 @@
 
 	//method used in a non managed environment
 	private JarVisitor getMainJarVisitor(URL url, PersistenceMetadata metadata, Map integration) {
-		URL jarURL = JarVisitor.getJarURLFromURLEntry( url, "/META-INF/persistence.xml" );
-		JarVisitor.Filter[] persistenceXmlFilter = getFilters( metadata, integration, metadata.getExcludeUnlistedClasses() );
-		return JarVisitor.getVisitor( jarURL, persistenceXmlFilter );
+		URL jarURL = JarVisitorFactory.getJarURLFromURLEntry( url, "/META-INF/persistence.xml" );
+		Filter[] persistenceXmlFilter = getFilters( metadata, integration, metadata.getExcludeUnlistedClasses() );
+		return JarVisitorFactory.getVisitor( jarURL, persistenceXmlFilter );
 	}
 
 	private static void addMetadataFromVisitor(JarVisitor visitor, PersistenceMetadata metadata) throws IOException {
@@ -274,19 +280,19 @@
 	}
 
 	private static void addScannedEntries(JarVisitor visitor, List<String> classes, List<String> packages, List<NamedInputStream> hbmFiles, List<String> mappingFiles) throws IOException {
-		JarVisitor.Filter[] filters = visitor.getFilters();
+		Filter[] filters = visitor.getFilters();
 		Set[] entries = visitor.getMatchingEntries();
 		int size = filters.length;
 		for ( int index = 0; index < size ; index++ ) {
 			for (Object o : entries[index]) {
-				JarVisitor.Entry entry = (JarVisitor.Entry) o;
-				if ( filters[index] instanceof JarVisitor.ClassFilter ) {
+				Entry entry = (Entry) o;
+				if ( filters[index] instanceof ClassFilter ) {
 					classes.add( entry.getName() );
 				}
-				else if ( filters[index] instanceof JarVisitor.PackageFilter ) {
+				else if ( filters[index] instanceof PackageFilter ) {
 					packages.add( entry.getName() );
 				}
-				else if ( filters[index] instanceof JarVisitor.FileFilter ) {
+				else if ( filters[index] instanceof FileFilter ) {
 					hbmFiles.add( new NamedInputStream( entry.getName(), entry.getInputStream() ) );
 					if (mappingFiles != null) mappingFiles.remove( entry.getName() );
 				}
@@ -553,7 +559,7 @@
 		return result;
 	}
 
-	private JarVisitor.Filter[] getFilters(PersistenceMetadata metadata, Map overridenProperties, boolean excludeIfNotOverriden) {
+	private Filter[] getFilters(PersistenceMetadata metadata, Map overridenProperties, boolean excludeIfNotOverriden) {
 		Properties properties = metadata.getProps();
 		final List<String> mappingFiles = metadata.getMappingFiles();
 		boolean[] detectedArtifacts = getDetectedArtifacts( properties, overridenProperties, excludeIfNotOverriden );
@@ -561,17 +567,17 @@
 		return getFilters( detectedArtifacts, true, mappingFiles );
 	}
 
-	private JarVisitor.Filter[] getFilters(final boolean[] detectedArtifacts, final boolean searchORM, final List<String> mappingFiles) {
+	private Filter[] getFilters(final boolean[] detectedArtifacts, final boolean searchORM, final List<String> mappingFiles) {
 		final int mappingFilesSize = mappingFiles != null ? mappingFiles.size() : 0;
 		int size = ( detectedArtifacts[0] ? 2 : 0 ) + ( (searchORM || detectedArtifacts[1] || mappingFilesSize > 0 ) ? 1 : 0);
-		JarVisitor.Filter[] filters = new JarVisitor.Filter[size];
+		Filter[] filters = new Filter[size];
 		if ( detectedArtifacts[0] ) {
-			filters[0] = new JarVisitor.PackageFilter( false, null ) {
+			filters[0] = new PackageFilter( false, null ) {
 				public boolean accept(String javaElementName) {
 					return true;
 				}
 			};
-			filters[1] = new JarVisitor.ClassFilter(
+			filters[1] = new ClassFilter(
 					false, new Class[]{
 					Entity.class,
 					MappedSuperclass.class,
@@ -583,7 +589,7 @@
 			};
 		}
 		if ( detectedArtifacts[1] || searchORM || mappingFilesSize > 0) {
-			filters[size - 1] = new JarVisitor.FileFilter( true ) {
+			filters[size - 1] = new FileFilter( true ) {
 				public boolean accept(String javaElementName) {
 					return ( detectedArtifacts[1] && javaElementName.endsWith( "hbm.xml" ) )
 							|| ( searchORM && javaElementName.endsWith( META_INF_ORM_XML ) )
@@ -600,7 +606,7 @@
 			return;
 		}
 		try {
-			JarVisitor visitor = JarVisitor.getVisitor( jar, getFilters( detectedArtifacts, searchORM, null ) );
+			JarVisitor visitor = JarVisitorFactory.getVisitor( jar, getFilters( detectedArtifacts, searchORM, null ) );
 			addScannedEntries( visitor, entities, packages, hbmFiles, null );
 		}
 		catch (RuntimeException e) {

Copied: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/AbstractJarVisitor.java (from rev 14266, entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitor.java)
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/AbstractJarVisitor.java	                        (rev 0)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/AbstractJarVisitor.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,246 @@
+package org.hibernate.ejb.packaging;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+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.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * 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
+ */
+//TODO shortcut when filters are null or empty
+public abstract class AbstractJarVisitor implements JarVisitor {
+	private static Log log = LogFactory.getLog( AbstractJarVisitor.class );
+	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) {
+		URL jarUrl;
+		try {
+			//is it an url
+			jarUrl = new URL( jarPath );
+		}
+		catch (MalformedURLException e) {
+			try {
+				//consider it as a file path
+				jarUrl = new URL( "file:" + jarPath );
+			}
+			catch (MalformedURLException ee) {
+				throw new IllegalArgumentException( "Unable to find jar:" + jarPath, ee );
+			}
+		}
+		this.jarUrl = jarUrl;
+		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.debug( "Searching mapped entities in jar/par: " + 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 {
+		if ( entryName.endsWith( "package-info.class" ) ) {
+			String name = entryName.substring( 0, entryName.length() - ".package-info.class".length() )
+					.replace( '/', '.' );
+			executeJavaElementFilter( name, packageFilters, is, secondIs );
+		}
+		else if ( entryName.endsWith( ".class" ) ) {
+			String name = entryName.substring( 0, entryName.length() - ".class".length() ).replace( '/', '.' );
+			log.debug( "Filtering: " + 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.debug( "File Filter matched for " + 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.debug( "Java element filter matched for " + 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;
+	}
+}


Property changes on: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/AbstractJarVisitor.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Added: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/ClassFilter.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/ClassFilter.java	                        (rev 0)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/ClassFilter.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,17 @@
+//$
+package org.hibernate.ejb.packaging;
+
+/**
+ * Filter on class elements
+ *
+ * @author Emmanuel Bernard
+ * @see JavaElementFilter
+ */
+public abstract class ClassFilter extends JavaElementFilter {
+	/**
+	 * @see JavaElementFilter#JavaElementFilter(boolean, Class[])
+	 */
+	protected ClassFilter(boolean retrieveStream, Class[] annotations) {
+		super( retrieveStream, annotations );
+	}
+}
\ No newline at end of file

Added: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/Entry.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/Entry.java	                        (rev 0)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/Entry.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,43 @@
+//$
+package org.hibernate.ejb.packaging;
+
+import java.io.InputStream;
+
+/**
+ * Represent a JAR entry
+ * Contains a name and an optional Input stream to the entry
+ *
+ * @author Emmanuel Bernard
+ */
+public class Entry {
+	private String name;
+	private InputStream is;
+
+	public Entry(String name, InputStream is) {
+		this.name = name;
+		this.is = is;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public InputStream getInputStream() {
+		return is;
+	}
+
+	public boolean equals(Object o) {
+		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;
+	}
+
+	public int hashCode() {
+		return name.hashCode();
+	}
+}
\ No newline at end of file

Modified: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/ExplodedJarVisitor.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/ExplodedJarVisitor.java	2008-01-10 10:11:13 UTC (rev 14272)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/ExplodedJarVisitor.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -14,11 +14,13 @@
 /**
  * @author Emmanuel Bernard
  */
-public class ExplodedJarVisitor extends JarVisitor {
+public class ExplodedJarVisitor extends AbstractJarVisitor {
 	private static Log log = LogFactory.getLog( ExplodedJarVisitor.class );
+	private String entry;
 
-	public ExplodedJarVisitor(URL url, Filter[] filters) {
+	public ExplodedJarVisitor(URL url, Filter[] filters, String entry) {
 		super( url, filters );
+		this.entry = entry;
 	}
 
 	public ExplodedJarVisitor(String fileName, Filter[] filters) {
@@ -42,7 +44,14 @@
 			log.warn( "Exploded jar file not a directory (ignored): " + jarUrl );
 			return;
 		}
-		getClassNamesInTree( jarFile, null );
+		File rootFile;
+		if (entry != null && entry.length() > 0 && ! "/".equals( entry ) ) {
+			rootFile = new File(jarFile, entry);
+		}
+		else {
+			rootFile = jarFile;
+		}
+		getClassNamesInTree( rootFile, null );
 	}
 
 	private void getClassNamesInTree(File jarFile, String header) throws IOException {

Added: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/FileFilter.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/FileFilter.java	                        (rev 0)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/FileFilter.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,22 @@
+//$
+package org.hibernate.ejb.packaging;
+
+/**
+ * Filter use to match a file by its name
+ *
+ * @author Emmanuel Bernard
+ */
+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);
+	}
\ No newline at end of file

Modified: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/FileZippedJarVisitor.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/FileZippedJarVisitor.java	2008-01-10 10:11:13 UTC (rev 14272)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/FileZippedJarVisitor.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -17,15 +17,17 @@
  *
  * @author Emmanuel Bernard
  */
-public class FileZippedJarVisitor extends JarVisitor {
+public class FileZippedJarVisitor extends AbstractJarVisitor {
 	private static Log log = LogFactory.getLog( FileZippedJarVisitor.class );
+	private String entry;
 
 	public FileZippedJarVisitor(String fileName, Filter[] filters) {
 		super( fileName, filters );
 	}
 
-	public FileZippedJarVisitor(URL url, Filter[] filters) {
+	public FileZippedJarVisitor(URL url, Filter[] filters, String entry) {
 		super( url, filters );
+		this.entry = entry;
 	}
 
 	protected void doProcessElements() throws IOException {
@@ -41,14 +43,22 @@
 			log.warn( "Malformed url: " + 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 entry = entries.nextElement();
-			if ( !entry.isDirectory() ) {
+			ZipEntry zipEntry = entries.nextElement();
+			String name = zipEntry.getName();
+			if ( entry != null && ! name.startsWith( entry ) ) continue; //filter it out
+			if ( !zipEntry.isDirectory() ) {
+				//build relative name
+				if (entry != null) name = name.substring( entry.length() );
+				if ( name.startsWith( "/" ) ) name = name.substring( 1 );
 				addElement(
-						entry.getName(),
-						new BufferedInputStream( jarFile.getInputStream( entry ) ),
-						new BufferedInputStream( jarFile.getInputStream( entry ) )
+						name,
+						new BufferedInputStream( jarFile.getInputStream( zipEntry ) ),
+						new BufferedInputStream( jarFile.getInputStream( zipEntry ) )
 				);
 			}
 		}

Added: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/Filter.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/Filter.java	                        (rev 0)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/Filter.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,19 @@
+//$
+package org.hibernate.ejb.packaging;
+
+/**
+ * Filter used when searching elements in a JAR
+ *
+ * @author Emmanuel Bernard
+ */
+public abstract class Filter {
+	private boolean retrieveStream;
+
+	protected Filter(boolean retrieveStream) {
+		this.retrieveStream = retrieveStream;
+	}
+
+	public boolean getStream() {
+		return retrieveStream;
+	}
+}

Modified: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/InputStreamZippedJarVisitor.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/InputStreamZippedJarVisitor.java	2008-01-10 10:11:13 UTC (rev 14272)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/InputStreamZippedJarVisitor.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -16,11 +16,13 @@
  *
  * @author Emmanuel Bernard
  */
-public class InputStreamZippedJarVisitor extends JarVisitor {
+public class InputStreamZippedJarVisitor extends AbstractJarVisitor {
 	private static Log log = LogFactory.getLog( InputStreamZippedJarVisitor.class );
+	private String entry;
 
-	public InputStreamZippedJarVisitor(URL url, Filter[] filters) {
+	public InputStreamZippedJarVisitor(URL url, Filter[] filters, String entry) {
 		super( url, filters );
+		this.entry = entry;
 	}
 
 	public InputStreamZippedJarVisitor(String fileName, Filter[] filters) {
@@ -37,9 +39,14 @@
 			log.warn( "Unable to find file (ignored): " + jarUrl, ze );
 			return;
 		}
-		JarEntry entry;
-		while ( ( entry = jis.getNextJarEntry() ) != null ) {
-			if ( !entry.isDirectory() ) {
+		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() ) {
 				int size;
 				byte[] tmpByte = new byte[ 4096 ];
 				byte[] entryBytes = new byte[0];
@@ -51,9 +58,12 @@
 					System.arraycopy( tmpByte, 0, current, entryBytes.length, size );
 					entryBytes = current;
 				}
+				//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(
-						entry.getName(),
+						name,
 						new ByteArrayInputStream( entryBytes ),
 						new ByteArrayInputStream( entryBytes )
 				);

Added: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarProtocolVisitor.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarProtocolVisitor.java	                        (rev 0)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarProtocolVisitor.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,53 @@
+//$
+package org.hibernate.ejb.packaging;
+
+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();
+	}
+
+}

Deleted: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitor.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitor.java	2008-01-10 10:11:13 UTC (rev 14272)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitor.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -1,475 +0,0 @@
-package org.hibernate.ejb.packaging;
-
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URISyntaxException;
-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.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.util.StringHelper;
-
-/**
- * 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
- */
-//TODO shortcut when filters are null or empty
-public abstract class JarVisitor {
-	private static Log log = LogFactory.getLog( JarVisitor.class );
-	protected String unqualifiedJarName;
-	protected URL jarUrl;
-	private 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;
-
-	/**
-	 * Get the JAR URL of the JAR containing the given entry
-	 * Method used in a non managed environment
-	 *
-	 * @param url URL pointing to the known file in the JAR
-	 * @param entry file known to be in the JAR
-	 * @return the JAR URL
-	 * @throws IllegalArgumentException if none URL is found
-	 */
-	public static final URL getJarURLFromURLEntry(URL url, String entry) throws IllegalArgumentException {
-		URL jarUrl;
-		String file = url.getFile();
-		if ( ! entry.startsWith( "/" ) ) entry = "/" + entry;
-		file = file.substring( 0, file.length() - entry.length() );
-		if ( file.endsWith( "!" ) ) file = file.substring( 0, file.length() - 1 );
-		try {
-			String protocol = url.getProtocol();
-
-			if ( "jar".equals( protocol )
-					|| "wsjar".equals( protocol ) ) { //Websphere has it's own way
-				//Original URL is like jar:protocol
-				jarUrl = new URL( file );
-				if ( "file".equals( jarUrl.getProtocol() ) ) {
-					//not escaped, need to voodoo
-					if ( file.indexOf( ' ' ) != -1 ) {
-						//not escaped, need to voodoo
-						jarUrl = new File( jarUrl.getFile() ).toURI().toURL(); //goes by toURI to escape the path
-					}
-				} //otherwise left as is
-			}
-			else if ( "zip".equals( protocol ) //Weblogic has it's own way
-					|| "code-source".equals( url.getProtocol() ) //OC4J prevent ejb.jar access (ie everything without path)
-					|| "file".equals( protocol ) ) { //if no wrapping is done
-				//we have extracted the zip file, so it should be read as a file
-				if ( file.indexOf( ' ' ) != -1 ) {
-					//not escaped, need to voodoo
-					jarUrl = new File(file).toURI().toURL(); //goes by toURI to escape the path
-				}
-				else {
-					jarUrl = new File(file).toURL();
-				}
-			}
-			else {
-				jarUrl = new URL( protocol, url.getHost(), url.getPort(), file );
-			}
-		}
-		catch (MalformedURLException e) {
-			throw new IllegalArgumentException(
-					"Unable to determine JAR Url from " + url + ". Cause: " + e.getMessage()
-			);
-		}
-		log.trace("JAR URL from URL Entry: " + url + " >> " + jarUrl);
-		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 final JarVisitor getVisitor(String jarPath, Filter[] filters) throws IllegalArgumentException {
-		File file = new File( jarPath );
-		if ( file.isFile() ) {
-			return new InputStreamZippedJarVisitor( jarPath, filters );
-		}
-		else {
-			return new ExplodedJarVisitor( jarPath, filters );
-		}
-	}
-
-	/**
-	 * Build a JarVisitor on the given JAR URL applying the given filters
-	 *
-	 * @throws IllegalArgumentException if the URL is malformed
-	 */
-	public static final JarVisitor getVisitor(URL jarUrl, Filter[] filters) throws IllegalArgumentException {
-		String protocol = jarUrl.getProtocol();
-		if ( "jar".equals( protocol ) ) {
-			return new InputStreamZippedJarVisitor( jarUrl, filters );
-		}
-		else if ( StringHelper.isEmpty( protocol ) || "file".equals( protocol ) ) {
-			File file;
-			try {
-				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 );
-			}
-			else {
-				return new FileZippedJarVisitor( jarUrl, filters );
-			}
-		}
-		else {
-			//let's assume the url can return the jar as a zip stream
-			return new InputStreamZippedJarVisitor( jarUrl, filters );
-		}
-	}
-
-	/**
-	 * Build a jar visitor from its jar string path
-	 */
-	private JarVisitor(String jarPath) {
-		URL jarUrl;
-		try {
-			//is it an url
-			jarUrl = new URL( jarPath );
-		}
-		catch (MalformedURLException e) {
-			try {
-				//consider it as a file path
-				jarUrl = new URL( "file:" + jarPath );
-			}
-			catch (MalformedURLException ee) {
-				throw new IllegalArgumentException( "Unable to find jar:" + jarPath, ee );
-			}
-		}
-		this.jarUrl = jarUrl;
-		unqualify();
-	}
-
-	protected JarVisitor(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 JarVisitor(URL url, Filter[] filters) {
-		this( url );
-		initFilters( filters );
-	}
-
-	private JarVisitor(URL url) {
-		jarUrl = url;
-		unqualify();
-	}
-
-	protected void unqualify() {
-		//FIXME weak algorithm subject to AOOBE
-		String fileName = jarUrl.getFile();
-		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.debug( "Searching mapped entities in jar/par: " + 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 final 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 {
-		if ( entryName.endsWith( "package-info.class" ) ) {
-			String name = entryName.substring( 0, entryName.length() - ".package-info.class".length() )
-					.replace( '/', '.' );
-			executeJavaElementFilter( name, packageFilters, is, secondIs );
-		}
-		else if ( entryName.endsWith( ".class" ) ) {
-			String name = entryName.substring( 0, entryName.length() - ".class".length() ).replace( '/', '.' );
-			log.debug( "Filtering: " + 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.debug( "File Filter matched for " + 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.debug( "Java element filter matched for " + 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;
-	}
-
-	/**
-	 * Filter used when searching elements in a JAR
-	 */
-	public static abstract class Filter {
-		private boolean retrieveStream;
-
-		protected Filter(boolean retrieveStream) {
-			this.retrieveStream = retrieveStream;
-		}
-
-		public boolean getStream() {
-			return retrieveStream;
-		}
-	}
-
-	/**
-	 * Filter use to match a file by its name
-	 */
-	public static 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);
-	}
-
-	/**
-	 * 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.
-	 */
-	public static 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);
-	}
-
-	/**
-	 * Filter on class elements
-	 *
-	 * @see JavaElementFilter
-	 */
-	public static abstract class ClassFilter extends JavaElementFilter {
-		/**
-		 * @see JavaElementFilter#JavaElementFilter(boolean, Class[])
-		 */
-		protected ClassFilter(boolean retrieveStream, Class[] annotations) {
-			super( retrieveStream, annotations );
-		}
-	}
-
-	/**
-	 * Filter on pachage element
-	 *
-	 * @see JavaElementFilter
-	 */
-	public static abstract class PackageFilter extends JavaElementFilter {
-		/**
-		 * @see JavaElementFilter#JavaElementFilter(boolean, Class[])
-		 */
-		protected PackageFilter(boolean retrieveStream, Class[] annotations) {
-			super( retrieveStream, annotations );
-		}
-	}
-
-	/**
-	 * Represent a JAR entry
-	 * Contains a name and an optional Input stream to the entry
-	 */
-	public static class Entry {
-		private String name;
-		private InputStream is;
-
-		public Entry(String name, InputStream is) {
-			this.name = name;
-			this.is = is;
-		}
-
-		public String getName() {
-			return name;
-		}
-
-		public InputStream getInputStream() {
-			return is;
-		}
-
-		public boolean equals(Object o) {
-			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;
-		}
-
-		public int hashCode() {
-			return name.hashCode();
-		}
-	}
-}

Added: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitor.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitor.java	                        (rev 0)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitor.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,25 @@
+//$
+package org.hibernate.ejb.packaging;
+
+import java.util.Set;
+import java.io.IOException;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface JarVisitor {
+	/**
+	 * Get the unqualified Jar name (ie wo path and wo extension)
+	 */
+	String getUnqualifiedJarName();
+
+	Filter[] getFilters();
+
+	/**
+	 * Return the matching entries for each filter in the same order the filter where passed
+	 *
+	 * @return array of Set of JarVisitor.Entry
+	 * @throws java.io.IOException if something went wrong
+	 */
+	Set[] getMatchingEntries() throws IOException;
+}

Added: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitorFactory.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitorFactory.java	                        (rev 0)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitorFactory.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,127 @@
+//$
+package org.hibernate.ejb.packaging;
+
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.io.File;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class JarVisitorFactory {
+	private static Log log = LogFactory.getLog( JarVisitorFactory.class );
+
+	/**
+	 * Get the JAR URL of the JAR containing the given entry
+	 * Method used in a non managed environment
+	 *
+	 * @param url URL pointing to the known file in the JAR
+	 * @param entry file known to be in the JAR
+	 * @return the JAR URL
+	 * @throws IllegalArgumentException if none URL is found
+	 */
+	public static URL getJarURLFromURLEntry(URL url, String entry) throws IllegalArgumentException {
+		URL jarUrl;
+		String file = url.getFile();
+		if ( ! entry.startsWith( "/" ) ) entry = "/" + entry;
+		file = file.substring( 0, file.length() - entry.length() );
+		if ( file.endsWith( "!" ) ) file = file.substring( 0, file.length() - 1 );
+		try {
+			String protocol = url.getProtocol();
+
+			if ( "jar".equals( protocol )
+					|| "wsjar".equals( protocol ) ) { //Websphere has it's own way
+				//Original URL is like jar:protocol
+				jarUrl = new URL( file );
+				if ( "file".equals( jarUrl.getProtocol() ) ) {
+					//not escaped, need to voodoo
+					if ( file.indexOf( ' ' ) != -1 ) {
+						//not escaped, need to voodoo
+						jarUrl = new File( jarUrl.getFile() ).toURI().toURL(); //goes by toURI to escape the path
+					}
+				} //otherwise left as is
+			}
+			else if ( "zip".equals( protocol ) //Weblogic has it's own way
+					|| "code-source".equals( url.getProtocol() ) //OC4J prevent ejb.jar access (ie everything without path)
+					|| "file".equals( protocol ) ) { //if no wrapping is done
+				//we have extracted the zip file, so it should be read as a file
+				if ( file.indexOf( ' ' ) != -1 ) {
+					//not escaped, need to voodoo
+					jarUrl = new File(file).toURI().toURL(); //goes by toURI to escape the path
+				}
+				else {
+					jarUrl = new File(file).toURL();
+				}
+			}
+			else {
+				jarUrl = new URL( protocol, url.getHost(), url.getPort(), file );
+			}
+		}
+		catch (MalformedURLException e) {
+			throw new IllegalArgumentException(
+					"Unable to determine JAR Url from " + url + ". Cause: " + e.getMessage()
+			);
+		}
+		log.trace("JAR URL from URL Entry: " + url + " >> " + jarUrl);
+		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 );
+		}
+		else {
+			return new ExplodedJarVisitor( jarPath, filters );
+		}
+	}
+
+	/**
+	 * 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 ) ) {
+			File file;
+			try {
+				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 );
+		}
+	}
+}

Added: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JavaElementFilter.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JavaElementFilter.java	                        (rev 0)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JavaElementFilter.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,31 @@
+//$
+package org.hibernate.ejb.packaging;
+
+/**
+ * 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);
+}
\ No newline at end of file

Added: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/PackageFilter.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/PackageFilter.java	                        (rev 0)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/PackageFilter.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,17 @@
+//$
+package org.hibernate.ejb.packaging;
+
+/**
+ * Filter on pachage element
+ *
+ * @author Emmanuel Bernard
+ * @see JavaElementFilter
+ */
+public abstract class PackageFilter extends JavaElementFilter {
+	/**
+	 * @see JavaElementFilter#JavaElementFilter(boolean, Class[])
+	 */
+	protected PackageFilter(boolean retrieveStream, Class[] annotations) {
+		super( retrieveStream, annotations );
+	}
+}
\ No newline at end of file

Added: entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/ApplicationServer.java
===================================================================
--- entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/ApplicationServer.java	                        (rev 0)
+++ entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/ApplicationServer.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,42 @@
+//$Id: ApplicationServer.java 11282 2007-03-14 22:05:59Z epbernard $
+package org.hibernate.ejb.test.pack.war;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+public class ApplicationServer {
+	private Integer id;
+	private String name;
+	private Version version;
+
+	@Id
+	@GeneratedValue
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Version getVersion() {
+		return version;
+	}
+
+	public void setVersion(Version version) {
+		this.version = version;
+	}
+}

Added: entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/IncrementListener.java
===================================================================
--- entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/IncrementListener.java	                        (rev 0)
+++ entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/IncrementListener.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,24 @@
+//$Id: $
+package org.hibernate.ejb.test.pack.war;
+
+import javax.persistence.PrePersist;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class IncrementListener {
+	private static int increment;
+
+	public static int getIncrement() {
+		return increment;
+	}
+
+	public static void reset() {
+		increment = 0;
+	}
+
+	@PrePersist
+	public void increment(Object entity) {
+		increment++;
+	}
+}

Added: entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Lighter.java
===================================================================
--- entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Lighter.java	                        (rev 0)
+++ entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Lighter.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,10 @@
+//$Id: $
+package org.hibernate.ejb.test.pack.war;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class Lighter {
+	public String name;
+	public String power;
+}

Added: entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Money.java
===================================================================
--- entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Money.java	                        (rev 0)
+++ entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Money.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,24 @@
+//$Id: $
+package org.hibernate.ejb.test.pack.war;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+public class Money {
+	private Integer id;
+
+	@Id @GeneratedValue
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+}

Added: entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Mouse.java
===================================================================
--- entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Mouse.java	                        (rev 0)
+++ entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Mouse.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,29 @@
+//$Id: Mouse.java 11282 2007-03-14 22:05:59Z epbernard $
+package org.hibernate.ejb.test.pack.war;
+
+import javax.persistence.ExcludeDefaultListeners;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at ExcludeDefaultListeners
+public class Mouse {
+	private Integer id;
+	private String name;
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+}

Added: entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/OtherIncrementListener.java
===================================================================
--- entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/OtherIncrementListener.java	                        (rev 0)
+++ entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/OtherIncrementListener.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,21 @@
+//$Id: $
+package org.hibernate.ejb.test.pack.war;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class OtherIncrementListener {
+	private static int increment;
+
+	public static int getIncrement() {
+		return OtherIncrementListener.increment;
+	}
+
+	public static void reset() {
+		increment = 0;
+	}
+
+	public void increment(Object entity) {
+		OtherIncrementListener.increment++;
+	}
+}

Added: entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Version.java
===================================================================
--- entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Version.java	                        (rev 0)
+++ entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/Version.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,43 @@
+//$Id: Version.java 11282 2007-03-14 22:05:59Z epbernard $
+package org.hibernate.ejb.test.pack.war;
+
+import javax.persistence.Embeddable;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Embeddable
+public class Version {
+	private static final String DOT = ".";
+	private int major;
+	private int minor;
+	private int micro;
+
+	public int getMajor() {
+		return major;
+	}
+
+	public void setMajor(int major) {
+		this.major = major;
+	}
+
+	public int getMinor() {
+		return minor;
+	}
+
+	public void setMinor(int minor) {
+		this.minor = minor;
+	}
+
+	public int getMicro() {
+		return micro;
+	}
+
+	public void setMicro(int micro) {
+		this.micro = micro;
+	}
+
+	public String toString() {
+		return new StringBuffer( major ).append( DOT ).append( minor ).append( DOT ).append( micro ).toString();
+	}
+}

Added: entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/package-info.java
===================================================================
--- entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/package-info.java	                        (rev 0)
+++ entitymanager/trunk/src/test/org/hibernate/ejb/test/pack/war/package-info.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,6 @@
+ at NamedQuery(name = "allMouse",
+		query = "select m from ApplicationServer m")
+package org.hibernate.ejb.test.pack.war;
+
+import org.hibernate.annotations.NamedQuery;
+

Modified: entitymanager/trunk/src/test/org/hibernate/ejb/test/packaging/JarVisitorTest.java
===================================================================
--- entitymanager/trunk/src/test/org/hibernate/ejb/test/packaging/JarVisitorTest.java	2008-01-10 10:11:13 UTC (rev 14272)
+++ entitymanager/trunk/src/test/org/hibernate/ejb/test/packaging/JarVisitorTest.java	2008-01-15 19:25:10 UTC (rev 14273)
@@ -6,6 +6,8 @@
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.Set;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarEntry;
 import javax.persistence.Embeddable;
 import javax.persistence.Entity;
 import javax.persistence.MappedSuperclass;
@@ -15,6 +17,13 @@
 import org.hibernate.ejb.packaging.InputStreamZippedJarVisitor;
 import org.hibernate.ejb.packaging.JarVisitor;
 import org.hibernate.ejb.packaging.FileZippedJarVisitor;
+import org.hibernate.ejb.packaging.JarProtocolVisitor;
+import org.hibernate.ejb.packaging.JarVisitorFactory;
+import org.hibernate.ejb.packaging.Filter;
+import org.hibernate.ejb.packaging.Entry;
+import org.hibernate.ejb.packaging.PackageFilter;
+import org.hibernate.ejb.packaging.ClassFilter;
+import org.hibernate.ejb.packaging.FileFilter;
 import org.hibernate.ejb.test.pack.defaultpar.ApplicationServer;
 import org.hibernate.ejb.test.pack.explodedpar.Carpet;
 
@@ -24,7 +33,7 @@
 public class JarVisitorTest extends TestCase {
 
 	public void testHttp() throws Exception {
-		URL url = JarVisitor.getJarURLFromURLEntry(
+		URL url = JarVisitorFactory.getJarURLFromURLEntry(
 				new URL(
 						"jar:http://www.ibiblio.org/maven/hibernate/jars/hibernate-annotations-3.0beta1.jar!/META-INF/persistence.xml"
 				),
@@ -38,7 +47,7 @@
 			//fail silently
 			return;
 		}
-		JarVisitor visitor = JarVisitor.getVisitor( url, getFilters() );
+		JarVisitor visitor = JarVisitorFactory.getVisitor( url, getFilters() );
 		assertEquals( 0, visitor.getMatchingEntries()[0].size() );
 		assertEquals( 0, visitor.getMatchingEntries()[1].size() );
 		assertEquals( 0, visitor.getMatchingEntries()[2].size() );
@@ -47,18 +56,18 @@
 	public void testInputStreamZippedJar() throws Exception {
 		String jarFileName = "file:./build/testresources/defaultpar.par";
 		//JarVisitor jarVisitor = new ZippedJarVisitor( jarFileName, true, true );
-		JarVisitor.Filter[] filters = getFilters();
-		JarVisitor jarVisitor = new InputStreamZippedJarVisitor( new URL( jarFileName ), filters );
+		Filter[] filters = getFilters();
+		JarVisitor jarVisitor = new InputStreamZippedJarVisitor( new URL( jarFileName ), filters, "" );
 		assertEquals( "defaultpar", jarVisitor.getUnqualifiedJarName() );
 		Set entries = jarVisitor.getMatchingEntries()[1];
 		assertEquals( 3, entries.size() );
-		JarVisitor.Entry entry = new JarVisitor.Entry( ApplicationServer.class.getName(), null );
+		Entry entry = new Entry( ApplicationServer.class.getName(), null );
 		assertTrue( entries.contains( entry ) );
-		entry = new JarVisitor.Entry( org.hibernate.ejb.test.pack.defaultpar.Version.class.getName(), null );
+		entry = new Entry( org.hibernate.ejb.test.pack.defaultpar.Version.class.getName(), null );
 		assertTrue( entries.contains( entry ) );
-		assertNull( ( (JarVisitor.Entry) entries.iterator().next() ).getInputStream() );
+		assertNull( ( (Entry) entries.iterator().next() ).getInputStream() );
 		assertEquals( 2, jarVisitor.getMatchingEntries()[2].size() );
-		for (JarVisitor.Entry localEntry : (Set<JarVisitor.Entry>) jarVisitor.getMatchingEntries()[2] ) {
+		for (Entry localEntry : (Set<Entry>) jarVisitor.getMatchingEntries()[2] ) {
 			assertNotNull( localEntry.getInputStream() );
 			localEntry.getInputStream().close();
 		}
@@ -70,21 +79,47 @@
 //		assertTrue( classes.contains( org.hibernate.ejb.test.pack.defaultpar.Version.class.getName() ) );
 	}
 
+	public void testJarProtocol() throws Exception {
+		String jarFileName = "jar:file:./build/testresources/war.war!/WEB-INF/classes";
+		//JarVisitor jarVisitor = new ZippedJarVisitor( jarFileName, true, true );
+		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.ejb.test.pack.war.ApplicationServer.class.getName(), null );
+		assertTrue( entries.contains( entry ) );
+		entry = new Entry( org.hibernate.ejb.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();
+		}
+
+//		Set<String> classes = jarVisitor.getClassNames();
+//		assertEquals( 3, classes.size() );
+//		assertTrue( classes.contains( ApplicationServer.class.getName() ) );
+//		assertTrue( classes.contains( Mouse.class.getName() ) );
+//		assertTrue( classes.contains( org.hibernate.ejb.test.pack.defaultpar.Version.class.getName() ) );
+	}
+
 	public void testZippedJar() throws Exception {
 		String jarFileName = "file:./build/testresources/defaultpar.par";
 		//JarVisitor jarVisitor = new ZippedJarVisitor( jarFileName, true, true );
-		JarVisitor.Filter[] filters = getFilters();
-		JarVisitor jarVisitor = new FileZippedJarVisitor( new URL( jarFileName ), filters );
+		Filter[] filters = getFilters();
+		JarVisitor jarVisitor = new FileZippedJarVisitor( new URL( jarFileName ), filters, "" );
 		assertEquals( "defaultpar", jarVisitor.getUnqualifiedJarName() );
 		Set entries = jarVisitor.getMatchingEntries()[1];
 		assertEquals( 3, entries.size() );
-		JarVisitor.Entry entry = new JarVisitor.Entry( ApplicationServer.class.getName(), null );
+		Entry entry = new Entry( ApplicationServer.class.getName(), null );
 		assertTrue( entries.contains( entry ) );
-		entry = new JarVisitor.Entry( org.hibernate.ejb.test.pack.defaultpar.Version.class.getName(), null );
+		entry = new Entry( org.hibernate.ejb.test.pack.defaultpar.Version.class.getName(), null );
 		assertTrue( entries.contains( entry ) );
-		assertNull( ( (JarVisitor.Entry) entries.iterator().next() ).getInputStream() );
+		assertNull( ( (Entry) entries.iterator().next() ).getInputStream() );
 		assertEquals( 2, jarVisitor.getMatchingEntries()[2].size() );
-		for (JarVisitor.Entry localEntry : (Set<JarVisitor.Entry>) jarVisitor.getMatchingEntries()[2] ) {
+		for (Entry localEntry : (Set<Entry>) jarVisitor.getMatchingEntries()[2] ) {
 			assertNotNull( localEntry.getInputStream() );
 			localEntry.getInputStream().close();
 		}
@@ -98,7 +133,7 @@
 	public void testExplodedJar() throws Exception {
 		String jarFileName = "./build/testresources/explodedpar.par";
 		//JarVisitor jarVisitor = new ExplodedJarVisitor( jarFileName, true, true );
-		JarVisitor.Filter[] filters = getFilters();
+		Filter[] filters = getFilters();
 		JarVisitor jarVisitor = new ExplodedJarVisitor( jarFileName, filters );
 		assertEquals( "explodedpar", jarVisitor.getUnqualifiedJarName() );
 		Set[] entries = jarVisitor.getMatchingEntries();
@@ -106,9 +141,9 @@
 		assertEquals( 1, entries[0].size() );
 		assertEquals( 1, entries[2].size() );
 
-		JarVisitor.Entry entry = new JarVisitor.Entry( Carpet.class.getName(), null );
+		Entry entry = new Entry( Carpet.class.getName(), null );
 		assertTrue( entries[1].contains( entry ) );
-		for (JarVisitor.Entry localEntry : (Set<JarVisitor.Entry>) jarVisitor.getMatchingEntries()[2] ) {
+		for (Entry localEntry : (Set<Entry>) jarVisitor.getMatchingEntries()[2] ) {
 			assertNotNull( localEntry.getInputStream() );
 			localEntry.getInputStream().close();
 		}
@@ -122,14 +157,14 @@
 	public void testDuplicateFilterExplodedJarExpectedfail() throws Exception {
 		String jarFileName = "./build/testresources/explodedpar.par";
 		//JarVisitor jarVisitor = new ExplodedJarVisitor( jarFileName, true, true );
-		JarVisitor.Filter[] filters = getFilters();
-		JarVisitor.Filter[] dupeFilters = new JarVisitor.Filter[filters.length * 2];
+		Filter[] filters = getFilters();
+		Filter[] dupeFilters = new Filter[filters.length * 2];
 		int index = 0;
-		for ( JarVisitor.Filter filter : filters ) {
+		for ( Filter filter : filters ) {
 			dupeFilters[index++] = filter;
 		}
 		filters = getFilters();
-		for ( JarVisitor.Filter filter : filters ) {
+		for ( Filter filter : filters ) {
 			dupeFilters[index++] = filter;
 		}
 		JarVisitor jarVisitor = new ExplodedJarVisitor( jarFileName, dupeFilters );
@@ -138,14 +173,14 @@
 		assertEquals( 1, entries[1].size() );
 		assertEquals( 1, entries[0].size() );
 		assertEquals( 1, entries[2].size() );
-		for ( JarVisitor.Entry entry : (Set<JarVisitor.Entry>) entries[2] ) {
+		for ( Entry entry : (Set<Entry>) entries[2] ) {
 			InputStream is = entry.getInputStream();
 			if ( is != null ) {
 				assertTrue( 0 < is.available() );
 				is.close();
 			}
 		}
-		for ( JarVisitor.Entry entry : (Set<JarVisitor.Entry>) entries[5] ) {
+		for ( Entry entry : (Set<Entry>) entries[5] ) {
 			InputStream is = entry.getInputStream();
 			if ( is != null ) {
 				assertTrue( 0 < is.available() );
@@ -153,18 +188,18 @@
 			}
 		}
 
-		JarVisitor.Entry entry = new JarVisitor.Entry( Carpet.class.getName(), null );
+		Entry entry = new Entry( Carpet.class.getName(), null );
 		assertTrue( entries[1].contains( entry ) );
 	}
 
-	private JarVisitor.Filter[] getFilters() {
-		return new JarVisitor.Filter[]{
-				new JarVisitor.PackageFilter( false, null ) {
+	private Filter[] getFilters() {
+		return new Filter[]{
+				new PackageFilter( false, null ) {
 					public boolean accept(String javaElementName) {
 						return true;
 					}
 				},
-				new JarVisitor.ClassFilter(
+				new ClassFilter(
 						false, new Class[]{
 						Entity.class,
 						MappedSuperclass.class,
@@ -174,7 +209,7 @@
 						return true;
 					}
 				},
-				new JarVisitor.FileFilter( true ) {
+				new FileFilter( true ) {
 					public boolean accept(String javaElementName) {
 						return javaElementName.endsWith( "hbm.xml" ) || javaElementName.endsWith( "META-INF/orm.xml" );
 					}

Added: entitymanager/trunk/src/test-resources/war/WEB-INF/classes/META-INF/orm.xml
===================================================================
--- entitymanager/trunk/src/test-resources/war/WEB-INF/classes/META-INF/orm.xml	                        (rev 0)
+++ entitymanager/trunk/src/test-resources/war/WEB-INF/classes/META-INF/orm.xml	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
+                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
+                 version="1.0"
+        >
+    <persistence-unit-metadata>
+        <persistence-unit-defaults>
+            <entity-listeners>
+                <entity-listener class="org.hibernate.ejb.test.pack.defaultpar.IncrementListener">
+                    <pre-persist method-name="increment"/>
+                </entity-listener>
+            </entity-listeners>
+        </persistence-unit-defaults>
+    </persistence-unit-metadata>
+    <package>org.hibernate.ejb.test.pack.defaultpar</package>
+    <entity class="Lighter" access="FIELD" metadata-complete="true">
+        <attributes>
+            <id name="name">
+                <column name="fld_id"/>
+            </id>
+            <basic name="power"></basic>
+        </attributes>
+    </entity>
+    <entity class="ApplicationServer">
+        <entity-listeners>
+            <entity-listener class="OtherIncrementListener">
+                <pre-persist method-name="increment"/>
+            </entity-listener>
+        </entity-listeners>
+    </entity>
+</entity-mappings>
\ No newline at end of file

Added: entitymanager/trunk/src/test-resources/war/WEB-INF/classes/META-INF/persistence.xml
===================================================================
--- entitymanager/trunk/src/test-resources/war/WEB-INF/classes/META-INF/persistence.xml	                        (rev 0)
+++ entitymanager/trunk/src/test-resources/war/WEB-INF/classes/META-INF/persistence.xml	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- example of a default persistence.xml -->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
+             version="1.0">
+    <persistence-unit name="defaultpar">
+        <class>org.hibernate.ejb.test.pack.defaultpar.Lighter</class>
+        <properties>
+            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
+            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
+            <property name="hibernate.connection.username" value="sa"/>
+            <property name="hibernate.connection.password" value=""/>
+            <property name="hibernate.connection.url" value="jdbc:hsqldb:."/>
+            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
+            <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/>
+        </properties>
+    </persistence-unit>
+</persistence>

Added: entitymanager/trunk/src/test-resources/war/WEB-INF/classes/org/hibernate/ejb/test/pack/war/Mouse.hbm.xml
===================================================================
--- entitymanager/trunk/src/test-resources/war/WEB-INF/classes/org/hibernate/ejb/test/pack/war/Mouse.hbm.xml	                        (rev 0)
+++ entitymanager/trunk/src/test-resources/war/WEB-INF/classes/org/hibernate/ejb/test/pack/war/Mouse.hbm.xml	2008-01-15 19:25:10 UTC (rev 14273)
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping
+        package="org.hibernate.ejb.test.pack.war"
+        >
+
+    <class name="Mouse">
+
+        <id name="id">
+            <generator class="native"/>
+        </id>
+        <property name="name"/>
+
+    </class>
+
+</hibernate-mapping>




More information about the hibernate-commits mailing list