/* * HA-JDBC: High-Availability JDBC * Copyright (C) 2014 Paul Ferraro * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.hajdbc.xml; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.util.StreamReaderDelegate; import net.sf.hajdbc.util.Strings; import net.sf.hajdbc.util.SystemProperties; public class PropertyReplacementFilter extends StreamReaderDelegate { private static final Pattern PATTERN = Pattern.compile("\\$\\{([^\\}]+)\\}"); private final Properties properties; public PropertyReplacementFilter(XMLStreamReader reader) { this(reader, SystemProperties.getSystemProperties()); } public PropertyReplacementFilter(XMLStreamReader reader, Properties properties) { super(reader); this.properties = properties; } @Override public String getAttributeValue(int index) { return this.replace(super.getAttributeValue(index)); } @Override public String getAttributeValue(String namespaceUri, String localName) { return this.replace(super.getAttributeValue(namespaceUri, localName)); } @Override public String getElementText() throws XMLStreamException { return this.replace(super.getElementText()); } @Override public String getText() { return this.replace(super.getText()); } @Override public char[] getTextCharacters() { return this.replace(String.valueOf(super.getTextCharacters())).toCharArray(); } @Override public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException { throw new UnsupportedOperationException(); } private String replace(String input) { if (input == null) return null; Matcher matcher = PATTERN.matcher(input); if (!matcher.find()) return input; StringBuilder builder = new StringBuilder(); int tail = 0; do { builder.append(input, tail, matcher.start()); String group = matcher.group(1); if (group.equals("/")) { builder.append(Strings.FILE_SEPARATOR); } else if (group.equals(":")) { builder.append(Strings.PATH_SEPARATOR); } else { String key = group; String defaultValue = null; int index = group.indexOf(":"); if (index > 0) { key = group.substring(0, index); defaultValue = group.substring(index + 1); } String value = this.getProperty(key.split(","), defaultValue); builder.append((value != null) ? value : matcher.group()); } tail = matcher.end(); } while (matcher.find()); builder.append(input, tail, input.length()); return builder.toString(); } private String getProperty(String[] keys, String defaultValue) { for (String key: keys) { String value = this.properties.getProperty(key.trim()); if (value != null) return value; } return defaultValue; } }