Source Code Cross Referenced for LocaleMatcher.java in  » Web-Framework » cocoon » org » apache » cocoon » matching » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Framework » cocoon » org.apache.cocoon.matching 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.cocoon.matching;
018:
019:        import org.apache.avalon.framework.activity.Disposable;
020:        import org.apache.avalon.framework.configuration.Configurable;
021:        import org.apache.avalon.framework.configuration.Configuration;
022:        import org.apache.avalon.framework.logger.AbstractLogEnabled;
023:        import org.apache.avalon.framework.parameters.Parameters;
024:        import org.apache.avalon.framework.service.ServiceException;
025:        import org.apache.avalon.framework.service.ServiceManager;
026:        import org.apache.avalon.framework.service.Serviceable;
027:        import org.apache.avalon.framework.thread.ThreadSafe;
028:
029:        import org.apache.cocoon.i18n.I18nUtils;
030:        import org.apache.cocoon.sitemap.PatternException;
031:
032:        import org.apache.commons.lang.StringUtils;
033:        import org.apache.excalibur.source.Source;
034:        import org.apache.excalibur.source.SourceResolver;
035:
036:        import java.io.IOException;
037:        import java.util.HashMap;
038:        import java.util.Locale;
039:        import java.util.Map;
040:
041:        /**
042:         * A matcher that locates and identifies to the pipeline a source document to
043:         * be used as the content for an i18n site, based upon a locale provided in a
044:         * range of ways.
045:         *
046:         * <h1>Configuration</h1>
047:         * <p>A sample configuration (given in the &lt;map:matchers&gt; section of the
048:         * sitemap) is given below. This configuration shows default values.
049:         * </p>
050:         * <pre>
051:         *   &lt;map:matcher name="i18n" src="org.apache.cocoon.matching.LocaleMatcher"&gt;
052:         *     &lt;locale-attribute&gt;locale&lt;/locale-attribute&gt;
053:         *     &lt;negotiate&gt;false&lt;/negotiate&gt;
054:         *     &lt;use-locale&gt;true&lt;/use-locale&gt;
055:         *     &lt;use-locales&gt;false&lt;/use-locales&gt;
056:         *     &lt;use-blank-locale&gt;true&lt;/use-blank-locale&gt;
057:         *     &lt;default-locale language="en" country="US"/&gt;
058:         *     &lt;store-in-request&gt;false&lt;store-in-request&gt;
059:         *     &lt;create-session&gt;false&lt;create-session&gt;
060:         *     &lt;store-in-session&gt;false&lt;store-in-session&gt;
061:         *     &lt;store-in-cookie&gt;false&lt;store-in-cookie&gt;
062:         *   &lt;/map:matcher&gt;
063:         * </pre>
064:         *
065:         * <p>Above configuration parameters mean:
066:         *   <ul>
067:         *     <li><b>locale-attribute</b> specifies the name of the request
068:         *     parameter / session attribute / cookie that is to be used as a locale
069:         *     (defaults to <code>locale</code>)</li>
070:         *     <li><b>negotiate</b> specifies whether matcher should check that
071:         *     resource exists. If set to true, matcher will look for the locale
072:         *     till matching resource is found. If no resource found even with
073:         *     default or blank locale, matcher will not match.</li>
074:         *     <li><b>use-locale</b> specifies whether the primary locale provided
075:         *     by the user agent (or server default, is no locale passed by the agent)
076:         *     is to be used</li>
077:         *     <li><b>use-locales</b> specifies whether each locale provided by the
078:         *     user agent should be tested in turn (makes sense only when
079:         *     <code>negotiate</code> is set to <code>true</code>)</li>
080:         *     <li><b>default-locale</b> specifies the default locale to be used when
081:         *     none matches any of the previous ones.</li>
082:         *     <li><b>use-blank-locale</b> specifies whether a file should be looked
083:         *     for without a locale in its filename or filepath (e.g. after looking
084:         *     for index.en.html, try index.html) if none matches any of the previous
085:         *     locales.</li>
086:         *     <li><b>store-in-request</b> specifies whether found locale should be
087:         *     stored as request attribute.</li>
088:         *     <li><b>create-session</b> specifies whether session should be created
089:         *     when storing found locale as session attribute.</li>
090:         *     <li><b>store-in-session</b> specifies whether found locale should be
091:         *     stored as session attribute.</li>
092:         *     <li><b>store-in-cookie</b> specifies whether found locale should be
093:         *     stored as cookie.</li>
094:         *   </ul>
095:         * </p>
096:         *
097:         * <h1>Usage</h1>
098:         * <p>This matcher will be used in a pipeline like so:</p>
099:         * <pre>
100:         *   &lt;map:match pattern="*.html"&gt;
101:         *     &lt;map:match type="i18n" pattern="xml/{1}.*.xml"&gt;
102:         *       &lt;map:generate src="{source}"/&gt;
103:         *       ...
104:         *     &lt;/map:match&gt;
105:         *   &lt;/map:match&gt;
106:         * </pre>
107:         * <p><code>*</code> in the pattern identifies the place where locale should
108:         * be inserted. In case of a blank locale, if character before and after
109:         * <code>*</code> is the same (like in example above), duplicate will
110:         * be removed (<code>xml/{1}.*.xml</code> becomes <code>xml/{1}.xml</code>).</p>
111:         *
112:         * <h1>Locale Identification</h1>
113:         * <p>Locales will be tested in following order:</p>
114:         * <ul>
115:         *   <li>Locale provided as a request parameter</li>
116:         *   <li>Locale provided as a session attribute</li>
117:         *   <li>Locale provided as a cookie</li>
118:         *   <li>Locale provided using a sitemap parameter<br>
119:         *   (&lt;map:parameter name="locale" value="{1}"/&gt; style parameter within
120:         *   the &lt;map:match&gt; node)</li>
121:         *   <li>Locale provided by the user agent, or server default,
122:         *   if <code>use-locale</code> is set to <code>true</code></li>
123:         *   <li>Locales provided by the user agent, if <code>use-locales</code>
124:         *   is set to <code>true</code>.</li>
125:         *   <li>The default locale, if specified in the matcher's configuration</li>
126:         *   <li>Resources with no defined locale (blank locale)</li>
127:         * </ul>
128:         * <p>If <code>negotiate</code> mode is set to <code>true</code>, a source will
129:         * be looked up using each locale. Where the full locale (language, country,
130:         * variant) doesn't match, it will fall back first to language and country,
131:         * and then just language, before moving on to the next locale.</p>
132:         * <p>If <code>negotiate</code> mode is set to <code>false</code> (default),
133:         * first found locale will be returned.</p>
134:         *
135:         * <h1>Sitemap Variables</h1>
136:         * <p>Once a matching locale has been found, the following sitemap variables
137:         * will be available to sitemap elements contained within the matcher:</p>
138:         * <ul>
139:         *   <li>{source}: The URI of the source that matched</li>
140:         *   <li>{locale}: The locale that matched that resource</li>
141:         *   <li>{matched-locale}: The part of the locale that matched the resource</li>
142:         *   <li>{language}: The language of the matching resource</li>
143:         *   <li>{country}: The country of the matching resource</li>
144:         *   <li>{variant}: The variant of the matching resource</li>
145:         * </ul>
146:         *
147:         * @since 2.1.6
148:         * @author <a href="mailto:uv@upaya.co.uk">Upayavira</a>
149:         * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
150:         * @version CVS $Id: LocaleMatcher.java 433543 2006-08-22 06:22:54Z crossley $
151:         */
152:        public class LocaleMatcher extends AbstractLogEnabled implements 
153:                Matcher, ThreadSafe, Serviceable, Configurable, Disposable {
154:
155:            private static final String DEFAULT_LOCALE_ATTRIBUTE = "locale";
156:            private static final String DEFAULT_DEFAULT_LANG = "en";
157:            private static final String DEFAULT_DEFAULT_COUNTRY = "US";
158:            private static final String DEFAULT_DEFAULT_VARIANT = "";
159:
160:            private ServiceManager manager;
161:            private SourceResolver resolver;
162:
163:            /**
164:             * Name of the locale request parameter, session attribute, cookie.
165:             */
166:            private String localeAttribute;
167:
168:            /**
169:             * Whether to query locale provided by the user agent or not.
170:             */
171:            private boolean useLocale;
172:
173:            private boolean useLocales;
174:            private Locale defaultLocale;
175:            private boolean useBlankLocale;
176:            private boolean testResourceExists;
177:
178:            /**
179:             * Store the locale in request. Default is not to do this.
180:             */
181:            private boolean storeInRequest;
182:
183:            /**
184:             * Store the locale in session, if available. Default is not to do this.
185:             */
186:            private boolean storeInSession;
187:
188:            /**
189:             * Should we create a session if needed. Default is not to do this.
190:             */
191:            private boolean createSession;
192:
193:            /**
194:             * Should we add a cookie with the locale. Default is not to do this.
195:             */
196:            private boolean storeInCookie;
197:
198:            public void service(ServiceManager manager) throws ServiceException {
199:                this .manager = manager;
200:                this .resolver = (SourceResolver) this .manager
201:                        .lookup(SourceResolver.ROLE);
202:            }
203:
204:            public void configure(Configuration config) {
205:                this .storeInRequest = config.getChild("store-in-request")
206:                        .getValueAsBoolean(false);
207:                this .createSession = config.getChild("create-session")
208:                        .getValueAsBoolean(false);
209:                this .storeInSession = config.getChild("store-in-session")
210:                        .getValueAsBoolean(false);
211:                this .storeInCookie = config.getChild("store-in-cookie")
212:                        .getValueAsBoolean(false);
213:                if (getLogger().isDebugEnabled()) {
214:                    getLogger().debug(
215:                            (this .storeInRequest ? "will" : "won't")
216:                                    + " set values in request");
217:                    getLogger().debug(
218:                            (this .createSession ? "will" : "won't")
219:                                    + " create session");
220:                    getLogger().debug(
221:                            (this .storeInSession ? "will" : "won't")
222:                                    + " set values in session");
223:                    getLogger().debug(
224:                            (this .storeInCookie ? "will" : "won't")
225:                                    + " set values in cookies");
226:                }
227:
228:                this .localeAttribute = config.getChild("locale-attribute")
229:                        .getValue(DEFAULT_LOCALE_ATTRIBUTE);
230:                this .testResourceExists = config.getChild("negotiate")
231:                        .getValueAsBoolean(false);
232:
233:                this .useLocale = config.getChild("use-locale")
234:                        .getValueAsBoolean(true);
235:                this .useLocales = config.getChild("use-locales")
236:                        .getValueAsBoolean(false);
237:                this .useBlankLocale = config.getChild("use-blank-locale")
238:                        .getValueAsBoolean(true);
239:
240:                Configuration child = config.getChild("default-locale", false);
241:                if (child != null) {
242:                    this .defaultLocale = new Locale(child.getAttribute(
243:                            "language", DEFAULT_DEFAULT_LANG), child
244:                            .getAttribute("country", DEFAULT_DEFAULT_COUNTRY),
245:                            child.getAttribute("variant",
246:                                    DEFAULT_DEFAULT_VARIANT));
247:                }
248:
249:                if (getLogger().isDebugEnabled()) {
250:                    getLogger().debug(
251:                            "Locale attribute name is " + this .localeAttribute);
252:                    getLogger().debug(
253:                            (this .testResourceExists ? "will" : "won't")
254:                                    + " negotiate locale");
255:                    getLogger().debug(
256:                            (this .useLocale ? "will" : "won't")
257:                                    + " use request locale");
258:                    getLogger().debug(
259:                            (this .useLocales ? "will" : "won't")
260:                                    + " use request locales");
261:                    getLogger().debug(
262:                            (this .useBlankLocale ? "will" : "won't")
263:                                    + " blank locales");
264:                    getLogger().debug("default locale " + this .defaultLocale);
265:                }
266:            }
267:
268:            public void dispose() {
269:                this .manager.release(this .resolver);
270:                this .resolver = null;
271:                this .manager = null;
272:            }
273:
274:            public Map match(final String pattern, Map objectModel,
275:                    Parameters parameters) throws PatternException {
276:                final Map map = new HashMap();
277:
278:                I18nUtils.LocaleValidator validator = new I18nUtils.LocaleValidator() {
279:                    public boolean test(String name, Locale locale) {
280:                        if (getLogger().isDebugEnabled()) {
281:                            getLogger().debug(
282:                                    "Testing " + name + " locale: '" + locale
283:                                            + "'");
284:                        }
285:                        return isValidResource(pattern, locale, map);
286:                    }
287:                };
288:
289:                Locale locale = I18nUtils.findLocale(objectModel,
290:                        localeAttribute, parameters, defaultLocale, useLocale,
291:                        useLocales, useBlankLocale, validator);
292:
293:                if (locale == null) {
294:                    if (getLogger().isDebugEnabled()) {
295:                        getLogger().debug(
296:                                "No locale found for resource: " + pattern);
297:                    }
298:                    return null;
299:                }
300:
301:                String localeStr = locale.toString();
302:                if (getLogger().isDebugEnabled()) {
303:                    getLogger().debug(
304:                            "Locale " + localeStr + " found for resource: "
305:                                    + pattern);
306:                }
307:
308:                I18nUtils.storeLocale(objectModel, localeAttribute, localeStr,
309:                        storeInRequest, storeInSession, storeInCookie,
310:                        createSession);
311:
312:                return map;
313:            }
314:
315:            private boolean isValidResource(String pattern, Locale locale,
316:                    Map map) {
317:                Locale testLocale;
318:
319:                // Test "language, country, variant" locale
320:                if (locale.getVariant().length() > 0) {
321:                    if (isValidResource(pattern, locale, locale, map)) {
322:                        return true;
323:                    }
324:                }
325:
326:                // Test "language, country" locale
327:                if (locale.getCountry().length() > 0) {
328:                    testLocale = new Locale(locale.getLanguage(), locale
329:                            .getCountry());
330:                    if (isValidResource(pattern, locale, testLocale, map)) {
331:                        return true;
332:                    }
333:                }
334:
335:                // Test "language" locale (or empty - if language is "")
336:                testLocale = new Locale(locale.getLanguage(), ""); // Use JDK1.3 constructor
337:                if (isValidResource(pattern, locale, testLocale, map)) {
338:                    return true;
339:                }
340:
341:                return false;
342:            }
343:
344:            private boolean isValidResource(String pattern, Locale locale,
345:                    Locale testLocale, Map map) {
346:                String url;
347:
348:                String testLocaleStr = testLocale.toString();
349:                if ("".equals(testLocaleStr)) {
350:                    // If same character found before and after the '*', leave only one.
351:                    int starPos = pattern.indexOf("*");
352:                    if (starPos < pattern.length() - 1
353:                            && starPos > 1
354:                            && pattern.charAt(starPos - 1) == pattern
355:                                    .charAt(starPos + 1)) {
356:                        url = pattern.substring(0, starPos - 1)
357:                                + pattern.substring(starPos + 1);
358:                    } else {
359:                        url = StringUtils.replace(pattern, "*", "");
360:                    }
361:                } else {
362:                    url = StringUtils.replace(pattern, "*", testLocaleStr);
363:                }
364:
365:                boolean result = true;
366:                if (testResourceExists) {
367:                    Source source = null;
368:                    try {
369:                        source = resolver.resolveURI(url);
370:                        result = source.exists();
371:                    } catch (IOException e) {
372:                        result = false;
373:                    } finally {
374:                        if (source != null) {
375:                            resolver.release(source);
376:                        }
377:                    }
378:                }
379:
380:                if (result) {
381:                    map.put("source", url);
382:                    map.put("matched-locale", testLocaleStr);
383:                    if (locale != null) {
384:                        map.put("locale", locale.toString());
385:                        map.put("language", locale.getLanguage());
386:                        map.put("country", locale.getCountry());
387:                        map.put("variant", locale.getVariant());
388:                    }
389:                }
390:
391:                return result;
392:            }
393:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.