Skip to content

Instantly share code, notes, and snippets.

@mrenouf
Created April 3, 2011 22:54
Show Gist options
  • Save mrenouf/900896 to your computer and use it in GitHub Desktop.
Save mrenouf/900896 to your computer and use it in GitHub Desktop.
Simplest possible streaming (filter) expansion of property references like ${property}
/*
* Copyright (C) 2011, Mark Renouf
*
* This code is licensed to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.bitgrind.util;
import java.io.BufferedReader;
import java.io.FilterReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.nio.CharBuffer;
import java.util.HashMap;
import java.util.Map;
public class PropertyFilter extends FilterReader {
static int maxVariableNameLength = 255;
CharBuffer buffer = CharBuffer.allocate(65535);
private Map<String, String> map;
protected PropertyFilter(Map<String, String> variables, Reader in) {
super(new BufferedReader(in, maxVariableNameLength + 3));
this.map = variables;
buffer.limit(0);
}
int rewindAndRead() throws IOException {
in.reset();
return in.read();
}
@Override
public int read() throws IOException {
// read from previously expanded buffer
if (buffer.remaining() > 0) {
return buffer.get();
}
in.mark(maxVariableNameLength + 3);
char ch = (char) in.read();
if (ch != '$') {
return rewindAndRead();
}
ch = (char) in.read();
if (ch != '{') {
return rewindAndRead();
}
int charsRead = 0;
ch = (char) in.read();
buffer.clear();
while (ch != '}' && ch != -1 && !Character.isWhitespace(ch) && charsRead < maxVariableNameLength) {
charsRead++;
buffer.append(ch);
ch = (char) in.read();
}
// abnormal termination or empty variable name
if (ch != '}' || buffer.position() == 0) {
buffer.clear();
buffer.limit(0);
return rewindAndRead();
}
buffer.flip();
String variable = buffer.toString();
if (map.containsKey(variable)) {
// add expanded value to buffer
buffer.clear();
buffer.put(map.get(variable));
buffer.flip();
// clear mark and skip over variable
in.reset();
in.skip(charsRead + 3);
return buffer.get();
} else {
// no matching key so output unchanged
return rewindAndRead();
}
}
@Override
public int read(char[] buffer, int offset, int count) throws IOException {
int i;
for (i = 0; i < count; i++) {
int ch = this.read();
if (ch == -1) {
if (i == 0) return -1;
break;
}
buffer[offset++] = (char) ch;
}
return i;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment