package org.xmind.core.io;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
*
* @author Frank Shaka
* @since 3.6.50
*/
public class PrefixedStorage implements IStorage {
private class PrefixedInputSource implements IInputSource, Closeable {
private IInputSource source;
public PrefixedInputSource(IInputSource source) {
this.source = source;
}
public boolean hasEntry(String entryName) {
return source.hasEntry(prefix + entryName);
}
public Iterator<String> getEntries() {
return new Iterator<String>() {
Iterator<String> it = source.getEntries();
String next = findNext();
private String findNext() {
while (it.hasNext()) {
String n = it.next();
if (n != null && n.startsWith(prefix)) {
return n.substring(prefix.length());
}
}
return null;
}
public void remove() {
}
public String next() {
String n = next;
next = findNext();
return n;
}
public boolean hasNext() {
return next != null;
}
};
}
public boolean isEntryAvailable(String entryName) {
return source.isEntryAvailable(prefix + entryName);
}
@Deprecated
public InputStream getEntryStream(String entryName) {
return source.getEntryStream(prefix + entryName);
}
public InputStream openEntryStream(String entryName)
throws IOException {
return source.openEntryStream(prefix + entryName);
}
public long getEntrySize(String entryName) {
return source.getEntrySize(prefix + entryName);
}
public long getEntryTime(String entryName) {
return source.getEntryTime(prefix + entryName);
}
public void close() throws IOException {
if (source instanceof Closeable) {
((Closeable) source).close();
}
}
}
private class PrefixedOutputTarget implements IOutputTarget, Closeable {
private IOutputTarget target;
public PrefixedOutputTarget(IOutputTarget target) {
this.target = target;
}
public boolean isEntryAvaialble(String entryName) {
return target.isEntryAvaialble(prefix + entryName);
}
@Deprecated
public OutputStream getEntryStream(String entryName) {
return target.getEntryStream(prefix + entryName);
}
public OutputStream openEntryStream(String entryName)
throws IOException {
return target.openEntryStream(prefix + entryName);
}
public void setEntryTime(String entryName, long time) {
target.setEntryTime(prefix + entryName, time);
}
public void close() throws IOException {
if (target instanceof Closeable) {
((Closeable) target).close();
}
}
}
private IStorage storage;
private String prefix;
public PrefixedStorage(IStorage storage, String prefix) {
this.storage = storage;
this.prefix = prefix;
}
public String getPrefix() {
return prefix;
}
public IStorage getStorage() {
return storage;
}
public IInputSource getInputSource() {
return new PrefixedInputSource(storage.getInputSource());
}
public IOutputTarget getOutputTarget() {
return new PrefixedOutputTarget(storage.getOutputTarget());
}
public String getName() {
return storage.getName();
}
public String getFullPath() {
return storage.getFullPath();
}
public void clear() {
Set<String> entriesToDelete = new HashSet<String>();
Iterator<String> it = storage.getInputSource().getEntries();
while (it.hasNext()) {
String entry = it.next();
while (entry.startsWith(prefix)) {
entriesToDelete.add(entry);
int slashIndex = entry.lastIndexOf('/');
if (slashIndex <= 0)
break;
entry = entry.substring(0, slashIndex);
}
}
List<String> entryList = new ArrayList<String>(entriesToDelete);
Collections.sort(entryList, Collections.reverseOrder());
for (String entry : entryList) {
storage.deleteEntry(entry);
}
storage.deleteEntry(prefix);
}
public void deleteEntry(String entryName) {
storage.deleteEntry(prefix + entryName);
}
public void renameEntry(String entryName, String newName) {
storage.renameEntry(prefix + entryName, prefix + newName);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return storage.hashCode() ^ prefix.hashCode();
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj == null || !(obj instanceof PrefixedStorage))
return false;
PrefixedStorage that = (PrefixedStorage) obj;
return this.storage.equals(that.storage)
&& this.prefix.equals(that.prefix);
}
}