/* * Copyright (c) 2013 EMC Corporation * All Rights Reserved */ package com.emc.storageos.apidiff.model; import com.emc.storageos.apidiff.Constants; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.input.SAXBuilder; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Helper class to parse XML File into data structure ServiceCatalog. * Prepare data for further comparison */ public class ServiceCatalogBuilder { private ServiceCatalogBuilder() { } public static ServiceCatalog build(final String filePath) { return build(new File(filePath)); } /** * Parses xml file to ServiceCatalog with Jdom * * @param xmlFile * The instance of xml file * @return instance of ServiceCatalog */ public static ServiceCatalog build(final File xmlFile) { String fileName = xmlFile.getName().trim().toLowerCase(); // remove suffix if (fileName.endsWith(Constants.XML_FILE_SUFFIX)) { fileName = fileName.substring(0, fileName.length() - Constants.XML_FILE_SUFFIX.length() - 1); } else { throw new IllegalArgumentException("API file is not xml format: " + fileName); } // filter name int separatorIndex = fileName.indexOf(Constants.NAME_STRING_SEPARATOR); if (separatorIndex == -1) { throw new IllegalArgumentException("API file name should split with " + Constants.NAME_STRING_SEPARATOR + " actually: " + fileName); } String serviceName = fileName.substring(0, separatorIndex); String version = fileName.substring(separatorIndex + 1, fileName.length()); Document document; try { document = new SAXBuilder().build(xmlFile); } catch (Exception ex) { throw new IllegalArgumentException("Invalid XML file:\n " + xmlFile.getAbsolutePath(), ex); } if (document == null) { return null; } // Navigates to resource tag, it's a little tricky here, depends on structure of xml file completely. List<Element> resourceList = document.getRootElement() .getChild(Constants.REST_NODE) .getChild(Constants.RESOURCES_NODE) .getChildren(); // Navigates to element tag, it's a little tricky here, depends on structure of xml file completely. List<Element> elementList = document.getRootElement() .getChild(Constants.DATA_NODE) .getChild(Constants.DATA_SCHEMA_NODE) .getChild(Constants.ELEMENTS_NODE) .getChildren(); return new ServiceCatalog(parseResource(resourceList), parseElement(elementList), serviceName, version); } /** * Parses tag list <resource> to get REST API details * * @param resourceList * The list of resource tag * @return details of api resource */ public static Map<ApiIdentifier, ApiDescriptor> parseResource(List<Element> resourceList) { if (resourceList == null) { throw new NullPointerException("Please navigate to right resource tag before parse it"); } Map<ApiIdentifier, ApiDescriptor> resourceMap = new HashMap<ApiIdentifier, ApiDescriptor>(); for (Element element : resourceList) { String path = element.getAttributeValue(Constants.ATTRIBUTE_NAME).trim(); Element opElement = element.getChild(Constants.OPERATION_NODE); String method = opElement.getAttributeValue(Constants.ATTRIBUTE_NAME).trim(); ApiIdentifier apiIdentifier = new ApiIdentifier(method, path); ApiDescriptor apiResource = new ApiDescriptor(); Element opInValue = opElement.getChild(Constants.OPERATION_INVALUE_NODE); if (opInValue != null) { Element xmlElement = opInValue.getChild(Constants.XML_ELEMENT_NODE); if (xmlElement != null && xmlElement.getAttributeValue(Constants.ATTRIBUTE_ELEMENT_NAME) != null) { apiResource.setRequestElement(xmlElement.getAttributeValue(Constants.ATTRIBUTE_ELEMENT_NAME).trim()); } } Element opOutValue = opElement.getChild(Constants.OPERATION_OUTVALUE_NODE); if (opOutValue != null) { Element xmlElement = opOutValue.getChild(Constants.XML_ELEMENT_NODE); if (xmlElement != null && xmlElement.getAttributeValue(Constants.ATTRIBUTE_ELEMENT_NAME) != null) { apiResource.setResponseElement(xmlElement.getAttributeValue(Constants.ATTRIBUTE_ELEMENT_NAME).trim()); } } for (Element paramElement : opElement.getChildren(Constants.OPERATION_PARAMETER_NODE)) { if (paramElement.getAttributeValue(Constants.ATTRIBUTE_NAME) != null) { apiResource.getParameters().add(paramElement.getAttributeValue(Constants.ATTRIBUTE_NAME).trim()); } } resourceMap.put(apiIdentifier, apiResource); } return resourceMap; } /** * Parses tag list <element> to get REST API details * * @param elementList * The list of element tag * @return details of API element */ public static Map<String, String> parseElement(List<Element> elementList) { if (elementList == null) { throw new NullPointerException("Please navigate to right element tag before parse it"); } Map<String, String> elmentMap = new HashMap<String, String>(); for (Element element : elementList) { String exampleXml = filterExampleXml(element.getChildText(Constants.ELEMENT_EXAMPLE_XML_NODE).trim()); elmentMap.put(element.getAttributeValue(Constants.ATTRIBUTE_NAME).trim(), exampleXml); } return elmentMap; } /** * Helper method to filter example xml * * @param examplXml * The content of example xml * @return the filtered example xml */ private static String filterExampleXml(String examplXml) { int begin = 0; int end = examplXml.length(); if (examplXml.startsWith(Constants.EXAMLE_XML_HEADER)) { begin = Constants.EXAMLE_XML_HEADER.length() - 1; } if (examplXml.endsWith(Constants.EXAMLE_XML_TAILER)) { end = end - Constants.EXAMLE_XML_TAILER.length(); } return examplXml.substring(begin, end); } }