package org.xmind.core.io; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.Enumeration; import java.util.Iterator; import java.util.Stack; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.osgi.framework.Bundle; public class BundleResourceInputSource implements IInputSource { private BundleResource base; public BundleResourceInputSource(BundleResource baseResource) { Assert.isNotNull(baseResource); BundleResource resolved = baseResource.resolve(); this.base = resolved == null ? baseResource : resolved; } public BundleResourceInputSource(String pluginId, String basePath) { this(new BundleResource(Platform.getBundle(pluginId), new Path(basePath))); } public BundleResourceInputSource(Bundle bundle, String basePath) { this(new BundleResource(bundle, new Path(basePath))); } private URL getEntry(String entryName) { BundleResource entryResource = new BundleResource(base.getBundle(), base.getPath().append(entryName)).resolve(); if (entryResource == null) return null; return entryResource.toPlatformURL(); } public boolean hasEntry(String entryName) { return getEntry(entryName) != null; } public Iterator<String> getEntries() { String basePath = base.getPath().toString(); final String prefix = basePath.startsWith("/") ? basePath.substring(1) //$NON-NLS-1$ : basePath; final Stack<Enumeration<String>> pathStack = new Stack<Enumeration<String>>(); pathStack.push(base.getBundle().getEntryPaths(basePath)); return new Iterator<String>() { private String nextPath = findNextPath(); private String findNextPath() { if (pathStack.isEmpty()) return null; Enumeration<String> paths = pathStack.peek(); if (!paths.hasMoreElements()) { // reached end of current path list pathStack.pop(); return findNextPath(); } String path = paths.nextElement(); if (path.endsWith("/")) { //$NON-NLS-1$ // directory path // add sub path list pathStack.push(base.getBundle().getEntryPaths(path)); return findNextPath(); } if (path.startsWith(prefix)) return path.substring(prefix.length()); return findNextPath(); } public void remove() { } public String next() { String p = nextPath; nextPath = findNextPath(); return p; } public boolean hasNext() { return nextPath != null; } }; } public boolean isEntryAvailable(String entryName) { return getEntry(entryName) != null; } public InputStream getEntryStream(String entryName) { try { return openEntryStream(entryName); } catch (IOException e) { return null; } } public InputStream openEntryStream(String entryName) throws IOException { URL entry = getEntry(entryName); if (entry == null) throw new FileNotFoundException(); return entry.openStream(); } public long getEntrySize(String entryName) { URL entry = getEntry(entryName); if (entry == null) return 0; URLConnection conn; try { conn = entry.openConnection(); } catch (IOException e) { return 0; } return conn.getContentLength(); } public long getEntryTime(String entryName) { URL entry = getEntry(entryName); if (entry == null) return 0; URLConnection conn; try { conn = entry.openConnection(); } catch (IOException e) { return 0; } return conn.getLastModified(); } }