/******************************************************************************
* Copyright (c) 2016 Oracle
* 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:
* Konstantin Komissarchik - initial implementation and ongoing maintenance
******************************************************************************/
package org.eclipse.sapphire;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
/**
* @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
*/
public abstract class FilteredListener<T extends Event> extends Listener
{
private final Class<T> type;
protected FilteredListener()
{
this.type = findEventType( getClass() );
}
@Override
public final void handle( final Event event )
{
if( this.type.isInstance( event ) )
{
handleTypedEvent( this.type.cast( event ) );
}
}
protected abstract void handleTypedEvent( T event );
@SuppressWarnings( "unchecked" )
private static <E extends Event> Class<E> findEventType( final Class<?> cl )
{
final Type superGenericType = cl.getGenericSuperclass();
if( superGenericType instanceof ParameterizedType )
{
final ParameterizedType superParameterizedType = (ParameterizedType) superGenericType;
final Class<?> superRawType = (Class<?>) superParameterizedType.getRawType();
if( superRawType == FilteredListener.class )
{
return (Class<E>) superParameterizedType.getActualTypeArguments()[ 0 ];
}
else
{
return findEventType( superRawType );
}
}
else
{
final Class<?> superRawType = (Class<?>) superGenericType;
if( superRawType == FilteredListener.class )
{
throw new IllegalStateException( "FilteredListener must be parameterized." );
}
else
{
return findEventType( superRawType );
}
}
}
}