1 package org.ocltf.translation.library;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashMap;
6 import java.util.Iterator;
7 import java.util.Map;
8
9 import org.apache.commons.lang.StringUtils;
10 import org.apache.commons.lang.builder.ToStringBuilder;
11 import org.apache.commons.logging.Log;
12 import org.apache.commons.logging.LogFactory;
13 import org.ocltf.translation.TranslationUtils;
14 import org.ocltf.utils.ExceptionUtils;
15
16
17 /***
18 * Represents a translation XML template found within a translation library.
19 *
20 * @author Chad Brandon
21 */
22 public class Translation {
23
24 private static final Log logger = LogFactory.getLog(Translation.class);
25
26 private String name;
27
28 private Map fragments;
29
30 private Collection ignorePatterns;
31
32 private Collection validatePatterns;
33
34 /***
35 * Constructs an instance of Translation.
36 */
37 public Translation() {
38 this.fragments = new HashMap();
39 this.ignorePatterns = new ArrayList();
40 }
41
42 /***
43 * The library translation to which this translation belongs.
44 */
45 private LibraryTranslation libraryTranslation;
46
47 /***
48 * Gets the LibraryTranslation to which this
49 * Translation belongs.
50 * @return LibraryTranslation
51 */
52 protected LibraryTranslation getLibraryTranslation() {
53 String methodName = "getLibraryTranslation";
54
55 if (this.libraryTranslation == null) {
56 throw new LibraryException(methodName
57 + " - libraryTranslation can not be null");
58 }
59 return libraryTranslation;
60 }
61
62 /***
63 * Sets the LibraryTranslation to which this Translation
64 * belongs.
65 *
66 * @param translation the LibraryTranslation to which this Translation belongs.
67 */
68 protected void setLibraryTranslation(LibraryTranslation translation) {
69 libraryTranslation = translation;
70 }
71
72 /***
73 * Gets the fragment matching (using regular expressions) the specified name.
74 *
75 * @param name the name of the fragment to retrieve.
76 *
77 * @return Fragment
78 */
79 protected Fragment getFragment(String name) {
80 Fragment fragment = null;
81 Iterator names = fragments.keySet().iterator();
82
83
84 while (names.hasNext()) {
85 String nextName = (String)names.next();
86 if (name.matches(nextName)) {
87 fragment = (Fragment)fragments.get(nextName);
88 }
89 }
90
91
92 if (fragment == null && !this.isIgnorePattern(name)) {
93 if (logger.isErrorEnabled()) {
94 logger.error("ERROR! expression fragment '"
95 + name
96 + "' is not currently supported --> add a <fragment/> with "
97 + " a name that matches this expression to your translation file "
98 + "'" + this.getLibraryTranslation().getFile()
99 + "' to enable support");
100 }
101 }
102 return fragment;
103 }
104
105 /***
106 * Adds a new Translation fragment to the Translation.
107 *
108 * @param fragment
109 */
110 public void addFragment(Fragment fragment) {
111 String methodName = "addFragment";
112 ExceptionUtils.checkNull(methodName, "fragment", fragment);
113 fragment.setTranslation(this);
114 this.fragments.put(fragment.getName(), fragment);
115 }
116
117 /***
118 * Gets the name of this Translation.
119 * @return String
120 */
121 protected String getName() {
122 return name;
123 }
124
125 /***
126 * @param name
127 */
128 protected void setName(String name) {
129 this.name = name;
130 }
131
132 /***
133 * Adds an <code>ignorePattern</code> to
134 * the Collection of ignorePatterns.
135 *
136 * @param ignorePattern the pattern to ignore.
137 */
138 public void addIgnorePattern(String ignorePattern) {
139 this.ignorePatterns.add(StringUtils.trimToEmpty(ignorePattern));
140 }
141
142 /***
143 * Adds an <code>validatePattern</code> to
144 * the Collection of validatePatterns.
145 *
146 * @param validatePattern the pattern to validate.
147 */
148 public void addValidatePattern(String validatePattern) {
149 this.validatePatterns.add(StringUtils.trimToEmpty(validatePattern));
150 }
151
152 /***
153 * Checks to see if the pattern is an ignore pattern.
154 * What this means is that if if this pattern matches
155 * on a regular expression found in the collection of ignore patterns
156 * then the TranslationLibrary won't complain if it doesn't match
157 * a fragment name.
158 * @param pattern
159 * @return boolean <code>true</code> if its an ignore pattern, <code>false</code> otherwise.
160 */
161 public boolean isIgnorePattern(String pattern) {
162 boolean isIgnorePattern = false;
163 pattern = StringUtils.trimToEmpty(pattern);
164 Iterator ignorePatterns = this.ignorePatterns.iterator();
165
166
167 while (ignorePatterns.hasNext()) {
168 String nextIgnorePattern =
169 StringUtils.trimToEmpty((String)ignorePatterns.next());
170 isIgnorePattern = pattern.matches(nextIgnorePattern);
171 if (isIgnorePattern) {
172 break;
173 }
174 }
175 return isIgnorePattern;
176 }
177
178 /***
179 * Gets the "translated" value of this Fragment if it
180 * exists. That is, it retrieves the fragment
181 * body for the name of this fragment and replaces
182 * any fragment references with other fragment bodies
183 * (if they exist)
184 * @param name the name of the fragment.
185 * @param kind the kind of the fragment.
186 * @return String the translated body of the fragment kind.
187 */
188 protected String getTranslated(String name, String kind) {
189 String methodName = "getTranslated";
190 if (logger.isDebugEnabled()) {
191 logger.debug("performing " + methodName +
192 " with name (" + name + ") and kind (" + kind + ")");
193 }
194
195
196 name = StringUtils.trimToEmpty(name);
197 kind = StringUtils.trimToEmpty(kind);
198
199 ExceptionUtils.checkEmpty(methodName, "name", name);
200
201 Fragment fragment = this.getFragment(name);
202 String translated = "";
203 if (fragment != null) {
204 translated = fragment.getKind(kind);
205 String begin = "fragment{";
206 int beginLength = begin.length();
207 String end = "}";
208 for (int beginIndex = translated.indexOf(begin);
209 beginIndex != -1;
210 beginIndex = translated.indexOf(begin)) {
211 String fragmentName =
212 translated.substring(beginIndex + beginLength, translated.length());
213 int endIndex = fragmentName.indexOf(end);
214 if (endIndex != -1) {
215 fragmentName = fragmentName.substring(0, endIndex);
216 }
217 StringBuffer toReplace = new StringBuffer(begin);
218 toReplace.append(fragmentName);
219 toReplace.append(end);
220 translated = StringUtils.replace(
221 translated,
222 toReplace.toString(),
223 this.getTranslated(fragmentName, kind));
224 }
225 }
226
227 return TranslationUtils.removeExtraWhitespace(translated);
228 }
229
230 /***
231 * @see java.lang.Object#toString()
232 */
233 public String toString() {
234 return ToStringBuilder.reflectionToString(this);
235 }
236
237 }