/******************************************************************************* * Copyright (c) 2009, 2015 EclipseSource 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: * EclipseSource - initial API and implementation * Frank Appel - removed singletons and static fields (Bug 227787) ******************************************************************************/ package org.eclipse.rap.rwt.internal.theme; import java.util.HashMap; import java.util.Map; import org.eclipse.rap.rwt.internal.lifecycle.LifeCycleAdapterUtil; import org.eclipse.rap.rwt.internal.util.ClassInstantiationException; import org.eclipse.rap.rwt.internal.util.ClassUtil; import org.eclipse.swt.internal.widgets.controlkit.ControlThemeAdapterImpl; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Widget; public final class ThemeAdapterManager { private final Map<Class<? extends Widget>, ThemeAdapter> themeAdapters; public ThemeAdapterManager() { themeAdapters = new HashMap<>(); } public void reset() { themeAdapters.clear(); } public ThemeAdapter getThemeAdapter( Widget widget ) { Class<? extends Widget> widgetClass = widget.getClass(); ThemeAdapter result; synchronized( themeAdapters ) { result = themeAdapters.get( widgetClass ); if( result == null ) { ThemeAdapter adapter = findThemeAdapter( widgetClass ); themeAdapters.put( widgetClass, adapter ); result = adapter; } } ensureThemeAdapterWasFound( widgetClass, result ); return result; } private static ThemeAdapter findThemeAdapter( Class<? extends Widget> widgetClass ) { ThemeAdapter result = null; Class<?> superClass = widgetClass; while( !Object.class.equals( superClass ) && result == null ) { result = loadThemeAdapter( superClass ); if( result == null ) { superClass = superClass.getSuperclass(); } } return result; } private static ThemeAdapter loadThemeAdapter( Class<?> superClass ) { if( superClass == Control.class ) { return new ControlThemeAdapterImpl(); } String className = superClass.getSimpleName(); String[] variants = LifeCycleAdapterUtil.getKitPackageVariants( superClass.getName() ); for( String variant : variants ) { String classToLoad = new StringBuilder() .append( variant ) .append( "." ) .append( className ) .append( "ThemeAdapter" ) .toString(); ThemeAdapter adapter = loadThemeAdapter( classToLoad, superClass.getClassLoader() ); if( adapter != null ) { return adapter; } } return null; } private static ThemeAdapter loadThemeAdapter( String className, ClassLoader classLoader ) { try { return ( ThemeAdapter )ClassUtil.newInstance( classLoader, className ); } catch( @SuppressWarnings( "unused" ) ClassInstantiationException cie ) { // ignore, try to load from next package name variant return null; } } private static void ensureThemeAdapterWasFound( Class< ? extends Widget> widgetClass, ThemeAdapter result ) { if( result == null ) { String msg = "Failed to obtain theme adapter for class: " + widgetClass.getName(); throw new ThemeManagerException( msg ); } } }