/* * Copyright (C) 2015 Jan Pokorsky * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package cz.cas.lib.proarc.common.workflow; import cz.cas.lib.proarc.common.workflow.model.Task; import cz.cas.lib.proarc.common.workflow.model.TaskParameterFilter; import cz.cas.lib.proarc.common.workflow.model.TaskParameterView; import cz.cas.lib.proarc.common.workflow.profile.ParamDefinition; import cz.cas.lib.proarc.common.workflow.profile.TaskDefinition; import cz.cas.lib.proarc.common.workflow.profile.WorkflowDefinition; import cz.cas.lib.proarc.common.workflow.profile.WorkflowProfiles; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * Joins parameters stored in DB with parameters declared in workflow XML. * * @author Jan Pokorsky */ public class FilterFindParameterQuery { private final WorkflowProfiles wp; public FilterFindParameterQuery(WorkflowProfiles wp) { this.wp = wp; } /** * @param params parameters fetched from DB * @param filter query * @param optionalTask the task necessary in case there is no fetched parameter or {@code null} * @param wd workflow definition * @return the list of parameters */ public List<TaskParameterView> filter( List<TaskParameterView> params, TaskParameterFilter filter, Task optionalTask, WorkflowDefinition wd) { // outer join of db params with task params declared in workflow Map<String, Map<String, ParamEntry>> join = new LinkedHashMap<String, Map<String, ParamEntry>>(); if (params.isEmpty() && optionalTask != null) { TaskParameterView param = new TaskParameterView(); param.setJobId(optionalTask.getJobId()); param.setTaskId(optionalTask.getId()); param.setTaskProfileName(optionalTask.getTypeRef()); selectProfileTaskParams(join, param, wd); } for (TaskParameterView param : params) { Map<String, ParamEntry> taskParamCache = selectProfileTaskParams(join, param, wd); // left outer join of db param with param profile outerJoinDbParamsWithProfileParams(taskParamCache, param, filter); } // right outer join of db param with param profiles return outerJoinProfileParamsWithDbParams(join, filter); } /** * Returns a mapping of param names to param entries with param profiles of given task. */ private Map<String, ParamEntry> selectProfileTaskParams( Map<String, Map<String, ParamEntry>> join, TaskParameterView param, WorkflowDefinition wd ) { String taskProfileName = param.getTaskProfileName(); Map<String, ParamEntry> taskParams = join.get(taskProfileName); if (taskParams == null) { taskParams = new LinkedHashMap<String, ParamEntry>(); join.put(taskProfileName, taskParams); TaskDefinition taskProfile = wp.getTaskProfile(wd, taskProfileName); if (taskProfile != null) { for (ParamDefinition pd : taskProfile.getParams()) { taskParams.put(pd.getName(), new ParamEntry(null, pd, param)); } } } return taskParams; } private Map<String, ParamEntry> outerJoinDbParamsWithProfileParams( Map<String, ParamEntry> taskParams, TaskParameterView param, TaskParameterFilter filter ) { // left join of db param with param profile ParamEntry paramEntry = taskParams.get(param.getParamRef()); if (paramEntry != null) { ParamDefinition profile = paramEntry.getDefinition(); String lang = filter.getLocale().getLanguage(); String label = profile.getTitle(lang, param.getParamRef()); String hint = profile.getHint(lang, null); param.setProfileLabel(label); param.setProfileHint(hint); param.setProfile(profile); paramEntry.setParam(param); } else { // no param definition String hint = "Unknow parameter profile: " + param.getParamRef() + " in task: " + param.getTaskProfileName(); param.setProfileLabel(param.getParamRef()); param.setProfileHint(hint); paramEntry = new ParamEntry(param, null, param); taskParams.put(param.getParamRef(), paramEntry); } return taskParams; } /** * Creates TaskParameterView for not db stored params. * Adds params that are declared but have no value yet * or newly declared params. */ private ArrayList<TaskParameterView> outerJoinProfileParamsWithDbParams( Map<String, Map<String, ParamEntry>> join, TaskParameterFilter filter ) { // right outer join of db param with param profiles String lang = filter.getLocale().getLanguage(); ArrayList<TaskParameterView> result = new ArrayList<TaskParameterView>(); for (Map<String, ParamEntry> taskParams : join.values()) { for (ParamEntry entry : taskParams.values()) { TaskParameterView param = entry.getParam(); ParamDefinition profile = entry.getDefinition(); if (param == null && !profile.isDisabled()) { param = new TaskParameterView(); param.setJobId(entry.getPrototype().getJobId()); param.setParamRef(profile.getName()); param.setProfile(profile); param.setProfileLabel(profile.getTitle(lang, profile.getName())); param.setProfileHint(profile.getHint(lang, null)); param.setTaskId(entry.getPrototype().getTaskId()); param.setTaskProfileName(entry.getPrototype().getTaskProfileName()); param.setValueType(profile.getValueType()); } result.add(param); } } return result; } private static class ParamEntry { private TaskParameterView param; private ParamDefinition definition; private final TaskParameterView prototype; public ParamEntry(TaskParameterView param, ParamDefinition definition, TaskParameterView protoype) { this.param = param; this.definition = definition; this.prototype = protoype; } public TaskParameterView getParam() { return param; } public void setParam(TaskParameterView param) { this.param = param; } public ParamDefinition getDefinition() { return definition; } public void setDefinition(ParamDefinition definition) { this.definition = definition; } public TaskParameterView getPrototype() { return prototype; } } }