brooklyn.enricher.basic.AbstractCombiningEnricher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of brooklyn-core Show documentation
Show all versions of brooklyn-core Show documentation
Entity implementation classes, events, and other core elements
package brooklyn.enricher.basic;
import java.lang.reflect.Field;
import java.util.LinkedHashSet;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import brooklyn.entity.Entity;
import brooklyn.entity.basic.EntityLocal;
import brooklyn.event.AttributeSensor;
import brooklyn.event.SensorEvent;
import brooklyn.event.SensorEventListener;
import brooklyn.event.basic.BasicSensorEvent;
import brooklyn.management.SubscriptionHandle;
/**
* Convenience base for transforming multiple sensors into a single new sensor.
* Usage:
*
* {@code
* }
*
*
* @deprecated in 0.5; unused code that relies on reflection; not recommended;
* use {@link AbstractEnricher} (at least until compelling use-case)
*/
public abstract class AbstractCombiningEnricher extends AbstractEnricher {
public static final Logger log = LoggerFactory.getLogger(AbstractCombiningEnricher.class);
protected AttributeSensor target;
static class SubscriptionDetails {
Field field;
Entity source;
AttributeSensor sensor;
int count=0;
SubscriptionHandle handle;
public SubscriptionDetails(Field field, Entity source, AttributeSensor sensor) {
this.field = field;
this.source = source;
this.sensor = sensor;
}
}
Set subscriptions;
public AbstractCombiningEnricher(AttributeSensor target) {
this.target = target;
}
/** subscribes to a given sensor on the entity where this enricher is attached,
* setting the value in the variable name indicated,
* which must be a field in this class */
protected synchronized void subscribe(String varName, AttributeSensor sensor) {
subscribe(varName, null, sensor);
}
/** @see #subscribe(String, AttributeSensor) */
protected synchronized void subscribe(Field field, AttributeSensor sensor) {
subscribe(field, null, sensor);
}
/** subscribes to a given sensor on the given entity, setting the value in the variable name indicated,
* which must be a field in this class */
protected synchronized void subscribe(String varName, Entity source, AttributeSensor sensor) {
Field[] fields = AbstractCombiningEnricher.this.getClass().getDeclaredFields();
for (Field f: fields) {
if (f.getName().equals(varName)) {
subscribe(f, source, sensor);
return;
}
}
throw new IllegalStateException("Field "+varName+" does not exist");
}
/** @see #subscribe(String, AttributeSensor) */
protected synchronized void subscribe(Field field, Entity source, AttributeSensor sensor) {
if (subscriptions==null) subscriptions = new LinkedHashSet();
subscriptions.add(new SubscriptionDetails(field, source, sensor));
}
@Override
public void setEntity(final EntityLocal entity) {
super.setEntity(entity);
for (final SubscriptionDetails s: subscriptions) {
final Entity source = (s.source==null ? entity : s.source);
SensorEventListener listener = new SensorEventListener() {
@Override
public void onEvent(SensorEvent event) {
try {
s.field.setAccessible(true);
s.field.set(AbstractCombiningEnricher.this, event.getValue());
s.count++;
update();
return;
} catch (Exception e) {
log.error("Error setting "+s.field.getName()+" to "+event.getValue()+" from sensor "+s.sensor+"" +
"in enricher "+this+" on "+entity+": "+
"ensure variable exists and has the correct type and permissions ("+e+")", e);
if (s.handle!=null) unsubscribe(source, s.handle);
}
}
};
s.handle = subscribe( source, s.sensor, listener);
Object value = source.getAttribute(s.sensor);
// TODO Aled didn't you write a convenience to "subscribeAndRunIfSet" ? (-Alex)
if (value!=null)
listener.onEvent(new BasicSensorEvent(s.sensor, source, value));
}
}
public void update() {
for (SubscriptionDetails s: subscriptions) {
if (s.count==0) return;
}
entity.setAttribute(target, compute());
}
/** supply the computation in terms of subscribed variables; by default this is only invoked
* once all fields have been set at least once, then subsequently on any change to either of them */
public abstract T compute();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy