1 16 package org.apache.cocoon.matching; 17 18 import org.apache.avalon.framework.activity.Disposable; 19 import org.apache.avalon.framework.configuration.Configurable; 20 import org.apache.avalon.framework.configuration.Configuration; 21 import org.apache.avalon.framework.logger.AbstractLogEnabled; 22 import org.apache.avalon.framework.parameters.Parameters; 23 import org.apache.avalon.framework.service.ServiceException; 24 import org.apache.avalon.framework.service.ServiceManager; 25 import org.apache.avalon.framework.service.Serviceable; 26 import org.apache.avalon.framework.thread.ThreadSafe; 27 28 import org.apache.cocoon.i18n.I18nUtils; 29 import org.apache.cocoon.sitemap.PatternException; 30 31 import org.apache.commons.lang.StringUtils; 32 import org.apache.excalibur.source.Source; 33 import org.apache.excalibur.source.SourceResolver; 34 35 import java.io.IOException ; 36 import java.util.HashMap ; 37 import java.util.Locale ; 38 import java.util.Map ; 39 40 151 public class LocaleMatcher extends AbstractLogEnabled 152 implements Matcher, ThreadSafe, Serviceable, Configurable, Disposable { 153 154 private static final String DEFAULT_LOCALE_ATTRIBUTE = "locale"; 155 private static final String DEFAULT_DEFAULT_LANG = "en"; 156 private static final String DEFAULT_DEFAULT_COUNTRY = "US"; 157 private static final String DEFAULT_DEFAULT_VARIANT = ""; 158 159 private ServiceManager manager; 160 private SourceResolver resolver; 161 162 165 private String localeAttribute; 166 167 170 private boolean useLocale; 171 172 private boolean useLocales; 173 private Locale defaultLocale; 174 private boolean useBlankLocale; 175 private boolean testResourceExists; 176 177 180 private boolean storeInRequest; 181 182 185 private boolean storeInSession; 186 187 190 private boolean createSession; 191 192 195 private boolean storeInCookie; 196 197 198 public void service(ServiceManager manager) throws ServiceException { 199 this.manager = manager; 200 this.resolver = (SourceResolver)this.manager.lookup(SourceResolver.ROLE); 201 } 202 203 public void configure(Configuration config) { 204 this.storeInRequest = config.getChild("store-in-request").getValueAsBoolean(false); 205 this.createSession = config.getChild("create-session").getValueAsBoolean(false); 206 this.storeInSession = config.getChild("store-in-session").getValueAsBoolean(false); 207 this.storeInCookie = config.getChild("store-in-cookie").getValueAsBoolean(false); 208 if (getLogger().isDebugEnabled()) { 209 getLogger().debug((this.storeInRequest ? "will" : "won't") + " set values in request"); 210 getLogger().debug((this.createSession ? "will" : "won't") + " create session"); 211 getLogger().debug((this.storeInSession ? "will" : "won't") + " set values in session"); 212 getLogger().debug((this.storeInCookie ? "will" : "won't") + " set values in cookies"); 213 } 214 215 this.localeAttribute = config.getChild("locale-attribute").getValue(DEFAULT_LOCALE_ATTRIBUTE); 216 this.testResourceExists = config.getChild("negotiate").getValueAsBoolean(false); 217 218 this.useLocale = config.getChild("use-locale").getValueAsBoolean(true); 219 this.useLocales = config.getChild("use-locales").getValueAsBoolean(false); 220 this.useBlankLocale = config.getChild("use-blank-locale").getValueAsBoolean(true); 221 222 Configuration child = config.getChild("default-locale", false); 223 if (child != null) { 224 this.defaultLocale = new Locale (child.getAttribute("language", DEFAULT_DEFAULT_LANG), 225 child.getAttribute("country", DEFAULT_DEFAULT_COUNTRY), 226 child.getAttribute("variant", DEFAULT_DEFAULT_VARIANT)); 227 } 228 229 if (getLogger().isDebugEnabled()) { 230 getLogger().debug("Locale attribute name is " + this.localeAttribute); 231 getLogger().debug((this.testResourceExists ? "will" : "won't") + " negotiate locale"); 232 getLogger().debug((this.useLocale ? "will" : "won't") + " use request locale"); 233 getLogger().debug((this.useLocales ? "will" : "won't") + " use request locales"); 234 getLogger().debug((this.useBlankLocale ? "will" : "won't") + " blank locales"); 235 getLogger().debug("default locale " + this.defaultLocale); 236 } 237 } 238 239 public void dispose() { 240 this.manager.release(this.resolver); 241 this.resolver = null; 242 this.manager = null; 243 } 244 245 246 public Map match(final String pattern, Map objectModel, Parameters parameters) 247 throws PatternException { 248 final Map map = new HashMap (); 249 250 I18nUtils.LocaleValidator validator = new I18nUtils.LocaleValidator() { 251 public boolean test(String name, Locale locale) { 252 if (getLogger().isDebugEnabled()) { 253 getLogger().debug("Testing " + name + " locale: '" + locale + "'"); 254 } 255 return isValidResource(pattern, locale, map); 256 } 257 }; 258 259 Locale locale = I18nUtils.findLocale(objectModel, 260 localeAttribute, 261 parameters, 262 defaultLocale, 263 useLocale, 264 useLocales, 265 useBlankLocale, 266 validator); 267 268 if (locale == null) { 269 if (getLogger().isDebugEnabled()) { 270 getLogger().debug("No locale found for resource: " + pattern); 271 } 272 return null; 273 } 274 275 String localeStr = locale.toString(); 276 if (getLogger().isDebugEnabled()) { 277 getLogger().debug("Locale " + localeStr + " found for resource: " + pattern); 278 } 279 280 I18nUtils.storeLocale(objectModel, 281 localeAttribute, 282 localeStr, 283 storeInRequest, 284 storeInSession, 285 storeInCookie, 286 createSession); 287 288 return map; 289 } 290 291 private boolean isValidResource(String pattern, Locale locale, Map map) { 292 Locale testLocale; 293 294 if (locale.getVariant().length() > 0) { 296 if (isValidResource(pattern, locale, locale, map)) { 297 return true; 298 } 299 } 300 301 if (locale.getCountry().length() > 0) { 303 testLocale = new Locale (locale.getLanguage(), locale.getCountry()); 304 if (isValidResource(pattern, locale, testLocale, map)) { 305 return true; 306 } 307 } 308 309 testLocale = new Locale (locale.getLanguage(), ""); if (isValidResource(pattern, locale, testLocale, map)) { 312 return true; 313 } 314 315 return false; 316 } 317 318 private boolean isValidResource(String pattern, Locale locale, Locale testLocale, Map map) { 319 String url; 320 321 String testLocaleStr = testLocale.toString(); 322 if ("".equals(testLocaleStr)) { 323 int starPos = pattern.indexOf("*"); 325 if (starPos < pattern.length() - 1 && starPos > 1 && 326 pattern.charAt(starPos - 1) == pattern.charAt(starPos + 1)) { 327 url = pattern.substring(0, starPos - 1) + pattern.substring(starPos + 1); 328 } else { 329 url = StringUtils.replace(pattern, "*", ""); 330 } 331 } else { 332 url = StringUtils.replace(pattern, "*", testLocaleStr); 333 } 334 335 boolean result = true; 336 if (testResourceExists) { 337 Source source = null; 338 try { 339 source = resolver.resolveURI(url); 340 result = source.exists(); 341 } catch (IOException e) { 342 result = false; 343 } finally { 344 if (source != null) { 345 resolver.release(source); 346 } 347 } 348 } 349 350 if (result) { 351 map.put("source", url); 352 map.put("matched-locale", testLocaleStr); 353 if (locale != null) { 354 map.put("locale", locale.toString()); 355 map.put("language", locale.getLanguage()); 356 map.put("country", locale.getCountry()); 357 map.put("variant", locale.getVariant()); 358 } 359 } 360 361 return result; 362 } 363 } 364 | Popular Tags |