/******************************************************************************* * 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.rwt.internal.events; import java.lang.reflect.Array; import java.util.*; import org.eclipse.rwt.internal.util.ParamCheck; import org.eclipse.swt.SWT; public class EventAdapter implements IEventAdapter { private static final Object[] EMPTY_RESULT = new Object[ 0 ]; private Map listenerSets; /** * <p>Custom Set implementation (intended to hold Listeners) to reduce * memory consumption.</p> */ private static final class ListenerSet implements Set { // Start with low capacity, assuming that only few listeners are added private final List list = new ArrayList( 3 ); public int size() { return list.size(); } public void clear() { list.clear(); } public boolean isEmpty() { return list.isEmpty(); } public Object[] toArray() { return list.toArray(); } public boolean add( final Object o ) { boolean result = !contains( o ) ; if( result ) { list.add( o ); } return result; } public boolean contains( final Object o ) { return list.contains( o ); } public boolean remove( final Object o ) { return list.remove( o ); } public boolean addAll( final Collection c ) { throw new UnsupportedOperationException(); } public boolean containsAll( final Collection c ) { throw new UnsupportedOperationException(); } public boolean removeAll( final Collection c ) { throw new UnsupportedOperationException(); } public boolean retainAll( final Collection c ) { throw new UnsupportedOperationException(); } public Iterator iterator() { throw new UnsupportedOperationException(); } public Object[] toArray( final Object[] a ) { return list.toArray( a ); } } public Object[] getListener( final Class listenerType ) { ParamCheck.notNull( listenerType, "listenerType" ); Set listenerSet = getListenerSet( listenerType ); int size = listenerSet.size(); Object[] result = ( Object[] )Array.newInstance( listenerType, size ); listenerSet.toArray( result ); return result; } public boolean hasListener( final Class listenerType ) { ParamCheck.notNull( listenerType, "listenerType" ); checkListenerType( listenerType ); boolean result = false; if( listenerSets != null && listenerSets.containsKey( listenerType ) ) { result = !getListenerSet( listenerType ).isEmpty(); } return result; } public void addListener( final Class listenerType, final Object listener ) { if( listenerType == null ) { SWT.error( SWT.ERROR_NULL_ARGUMENT ); } if( listener == null ) { SWT.error( SWT.ERROR_NULL_ARGUMENT ); } checkTypeCompatibility( listenerType, listener ); getListenerSet( listenerType ).add( listener ); } public void removeListener( final Class listenerType, final Object listener ) { if( listenerType == null ) { SWT.error( SWT.ERROR_NULL_ARGUMENT ); } if( listener == null ) { SWT.error( SWT.ERROR_NULL_ARGUMENT ); } checkTypeCompatibility( listenerType, listener ); if( hasListener( listenerType ) ) { getListenerSet( listenerType ).remove( listener ); } } private Set getListenerSet( final Class listenerType ) { checkListenerType( listenerType ); if( listenerSets == null ) { // Create with low capacity, assuming that there are only few // listener types used listenerSets = new HashMap( 4, 1.0f ); } if( !listenerSets.containsKey( listenerType ) ) { listenerSets.put( listenerType, new ListenerSet() ); } return ( Set )listenerSets.get( listenerType ); } public Object[] getListener() { Object[] result = EMPTY_RESULT; if( listenerSets != null ) { Set buffer = new HashSet(); Object[] sets = listenerSets.values().toArray(); for( int i = 0; i < sets.length; i++ ) { Set set = ( Set )sets[ i ]; Object[] listeners = set.toArray(); for( int j = 0; j < listeners.length; j++ ) { buffer.add( listeners[ j ] ); } } result = buffer.toArray(); } return result; } private void checkTypeCompatibility( final Class listenerType, final Object listener ) { if( !listenerType.isAssignableFrom( listener.getClass() ) ) { String msg = "Parameter 'listener' must be of type '" + listenerType.getName() + "'."; throw new IllegalArgumentException( msg ); } } private static void checkListenerType( final Class listenerType ) { if( !EventListener.class.isAssignableFrom( listenerType ) ) { String msg = "Parameter 'listenerType' must implement '" + EventListener.class.getName() + "'"; throw new IllegalArgumentException( msg ); } } }