>
> ----- Original Message -----
> From: "Leandro Rodrigo Saad Cruz" <[EMAIL PROTECTED]>
> To: "Turbine Users List" <[EMAIL PROTECTED]>
> Sent: Tuesday, March 19, 2002 3:52 PM
> Subject: Re: Localization
>
>
> > You can use the Localization accessor with any locale you would like.
> > Maybe you can change TLocalizationService.java or LocalizationTool.java
> > to allow some order or user preference regarding localized objects.
> > I created a class called LocaleHelper that has the business logic used
> > to pick up a locale acording to values in user session and http headers.
> > If you wnat I can send it to you.
Ok.. that's what I've done.
I need to grab *localized objects and maybe choose between **localized
templates
* to accomplish this I wrote LocalizationHelper, this class is used in
behalf of *new* LocalizationTool and encapsulates the logic that chooses
locales.
** I wrote a new Screen that tries to find different templates accordign
to some locale info. For example : locale=pt_BR, then
SomeTemplate-pt_BR.vm is looked up, then SomeTemplate.vm
OBS : you will have to change the package of this files and possibly
some code (chanbe ACCEPTED_LOACES for example) to make it work.
Want any help ??
To see it working visit
http://www.intercontinental.ind.br:8180/inter/servlet/main
this site is supposed to be viewed in English and Portuguese
--
Leandro Rodrigo Saad Cruz
IT - Inter Business Tecnologia e Servicos (IB)
http://www.ibnetwork.com.br
package br.com.ibnetwork.intercontinental.modules.screens;
//APP
import br.com.ibnetwork.intercontinental.services.localization.LocalizationHelper;
//T2
import org.apache.turbine.util.RunData;
import org.apache.turbine.util.Log;
import org.apache.turbine.modules.screens.VelocityScreen;
import org.apache.turbine.services.template.TurbineTemplate;
import org.apache.turbine.services.velocity.TurbineVelocity;
import org.apache.velocity.context.Context;
import org.apache.velocity.app.Velocity;
import org.apache.ecs.ConcreteElement;
//JAVA
import java.util.Locale;
import java.io.File;
/**
* This module is responsible for searching a template file accordign to LocalizationHelper.getLocale()
* <br>
* This way we can stil use links like $link.setPage("SomeTemplate.vm") and this module will handle the template engine the right template. For Example :
* <br>
* <b>USER_LOCALE = pt_BR</b>
* <br>
* search for : SomeTemplate-pt_BR.vm, then SomeTemplate.vm ....
*
* @author <a href="mailto:[EMAIL PROTECTED]">Leandro Rodrigo Saad Cruz</a>
*/
public class IntercontinentalVelocityScreen extends VelocityScreen
{
/**
* Este metodo sera executado apos os metodos dos screens que estendem esta classe<br>
* Sua funcao eh tentar localizar um template com o mesmo nome do presente em RunData, mas com conteudo sensivel ao locale correto.
* O locale pesquisado pode variar de acordo com as regras em LocalizationHelper.
* Este m�dulo apenas faz uma tentativa de mudar o template, caso o template-locale n�o exista, o template original ser� executado
*/
public void setTemplateLocalizationExtension(RunData data)
{
Locale locale = LocalizationHelper.getLocale(data);
Log.debug("debug","IntercontinentalScreen - Searching for new template for locale["+locale+"]");
if(locale != null)
{
try
{
//caso algum locale esteja disponivel nos tentaremos achar outros template
String templateName = TurbineTemplate.getScreenTemplateName(data.getTemplateInfo().getScreenTemplate());
Log.debug("debug","IntercontinentalScreen - original template["+templateName+"]");
data.setScreenTemplate(composeLocaleInfoAndTemplateName(templateName,locale));
}
catch(Exception e)
{
Log.debug("Erro",e);
//em caso de erro, o template original sera pesquisado
}
}
}
/**
* This method is called by the Screenloader to construct the
* Screen.
*
* @param data Turbine information.
* @return A ConcreteElement.
* @exception Exception, a generic exception.
*/
public ConcreteElement doBuild( RunData data )
throws Exception
{
Log.debug("debug","IntercontinentalScreen - Executing doBuild(data)");
ConcreteElement out = null;
try
{
doBuildTemplate(data);
setTemplateLocalizationExtension(data);
out = buildTemplate(data);
}
finally
{
doPostBuildTemplate(data);
}
return out;
}
private String composeLocaleInfoAndTemplateName(String templateName,Locale locale)
{
int pathSeparatorPosition = templateName.lastIndexOf("/");
if(pathSeparatorPosition >= 0)
{
String minusPath = templateName.substring(pathSeparatorPosition + 1);
String path = templateName.substring(0,pathSeparatorPosition+1);
Log.debug("debug","IntercontinentalScreen - path["+path+"] name["+minusPath+"]");
int dotPosition = minusPath.lastIndexOf(".");
StringBuffer sb = new StringBuffer();
sb.append(path)
.append(minusPath.substring(0,dotPosition))
.append("-")
.append(locale)
.append(minusPath.substring(dotPosition));
String newTemplateName = sb.toString();
if(Velocity.templateExists("/screens"+newTemplateName))
{
Log.info("debug","IntercontinentalScreen - localizedTemplateName found ["+newTemplateName+"] ");
return newTemplateName;
}
}
Log.info("debug","IntercontinentalScreen - localizedTemplateName found ["+templateName+"] ");
return templateName;
}
}
package br.com.ibnetwork.intercontinental.services.localization;
//T2
import org.apache.turbine.util.Log;
import org.apache.turbine.util.RunData;
import org.apache.turbine.services.localization.Localization;
//JAVA
import java.util.Locale;
import java.util.StringTokenizer;
/**
* This class is a helper tool to be used when you have to decide which Locale to choose.
* This implementation follows this criteria : <br>
* i - first it checks to see if there is locale in the user session <br>
* ii - then it tries to build a locale from HTTP headers <br>
* iii - then it uses the default locale in TR.conf <br>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Leandro Rodrigo Saad Cruz</a>
*/
public class LocalizationHelper
{
/**
* Key used to put a Locale Object
* into the session and used as a form field name
* OBS : if you want this to work between user logins you will have to patch Turbine.java to not exclude this key/val from Session
*/
public static final String USER_LOCALE = "user.locale";
/**
* Key used to define the locale separator char
*/
public static final String SEPARATOR = "_";
/**
* All locales that we are prepard to handle PORTUGUES and ENGLISH
* <br>
* OBS : Remenber, if you want do add the locales to this array you will have to add new templates to your system too
*/
public static Locale[] ACCEPTED_LOCALES = { new Locale("pt","BR"), Locale.US,Locale.ENGLISH };
/**
* Performs Locale selection
*/
public static Locale getLocale(RunData data)
{
//Session
Locale locale = (Locale) ((RunData)data).getSession().getValue(USER_LOCALE);
//HEADERS HTTP
if(locale == null)
{
locale = Localization.getLocale( ((RunData) data).getRequest() );
boolean accepted = false;
for(int i=0 ; i < ACCEPTED_LOCALES.length ; i++)
{
Log.debug("debug","LocalizationHelper: searching locale["+ACCEPTED_LOCALES[i]+"] in ACCEPTED list");
if(locale.equals(ACCEPTED_LOCALES[i]))
{
accepted = true;
break;
}
}
locale = (accepted == false ? null : locale);
}
//TR.conf
if(locale == null)
{
locale = Localization.getBundle(Localization.getDefaultBundleName()).getLocale();
}
return locale;
}
/**
* helper method used to build a locale from HTTP HEADERS
* @return a new locale obj or null when an error occur
*/
public static Locale buildLocaleFromParameter(String param)
{
if(param != null)
{
Locale locale;
StringTokenizer st = new StringTokenizer(param,SEPARATOR);
int total = st.countTokens();
String tokens[] = new String[total];
while (st.hasMoreTokens())
{
String token = st.nextToken();
Log.debug("debug","TOKEN ["+token+"]");
tokens[--total] = token;
}
if(tokens.length == 2)
{
return new Locale(tokens[1],tokens[0]);
}
if(tokens.length == 3)
{
return new Locale(tokens[2],tokens[1],tokens[0]);
}
}
return null;
}
}
package br.com.ibnetwork.intercontinental.services.localization;
//APP
//T2
import org.apache.turbine.services.localization.Localization;
import org.apache.turbine.services.pull.ApplicationTool;
import org.apache.turbine.om.security.User;
import org.apache.turbine.util.Log;
import org.apache.turbine.util.RunData;
//JAVA
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
* Localization Tool usado nos templates para disponibilizar conte�do localizado com ajuda de
* {@link br.com.ibnetwork.intercontinental.services.localization.LocalizationHelper}
*
* @author <a href="mailto:[EMAIL PROTECTED]">Leandro Rodrigo Saad Cruz</a>
*/
public class LocalizationTool implements ApplicationTool
{
/**
* The language and country information parsed from the request's
* <code>Accept-Language</code> header. Reset on each request.
*/
protected Locale locale;
/**
* The bundle for this request.
*/
private ResourceBundle bundle;
/**
* The name of the bundle for this tool to use.
*/
private String bundleName;
/**
* Creates a new instance. Used by <code>PullService</code>.
*/
public LocalizationTool()
{
locale = null;
bundle = null;
bundleName = null;
}
/**
* <p>Performs text lookups for localization.</p>
*
* <p>Assuming there is a instance of this class with a HTTP
* request set in your template's context named <code>l10n</code>,
* the VTL <code>$l10n.HELLO</code> would render to
* <code>hello</code> for English requests and <code>hola</code>
* in Spanish (depending on the value of the HTTP request's
* <code>Accept-Language</code> header).</p>
*
* @param key The identifier for the localized text to retrieve.
* @return The localized text.
*/
public String get(String key)
{
try
{
//Log.debug("service","Localization tool :Bundle["+bundleName+"]=["+bundle+"] used for key["+key+"] and locale["+locale+"]");
return bundle.getString(key);
}
catch (MissingResourceException noKey)
{
Log.warn("service","Missing Resource",noKey);
return null;
}
}
/**
* The return value of this method is used to set the name of the
* bundle used by this tool. Useful as a hook for using a
* different bundle than specifed in your
* <code>LocalizationService</code> configuration.
*
* @param data The inputs passed from {@link #init(Object)}.
* (ignored by this implementation).
*/
protected String getBundleName(Object data)
{
return Localization.getDefaultBundleName();
}
/**
* Tool initialization
* <BR>
* GLOBAL
* <blockquote>
* Locale comes from TR.conf
* </blockquote>
* <BR>
* REQUEST
* <blockquote>
* Check if user.locale is in Session, otherwise build a locale from HTTP HEADERS
* </blockquote>
*
*/
public final void init(Object data)
{
if(data == null)
{
Log.debug("service","Localization tool initializing with scope GLOBAL");
//bundle default em TR.conf since no request data is available
bundle = Localization.getBundle(Localization.getDefaultBundleName());
}
if(data instanceof User)
{
Log.debug("service","Localization tool initializing with scope SESSION");
// Pull necessary information out of Session.
}
if (data instanceof RunData)
{
Log.debug("service","Localization tool initializing with scope REQUEST");
// Pull necessary information out of RunData while we have a reference to it.
locale = LocalizationHelper.getLocale((RunData)data);
bundleName = getBundleName(data);
//bundle acoording to request information
bundle = Localization.getBundle(bundleName, locale);
Log.debug("service","Localization tool initialized with bundleName["+bundleName+"] locale["+locale+"]");
}
}
/**
* No-op.
*/
public void refresh()
{
Log.debug("service","Localization tool refreshing...");
}
/**
* helper method to be used inside templates
*/
public String getUserLocale()
{
return LocalizationHelper.USER_LOCALE;
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>