001 package org.apache.turbine.services.localization; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import java.util.Locale; 023 import java.util.MissingResourceException; 024 025 import org.apache.commons.logging.Log; 026 import org.apache.commons.logging.LogFactory; 027 import org.apache.fulcrum.localization.LocalizationService; 028 import org.apache.turbine.services.InstantiationException; 029 import org.apache.turbine.services.TurbineServices; 030 import org.apache.turbine.services.pull.ApplicationTool; 031 import org.apache.turbine.util.RunData; 032 /** 033 * A pull tool which provides lookups for localized text by delegating 034 * to the configured Fulcrum <code>LocalizationService</code>. 035 * 036 * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a> 037 * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> 038 * @author <a href="mailto:jon@collab.net">Jon Stevens</a> 039 */ 040 public class LocalizationTool implements ApplicationTool 041 { 042 /** Logging */ 043 private static Log log = LogFactory.getLog(LocalizationTool.class); 044 /** Fulcrum Localization component */ 045 private LocalizationService localizationService; 046 /** 047 * The language and country information parsed from the request's 048 * <code>Accept-Language</code> header. Reset on each request. 049 */ 050 protected Locale locale; 051 052 /** 053 * Lazy load the LocalizationService. 054 * @return a fulcrum LocalizationService 055 */ 056 public LocalizationService getLocalizationService() 057 { 058 if (localizationService == null) 059 { 060 try 061 { 062 localizationService = (LocalizationService)TurbineServices.getInstance() 063 .getService(LocalizationService.ROLE); 064 } 065 catch (Exception e) 066 { 067 throw new InstantiationException("Problem looking up Localization Service:"+e.getMessage()); 068 } 069 } 070 return localizationService; 071 } 072 073 /** 074 * Creates a new instance. Used by <code>PullService</code>. 075 */ 076 public LocalizationTool() 077 { 078 refresh(); 079 } 080 081 /** 082 * <p>Performs text lookups for localization.</p> 083 * 084 * <p>Assuming there is a instance of this class with a HTTP 085 * request set in your template's context named <code>l10n</code>, 086 * the VTL <code>$l10n.HELLO</code> would render to 087 * <code>hello</code> for English requests and <code>hola</code> 088 * in Spanish (depending on the value of the HTTP request's 089 * <code>Accept-Language</code> header).</p> 090 * 091 * @param key The identifier for the localized text to retrieve. 092 * @return The localized text. 093 */ 094 public String get(String key) 095 { 096 try 097 { 098 return getLocalizationService().getString(getBundleName(null), getLocale(), key); 099 } 100 catch (MissingResourceException noKey) 101 { 102 log.error(noKey); 103 return null; 104 } 105 } 106 107 /** 108 * Gets the current locale. 109 * 110 * @return The locale currently in use. 111 */ 112 public Locale getLocale() 113 { 114 return locale; 115 } 116 117 /** 118 * The return value of this method is used to set the name of the 119 * bundle used by this tool. Useful as a hook for using a 120 * different bundle than specified in your 121 * <code>LocalizationService</code> configuration. 122 * 123 * @param data The inputs passed from {@link #init(Object)}. 124 * (ignored by this implementation). 125 */ 126 protected String getBundleName(Object data) 127 { 128 return getLocalizationService().getDefaultBundleName(); 129 } 130 131 /** 132 * Formats a localized value using the provided object. 133 * 134 * @param key The identifier for the localized text to retrieve, 135 * @param arg1 The object to use as {0} when formatting the localized text. 136 * @return Formatted localized text. 137 * @see #format(String, Locale, String, Object[]) 138 */ 139 public String format(String key, Object arg1) 140 { 141 return getLocalizationService() 142 .format(getBundleName(null), getLocale(), key, arg1); 143 } 144 145 /** 146 * Formats a localized value using the provided objects. 147 * 148 * @param key The identifier for the localized text to retrieve, 149 * @param arg1 The object to use as {0} when formatting the localized text. 150 * @param arg2 The object to use as {1} when formatting the localized text. 151 * @return Formatted localized text. 152 * @see #format(String, Locale, String, Object[]) 153 */ 154 public String format(String key, Object arg1, Object arg2) 155 { 156 return getLocalizationService() 157 .format(getBundleName(null), getLocale(), key, arg1, arg2); 158 } 159 160 /** 161 * Formats a localized value using the provided objects. 162 * 163 * @param key The identifier for the localized text to retrieve, 164 * @param args The objects to use as {0}, {1}, etc. when 165 * formatting the localized text. 166 * @return Formatted localized text. 167 */ 168 public String format(String key, Object[] args) 169 { 170 return getLocalizationService() 171 .format(getBundleName(null), getLocale(), key, args); 172 } 173 174 // ApplicationTool implementation 175 176 /** 177 * Sets the request to get the <code>Accept-Language</code> header 178 * from (reset on each request). 179 */ 180 public void init(Object data) 181 { 182 if (data instanceof RunData) 183 { 184 // Pull necessary information out of RunData while we have 185 // a reference to it. 186 locale = getLocalizationService().getLocale(((RunData) data).getRequest()); 187 } 188 } 189 190 /** 191 * No-op. 192 */ 193 public void refresh() 194 { 195 locale = null; 196 } 197 }