From 7af9cc6a222e81c3d73450dc423d89bd58b55cd0 Mon Sep 17 00:00:00 2001 From: hns Date: Thu, 24 Mar 2005 18:23:50 +0000 Subject: [PATCH] * Implement createResource() method so child resources can be used even if they don't exist * Fix horrible bug in update() where child items were created that weren't child resources at all --- .../repository/AbstractRepository.java | 14 +++- .../framework/repository/FileRepository.java | 7 ++ .../framework/repository/ZipRepository.java | 64 ++++++++++++++----- 3 files changed, 66 insertions(+), 19 deletions(-) diff --git a/src/helma/framework/repository/AbstractRepository.java b/src/helma/framework/repository/AbstractRepository.java index 144ad7d2..88ad88e5 100644 --- a/src/helma/framework/repository/AbstractRepository.java +++ b/src/helma/framework/repository/AbstractRepository.java @@ -55,10 +55,14 @@ public abstract class AbstractRepository implements Repository { String shortName; /** - * + * Called to check the repository's content. */ public abstract void update(); + /** + * Called to create a child resource for this repository + */ + protected abstract Resource createResource(String name); /** * @@ -83,7 +87,13 @@ public abstract class AbstractRepository implements Repository { public Resource getResource(String name) { update(); - return (Resource) resources.get(name); + Resource res = (Resource) resources.get(name); + // if resource does not exist, create it + if (res == null) { + res = createResource(name); + resources.put(name, res); + } + return res; } public Iterator getResources() { diff --git a/src/helma/framework/repository/FileRepository.java b/src/helma/framework/repository/FileRepository.java index c7f26440..7fe7149a 100644 --- a/src/helma/framework/repository/FileRepository.java +++ b/src/helma/framework/repository/FileRepository.java @@ -165,6 +165,13 @@ public class FileRepository extends AbstractRepository { } } + /** + * Called to create a child resource for this repository + */ + protected Resource createResource(String name) { + return new FileResource(new File(dir, name), this); + } + public int hashCode() { return 17 + (37 * dir.hashCode()); } diff --git a/src/helma/framework/repository/ZipRepository.java b/src/helma/framework/repository/ZipRepository.java index 5ee44a9c..463435dd 100644 --- a/src/helma/framework/repository/ZipRepository.java +++ b/src/helma/framework/repository/ZipRepository.java @@ -32,6 +32,8 @@ public final class ZipRepository extends AbstractRepository { // the nested directory depth of this repository private int depth; + String entryPath; + private long lastModified = -1; /** @@ -52,10 +54,10 @@ public final class ZipRepository extends AbstractRepository { } /** - * Constructs a ZipRepository using the zip entry belonging to the given + * Constructs a ZipRepository using the zip entryName belonging to the given * zip file and top-level repository * @param file a zip file - * @param zipentry zip entry + * @param zipentry zip entryName * @param parent repository */ private ZipRepository(File file, Repository parent, ZipEntry zipentry) { @@ -65,10 +67,12 @@ public final class ZipRepository extends AbstractRepository { if (zipentry == null) { name = shortName = file.getName(); depth = 0; + entryPath = ""; } else { - String[] entrypath = StringUtils.split(zipentry.getName(), "/"); - depth = entrypath.length; - shortName = entrypath[depth - 1]; + String[] pathArray = StringUtils.split(zipentry.getName(), "/"); + depth = pathArray.length; + shortName = pathArray[depth - 1]; + entryPath = zipentry.getName(); name = new StringBuffer(parent.getName()) .append('/').append(shortName).toString(); } @@ -92,31 +96,40 @@ public final class ZipRepository extends AbstractRepository { try { zipfile = getZipFile(); Enumeration en = zipfile.entries(); - ArrayList newRepositories = new ArrayList(); + HashMap newRepositories = new HashMap(); HashMap newResources = new HashMap(); while (en.hasMoreElements()) { ZipEntry entry = (ZipEntry) en.nextElement(); - String entryname = entry.getName(); - String[] entrypath = StringUtils.split(entryname, "/"); + String eName = entry.getName(); + + if (!eName.regionMatches(0, entryPath, 0, entryPath.length())) { + // not a child of ours + continue; + } + String[] entrypath = StringUtils.split(eName, "/"); // create new repositories and resources for all entries with a // path depth of this.depth + 1 - if (entrypath.length == depth + 1) { - if (entry.isDirectory()) { - newRepositories.add(new ZipRepository(file, this, entry)); - } else { - ZipResource resource = new ZipResource(file, entry, this); - newResources.put(resource.getShortName(), resource); + if (entrypath.length == depth + 1 && !entry.isDirectory()) { + // create a new child resource + ZipResource resource = new ZipResource(file, entry, this); + newResources.put(resource.getShortName(), resource); + } else if (entrypath.length > depth) { + // create a new child repository + if (!newRepositories.containsKey(entrypath[depth])) { + ZipEntry child = composeChildEntry(entrypath[depth]); + ZipRepository rep = new ZipRepository(file, this, child); + newRepositories.put(entrypath[depth], rep); } } } - repositories = (Repository[]) - newRepositories.toArray(new Repository[newRepositories.size()]); + repositories = (Repository[]) newRepositories.values() + .toArray(new Repository[newRepositories.size()]); resources = newResources; - } catch (IOException ex) { + } catch (Exception ex) { ex.printStackTrace(); repositories = new Repository[0]; if (resources == null) { @@ -134,6 +147,23 @@ public final class ZipRepository extends AbstractRepository { } } + private ZipEntry composeChildEntry(String name) { + if (entryPath == null || entryPath.length() == 0) { + return new ZipEntry(name); + } else if (entryPath.endsWith("/")) { + return new ZipEntry(entryPath + name); + } else { + return new ZipEntry(entryPath + "/" + name); + } + } + + /** + * Called to create a child resource for this repository + */ + protected Resource createResource(String name) { + return new ZipResource(file, new ZipEntry(entryPath + "/" + name), this); + } + public long getChecksum() { return file.lastModified(); }