package org.docear.plugin.core.io; import java.io.IOException; import java.io.InputStream; import java.util.Map; import java.util.Set; public class ReplacingInputStream extends InputStream { private final InputStream innerStream; private Map<String, String> mapping; private StringBuffer buffer = new StringBuffer(); private Set<String> keys; public ReplacingInputStream(Map<String, String> replaceMap, InputStream is) { this.innerStream = is; this.mapping = replaceMap; this.keys = mapping.keySet(); } public int available() throws IOException{ return innerStream.available()+buffer.length(); } public int read() throws IOException { if(buffer.length() > 0) { try { return buffer.charAt(0); } finally { buffer.deleteCharAt(0); } } int c = innerStream.read(); if(c > -1) { buffer.append((char)c); boolean try2Replace = false; while(keyStartsWith(buffer.toString())) { c = innerStream.read(); buffer.append((char)c); if(keys.contains(buffer.toString())) { try2Replace = true; break; } } if(try2Replace) { tryToReplace(); } try { return buffer.charAt(0); } finally { buffer.deleteCharAt(0); } } return c; } private void tryToReplace() { String replacement = mapping.get(buffer.toString()); if(replacement != null) { buffer.delete(0, buffer.length()); buffer.append(replacement); } } public boolean keyStartsWith(String prefix) { for(String key : keys) { if(key.startsWith(prefix)) { return true; } } return false; } public void close() throws IOException { innerStream.close(); } }