All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.org.retep.util.string.PatternReplacer Maven / Gradle / Ivy

The newest version!
/*
 * 

Copyright (c) 1998-2010, Peter T Mount
* All rights reserved.

* *

Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met:

* *
    *
  • Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
  • * *
  • Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution.
  • * *
  • Neither the name of the retep.org.uk nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission.
  • * *
* *

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/ package uk.org.retep.util.string; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.concurrent.NotThreadSafe; /** * PatternReplacer replaces all keywords found within a String or StringBuffer * with values stored within a Map. * * The pattern must contain two groups. The second group is taken to be the key * to lookup within the string, whilst the first the delimiters for finding the key. * * For example: In the default pattern "(@@(.*?)@@)" group 2 is (.*?) and would * be in the source template as "@@mykey@@". We use a nested group so that the "@@" * symbols are removed from the output as well. * * @author Peter T Mount * @version 8.7 */ @NotThreadSafe public class PatternReplacer { /** * The default pattern that matches @@key@@ * * "(@@(.*?)@@)" where group 2 is the key "(.*?)" and group 1 contains * they key identifiers "@@" */ public static final String DEFAULT_PATTERN = "(@@(.*?)@@)"; /** Holds value of property pattern. */ private Pattern pattern; /** Holds value of property values. */ private Map values; /** Holds value of property customReplacer. */ private PatternReplacer.Replacer customReplacer; /** * Create an instance using DEFAULT_PATTERN */ public PatternReplacer() { this( DEFAULT_PATTERN, null ); } /** * Create an instance using an alternative pattern. * This pattern must contain two groups. * * @see #DEFAULT_PATTERN * @param pattern to use */ public PatternReplacer( final String pattern ) { this( pattern, null ); } /** * Create an instance using an alternative pattern. * This pattern must contain two groups. * * @see #DEFAULT_PATTERN * @param replacer to use */ public PatternReplacer( final PatternReplacer.Replacer replacer ) { this( DEFAULT_PATTERN, replacer ); } /** * Create an instance using an alternative pattern. * This pattern must contain two groups. * * @see #DEFAULT_PATTERN * @param pattern to use * @param replacer PatternReplacer.Replacer instance to use, null for default lookup */ public PatternReplacer( final String pattern, final PatternReplacer.Replacer replacer ) { this.customReplacer = replacer; this.pattern = Pattern.compile( pattern ); } /** * Given a String return a String with all instances of the pattern replaced. * * @param string String containing the template * @param values Map containing the values to use * @return new String containing the replaced text */ public String replaceString( final String string, final Map values ) { setValues( values ); return replaceString( string ); } /** * Given a String return a String with all instances of the pattern replaced. * * @param string String containing the template * @return new String containing the replaced text */ public String replaceString( final String string ) { return replace( string ).toString(); } /** * Given a StringBuffer return a new StringBuffer with all instances of the * pattern replaced. * * @param sb StringBuffer containing the template * @param values Map containing the values to use * @return new StringBuffer containing the replaced text */ public StringBuffer replaceStringBuffer( final StringBuffer sb, final Map values ) { setValues( values ); return replaceStringBuffer( sb ); } /** * Given a StringBuffer return a new StringBuffer with all instances of the * pattern replaced. * * @param sb StringBuffer containing the template * @return new StringBuffer containing the replaced text */ public StringBuffer replaceStringBuffer( final StringBuffer sb ) { return (StringBuffer) replace( sb ); } /** * Given a StringBuffer return a new StringBuffer with all instances of the * pattern replaced. * * @param sb StringBuilder containing the template * @param values Map containing the values to use * @return new StringBuffer containing the replaced text */ public StringBuilder replaceStringBuilder( final StringBuilder sb, final Map values ) { setValues( values ); return replaceStringBuilder( sb ); } /** * Given a StringBuffer return a new StringBuffer with all instances of the * pattern replaced. * * @param sb StringBuilder containing the template * @return new StringBuffer containing the replaced text */ public StringBuilder replaceStringBuilder( final StringBuilder sb ) { return new StringBuilder( replace( sb ) ); } /** * Given a Map return a new Map with all values of the * pattern replaced. * * @param map Map who's values contain the templates * @param values Map containing the values to use * @return new StringBuffer containing the replaced text */ public Map replaceMap( final Map map, final Map values ) { setValues( values ); return replaceMap( map ); } /** * Given a Map return a new Map with all values of the * pattern replaced. * * @param map Map who's values contain the templates * @return new StringBuffer containing the replaced text */ public Map replaceMap( final Map map ) { final Map newMap = new HashMap(); for( Map.Entry entry : map.entrySet() ) { newMap.put( entry.getKey(), replace( entry.getValue() ).toString() ); } return newMap; } /** * Given a CharSequence return a new CharSequence with all instances of the * pattern replaced. * * @param seq CharSequence containing the template * @param values Map containing the values to use * @return new CharSequence containing the replaced text */ public CharSequence replace( final CharSequence seq, final Map values ) { setValues( values ); return replace( seq ); } /** * Given a StringBuffer return a new StringBuffer with all instances of the * pattern replaced. * * @param seq CharSequnce containing the template * @return new CharSequence containing the replaced text */ public CharSequence replace( final CharSequence seq ) { final StringBuffer sb = new StringBuffer(); final Matcher mat = pattern.matcher( seq ); while( mat.find() ) { mat.appendReplacement( sb, replace( mat, values ) ); } mat.appendTail( sb ); return (CharSequence) sb; } /** * This method converts the replacement text. * If there is no customReplacer, then it just uses the key for the value * in the Map. But if a customReplacer exists, then it uses it to create * the replacement text instead. */ private String replace( final Matcher matcher, final Map values ) { String ret = ""; if( getCustomReplacer() == null ) { // default - just lookup the value String key = matcher.group( 2 ); ret = values.containsKey( key ) ? values.get( key ).toString() : ""; } else { // Use the custom replacer to resolve ret = getCustomReplacer().lookupReplacement( matcher, values ); } return ret; } /** * Return the Pattern object being used * @return Pattern * */ public Pattern getPattern() { return this.pattern; } /** * Return the current/last used values Map * @return Map of values * */ public Map getValues() { return this.values; } /** * Set the values to be used in the next call to replace. * @param values New Map containing values * */ public void setValues( final Map values ) { this.values = values; } /** * Returns the custom replacer instance for this object * @return The custom replacer instance for this object * */ public PatternReplacer.Replacer getCustomReplacer() { return customReplacer; } /** * Interface that a custom replace handler must implement. * * By default, no instance is used, and the key name is used as the key * within the Map. However, by implementing this interface, any complex * pattern may be used. * * For example, implementations of this interface can perform specialist * transformations, like using Apache BeanUtils to perform bean lookups * from a bean contained in the map. * * ie: the pattern (@@(.*?)\\.(.*?)@@) could be used for the syntax: * @@bean.property@@ where bean is retrieved using matcher.group(2) * and property by using matcher.group(3). Then the entire pattern is * replaced with the value of that property. */ public static interface Replacer { /** * Given a Matcher, use its group(int) method to lookup * a replacement value from the map, and return as a String. * * @param matcher Matcher with current value * @param values Map containing the supplied values * @return replacement value */ public String lookupReplacement( Matcher matcher, Map values ); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy