/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.brooklyn.feed.function;
import static com.google.common.base.Preconditions.checkNotNull;
import groovy.lang.Closure;
import java.util.concurrent.Callable;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.feed.FeedConfig;
import org.apache.brooklyn.core.feed.PollConfig;
import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
import org.apache.brooklyn.util.guava.Functionals;
import org.apache.brooklyn.util.javalang.JavaClassNames;
import com.google.common.base.Supplier;
public class FunctionPollConfig<S, T> extends PollConfig<S, T, FunctionPollConfig<S, T>> {
private Callable<?> callable;
public static <T> FunctionPollConfig<?, T> forSensor(AttributeSensor<T> sensor) {
return new FunctionPollConfig<Object, T>(sensor);
}
public FunctionPollConfig(AttributeSensor<T> sensor) {
super(sensor);
}
public FunctionPollConfig(FunctionPollConfig<S, T> other) {
super(other);
callable = other.callable;
}
public Callable<? extends Object> getCallable() {
return callable;
}
/**
* The {@link Callable} to be invoked on each poll.
* <p>
* Note this <em>must</em> use generics, otherwise the return type of subsequent chained
* calls will (e.g. to {@link FeedConfig#onException(com.google.common.base.Function)} will
* return the wrong type.
*/
@SuppressWarnings("unchecked")
public <newS> FunctionPollConfig<newS, T> callable(Callable<? extends newS> val) {
this.callable = checkNotNull(val, "callable");
return (FunctionPollConfig<newS, T>) this;
}
/**
* Supplies the value to be returned by each poll.
* <p>
* Note this <em>must</em> use generics, otherwise the return type of subsequent chained
* calls will (e.g. to {@link FeedConfig#onException(com.google.common.base.Function)} will
* return the wrong type.
*/
@SuppressWarnings("unchecked")
public <newS> FunctionPollConfig<newS, T> supplier(final Supplier<? extends newS> val) {
this.callable = Functionals.callable( checkNotNull(val, "supplier") );
return (FunctionPollConfig<newS, T>) this;
}
/** @deprecated since 0.7.0, kept for legacy compatibility when deserializing */
@SuppressWarnings({ "unchecked", "unused" })
private <newS> FunctionPollConfig<newS, T> supplierLegacy(final Supplier<? extends newS> val) {
checkNotNull(val, "supplier");
this.callable = new Callable<newS>() {
@Override
public newS call() throws Exception {
return val.get();
}
};
return (FunctionPollConfig<newS, T>) this;
}
public FunctionPollConfig<S, T> closure(Closure<?> val) {
this.callable = GroovyJavaMethods.callableFromClosure(checkNotNull(val, "closure"));
return this;
}
@Override protected String toStringBaseName() { return "fn"; }
@Override protected String toStringPollSource() {
if (callable==null) return null;
String cs = callable.toString();
if (!cs.contains( ""+Integer.toHexString(callable.hashCode()) )) {
return cs;
}
// if hashcode is in callable it's probably a custom internal; return class name
return JavaClassNames.simpleClassName(callable);
}
}