blob: c81b163a9b835f37262f454901bb558c185c531c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2002-2006 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.swt.internal.lifecycle;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.swt.internal.widgets.displaykit.DisplayLCA;
import org.eclipse.swt.lifecycle.ILifeCycleAdapter;
import org.eclipse.swt.lifecycle.IWidgetLifeCycleAdapter;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Widget;
import com.w4t.AdapterFactory;
/**
* TODO [rh] JavaDoc
* <p></p>
*/
public final class LifeCycleAdapterFactory implements AdapterFactory {
private static final Class[] ADAPTER_LIST = new Class[] {
ILifeCycleAdapter.class,
};
// Holds the single display life cycle adapter. MUST be created lazily
// because its constructor needs a resource manager to be in place
private static IDisplayLifeCycleAdapter displayAdapter;
// Maps widget classes to their respective life cycle adapters
// Key: Class<Widget>, value: IWidgetLifeCycleAdapter
private static final Map widgetAdapters = new HashMap();
public Object getAdapter( final Object adaptable, final Class adapter ) {
Object result = null;
if( isDisplayLCA( adaptable, adapter ) ) {
result = getDisplayLCA();
} else if( isWidgetLCA( adaptable, adapter ) ) {
result = getWidgetLCA( adaptable.getClass() );
}
return result;
}
public Class[] getAdapterList() {
return ADAPTER_LIST;
}
///////////////////////////////////////////////////////////
// Helping methods to obtain life cycle adapter for display
private boolean isDisplayLCA( final Object adaptable, final Class adapter ) {
return adaptable instanceof Display && adapter == ILifeCycleAdapter.class;
}
private static synchronized ILifeCycleAdapter getDisplayLCA() {
if( displayAdapter == null ) {
displayAdapter = new DisplayLCA();
}
return displayAdapter;
}
////////////////////////////////////////////////////////////
// Helping methods to obtain life cycle adapters for widgets
private boolean isWidgetLCA( final Object adaptable, final Class adapter ) {
return adaptable instanceof Widget && adapter == ILifeCycleAdapter.class;
}
private static String getSimpleClassName( final Class clazz ) {
String className = clazz.getName();
int idx = className.lastIndexOf( '.' );
return className.substring( idx + 1 );
}
private static synchronized ILifeCycleAdapter getWidgetLCA(
final Class clazz )
{
// Note [fappel]: Since this code is performance critical, don't change
// anything without checking it against a profiler.
ILifeCycleAdapter result = ( ILifeCycleAdapter )widgetAdapters.get( clazz );
if( result == null ) {
ILifeCycleAdapter adapter = null;
Class superClass = clazz;
while( !Object.class.equals( superClass ) && adapter == null ) {
adapter = loadWidgetLCA( superClass );
if( adapter == null ) {
superClass = superClass.getSuperclass();
}
}
widgetAdapters.put( clazz, adapter );
result = adapter;
}
if( result == null ) {
String text = "Failed to obtain life cycle adapter for class ''{0}\''.";
Object[] params = new Object[]{ clazz.getName() };
String msg = MessageFormat.format( text, params );
throw new LifeCycleAdapterException( msg );
}
return result;
}
private static IWidgetLifeCycleAdapter loadWidgetLCA( final Class clazz )
{
IWidgetLifeCycleAdapter result = null;
String[] variants = getPackageVariants( clazz.getPackage().getName() );
for( int i = 0; result == null && i < variants.length; i++ ) {
StringBuffer buffer = new StringBuffer();
buffer.append( variants[ i ] );
buffer.append( "." );
buffer.append( getSimpleClassName( clazz ).toLowerCase() );
buffer.append( "kit." );
buffer.append( getSimpleClassName( clazz ) );
buffer.append( "LCA" );
String classToLoad = buffer.toString();
ClassLoader loader = clazz.getClassLoader();
try {
Class adapterClass = loader.loadClass( classToLoad );
result = ( IWidgetLifeCycleAdapter )adapterClass.newInstance();
} catch( final Throwable thr ) {
// ignore and try to load next package name variant
}
}
return result;
}
static String[] getPackageVariants( final String packageName ) {
String[] result;
if( packageName == null || "".equals( packageName ) ) {
result = new String[] { "internal" };
} else {
String[] segments = packageName.split( "\\." );
result = new String[ segments.length + 1 ];
for( int i = 0; i < result.length; i++ ) {
StringBuffer buffer = new StringBuffer();
for( int j = 0; j < segments.length; j++ ) {
if( j == i ) {
buffer.append( "internal." );
}
buffer.append( segments[ j ] );
if( j < segments.length - 1 ) {
buffer.append( "." );
}
}
if( i == segments.length ) {
buffer.append( ".internal" );
}
result[ i ] = buffer.toString();
}
}
return result;
}
}