KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mondrian > i18n > LocalizingDynamicSchemaProcessor


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/i18n/LocalizingDynamicSchemaProcessor.java#2 $
3 // This software is subject to the terms of the Common Public License
4 // Agreement, available at the following URL:
5 // http://www.opensource.org/licenses/cpl.html.
6 // Copyright (C) 2005-2006 Julian Hyde
7 // All Rights Reserved.
8 // You must accept the terms of that agreement to use this software.
9 */

10
11 package mondrian.i18n;
12 import mondrian.olap.MondrianProperties;
13 import mondrian.olap.Util;
14 import mondrian.rolap.DynamicSchemaProcessor;
15 import org.apache.log4j.Logger;
16
17 import java.io.*;
18 import java.net.MalformedURLException JavaDoc;
19 import java.net.URL JavaDoc;
20 import java.util.*;
21 import java.util.regex.Matcher JavaDoc;
22 import java.util.regex.Pattern JavaDoc;
23
24 /**
25  * Schema processor which helps localize data and metadata.
26  *
27  * @author arosselet
28  * @since August 26, 2005
29  * @version $Id: //open/mondrian/src/main/mondrian/i18n/LocalizingDynamicSchemaProcessor.java#2 $
30  */

31 public class LocalizingDynamicSchemaProcessor
32         implements DynamicSchemaProcessor {
33     private static final Logger LOGGER =
34             Logger.getLogger(LocalizingDynamicSchemaProcessor.class);
35
36     /** Creates a new instance of LocalizingDynamicSchemaProcessor */
37     public LocalizingDynamicSchemaProcessor() {
38     }
39
40     private PropertyResourceBundle i8n;
41
42     /**
43      * Regular expression for variables.
44      */

45     private static final Pattern JavaDoc pattern = Pattern.compile("(%\\{.*?\\})");
46     private static final int INVALID_LOCALE = 1;
47     private static final int FULL_LOCALE = 3;
48     private static final int LANG_LOCALE = 2;
49     private static final Set<String JavaDoc> countries = Collections.unmodifiableSet(
50             new HashSet<String JavaDoc>(Arrays.asList(Locale.getISOCountries())));
51     private static final Set<String JavaDoc> languages = Collections.unmodifiableSet(
52             new HashSet<String JavaDoc>(Arrays.asList(Locale.getISOLanguages())));
53     private int localeType = INVALID_LOCALE;
54
55     void populate(String JavaDoc propFile) {
56         String JavaDoc localizedPropFileBase = "";
57         String JavaDoc [] tokens = propFile.split("\\.");
58
59         for (int i = 0; i < tokens.length - 1; i++) {
60             localizedPropFileBase = localizedPropFileBase +
61                     ((localizedPropFileBase.length() == 0) ? "" : ".") +
62                     tokens[i];
63         }
64
65         String JavaDoc [] localePropFilename = new String JavaDoc[localeType];
66         String JavaDoc [] localeTokens = locale.split("\\_");
67         int index = localeType;
68         for (int i = 0; i <localeType;i++) {
69             //"en_GB" -> [en][GB] first
70
String JavaDoc catName = "";
71             /*
72              * if en_GB, then append [0]=_en_GB [1]=_en
73              * if en, then append [0]=_en
74              * if null/bad then append nothing;
75              */

76             for (int j = 0;j <= i - 1; j++) {
77                 catName += "_" + localeTokens[j];
78             }
79             localePropFilename[--index] = localizedPropFileBase + catName +
80                     "." + tokens[tokens.length-1];
81         }
82         boolean fileExists = false;
83         File file = null;
84         for (int i = 0;i < localeType && !fileExists; i++) {
85             file = new File(localePropFilename[i]);
86             if (LOGGER.isDebugEnabled()) {
87                 LOGGER.debug("populate: file=" +
88                         file.getAbsolutePath() +
89                         " exists=" +
90                         file.exists()
91                         );
92             }
93             if (!file.exists()) {
94                 LOGGER.warn("Mondrian: Warning: file '"
95                         + file.getAbsolutePath()
96                         + "' not found - trying next default locale");
97             }
98             fileExists = file.exists();
99         }
100
101         if (fileExists) {
102             try {
103                 URL JavaDoc url = Util.toURL(file);
104                 i8n = new PropertyResourceBundle(url.openStream());
105                 LOGGER.info("Mondrian: locale file '"
106                         + file.getAbsolutePath()
107                         + "' loaded");
108
109             } catch (MalformedURLException JavaDoc e) {
110                 LOGGER.error("Mondrian: locale file '"
111                         + file.getAbsolutePath()
112                         + "' could not be loaded ("
113                         + e
114                         + ")");
115             } catch (java.io.IOException JavaDoc e){
116                 LOGGER.error("Mondrian: locale file '"
117                         + file.getAbsolutePath()
118                         + "' could not be loaded ("
119                         + e
120                         + ")");
121             }
122         } else {
123             LOGGER.warn("Mondrian: Warning: no suitable locale file found for locale '"
124                     + locale
125                     + "'");
126         }
127     }
128
129     private void loadProperties() {
130         String JavaDoc propFile = MondrianProperties.instance().LocalePropFile.get();
131         if (propFile != null) {
132             populate(propFile);
133         }
134     }
135
136     public String JavaDoc processSchema(
137             URL JavaDoc schemaUrl, Util.PropertyList connectInfo) throws Exception JavaDoc {
138
139         setLocale(connectInfo.get("Locale"));
140
141         loadProperties();
142
143         StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
144         BufferedReader in = new BufferedReader(
145                 new InputStreamReader(
146                         schemaUrl.openStream()));
147         String JavaDoc inputLine;
148         while ((inputLine = in.readLine()) != null) {
149             buf.append(inputLine);
150         }
151         in.close();
152         String JavaDoc schema = buf.toString();
153         if (i8n != null) {
154             schema = doRegExReplacements(schema);
155         }
156         LOGGER.debug(schema);
157         return schema;
158     }
159
160     private String JavaDoc doRegExReplacements(String JavaDoc schema) {
161         StringBuffer JavaDoc intlSchema = new StringBuffer JavaDoc();
162         Matcher JavaDoc match = pattern.matcher(schema);
163         String JavaDoc key;
164         while (match.find()) {
165             key = extractKey(match.group());
166             int start = match.start();
167             int end = match.end();
168
169             try {
170                 String JavaDoc intlProperty = i8n.getString(key);
171                 if (intlProperty!=null){
172                     match.appendReplacement(intlSchema, intlProperty);
173                 }
174             } catch (java.util.MissingResourceException JavaDoc e){
175                 LOGGER.error("Missing resource for key ["+key+"]",e);
176             } catch (java.lang.NullPointerException JavaDoc e){
177                 LOGGER.error("missing resource key at substring("+start+","+end+")",e);
178             }
179         }
180         match.appendTail(intlSchema);
181         return intlSchema.toString();
182     }
183
184     private String JavaDoc extractKey(String JavaDoc group) {
185         // removes leading '%{' and tailing '%' from the matched string
186
// to obtain the required key
187
return group.substring(2, group.length() - 1);
188     }
189
190     /**
191      * Property locale.
192      */

193     private String JavaDoc locale;
194
195     /**
196      * Returns the property locale.
197      *
198      * @return Value of property locale.
199      */

200     public String JavaDoc getLocale() {
201         return this.locale;
202     }
203
204     /**
205      * Sets the property locale.
206      *
207      * @param locale New value of property locale.
208      */

209     public void setLocale(String JavaDoc locale) {
210         this.locale = locale;
211         localeType = INVALID_LOCALE; // if invalid/missing, default localefile will be tried.
212
// make sure that both language and country fields are valid
213
if (locale.indexOf("_") != -1 && locale.length() == 5) {
214             if (languages.contains(locale.substring(0, 2)) &&
215                     countries.contains(locale.substring(3, 5))) {
216                 localeType = FULL_LOCALE;
217             }
218         } else {
219             if (locale.length()==2){
220             //make sure that the language field is valid since that is all that was provided
221
if (languages.contains(locale.substring(0, 2))) {
222                     localeType = LANG_LOCALE;
223                 }
224             }
225         }
226     }
227 }
228
229 // End LocalizingDynamicSchemaProcessor.java
230
Popular Tags