/******************************************************************************* * Copyright (c) 2002-2007 Innoopract Informationssysteme GmbH. * 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 ******************************************************************************/ package org.eclipse.ui.internal; import java.lang.reflect.*; 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.rwt.RWT; import org.eclipse.rwt.internal.service.ContextProvider; import org.osgi.framework.*; /** * 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 * 'org.eclipse.rap.equinox.registry' fragment is available.</p> */ class ResourceTranslatorHelper { private static final Class[] PARAM_TYPE_ALGORITHM = new Class[] { Runnable.class }; private static final String METHOD_SET_TRANSLATOR_ALGORITHM = "setTranslatorAlgorithm"; private static final String METHOD_GET_BUNDLE_CONTEXT = "getBundleContext"; private static final String FIELD_ALGORITHM_IO = "algorithmIO"; private static Class CLASS_REGISTRY_FACTORY = RegistryFactory.class; /** * Plugable 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; try { if( ContextProvider.hasContext() ) { bundle = getResourceBundle(); } } catch( final Exception shouldNotHappen ) { // TODO [fappel]: I use reflection to get the bundle context since this // is not available in 3.2. We do not support the // NLS patch fragment in 3.2 but unfortunately our build // process for 3.2 fails. As we will skip support for // 3.2 soon, this seems to be the easiest solution. // Remove reflection usage after 3.2 support has been // skipped. shouldNotHappen.printStackTrace(); } if( bundle != null ) { result = ResourceTranslator.getResourceString( null, getKey(), bundle ); } getIOHandle().set( result ); } private ResourceBundle getResourceBundle() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { Bundle bundle = Platform.getBundle( getSymbolicName() ); BundleContext bundleContext = getBundleContext( bundle ); String id = BundleLocalization.class.getName(); ServiceReference reference = bundleContext.getServiceReference( id ); BundleLocalization localization = ( BundleLocalization )bundleContext.getService( reference ); return localization.getLocalization( bundle, RWT.getLocale().toString() ); } private BundleContext getBundleContext( final Bundle bundle ) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { Method getBundleContext = Bundle.class.getDeclaredMethod( METHOD_GET_BUNDLE_CONTEXT, null ); return ( BundleContext )getBundleContext.invoke( bundle, null ); } 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; } } 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 } }