Coverage Report - org.mule.util.TemplateParser
 
Classes in this File Line Coverage Branch Coverage Complexity
TemplateParser
90%
57/63
74%
25/34
2.917
TemplateParser$TemplateCallback
N/A
N/A
2.917
 
 1  
 /*
 2  
  * $Id: TemplateParser.java 7963 2007-08-21 08:53:15Z dirk.olmes $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.util;
 12  
 
 13  
 import java.util.ArrayList;
 14  
 import java.util.HashMap;
 15  
 import java.util.Iterator;
 16  
 import java.util.List;
 17  
 import java.util.Map;
 18  
 import java.util.regex.Matcher;
 19  
 import java.util.regex.Pattern;
 20  
 
 21  
 import org.apache.commons.logging.Log;
 22  
 import org.apache.commons.logging.LogFactory;
 23  
 
 24  
 /**
 25  
  * <code>TemplateParser</code> is a simple string parser that will substitute
 26  
  * tokens in a string with values supplied in a Map.
 27  
  */
 28  
 public final class TemplateParser
 29  
 {
 30  
     public static final String ANT_TEMPLATE_STYLE = "ant";
 31  
     public static final String SQUARE_TEMPLATE_STYLE = "square";
 32  
 
 33  
     /**
 34  
      * logger used by this class
 35  
      */
 36  4
     protected static final Log logger = LogFactory.getLog(TemplateParser.class);
 37  
 
 38  
     private final Pattern pattern;
 39  
     private final int pre;
 40  
     private final int post;
 41  
     private final String style;
 42  
 
 43  
 
 44  
     public static TemplateParser createAntStyleParser()
 45  
     {
 46  8
         return new TemplateParser(ANT_TEMPLATE_STYLE);
 47  
     }
 48  
 
 49  
     public static TemplateParser createSquareBracesStyleParser()
 50  
     {
 51  470
         return new TemplateParser(SQUARE_TEMPLATE_STYLE);
 52  
     }
 53  
 
 54  
     private TemplateParser(String style)
 55  478
     {
 56  478
         if (ANT_TEMPLATE_STYLE.equals(style))
 57  
         {
 58  8
             pattern = Pattern.compile("\\$\\{[^\\}]+\\}");
 59  8
             pre = 2;
 60  8
             post = 1;
 61  
         }
 62  470
         else if (SQUARE_TEMPLATE_STYLE.equals(style))
 63  
         {
 64  470
             pattern = Pattern.compile("\\[[^\\]]+\\]");
 65  470
             pre = 1;
 66  470
             post = 1;
 67  
         }
 68  
         else
 69  
         {
 70  0
             throw new IllegalArgumentException("Unknown template style: " + style);
 71  
         }
 72  478
         this.style = style;
 73  478
     }
 74  
 
 75  
     /**
 76  
      * Matches one or more templates against a Map of key value pairs. If a value for
 77  
      * a template is not found in the map the template is left as is in the return
 78  
      * String
 79  
      * 
 80  
      * @param props the key/value pairs to match against
 81  
      * @param template the string containing the template place holders i.e. My name
 82  
      *            is ${name}
 83  
      * @return the parsed String
 84  
      */
 85  
     public String parse(Map props, String template)
 86  
     {
 87  34
         return parse(props, template, null);
 88  
     }
 89  
 
 90  
     /**
 91  
      * Matches one or more templates against a Map of key value pairs. If a value for
 92  
      * a template is not found in the map the template is left as is in the return
 93  
      * String
 94  
      * 
 95  
      * @param callback a callback used to resolve the property name
 96  
      * @param template the string containing the template place holders i.e. My name
 97  
      *            is ${name}
 98  
      * @return the parsed String
 99  
      */
 100  
     public String parse(TemplateCallback callback, String template)
 101  
     {
 102  0
         return parse(null, template, callback);
 103  
     }
 104  
 
 105  
     protected String parse(Map props, String template, TemplateCallback callback)
 106  
     {
 107  34
         String result = template;
 108  34
         Matcher m = pattern.matcher(template);
 109  
 
 110  80
         while (m.find())
 111  
         {
 112  46
             Object value = null;
 113  
 
 114  46
             String match = m.group();
 115  46
             String propname = match.substring(pre, match.length() - post);
 116  
 
 117  46
             if (callback != null)
 118  
             {
 119  0
                 value = callback.match(propname);
 120  
             }
 121  46
             else if (props != null)
 122  
             {
 123  46
                 value = props.get(propname);
 124  
             }
 125  
 
 126  46
             if (value == null)
 127  
             {
 128  4
                 if (logger.isDebugEnabled())
 129  
                 {
 130  0
                     logger.debug("Value " + propname + " not found in context");
 131  
                 }
 132  
             }
 133  
             else
 134  
             {
 135  42
                 String matchRegex = escape(match);
 136  42
                 String valueString = value.toString();
 137  
 
 138  42
                 if (valueString.indexOf('\\') != -1)
 139  
                 {
 140  2
                     valueString = valueString.replaceAll("\\\\", "\\\\\\\\");
 141  
                 }
 142  
 
 143  42
                 result = result.replaceAll(matchRegex, valueString);
 144  
             }
 145  46
         }
 146  34
         return result;
 147  
     }
 148  
 
 149  
     /**
 150  
      * Matches one or more templates against a Map of key value pairs. If a value for
 151  
      * a template is not found in the map the template is left as is in the return
 152  
      * String
 153  
      * 
 154  
      * @param props the key/value pairs to match against
 155  
      * @param templates A List of templates
 156  
      * @return the parsed String
 157  
      */
 158  
     public List parse(Map props, List templates)
 159  
     {
 160  4
         if (templates == null)
 161  
         {
 162  2
             return new ArrayList();
 163  
         }
 164  2
         List list = new ArrayList(templates.size());
 165  2
         for (Iterator iterator = templates.iterator(); iterator.hasNext();)
 166  
         {
 167  4
             list.add(parse(props, iterator.next().toString()));
 168  
         }
 169  2
         return list;
 170  
     }
 171  
 
 172  
     /**
 173  
      * Matches one or more templates against a Map of key value pairs. If a value for
 174  
      * a template is not found in the map the template is left as is in the return
 175  
      * String
 176  
      * 
 177  
      * @param props the key/value pairs to match against
 178  
      * @param templates A Map of templates. The values for each map entry will be
 179  
      *            parsed
 180  
      * @return the parsed String
 181  
      */
 182  
     public Map parse(Map props, Map templates)
 183  
     {
 184  4
         if (templates == null)
 185  
         {
 186  2
             return new HashMap();
 187  
         }
 188  2
         Map map = new HashMap(templates.size());
 189  
         Map.Entry entry;
 190  2
         for (Iterator iterator = templates.entrySet().iterator(); iterator.hasNext();)
 191  
         {
 192  4
             entry = (Map.Entry) iterator.next();
 193  4
             map.put(entry.getKey(), parse(props, entry.getValue().toString()));
 194  
         }
 195  2
         return map;
 196  
     }
 197  
 
 198  
     private String escape(String string)
 199  
     {
 200  42
         int length = string.length();
 201  42
         if (length == 0)
 202  
         {
 203  
             // nothing to do
 204  0
             return string;
 205  
         }
 206  
         else
 207  
         {
 208  42
             StringBuffer buffer = new StringBuffer(length * 2);
 209  432
             for (int i = 0; i < length; i++)
 210  
             {
 211  390
                 char currentCharacter = string.charAt(i);
 212  390
                 switch (currentCharacter)
 213  
                 {
 214  
                     case '[' :
 215  
                     case ']' :
 216  
                     case '{' :
 217  
                     case '}' :
 218  
                     case '$' :
 219  118
                         buffer.append("\\");
 220  
                         // fall through to append original character
 221  
                     default :
 222  390
                         buffer.append(currentCharacter);
 223  
                 }
 224  
             }
 225  42
             return buffer.toString();
 226  
         }
 227  
     }
 228  
 
 229  
     public String getStyle()
 230  
     {
 231  0
         return style;
 232  
     }
 233  
 
 234  
     public boolean isContainsTemplate(String value)
 235  
     {
 236  476
         Matcher m = pattern.matcher(value);
 237  476
         return m.find();
 238  
     }
 239  
 
 240  
     public static interface TemplateCallback
 241  
     {
 242  
         Object match(String token);
 243  
     }
 244  
 
 245  
 }