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

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Feb 4 17:25:33 EST 2008


Author: epbernard
Date: 2008-02-04 17:25:33 -0500 (Mon, 04 Feb 2008)
New Revision: 14309

Modified:
   entitymanager/trunk/build.xml
   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/java/org/hibernate/ejb/packaging/JarVisitorFactory.java
   entitymanager/trunk/src/test/org/hibernate/ejb/test/packaging/JarVisitorTest.java
Log:
EJB-332 handled nested jars if the root URL points to one jar:file:...foo.ear!/bar.jar

Modified: entitymanager/trunk/build.xml
===================================================================
--- entitymanager/trunk/build.xml	2008-02-03 05:57:08 UTC (rev 14308)
+++ entitymanager/trunk/build.xml	2008-02-04 22:25:33 UTC (rev 14309)
@@ -17,7 +17,7 @@
     <!-- Name of project and version, used to create filenames -->
     <property name="Name" value="Hibernate EntityManager"/>
     <property name="name" value="hibernate-entitymanager"/>
-    <property name="version" value="3.3.2.Beta2"/>
+    <property name="version" value="3.3.2.Beta3"/>
     <property name="javadoc.packagenames" value="org.hibernate.ejb.*"/>
     <property name="jdbc.dir" value="jdbc"/>
     <property name="copy.test" value="true"/>
@@ -203,6 +203,18 @@
             <param name="jarname" value="overridenpar"/>
         </antcall>
 
+        <!-- nested jar -->
+        <jar destfile="${build.testresources.dir}/nestedjar.ear">
+            <fileset dir="${build.testresources.dir}">
+                <include name="defaultpar.par"/>
+            </fileset>
+        </jar>
+        <copy todir="${build.testresources.dir}/nesteddir.ear">
+            <fileset dir="${build.testresources.dir}">
+                <include name="defaultpar.par"/>
+            </fileset>
+        </copy>
+
         <antcall target="packjar" inheritall="true">
             <param name="extension" value="war"/>
             <param name="jarname" value="war"/>

Modified: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/ExplodedJarVisitor.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/ExplodedJarVisitor.java	2008-02-03 05:57:08 UTC (rev 14308)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/ExplodedJarVisitor.java	2008-02-04 22:25:33 UTC (rev 14309)
@@ -5,8 +5,14 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
 import java.net.URL;
 import java.net.URISyntaxException;
+import java.util.zip.ZipEntry;
+import java.util.Enumeration;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarFile;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -51,9 +57,35 @@
 		else {
 			rootFile = jarFile;
 		}
-		getClassNamesInTree( rootFile, null );
+		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 + "/";

Modified: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/FileZippedJarVisitor.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/FileZippedJarVisitor.java	2008-02-03 05:57:08 UTC (rev 14308)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/FileZippedJarVisitor.java	2008-02-04 22:25:33 UTC (rev 14309)
@@ -3,10 +3,13 @@
 
 import java.io.BufferedInputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
 import java.net.URL;
 import java.net.URISyntaxException;
 import java.util.Enumeration;
 import java.util.jar.JarFile;
+import java.util.jar.JarInputStream;
 import java.util.zip.ZipEntry;
 
 import org.apache.commons.logging.Log;
@@ -52,14 +55,45 @@
 			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(
-						name,
-						new BufferedInputStream( jarFile.getInputStream( zipEntry ) ),
-						new BufferedInputStream( jarFile.getInputStream( zipEntry ) )
-				);
+				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 ) )
+					);
+				}
 			}
 		}
 	}

Modified: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/InputStreamZippedJarVisitor.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/InputStreamZippedJarVisitor.java	2008-02-03 05:57:08 UTC (rev 14308)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/InputStreamZippedJarVisitor.java	2008-02-04 22:25:33 UTC (rev 14309)
@@ -3,9 +3,12 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.BufferedInputStream;
 import java.net.URL;
 import java.util.jar.JarEntry;
 import java.util.jar.JarInputStream;
+import java.util.zip.ZipEntry;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -47,26 +50,46 @@
 			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];
-				for ( ; ; ) {
-					size = jis.read( tmpByte );
-					if ( size == -1 ) break;
-					byte[] current = new byte[ entryBytes.length + size ];
-					System.arraycopy( entryBytes, 0, current, 0, entryBytes.length );
-					System.arraycopy( tmpByte, 0, current, entryBytes.length, size );
-					entryBytes = current;
+				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();
+					}
 				}
-				//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 )
-				);
+				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();

Modified: entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitorFactory.java
===================================================================
--- entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitorFactory.java	2008-02-03 05:57:08 UTC (rev 14308)
+++ entitymanager/trunk/src/java/org/hibernate/ejb/packaging/JarVisitorFactory.java	2008-02-04 22:25:33 UTC (rev 14309)
@@ -5,6 +5,8 @@
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -124,4 +126,19 @@
 			return new InputStreamZippedJarVisitor( jarUrl, filters, entry );
 		}
 	}
+
+	public static byte[] getBytesFromInputStream(InputStream inputStream) throws IOException {
+		int size;
+		byte[] tmpByte = new byte[ 4096 ];
+		byte[] entryBytes = new byte[0];
+		for ( ; ; ) {
+			size = inputStream.read( tmpByte );
+			if ( size == -1 ) break;
+			byte[] current = new byte[ entryBytes.length + size ];
+			System.arraycopy( entryBytes, 0, current, 0, entryBytes.length );
+			System.arraycopy( tmpByte, 0, current, entryBytes.length, size );
+			entryBytes = current;
+		}
+		return entryBytes;
+	}
 }

Modified: entitymanager/trunk/src/test/org/hibernate/ejb/test/packaging/JarVisitorTest.java
===================================================================
--- entitymanager/trunk/src/test/org/hibernate/ejb/test/packaging/JarVisitorTest.java	2008-02-03 05:57:08 UTC (rev 14308)
+++ entitymanager/trunk/src/test/org/hibernate/ejb/test/packaging/JarVisitorTest.java	2008-02-04 22:25:33 UTC (rev 14309)
@@ -79,6 +79,52 @@
 //		assertTrue( classes.contains( org.hibernate.ejb.test.pack.defaultpar.Version.class.getName() ) );
 	}
 
+	public void testNestedJarProtocol() throws Exception {
+		String jarFileName = "jar:file:./build/testresources/nestedjar.ear!/defaultpar.par";
+		//JarVisitor jarVisitor = new ZippedJarVisitor( jarFileName, true, true );
+		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( ApplicationServer.class.getName(), null );
+		assertTrue( entries.contains( entry ) );
+		entry = new Entry( org.hibernate.ejb.test.pack.defaultpar.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();
+		}
+
+		jarFileName = "jar:file:./build/testresources/nesteddir.ear!/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( ApplicationServer.class.getName(), null );
+		assertTrue( entries.contains( entry ) );
+		entry = new Entry( org.hibernate.ejb.test.pack.defaultpar.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 testJarProtocol() throws Exception {
 		String jarFileName = "jar:file:./build/testresources/war.war!/WEB-INF/classes";
 		//JarVisitor jarVisitor = new ZippedJarVisitor( jarFileName, true, true );
@@ -130,6 +176,7 @@
 //		assertTrue( classes.contains( org.hibernate.ejb.test.pack.defaultpar.Version.class.getName() ) );
 	}
 
+
 	public void testExplodedJar() throws Exception {
 		String jarFileName = "./build/testresources/explodedpar.par";
 		//JarVisitor jarVisitor = new ExplodedJarVisitor( jarFileName, true, true );




More information about the hibernate-commits mailing list