/**
* Copyright 2007-2015 University Of Southern California
*
* Licensed 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 edu.isi.pegasus.common.util;
import org.apache.commons.lang3.text.StrSubstitutor;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.text.StrLookup;
/**
* Utility class to allow for variable expansions in strings.
*
* @author Karan Vahi
*/
public class VariableExpander {
/**
* The list of values mMap that need to be expanded.
*/
private Map<String,String> mValuesMap;
private StrSubstitutor mExpander;
/**
* The default constructor, which intializes the values from
* the System environment variables, and has case sensitivity turned off.
*/
public VariableExpander(){
this( false );
}
/**
* Overloaded constructor
*
* @param caseSensitive boolean indicating whether you want lookups to be
* case sensitive or not.
*/
public VariableExpander( boolean caseSensitive ){
mValuesMap = new HashMap(System.getenv());
mExpander = new StrSubstitutor( mValuesMap, "${", "}", '\\' );
mExpander.setVariableResolver( new CaseSensitiveStrLookup( this.mValuesMap, caseSensitive ));
}
/**
* Overloaded constructor. Constructs expander with case sensitivity turned off
*
* @param map containing variable names and values that need to be expanded
*/
public VariableExpander(Map<String,String> map ){
this( map, false );
}
/**
* Overloaded constructor
*
* @param map containing variable names and values that need to be expanded
* @param caseSensitive boolean indicating whether you want lookups to be
* case sensitive or not.
*/
public VariableExpander(Map<String,String> map, boolean caseSensitive ){
mValuesMap = map;
mExpander = new StrSubstitutor( map );
mExpander.setVariableResolver( new CaseSensitiveStrLookup( this.mValuesMap, caseSensitive ));
}
/**
* Expands the value passed with variable substitution
*
* @param text
*
* @return expanded value
*/
public String expand( String text ){
return mExpander.replace(text);
}
public static void main( String[] args ){
VariableExpander exp = new VariableExpander( );
System.out.println( exp.mValuesMap );
System.out.println( exp.expand( "Pegasus developer $(USER) rocks "));
System.out.println( exp.expand( "Pegasus developer $(USer) rocks "));
//System.out.println( exp.expand( "Pegasus developer $(USER1) rocks "));
System.out.println( exp.expand( "Pegasus developer \\$(USER) rocks "));
}
}
/**
* A case sensitive look up class to use in StrSubstitutor
* @author vahi
* @param <V>
*/
class CaseSensitiveStrLookup<V> extends StrLookup<V> {
private final Map<String, V> mMap;
private final boolean mCaseSensitive ;
CaseSensitiveStrLookup(final Map<String, V> map, boolean caseSensitive) {
mCaseSensitive = caseSensitive;
Map<String, V> setMap = new HashMap();
//explicitly lower case all the key in there
for( String key: map.keySet() ){
V value = map.get(key);
setMap.put( caseSensitive ? key : key.toLowerCase(), value);
}
this.mMap = setMap;
}
/**
* Looks up the key and throws an exception if invalid value found
*
* @param key
* @return
*/
public String lookup(final String key) {
String casedKey = mCaseSensitive ? key : key.toLowerCase(); //lowercase the key you're looking for
if (mMap == null) {
return null;
}
final Object obj = mMap.get(casedKey);
if (obj == null) {
throw new RuntimeException( "Unable to expand variable " + key );
}
return obj.toString();
}
}