org.eclipse.sisu.inject.WatchedBeans Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2010-present Sonatype, Inc.
* 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:
* Stuart McCulloch (Sonatype, Inc.) - initial API and implementation
*******************************************************************************/
package org.eclipse.sisu.inject;
import java.lang.annotation.Annotation;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import org.eclipse.sisu.BeanEntry;
import org.eclipse.sisu.Mediator;
import com.google.inject.Binding;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* Provides dynamic {@link BeanEntry} notifications by tracking qualified {@link Binding}s.
*
* @see BeanLocator#watch(Key, Mediator, Object)
*/
final class WatchedBeans
implements BindingSubscriber
{
// ----------------------------------------------------------------------
// Implementation fields
// ----------------------------------------------------------------------
private final BeanCache beans = new BeanCache();
private final Key key;
private final Mediator mediator;
private final QualifyingStrategy strategy;
private final Reference watcherRef;
// ----------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------
WatchedBeans( final Key key, final Mediator mediator, final W watcher )
{
this.key = key;
this.mediator = mediator;
strategy = QualifyingStrategy.selectFor( key );
watcherRef = new WeakReference( watcher );
}
// ----------------------------------------------------------------------
// Public methods
// ----------------------------------------------------------------------
public TypeLiteral type()
{
return key.getTypeLiteral();
}
public void add( final Binding binding, final int rank )
{
@SuppressWarnings( "unchecked" )
final Q qualifier = (Q) strategy.qualifies( key, binding );
if ( null != qualifier )
{
final W watcher = watcherRef.get();
if ( null != watcher )
{
final BeanEntry bean = beans.create( qualifier, binding, rank );
try
{
mediator.add( bean, watcher );
}
catch ( final Throwable e ) // NOPMD see Logs.catchThrowable
{
Logs.catchThrowable( e );
Logs.warn( "Problem adding: <> to: " + detail( watcher ), bean, e );
}
}
}
}
public void remove( final Binding binding )
{
final BeanEntry bean = beans.remove( binding );
if ( null != bean )
{
final W watcher = watcherRef.get();
if ( null != watcher )
{
try
{
mediator.remove( bean, watcher );
}
catch ( final Throwable e ) // NOPMD see Logs.catchThrowable
{
Logs.catchThrowable( e );
Logs.warn( "Problem removing: <> from: " + detail( watcher ), bean, e );
}
}
}
}
public Iterable> bindings()
{
return beans.bindings();
}
// ----------------------------------------------------------------------
// Implementation methods
// ----------------------------------------------------------------------
private String detail( final Object watcher )
{
return Logs.identityToString( watcher ) + " via: " + Logs.identityToString( mediator );
}
}