/*
# Licensed Materials - Property of IBM
# Copyright IBM Corp. 2015
*/
package com.ibm.streamsx.topology.internal.core;
import static com.ibm.streamsx.topology.builder.JParamTypes.TYPE_SUBMISSION_PARAMETER;
import java.util.HashMap;
import java.util.Map;
import com.ibm.json.java.JSONObject;
import com.ibm.streams.operator.Type.MetaType;
import com.ibm.streamsx.topology.Topology;
import com.ibm.streamsx.topology.function.Supplier;
import com.ibm.streamsx.topology.internal.functional.ops.SubmissionParameterManager;
import com.ibm.streamsx.topology.tuple.JSONAble;
/**
* A specification for a value of type {@code T}
* whose actual value is not defined until topology execution time.
*/
public class SubmissionParameter<T> implements Supplier<T>, JSONAble {
private static final long serialVersionUID = 1L;
private static final Map<Class<?>,MetaType> toMetaType = new HashMap<>();
static {
toMetaType.put(String.class, MetaType.RSTRING);
toMetaType.put(Boolean.class, MetaType.BOOLEAN);
toMetaType.put(Byte.class, MetaType.INT8);
toMetaType.put(Short.class, MetaType.INT16);
toMetaType.put(Integer.class, MetaType.INT32);
toMetaType.put(Long.class, MetaType.INT64);
toMetaType.put(Float.class, MetaType.FLOAT32);
toMetaType.put(Double.class, MetaType.FLOAT64);
}
private final String name;
private final MetaType metaType;
private final T defaultValue;
private transient final Topology top;
private transient T value;
private transient boolean initialized;
private static MetaType getMetaType(Class<?> valueClass) {
MetaType metaType = toMetaType.get(valueClass);
if (metaType == null)
throw new IllegalArgumentException("Unhandled valueClass " + valueClass.getCanonicalName());
return metaType;
}
/*
* A submission time parameter specification without a default value.
* @param top the associated topology
* @param name submission parameter name
* @param valueClass class object for {@code T}
* @throws IllegalArgumentException if {@code name} is null or empty
*/
public SubmissionParameter(Topology top, String name, Class<T> valueClass) {
if (name == null || name.trim().isEmpty())
throw new IllegalArgumentException("name");
this.top = top;
this.name = name;
this.metaType = getMetaType(valueClass);
this.defaultValue = null;
}
/**
* A submission time parameter specification with a default value.
* @param top the associated topology
* @param name submission parameter name
* @param defaultValue default value if parameter isn't specified.
* @throws IllegalArgumentException if {@code name} is null or empty
* @throws IllegalArgumentException if {@code defaultValue} is null
*/
public SubmissionParameter(Topology top, String name, T defaultValue) {
if (name == null || name.trim().isEmpty())
throw new IllegalArgumentException("name");
if (defaultValue == null)
throw new IllegalArgumentException("defaultValue");
this.top = top;
this.name = name;
this.metaType = getMetaType(defaultValue.getClass());
this.defaultValue = defaultValue;
}
/**
* A submission time parameter specification with or without a default value.
* <p>
* The {@code jvalue} parameter must be a Value object.
* The Value object is
* <pre><code>
* object {
* type : "__spl_value"
* value : object {
* value : any. non-null. type appropriate for metaType
* metaType : com.ibm.streams.operator.Type.MetaType.name() string.
* }
* }
* </code></pre>
* @param top the associated topology
* @param name
* @param jvalue JSONObject
* @param withDefault true create a submission parameter with a default value,
* false for one without a default value.
* When false, the wrapped value's value is ignored.
*/
@SuppressWarnings("unchecked")
public SubmissionParameter(Topology top, String name, JSONObject jvalue, boolean withDefault) {
String type = (String) jvalue.get("type");
if (!"__spl_value".equals(type))
throw new IllegalArgumentException("defaultValue");
JSONObject value = (JSONObject) jvalue.get("value");
this.top = top;
this.name = name;
this.defaultValue = withDefault ? (T) value.get("value") : null;
this.metaType = MetaType.valueOf((String) value.get("metaType"));
}
@SuppressWarnings("unchecked")
@Override
public T get() {
if (!initialized) {
if (top == null)
value = (T) SubmissionParameterManager.getValue(name, metaType);
initialized = true;
}
return value;
}
public String getName() {
return name;
}
public T getDefaultValue() {
return defaultValue;
}
@Override
public JSONObject toJSON() {
// meet the requirements of BOperatorInvocation.setParameter()
// and OperatorGenerator.parameterValue()
/*
* The SubmissionParameter parameter value json is:
* <pre><code>
* object {
* type : "submissionParameter"
* value : object {
* name : string. submission parameter name
* metaType : operator.Type.MetaType.name() string
* defaultValue : any. may be null. type appropriate for metaType.
* }
* }
* </code></pre>
*/
JSONObject jo = new JSONObject();
JSONObject jv = new JSONObject();
jo.put("type", TYPE_SUBMISSION_PARAMETER);
jo.put("value", jv);
jv.put("name", name);
jv.put("metaType", metaType.name());
if (defaultValue != null)
jv.put("defaultValue", defaultValue);
return jo;
}
@Override
public String toString() {
return toJSON().toString();
}
}