/*******************************************************************************
* Copyright (c) 2002, 2012 Innoopract Informationssysteme GmbH and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innoopract Informationssysteme GmbH - initial API and implementation
* EclipseSource - ongoing development
******************************************************************************/
package org.eclipse.rap.ui.internal;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ResourceBundle;
import org.eclipse.core.internal.runtime.ResourceTranslator;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.RegistryFactory;
import org.eclipse.osgi.service.localization.BundleLocalization;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.internal.service.ContextProvider;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
/**
* Helper class that registers a runnable that handles NLS for externalized
* labels in plugin.xml files regarding the setting of
* <code>{@link RWT#getLocale()}</code>.
*
* <p>Note that this functionality only takes effect if the
* <code>org.eclipse.rap.equinox.registry<code> fragment is available.</p>
*/
public final class ResourceTranslatorHelper {
private static final Class[] PARAM_TYPE_ALGORITHM
= new Class[] { Runnable.class };
private static final String METHOD_SET_TRANSLATOR_ALGORITHM
= "setTranslatorAlgorithm"; //$NON-NLS-1$
private static final String FIELD_ALGORITHM_IO = "algorithmIO"; //$NON-NLS-1$
private static final Class CLASS_REGISTRY_FACTORY = RegistryFactory.class;
/**
* Pluggable runnable that handles translation of externalized labels
* of extension declarations.
*/
private static final class TranslatorAlgorithm implements Runnable {
public void run() {
String result = getKey();
ResourceBundle bundle = null;
if( ContextProvider.hasContext() ) {
bundle = getResourceBundle();
}
if( bundle != null ) {
result = ResourceTranslator.getResourceString( null, getKey(), bundle );
}
getIOHandle().set( result );
}
private ResourceBundle getResourceBundle() {
Bundle bundle = Platform.getBundle( getSymbolicName() );
BundleContext bundleContext = bundle.getBundleContext();
String id = BundleLocalization.class.getName();
ServiceReference reference = bundleContext.getServiceReference( id );
BundleLocalization localization
= ( BundleLocalization )bundleContext.getService( reference );
return localization.getLocalization( bundle, RWT.getLocale().toString() );
}
private String getKey() {
return ( ( String[] )getIOHandle().get() )[ 0 ];
}
private String getSymbolicName() {
return ( ( String[] )getIOHandle().get() )[ 1 ];
}
private ThreadLocal getIOHandle() {
ThreadLocal io = null;
try {
io = ( ThreadLocal )getAlgorithmIO().get( null );
} catch( final Exception shouldNotHappen ) {
// the exceptional condition were already checked before setting
// this algorithm implementation
shouldNotHappen.printStackTrace();
}
return io;
}
}
public static void registerAlgorithm() {
if( isRWTLocalSpecificTranslationAllowed() ) {
try {
Object[] param = new Object[] { new TranslatorAlgorithm() };
getAlgorithmSetter().invoke( null, param );
} catch( final Exception shouldNotHappen ) {
shouldNotHappen.printStackTrace();
}
}
}
//////////////////
// helping methods
private static boolean isRWTLocalSpecificTranslationAllowed() {
boolean result = false;
try {
getAlgorithmIO();
getAlgorithmSetter();
result = true;
} catch( final Exception ignore ) {
// if an exception occures the patched version of RegistryFactory
// isn't available
}
return result ;
}
private static Method getAlgorithmSetter() throws NoSuchMethodException {
String name = METHOD_SET_TRANSLATOR_ALGORITHM;
Class[] type = PARAM_TYPE_ALGORITHM;
return CLASS_REGISTRY_FACTORY.getDeclaredMethod( name, type );
}
private static Field getAlgorithmIO() throws NoSuchFieldException {
return CLASS_REGISTRY_FACTORY.getDeclaredField( FIELD_ALGORITHM_IO );
}
private ResourceTranslatorHelper() {
// prevent instance creation
}
}