Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBorislav Kapukaranov2012-08-14 11:40:55 -0400
committerBorislav Kapukaranov2012-08-14 11:40:55 -0400
commit0c92c50b943b91b4dad0362ab9897641bca11aeb (patch)
tree9c302adef20ed92ad05eec146284624517bf9358 /org.eclipse.virgo.kernel.artifact
parent597521074e04a04f34805201c246e42b09afba0b (diff)
parent7650c986b40e8bdb82195e609afcb1c0b66538d0 (diff)
downloadorg.eclipse.virgo.kernel-0c92c50b943b91b4dad0362ab9897641bca11aeb.tar.gz
org.eclipse.virgo.kernel-0c92c50b943b91b4dad0362ab9897641bca11aeb.tar.xz
org.eclipse.virgo.kernel-0c92c50b943b91b4dad0362ab9897641bca11aeb.zip
Merge branch 'master' of ssh://git.eclipse.org/gitroot/virgo/org.eclipse.virgo.kernel into 380765-shared-ivycache
Diffstat (limited to 'org.eclipse.virgo.kernel.artifact')
-rw-r--r--org.eclipse.virgo.kernel.artifact/src/main/java/org/eclipse/virgo/kernel/artifact/fs/internal/JarFileArtifactFSEntry.java98
-rw-r--r--org.eclipse.virgo.kernel.artifact/src/test/java/org/eclipse/virgo/kernel/artifact/fs/internal/JarFileArtifactFSTests.java37
-rw-r--r--org.eclipse.virgo.kernel.artifact/src/test/resources/artifacts/bundle-with-missing-entries.jarbin0 -> 713 bytes
3 files changed, 130 insertions, 5 deletions
diff --git a/org.eclipse.virgo.kernel.artifact/src/main/java/org/eclipse/virgo/kernel/artifact/fs/internal/JarFileArtifactFSEntry.java b/org.eclipse.virgo.kernel.artifact/src/main/java/org/eclipse/virgo/kernel/artifact/fs/internal/JarFileArtifactFSEntry.java
index 916757fb..271037a7 100644
--- a/org.eclipse.virgo.kernel.artifact/src/main/java/org/eclipse/virgo/kernel/artifact/fs/internal/JarFileArtifactFSEntry.java
+++ b/org.eclipse.virgo.kernel.artifact/src/main/java/org/eclipse/virgo/kernel/artifact/fs/internal/JarFileArtifactFSEntry.java
@@ -36,6 +36,10 @@ import org.eclipse.virgo.kernel.artifact.fs.ArtifactFSEntry;
* ZipFile. See the note on caching in http://java.sun.com/developer/technicalArticles/Programming/compression/
* JarFile's caching behaviour is unsuitable as it produces incorrect results when a JAR file is replaced with a new
* version since the cache returns entries from the old version.
+ * <p/>
+ * The implementation handles missing directory entries by simulating them. Although this does not faithfully reflect
+ * the structure of a JAR with a missing directory entry, it is more robust for callers who may not expect, or test
+ * with, such JARs.
*
* <strong>Concurrent Semantics</strong><br />
*
@@ -92,7 +96,11 @@ final class JarFileArtifactFSEntry implements ArtifactFSEntry {
*/
public boolean isDirectory() {
ZipEntry zipEntry = findZipEntry();
- return zipEntry != null ? zipEntry.isDirectory() : false;
+ if (zipEntry != null) {
+ return zipEntry.isDirectory();
+ } else {
+ return hasChildren();
+ }
}
private ZipEntry findZipEntry() {
@@ -111,11 +119,32 @@ final class JarFileArtifactFSEntry implements ArtifactFSEntry {
}
}
+ // This method copes with non-existent entries.
+ private boolean hasChildren() {
+ boolean hasChildren = false;
+ if (this.entryName.endsWith("/")) {
+ JarFileScanner scanner = new JarFileScanner();
+ try {
+ ZipEntry entry = scanner.getNextEntry();
+ while (entry != null) {
+ String name = entry.getName();
+ if (name != null && name.startsWith(this.entryName)) {
+ hasChildren = true;
+ break;
+ }
+ entry = scanner.getNextEntry();
+ }
+ } finally {
+ scanner.close();
+ }
+ }
+ return hasChildren;
+ }
+
/**
* {@inheritDoc}
*/
- @SuppressWarnings("resource")
- public InputStream getInputStream() {
+ public InputStream getInputStream() {
JarFileScanner scanner = new JarFileScanner();
ZipEntry entry = scanner.getNextEntry();
while (entry != null && !this.entryName.equals(entry.getName())) {
@@ -156,7 +185,9 @@ final class JarFileArtifactFSEntry implements ArtifactFSEntry {
while (entry != null) {
String childEntry = entry.getName();
if (childEntry.length() > this.entryName.length() && childEntry.startsWith(this.entryName)) {
- children.add(new JarFileArtifactFSEntry(this.file, childEntry));
+ children.add(createChildEntry(childEntry));
+ // Ensure missing parents of this child are added.
+ addParentDirectories(childEntry, children);
}
entry = scanner.getNextEntry();
}
@@ -167,6 +198,22 @@ final class JarFileArtifactFSEntry implements ArtifactFSEntry {
return children.toArray(new ArtifactFSEntry[children.size()]);
}
+ public JarFileArtifactFSEntry createChildEntry(String childEntryName) {
+ return new JarFileArtifactFSEntry(this.file, childEntryName);
+ }
+
+ // Precondition: childEntry.length() > this.entryName.length() && childEntry.startsWith(this.entryName)
+ private void addParentDirectories(String childEntry, Set<ArtifactFSEntry> children) {
+ int l = this.entryName.length();
+ String childPath = childEntry.substring(l);
+ String[] childPathComponents = childPath.split("/");
+ String parentPath = this.entryName;
+ for (int parent = 0; parent < childPathComponents.length - 1; parent++) {
+ parentPath = parentPath + childPathComponents[parent]+ "/";
+ children.add(createChildEntry(parentPath));
+ }
+ }
+
/**
* {@inheritDoc}
*/
@@ -178,7 +225,11 @@ final class JarFileArtifactFSEntry implements ArtifactFSEntry {
* {@inheritDoc}
*/
public boolean exists() {
- return findZipEntry() != null;
+ if (findZipEntry() != null) {
+ return true;
+ } else {
+ return hasChildren();
+ }
}
private class JarFileScanner implements Closeable {
@@ -219,4 +270,41 @@ final class JarFileArtifactFSEntry implements ArtifactFSEntry {
}
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((entryName == null) ? 0 : entryName.hashCode());
+ result = prime * result + ((file == null) ? 0 : file.hashCode());
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof JarFileArtifactFSEntry))
+ return false;
+ JarFileArtifactFSEntry other = (JarFileArtifactFSEntry) obj;
+ if (entryName == null) {
+ if (other.entryName != null)
+ return false;
+ } else if (!entryName.equals(other.entryName))
+ return false;
+ if (file == null) {
+ if (other.file != null)
+ return false;
+ } else if (!file.equals(other.file))
+ return false;
+ return true;
+ }
+
}
diff --git a/org.eclipse.virgo.kernel.artifact/src/test/java/org/eclipse/virgo/kernel/artifact/fs/internal/JarFileArtifactFSTests.java b/org.eclipse.virgo.kernel.artifact/src/test/java/org/eclipse/virgo/kernel/artifact/fs/internal/JarFileArtifactFSTests.java
index 6bc33e84..f79b4a1f 100644
--- a/org.eclipse.virgo.kernel.artifact/src/test/java/org/eclipse/virgo/kernel/artifact/fs/internal/JarFileArtifactFSTests.java
+++ b/org.eclipse.virgo.kernel.artifact/src/test/java/org/eclipse/virgo/kernel/artifact/fs/internal/JarFileArtifactFSTests.java
@@ -28,6 +28,8 @@ public class JarFileArtifactFSTests {
private final FileArtifactFS artifactFS = new JarFileArtifactFS(new File("src/test/resources/artifacts/simple.jar"));
+ private final FileArtifactFS artifactFSWithMissingEntries = new JarFileArtifactFS(new File("src/test/resources/artifacts/bundle-with-missing-entries.jar"));
+
@Test(expected = IllegalArgumentException.class)
public void constructorDirectory() {
new JarFileArtifactFS(new File("target"));
@@ -221,5 +223,40 @@ public class JarFileArtifactFSTests {
String contents = new Scanner(inputStream).useDelimiter("\\A").next();
assertTrue(contents.startsWith("<beans xmlns=\"http://www.springframework.org/schema/beans\""));
}
+
+ @Test
+ public void getMissingDirectoryEntry() {
+ ArtifactFSEntry entry = this.artifactFSWithMissingEntries.getEntry("META-INF/spring/");
+ assertTrue(entry.exists());
+ assertTrue(entry.isDirectory());
+ }
+
+ @Test
+ public void getMissingDirectoryEntryName() {
+ ArtifactFSEntry entry = this.artifactFSWithMissingEntries.getEntry("META-INF/spring/");
+ assertEquals("spring", entry.getName());
+ assertEquals("META-INF/spring/", entry.getPath());
+ }
+
+ @Test
+ public void getMissingDirectoryEntryChildren() {
+ ArtifactFSEntry entry = this.artifactFSWithMissingEntries.getEntry("META-INF/spring/");
+ ArtifactFSEntry[] children = entry.getChildren();
+ assertEquals(1, children.length);
+ }
+
+ @Test
+ public void getChildrenIncludingMissingEntry() {
+ ArtifactFSEntry entry = this.artifactFSWithMissingEntries.getEntry("META-INF/");
+ ArtifactFSEntry[] children = entry.getChildren();
+ assertEquals(3, children.length);
+ boolean found = false;
+ for (ArtifactFSEntry artifactFSEntry : children) {
+ if (artifactFSEntry.getPath().equals("META-INF/spring/")) {
+ found = true;
+ }
+ }
+ assertTrue(found);
+ }
}
diff --git a/org.eclipse.virgo.kernel.artifact/src/test/resources/artifacts/bundle-with-missing-entries.jar b/org.eclipse.virgo.kernel.artifact/src/test/resources/artifacts/bundle-with-missing-entries.jar
new file mode 100644
index 00000000..ea524f8c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.artifact/src/test/resources/artifacts/bundle-with-missing-entries.jar
Binary files differ

Back to the top