/**
* 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.definition;
import com.streamsets.datacollector.config.ConfigGroupDefinition;
import com.streamsets.pipeline.api.ConfigGroups;
import com.streamsets.pipeline.api.Label;
import com.streamsets.pipeline.api.Stage;
import com.streamsets.pipeline.api.impl.ErrorMessage;
import com.streamsets.pipeline.api.impl.Utils;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public abstract class ConfigGroupExtractor {
private static final ConfigGroupExtractor EXTRACTOR = new ConfigGroupExtractor() {};
public static ConfigGroupExtractor get() {
return EXTRACTOR;
}
public List<ErrorMessage> validate(Class<? extends Stage> klass, Object contextMsg) {
List<ErrorMessage> errors = new ArrayList<>();
List<ConfigGroups> allConfigGroups = getAllConfigGroups(klass);
Set<String> allGroupNames = new HashSet<>();
if (!allConfigGroups.isEmpty()) {
for (ConfigGroups configGroups : allConfigGroups) {
Class<? extends Label> gKlass = configGroups.value();
if (!gKlass.isEnum()) {
errors.add(new ErrorMessage(DefinitionError.DEF_100, contextMsg, gKlass.getSimpleName()));
} else {
for (Label label : gKlass.getEnumConstants()) {
String groupName = label.toString();
if (allGroupNames.contains(groupName)) {
errors.add(new ErrorMessage(DefinitionError.DEF_101, contextMsg, groupName));
}
allGroupNames.add(groupName);
}
}
}
}
return errors;
}
public ConfigGroupDefinition extract(Class<? extends Stage> klass, Object contextMsg) {
List<ErrorMessage> errors = validate(klass, contextMsg);
if (errors.isEmpty()) {
List<ConfigGroups> allConfigGroups = getAllConfigGroups(klass);
Set<String> allGroupNames = new HashSet<>();
Map<String, List<String>> classNameToGroupsMap = new HashMap<>();
List<Map<String, String>> groupNameToLabelMapList = new ArrayList<>();
if (!allConfigGroups.isEmpty()) {
for (ConfigGroups configGroups : allConfigGroups) {
Class<? extends Label> gKlass = configGroups.value();
List<String> groupNames = new ArrayList<>();
classNameToGroupsMap.put(gKlass.getName(), groupNames);
for (Label label : gKlass.getEnumConstants()) {
String groupName = label.toString();
Map<String, String> groupNameToLabelMap = new LinkedHashMap<>();
allGroupNames.add(groupName);
groupNames.add(groupName);
groupNameToLabelMap.put("name", groupName);
groupNameToLabelMap.put("label", label.getLabel());
groupNameToLabelMapList.add(groupNameToLabelMap);
}
}
}
return new ConfigGroupDefinition(allGroupNames, classNameToGroupsMap, groupNameToLabelMapList);
} else {
throw new IllegalArgumentException(Utils.format("Invalid ConfigGroup definition: {}", errors));
}
}
@SuppressWarnings("unchecked")
private List<ConfigGroups> getAllConfigGroups(Class klass) {
List<ConfigGroups> groups;
if (klass == Object.class) {
groups = new ArrayList<>();
} else {
groups = getAllConfigGroups(klass.getSuperclass());
Annotation annotation = klass.getAnnotation(ConfigGroups.class);
if (annotation != null) {
groups.add((ConfigGroups)annotation);
}
}
return groups;
}
}