/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.extension.internal.loader.catalog.loader.xml; import static com.google.common.base.Throwables.propagate; import static javax.xml.parsers.DocumentBuilderFactory.newInstance; import static org.mule.runtime.extension.internal.loader.catalog.loader.common.XmlMatcher.match; import org.mule.runtime.extension.internal.loader.catalog.builder.TypesCatalogBuilder; import org.mule.runtime.extension.internal.loader.catalog.loader.TypesCatalogLoaderContext; import org.mule.runtime.extension.internal.loader.catalog.model.TypesCatalog; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import java.net.URL; /** * Loads a {@link TypesCatalog} from a {@link URL}. * TODO(fernandezlautaro: MULE-11501 this class must be moved to a separate module * * @since 4.0 */ public class TypesCatalogXmlLoader { private static final String NS_TYPES = "http://www.mulesoft.org/schema/mule/types"; private static final QName ELEM_MULE = new QName(NS_TYPES, "mule"); private static final QName ELEM_CATALOG = new QName(NS_TYPES, "catalog"); private static final QName ELEM_TYPE = new QName(NS_TYPES, "type"); private static final String ELEM_TYPE_ATTR_NAME = "name"; private static final String ELEM_TYPE_ATTR_LOCATION = "location"; public TypesCatalog load(URL resourceType) throws Exception { TypesCatalogBuilder typesCatalogBuilder = new TypesCatalogBuilder(resourceType.toURI()); TypesCatalogLoaderContext typesCatalogLoaderContext = new TypesCatalogLoaderContext(typesCatalogBuilder); load(resourceType, typesCatalogLoaderContext); return typesCatalogBuilder.build(); } private void load(URL resourceType, TypesCatalogLoaderContext typesCatalogLoaderContext) { final Element documentElement; try { documentElement = parseRootElement(resourceType); final TypesCatalogBuilder typesCatalogBuilder = typesCatalogLoaderContext.getTypesCatalogBuilder(); match(documentElement, ELEM_MULE).ifPresent(xmlMatcher -> { xmlMatcher.matchMany(ELEM_CATALOG).forEach(catalog -> { catalog.matchMany(ELEM_TYPE).forEach(type -> { typesCatalogBuilder.addTypesResolver(typesResolverBuilder -> { type.matchAttribute(ELEM_TYPE_ATTR_NAME).ifPresent(typesResolverBuilder::name); type.matchAttribute(ELEM_TYPE_ATTR_LOCATION).ifPresent(typesResolverBuilder::location); }); }); }); }); } catch (Exception e) { propagate(e); } } private Element parseRootElement(URL resourceType) throws ParserConfigurationException, SAXException, IOException { DocumentBuilderFactory documentBuilderFactory = newInstance(); documentBuilderFactory.setNamespaceAware(true); documentBuilderFactory.setValidating(false); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse(resourceType.openStream()); return document.getDocumentElement(); } }