content: /**
   * Licensed to 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
   * <p>
   * http://www.apache.org/licenses/LICENSE-2.0
   * <p>
   * 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 org.apache.oozie.ambari.view;
  
  import java.io.IOException;
  import java.io.StringReader;
  import java.util.Map;
  
  import javax.xml.parsers.DocumentBuilder;
  import javax.xml.parsers.DocumentBuilderFactory;
  import javax.xml.parsers.ParserConfigurationException;
  
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  
  import com.google.gson.JsonElement;
  import com.google.gson.JsonParser;
  
  public class OozieUtils {
    private final static Logger LOGGER = LoggerFactory
      .getLogger(OozieUtils.class);
    private Utils utils = new Utils();
  
    public String generateConfigXml(Map<String, String> map) {
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder db;
      try {
        dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        db = dbf.newDocumentBuilder();
        Document doc = db.newDocument();
        Element configElement = doc.createElement("configuration");
        doc.appendChild(configElement);
        for (Map.Entry<String, String> entry : map.entrySet()) {
          Element propElement = doc.createElement("property");
          configElement.appendChild(propElement);
          Element nameElem = doc.createElement("name");
          nameElem.setTextContent(entry.getKey());
          Element valueElem = doc.createElement("value");
          valueElem.setTextContent(entry.getValue());
          propElement.appendChild(nameElem);
          propElement.appendChild(valueElem);
        }
        return utils.generateXml(doc);
      } catch (ParserConfigurationException e) {
        LOGGER.error("error in generating config xml", e);
        throw new RuntimeException(e);
      }
    }
  
    public String getJobPathPropertyKey(JobType jobType) {
      switch (jobType) {
        case WORKFLOW:
          return "oozie.wf.application.path";
        case COORDINATOR:
          return "oozie.coord.application.path";
        case BUNDLE:
          return "oozie.bundle.application.path";
      }
      throw new RuntimeException("Unknown Job Type");
    }
  
    public JobType deduceJobType(String xml) {
      try {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        DocumentBuilder db = null;
  
        db = dbf.newDocumentBuilder();
        InputSource is = new InputSource();
        is.setCharacterStream(new StringReader(xml));
  
        Document doc = db.parse(is);
        String rootNode = doc.getDocumentElement().getNodeName();
        if ("workflow-app".equals(rootNode)) {
          return JobType.WORKFLOW;
        } else if ("coordinator-app".equals(rootNode)) {
          return JobType.COORDINATOR;
        } else if ("bundle-app".equals(rootNode)) {
          return JobType.BUNDLE;
        }
        throw new RuntimeException("invalid xml submitted");
      } catch (ParserConfigurationException | Exception e) {
        throw new RuntimeException(e);
      }
    }
  
    public String deduceWorkflowNameFromJson(String json) {
      JsonElement jsonElement = new JsonParser().parse(json);
      String name = jsonElement.getAsJsonObject().get("name").getAsString();
      return name;
    }
    public String deduceWorkflowSchemaVersionFromJson(String json) {
      JsonElement jsonElement = new JsonParser().parse(json);
      return jsonElement.getAsJsonObject().get("xmlns").getAsString();
    }
  
    public String deduceWorkflowNameFromXml(String xml) {
      try {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        InputSource is = new InputSource();
        is.setCharacterStream(new StringReader(xml));
        Document doc = db.parse(is);
        String name = doc.getDocumentElement().getAttributeNode("name").getValue();
        return name;
  
      } catch (ParserConfigurationException | Exception e) {
        throw new RuntimeException(e);
      }
    }
  
    public String generateWorkflowXml(String actionNodeXml) {
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder db;
      try {
        dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        db = dbf.newDocumentBuilder();
        Document doc = db.newDocument();
  
        Element workflowElement = doc.createElement("workflow-app");
        workflowElement.setAttribute("name", "testWorkflow");
        workflowElement.setAttribute("xmlns", "uri:oozie:workflow:0.5");
        doc.appendChild(workflowElement);
  
        Element startElement = doc.createElement("start");
        startElement.setAttribute("to", "testAction");
        workflowElement.appendChild(startElement);
  
        Element actionElement = doc.createElement("action");
        actionElement.setAttribute("name", "testAction");
        Element actionSettingsElement = db.parse(
          new InputSource(new StringReader(actionNodeXml)))
          .getDocumentElement();
        actionElement.appendChild(doc.importNode(actionSettingsElement,
          true));
        workflowElement.appendChild(actionElement);
  
        Element actionOkTransitionElement = doc.createElement("ok");
        actionOkTransitionElement.setAttribute("to", "end");
        actionElement.appendChild(actionOkTransitionElement);
  
        Element actionErrorTransitionElement = doc.createElement("error");
        actionErrorTransitionElement.setAttribute("to", "kill");
        actionElement.appendChild(actionErrorTransitionElement);
  
        Element killElement = doc.createElement("kill");
        killElement.setAttribute("name", "kill");
        Element killMessageElement = doc.createElement("message");
        killMessageElement.setTextContent("Kill node message");
        killElement.appendChild(killMessageElement);
        workflowElement.appendChild(killElement);
  
        Element endElement = doc.createElement("end");
        endElement.setAttribute("name", "end");
        workflowElement.appendChild(endElement);
  
        return utils.generateXml(doc);
      } catch (ParserConfigurationException | SAXException | IOException e) {
        LOGGER.error("error in generating workflow xml", e);
        throw new RuntimeException(e);
      }
    }
  
    public String getNoOpWorkflowXml(String json,JobType jobType) {
      String schema=deduceWorkflowSchemaVersionFromJson(json);
      String name=deduceWorkflowNameFromJson(json);
      switch (jobType){
        case WORKFLOW:
          return String.format("<workflow-app xmlns=\"%s\" name=\"%s\"><start to=\"end\"/><end name=\"end\"/></workflow-app>",schema,name);
        case COORDINATOR:
          return String.format("<coordinator-app xmlns=\"%s\" name=\"%s\"></coordinator-app>",schema,name);
        case BUNDLE:
          return String.format("<bundle-app xmlns=\"%s\" name=\"%s\"></bundle-app>",schema,name);
      }
      return null;
    }
  }
  