View Javadoc

1   /*
2    * ------------------------------------------------------------------------------
3    * Hermes FTP Server
4    * Copyright (c) 2005-2007 Lars Behnke
5    * ------------------------------------------------------------------------------
6    * 
7    * This file is part of Hermes FTP Server.
8    * 
9    * Hermes FTP Server is free software; you can redistribute it and/or modify
10   * it under the terms of the GNU General Public License as published by
11   * the Free Software Foundation; either version 2 of the License, or
12   * (at your option) any later version.
13   * 
14   * Hermes FTP Server is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Public License for more details.
18   * 
19   * You should have received a copy of the GNU General Public License
20   * along with Hermes FTP Server; if not, write to the Free Software
21   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22   * ------------------------------------------------------------------------------
23   */
24  
25  package net.sf.hermesftp.utils;
26  
27  import java.util.Properties;
28  import java.util.regex.Matcher;
29  import java.util.regex.Pattern;
30  
31  /***
32   * Replaces all placeholders in a given text document with the values of a properties-Object.
33   * Example: The text "Hello ${name}" becomes "Hello world" provided that passed properties object
34   * contains the entry name=world.
35   * <p>
36   * <code>
37   *   VarMerger vm = new VarMerger("The ${dog} chases the ${cat}");
38   *   Properties p = new Properties();
39   *   p.put("dog", "fox");
40   *   p.put("cat", "mouse");
41   *   vm.merge(p);
42   *   String neuerSatz = vm.getText();
43   * </code>
44   * 
45   * @author Lars Behnke
46   */
47  public class VarMerger {
48  
49      private static final String VAR_PATTERN = "(//$//{)([//w//.]*)(//})";
50  
51      private String              text;
52  
53      /***
54       * @param text Der Text containing placeholders.
55       */
56      public VarMerger(String text) {
57          setText(text);
58      }
59  
60      /***
61       * Replaces the placeholders with the passed values.
62       * 
63       * @param props The values.
64       */
65      public void merge(Properties props) {
66          StringBuffer sb = new StringBuffer();
67          Pattern pattern = Pattern.compile(VAR_PATTERN);
68          Matcher m = pattern.matcher(getText());
69          boolean hasNext = m.find();
70          while (hasNext) {
71              String key = m.group(2);
72              String val = props.getProperty(key);
73              if (val != null) {
74                  val = quoteReplacement(val);
75                  m.appendReplacement(sb, val);
76              }
77              hasNext = m.find();
78          }
79          m.appendTail(sb);
80          text = sb.toString();
81      }
82  
83      /***
84       * Returns a literal replacement <code>String</code> for the specified <code>String</code>.
85       * This method produces a <code>String</code> that will work use as a literal replacement
86       * <code>s</code> in the <code>appendReplacement</code> method of the {@link Matcher} class.
87       * The <code>String</code> produced will match the sequence of characters in <code>s</code>
88       * treated as a literal sequence. Slashes ('\') and dollar signs ('$') will be given no special
89       * meaning.
90       * 
91       * @param s The string to be literalized
92       * @return A literal string replacement
93       */
94      private static String quoteReplacement(String s) {
95          if ((s.indexOf('//') == -1) && (s.indexOf('$') == -1)) {
96              return s;
97          }
98          StringBuffer sb = new StringBuffer();
99          for (int i = 0; i < s.length(); i++) {
100             char c = s.charAt(i);
101             if (c == '//') {
102                 sb.append('//');
103                 sb.append('//');
104             } else if (c == '$') {
105                 sb.append('//');
106                 sb.append('$');
107             } else {
108                 sb.append(c);
109             }
110         }
111         return sb.toString();
112     }
113 
114     /***
115      * Sets the text containing placeholders.
116      * 
117      * @param text The text.
118      */
119     public void setText(String text) {
120         if (text == null) {
121             throw new IllegalArgumentException("NULL-Werte k�nnen nicht verarbeitet werden.");
122         }
123         this.text = text;
124     }
125 
126     /***
127      * @return Der Text mit den ersetzten Platzhaltern.
128      */
129     public String getText() {
130         return text;
131     }
132 
133     /***
134      * Pr�ft, ob der Text noch Platzhalter enth�lt, die noch nicht ersetzt wurden.
135      * 
136      * @return True, falls der Text keine Platzhalter mehr enth�lt.
137      */
138     public boolean isReplacementComplete() {
139         Pattern pattern = Pattern.compile(VAR_PATTERN);
140         boolean found = pattern.matcher(getText()).find();
141         return !found;
142     }
143 
144 }