001package org.galaxyproject.gxformat2;
002
003import java.util.ArrayList;
004import java.util.HashMap;
005import java.util.List;
006import java.util.Map;
007
008public class Format2WorkflowAdapter implements WorkflowAdapter {
009  private Map<String, Object> workflow;
010
011  public Format2WorkflowAdapter(final Map<String, Object> workflow) {
012    this.workflow = workflow;
013  }
014
015  @Override
016  public List<NormalizedStep> normalizedSteps() {
017    List<Map<String, Object>> steps = stepsAsList(this.workflow, true);
018    steps = convertInputsToSteps(this.workflow, steps);
019    final List<NormalizedStep> normalizedSteps = new ArrayList();
020    int orderIndex = 0;
021    for (Map<String, Object> stepDef : steps) {
022      final NormalizedStep step = new NormalizedStep();
023      ensurePosition(stepDef, orderIndex);
024      step.stepDefinition = stepDef;
025      step.inputs = new ArrayList<Input>();
026      Map<String, Object> in = new HashMap();
027      if (stepDef.containsKey("in")) {
028        in = (Map<String, Object>) stepDef.get("in");
029      }
030      for (final Map.Entry<String, Object> inputDef : in.entrySet()) {
031        final String inputName = inputDef.getKey();
032        String output = (String) inputDef.getValue();
033        int splitAt = output.indexOf('/');
034        String outputName = null;
035        if (splitAt >= 0) {
036          outputName = output.substring(splitAt + 1);
037          output = output.substring(0, splitAt);
038        }
039        final WorkflowAdapter.Input input = new WorkflowAdapter.Input();
040        input.sourceStepLabel = output;
041        input.sourceOutputName = outputName;
042        input.inputName = inputName;
043        step.inputs.add(input);
044      }
045      step.doc = (String) stepDef.get("doc");
046      step.label = (String) stepDef.get("label");
047      normalizedSteps.add(step);
048      orderIndex++;
049    }
050    return normalizedSteps;
051  }
052
053  private List<Map<String, Object>> convertInputsToSteps(
054      Map<String, Object> workflow, List<Map<String, Object>> steps) {
055    Map rawInputs = (Map) workflow.get("inputs");
056    List<Map<String, Object>> newSteps = new ArrayList();
057    List<Map<String, Object>> inputs = convertMapToIdListIfNeeded(rawInputs, false);
058    for (final Map<String, Object> input : inputs) {
059      final HashMap<String, Object> inputAsStep = new HashMap(input);
060      String rawLabel = (String) inputAsStep.remove("label");
061      String rawId = (String) inputAsStep.remove("id");
062      String label = rawLabel != null ? rawLabel : rawId;
063
064      String inputType = (String) inputAsStep.remove("type");
065      if (inputType == null) {
066        inputType = "data";
067      }
068      final String stepType;
069      if (inputType.equals("File") || inputType.equals("data") || inputType.equals("data_input")) {
070        stepType = "data_input";
071      } else if (inputType.equals("collection")
072          || inputType.equals("data_collection")
073          || inputType.equals("data_collection_input")) {
074        stepType = "data_collection_input";
075      } else {
076        stepType = "parameter_input";
077        inputAsStep.put("parameter_type", inputType);
078      }
079      inputAsStep.put("type", stepType);
080      inputAsStep.put("label", label);
081      newSteps.add(inputAsStep);
082    }
083    for (Map<String, Object> step : steps) {
084      newSteps.add(step);
085    }
086    return newSteps;
087  }
088
089  static List<Map<String, Object>> stepsAsList(
090      final Map<String, Object> workflow, final boolean addLabel) {
091    final Object stepsRaw = workflow.get("steps");
092    return convertMapToIdListIfNeeded(stepsRaw, addLabel);
093  }
094
095  static List<Map<String, Object>> convertMapToIdListIfNeeded(Object stepsRaw, boolean addLabel) {
096    if (stepsRaw instanceof List) {
097      return (List<Map<String, Object>>) stepsRaw;
098    }
099    final List<Map<String, Object>> asList = new ArrayList();
100    final Map<String, Object> stepsMap = (Map<String, Object>) stepsRaw;
101    for (final Map.Entry<String, Object> entry : stepsMap.entrySet()) {
102      Map<String, Object> step;
103      if (entry.getValue() instanceof Map) {
104        step = (Map<String, Object>) entry.getValue();
105      } else {
106        step = new HashMap();
107        step.put("type", entry.getValue());
108      }
109      if (addLabel) {
110        step.put("label", entry.getKey());
111      } else {
112        step.put("id", entry.getKey());
113      }
114      asList.add(step);
115    }
116    return asList;
117  }
118}