blob: 8babe1c0a0cd954f0a4aff3079bf3238c8743dc8 [file] [log] [blame]
// Copyright (C) 2019 The Android Open Source Project
//
// Licensed 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.googlesource.gerrit.plugins.task;
import com.googlesource.gerrit.plugins.task.TaskConfig.Task;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jgit.errors.ConfigInvalidException;
/** Use to pre-load a task definition with values from its preload-task definition. */
public class Preloader {
public static void preload(Task definition) throws ConfigInvalidException {
String name = definition.preloadTask;
if (name != null) {
Task task = definition.config.getTaskOptional(name);
if (task != null) {
preload(task);
preloadFrom(definition, task);
}
}
}
protected static void preloadFrom(Task definition, Task preloadFrom) {
for (Field field : definition.getClass().getFields()) {
String name = field.getName();
if ("isVisible".equals(name) || "isTrusted".equals(name) || "config".equals(name)) {
continue;
}
try {
field.setAccessible(true);
preloadField(field.getType(), field, definition, preloadFrom);
} catch (IllegalAccessException | IllegalArgumentException e) {
throw new RuntimeException();
}
}
}
protected static <T, S, K, V> void preloadField(
Class<T> clz, Field field, Task definition, Task preloadFrom)
throws IllegalArgumentException, IllegalAccessException {
T pre = getField(clz, field, preloadFrom);
if (pre != null) {
T val = getField(clz, field, definition);
if (val == null) {
field.set(definition, pre);
} else if (val instanceof List) {
List<?> valList = List.class.cast(val);
List<?> preList = List.class.cast(pre);
field.set(definition, preloadListFrom(castUnchecked(valList), castUnchecked(preList)));
} else if (val instanceof Map) {
Map<?, ?> valMap = Map.class.cast(val);
Map<?, ?> preMap = Map.class.cast(pre);
field.set(definition, preloadMapFrom(castUnchecked(valMap), castUnchecked(preMap)));
} // nothing to do for overridden preloaded scalars
}
}
protected static <T> T getField(Class<T> clz, Field field, Object obj)
throws IllegalArgumentException, IllegalAccessException {
return clz.cast(field.get(obj));
}
@SuppressWarnings("unchecked")
protected static <S> List<S> castUnchecked(List<?> list) {
List<S> forceCheck = (List<S>) list;
return forceCheck;
}
@SuppressWarnings("unchecked")
protected static <K, V> Map<K, V> castUnchecked(Map<?, ?> map) {
Map<K, V> forceCheck = (Map<K, V>) map;
return forceCheck;
}
protected static <T> List<T> preloadListFrom(List<T> list, List<T> preList) {
List<T> extended = list;
if (!preList.isEmpty()) {
extended = preList;
if (!list.isEmpty()) {
extended = new ArrayList<>(list.size() + preList.size());
extended.addAll(preList);
extended.addAll(list);
}
}
return extended;
}
protected static <K, V> Map<K, V> preloadMapFrom(Map<K, V> map, Map<K, V> preMap) {
Map<K, V> extended = map;
if (!preMap.isEmpty()) {
extended = preMap;
if (!map.isEmpty()) {
extended = new HashMap<>(map.size() + preMap.size());
extended.putAll(preMap);
extended.putAll(map);
}
}
return extended;
}
}