/**
* Copyright 2015 StreamSets Inc.
*
* Licensed under 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 com.streamsets.datacollector.config;
import com.streamsets.datacollector.el.ElConstantDefinition;
import com.streamsets.datacollector.el.ElFunctionDefinition;
import com.streamsets.pipeline.api.ChooserValues;
import com.streamsets.pipeline.api.ConfigDef;
import com.streamsets.pipeline.api.impl.LocalizableMessage;
import com.streamsets.pipeline.api.impl.Utils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Captures attributes related to individual configuration options
*/
public class ConfigDefinition {
private final Field configField;
private final String name;
private final ConfigDef.Type type;
private final String label;
private final String description;
private Object defaultValue;
private final boolean required;
private final String group;
private final String fieldName;
private String dependsOn;
private List<Object> triggeredByValues;
private final ModelDefinition model;
private final int displayPosition;
private List<ElFunctionDefinition> elFunctionDefinitions;
private List<ElConstantDefinition> elConstantDefinitions;
private List<String> elFunctionDefinitionsIdx;
private List<String> elConstantDefinitionsIdx;
private final long min;
private final long max;
private final String mode;
private final int lines;
private List<Class> elDefs;
private final ConfigDef.Evaluation evaluation;
private Map<String, List<Object>> dependsOnMap;
private String prefix;
public ConfigDefinition(String name, ConfigDef.Type type, String label, String description,
Object defaultValue,
boolean required, String group, String fieldName, ModelDefinition model, String dependsOn,
List<Object> triggeredByValues, int displayPosition, List<ElFunctionDefinition> elFunctionDefinitions,
List<ElConstantDefinition> elConstantDefinitions, long min, long max, String mode, int lines,
List<Class> elDefs, ConfigDef.Evaluation evaluation, Map<String, List<Object>> dependsOnMap) {
this(null, name, type, label, description, defaultValue, required, group, fieldName, model,
dependsOn, triggeredByValues, displayPosition, elFunctionDefinitions,
elConstantDefinitions, min, max, mode, lines, elDefs, evaluation, dependsOnMap);
}
public ConfigDefinition(Field configField, String name, ConfigDef.Type type, String label, String description,
Object defaultValue,
boolean required, String group, String fieldName, ModelDefinition model, String dependsOn,
List<Object> triggeredByValues, int displayPosition, List<ElFunctionDefinition> elFunctionDefinitions,
List<ElConstantDefinition> elConstantDefinitions, long min, long max, String mode, int lines,
List<Class> elDefs, ConfigDef.Evaluation evaluation, Map<String, List<Object>> dependsOnMap) {
this.configField = configField;
this.name = name;
this.type = type;
this.label = label;
this.description = description;
this.defaultValue = defaultValue;
this.required = required;
this.group = group;
this.fieldName = fieldName;
this.model = model;
this.dependsOn = dependsOn;
this.triggeredByValues = triggeredByValues;
this.displayPosition = displayPosition;
this.elDefs = new ArrayList<>();
this.elDefs.addAll(elDefs);
this.elFunctionDefinitions = new ArrayList<>();
elFunctionDefinitionsIdx = new ArrayList<>();
for (ElFunctionDefinition f : elFunctionDefinitions) {
addElFunction(f);
}
this.elConstantDefinitions = new ArrayList<>();
elConstantDefinitionsIdx = new ArrayList<>();
for (ElConstantDefinition c : elConstantDefinitions) {
addElConstant(c);
}
this.min = min;
this.max = max;
this.mode = mode;
this.lines = lines;
this.dependsOnMap = dependsOnMap;
this.evaluation = evaluation;
}
public void addAutoELDefinitions(StageLibraryDefinition libraryDef) {
if (this.getType() != ConfigDef.Type.MODEL || this.getModel().getModelType() != ModelType.LIST_BEAN) {
for (Class klass : libraryDef.getElDefs()) {
addElDef(klass);
}
for (ElFunctionDefinition f : libraryDef.getElFunctionDefinitions()) {
addElFunction(f);
}
for (ElConstantDefinition c : libraryDef.getElConstantDefinitions()) {
addElConstant(c);
}
} else {
for (ConfigDefinition configDef : this.getModel().getConfigDefinitions()) {
configDef.addAutoELDefinitions(libraryDef);
}
}
}
private void addElDef(Class klass) {
if (!elDefs.contains(klass)) {
elDefs.add(klass);
}
}
private void addElFunction(ElFunctionDefinition elF) {
if (!elFunctionDefinitionsIdx.contains(elF.getIndex())) {
elFunctionDefinitions.add(elF);
elFunctionDefinitionsIdx.add(elF.getIndex());
}
}
private void addElConstant(ElConstantDefinition elC) {
if (!elConstantDefinitionsIdx.contains(elC.getIndex())) {
elConstantDefinitions.add(elC);
elConstantDefinitionsIdx.add(elC.getIndex());
}
}
public Field getConfigField() {
return configField;
}
public String getName() {
return name;
}
public ConfigDef.Type getType() {
return type;
}
public String getLabel() {
return label;
}
public String getDescription() {
return description;
}
public Object getDefaultValue() {
return defaultValue;
}
public boolean isRequired() {
return required;
}
public String getGroup() { return group; }
public ModelDefinition getModel() {
return model;
}
public String getFieldName() {
return fieldName;
}
public void setDependsOn(String dependsOn) {
this.dependsOn = dependsOn;
}
public String getDependsOn() {
return dependsOn;
}
public long getMin() {
return min;
}
public long getMax() {
return max;
}
public String getMode() {
return mode;
}
public int getLines() {
return lines;
}
public List<Class> getElDefs() {
return elDefs;
}
public List<Object> getTriggeredByValues() {
return triggeredByValues;
}
public void setTriggeredByValues(List<Object> triggeredByValues) {
this.triggeredByValues = triggeredByValues;
}
public List<ElFunctionDefinition> getElFunctionDefinitions() {
return elFunctionDefinitions;
}
public List<ElConstantDefinition> getElConstantDefinitions() {
return elConstantDefinitions;
}
public List<String> getElFunctionDefinitionsIdx() {
return elFunctionDefinitionsIdx;
}
public List<String> getElConstantDefinitionsIdx() {
return elConstantDefinitionsIdx;
}
public int getDisplayPosition() {
return displayPosition;
}
public Map<String, List<Object>> getDependsOnMap() {
return dependsOnMap;
}
public void setDependsOnMap(Map<String, List<Object>> dependsOnMap) {
this.dependsOnMap = dependsOnMap;
}
public ConfigDef.Evaluation getEvaluation() {
return evaluation;
}
public ConfigDefinition localize(ClassLoader classLoader, String bundle) {
String labelKey = "configLabel." + getName();
String descriptionKey = "configDescription." + getName();
// config label & description
String label = new LocalizableMessage(classLoader, bundle, labelKey, getLabel(), null).getLocalized();
String description = new LocalizableMessage(classLoader, bundle, descriptionKey, getDescription(), null)
.getLocalized();
// config model
ModelDefinition model = getModel();
if(getType() == ConfigDef.Type.MODEL) {
switch (model.getModelType()) {
case VALUE_CHOOSER:
case MULTI_VALUE_CHOOSER:
try {
Class klass = classLoader.loadClass(model.getValuesProviderClass());
ChooserValues chooserValues = (ChooserValues) klass.newInstance();
List<String> values = chooserValues.getValues();
if (values != null) {
List<String> localizedValueChooserLabels = new ArrayList<>(chooserValues.getLabels());
String rbName = chooserValues.getResourceBundle();
if (rbName != null) {
for (int i = 0; i < values.size(); i++) {
String l = new LocalizableMessage(classLoader, rbName, values.get(i),
localizedValueChooserLabels.get(i), null).getLocalized();
localizedValueChooserLabels.set(i, l);
}
}
model = ModelDefinition.localizedValueChooser(model, values, localizedValueChooserLabels);
}
} catch (Exception ex) {
throw new RuntimeException(Utils.format("Could not extract localization info from '{}': {}",
model.getValuesProviderClass(), ex.toString()), ex);
}
break;
case LIST_BEAN:
List<ConfigDefinition> listBean = model.getConfigDefinitions();
List<ConfigDefinition> listBeanLocalize = new ArrayList<>(listBean.size());
for (ConfigDefinition def : listBean) {
listBeanLocalize.add(def.localize(classLoader, bundle));
}
model = ModelDefinition.localizedComplexField(model, listBeanLocalize);
break;
default:
break;
}
}
return new ConfigDefinition(getConfigField(), getName(), getType(), label, description, getDefaultValue(),
isRequired(), getGroup(), getFieldName(), model, getDependsOn(), getTriggeredByValues(),
getDisplayPosition(), getElFunctionDefinitions(), getElConstantDefinitions(), getMin(),
getMax(), getMode(), getLines(), getElDefs(), getEvaluation(), getDependsOnMap());
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
@Override
public String toString() {
return Utils.format("ConfigDefinition[name='{}' type='{}' required='{}' default='{}']", getName(), getType(),
isRequired(), getDefaultValue());
}
/**
* Only checks if the fields have the same name. Do not compare against various stages!!
* @param o
* @return
*/
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof ConfigDefinition)) {
return false;
}
return this.fieldName.equals(((ConfigDefinition) o).fieldName);
}
}