1 /*
2 * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3 * the spring framework, http://el4j.sf.net
4 * Copyright (C) 2006 by ELCA Informatique SA, Av. de la Harpe 22-24,
5 * 1000 Lausanne, Switzerland, http://www.elca.ch
6 *
7 * EL4J is published under the GNU Lesser General Public License (LGPL)
8 * Version 2.1. See http://www.gnu.org/licenses/
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * For alternative licensing, please contact info@elca.ch
16 */
17 package ch.elca.el4j.services.i18n;
18
19 import static java.lang.Character.isWhitespace;
20 import static java.lang.Character.toLowerCase;
21 import static java.lang.Character.toUpperCase;
22
23 import java.util.HashMap;
24 import java.util.Map;
25
26 /**
27 * A rewriting rule providing a set of utility functions. The keys accepted
28 * by this rule are of the form
29 *
30 * <pre><i>namespace</i> <i>function</i> . <i>argument</i> </pre>
31 *
32 * @svnLink $Revision: 3883 $;$Date: 2009-08-04 15:35:01 +0200 (Di, 04. Aug 2009) $;$Author: swismer $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/core/src/main/java/ch/elca/el4j/services/i18n/RewritingUtilities.java $
33 *
34 * @author Adrian Moos (AMS)
35 */
36 public class RewritingUtilities implements MessageRewriter.Rule {
37 /** A utility function. */
38 protected abstract static class Function {
39 /** The function's name. */
40 private String m_name;
41
42 /**
43 * Constructor.
44 * @param name the function's name
45 */
46 protected Function(String name) {
47 m_name = name;
48 }
49
50 /**
51 * Applies this utility function to {@code argument}, appending the
52 * result to {@code target}.
53 */
54 abstract void apply(String argument, StringBuffer target);
55 }
56
57 /** Default functions. */
58 private static Function[] s_defaultFunctions = {
59 new Function("decapitalize") {
60 @Override void apply(String argument, StringBuffer target) {
61 changeCapitalization(argument, false, target);
62 }
63 },
64 new Function("capitalize") {
65 @Override void apply(String argument, StringBuffer target) {
66 changeCapitalization(argument, true, target);
67 }
68 }
69 };
70
71 /** The package-like prefix to function names. Includes delimiter. */
72 protected String m_requiredPrefix;
73
74 /** the functions provided by this instance, keyed by function.m_name. */
75 protected Map<String, Function> m_functions
76 = new HashMap<String, Function>();
77
78
79 /**
80 * Creates a utility function package called {@code Utils} and
81 * adds default utility functions.
82 */
83 public RewritingUtilities() {
84 this("Utils.");
85 }
86
87 /**
88 * Constructor. Adds default utility functions.
89 * @param packageName the package name as used to form keys.
90 */
91 public RewritingUtilities(String packageName) {
92 m_requiredPrefix = packageName;
93 for (Function f : s_defaultFunctions) {
94 add(f);
95 }
96 }
97
98 /**
99 * Writes {@code argument} into {@code target} while changing the first
100 * character for each word.
101 * @param toUpper whether to change it to upper or lower case
102 */
103 private static void changeCapitalization(String argument, boolean toUpper,
104 StringBuffer target) {
105
106 int i = 0;
107 do {
108 target.append(
109 toUpper ? toUpperCase(argument.charAt(i))
110 : toLowerCase(argument.charAt(i))
111 );
112 i++;
113
114 int j;
115 for (j = i; j < argument.length(); j++) {
116 if (isWhitespace(argument.charAt(j))) {
117 break;
118 }
119 }
120 target.append(argument.substring(i, j));
121 i = j;
122 } while (i < argument.length());
123 }
124
125
126 /** Adds a function, replacing any previous function with the same name. */
127 public void add(Function f) {
128 m_functions.put(f.m_name, f);
129 }
130
131 /**
132 * removes a function. No effect if no matching function is present.
133 * @param functionName the name of the function to be removed
134 */
135 public void remove(String functionName) {
136 m_functions.remove(functionName);
137 }
138
139 /**
140 * {@inheritDoc}
141 */
142 public StringBuffer rewrite(String key, Object[] arguments,
143 StringBuffer target) {
144
145 if (!key.startsWith(m_requiredPrefix)) { return null; }
146
147 int i = key.indexOf('.', m_requiredPrefix.length());
148 if (i == -1) { return null; }
149
150 String functionName = key.substring(m_requiredPrefix.length(), i);
151 String argument = key.substring(i + 1);
152
153 Function function = m_functions.get(functionName);
154 if (function == null) { return null; }
155
156 function.apply(argument, target);
157 return target;
158 }
159 }