All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.petals.binding.rest.config.RESTProvidesConfigurationBuilder Maven / Gradle / Ivy

/**
 * Copyright (c) 2007-2012 EBM WebSourcing, 2012-2020 Linagora
 * 
 * This program/library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This program/library 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 Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program/library; If not, see http://www.gnu.org/licenses/
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.binding.rest.config;

import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.AUTHENTICATION;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.BUFFER_REQUEST;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.COOKIE_POLICY;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.FORM_DATA_PARAM;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.HTTP_BODY_TYPE;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.HTTP_CODE;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.HTTP_METHOD;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.IS_JSON_RESULT;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.ON_HTTP_STATUS;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.OPERATION_NAME;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.POST_QUERY;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.TRUST_ALL_CERTIFICATES;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.URI;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.WSDL;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.XPATH_PARAM;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.XPATH_PARAM_NAME;
import static org.ow2.petals.binding.rest.RESTConstants.ProvidesParameter.XSL;

import java.io.File;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.logging.Logger;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.glassfish.jersey.uri.UriTemplate;
import org.ow2.easywsdl.extensions.wsdl4complexwsdl.WSDL4ComplexWsdlFactory;
import org.ow2.easywsdl.wsdl.api.Description;
import org.ow2.easywsdl.wsdl.api.WSDLException;
import org.ow2.easywsdl.wsdl.api.abstractItf.AbsItfDescription.WSDLVersionConstants;
import org.ow2.petals.binding.rest.exchange.outgoing.auth.Authentication;
import org.ow2.petals.binding.rest.exchange.outgoing.auth.AuthenticationBuilder;
import org.ow2.petals.binding.rest.exchange.outgoing.auth.NoAuthentication;
import org.ow2.petals.binding.rest.exchange.outgoing.configurations.AttachementRequestConfiguration;
import org.ow2.petals.binding.rest.exchange.outgoing.configurations.CookiePolicy;
import org.ow2.petals.binding.rest.exchange.outgoing.configurations.JSONRequestConfiguration;
import org.ow2.petals.binding.rest.exchange.outgoing.configurations.MultipartFormDataRequestConfiguration;
import org.ow2.petals.binding.rest.exchange.outgoing.configurations.NoBodyRequestConfiguration;
import org.ow2.petals.binding.rest.exchange.outgoing.configurations.PostQueryRequestConfiguration;
import org.ow2.petals.binding.rest.exchange.outgoing.configurations.RESTRequestConfiguration;
import org.ow2.petals.binding.rest.exchange.outgoing.configurations.XMLRequestConfiguration;
import org.ow2.petals.binding.rest.exchange.outgoing.formdata.FormData;
import org.ow2.petals.binding.rest.exchange.outgoing.formdata.FormDataBuilder;
import org.ow2.petals.binding.rest.exchange.outgoing.onhttpstatus.DefaultResponseTransformation;
import org.ow2.petals.binding.rest.exchange.outgoing.onhttpstatus.Error;
import org.ow2.petals.binding.rest.exchange.outgoing.onhttpstatus.Fault;
import org.ow2.petals.binding.rest.exchange.outgoing.onhttpstatus.OnHttpStatus;
import org.ow2.petals.binding.rest.exchange.outgoing.onhttpstatus.OnHttpStatusConditionalTransformation;
import org.ow2.petals.binding.rest.exchange.outgoing.onhttpstatus.OnHttpStatusTransformation;
import org.ow2.petals.binding.rest.exchange.outgoing.onhttpstatus.OtherwiseError;
import org.ow2.petals.binding.rest.exchange.outgoing.onhttpstatus.OtherwiseFault;
import org.ow2.petals.binding.rest.exchange.outgoing.onhttpstatus.OtherwiseOut;
import org.ow2.petals.binding.rest.exchange.outgoing.onhttpstatus.Out;
import org.ow2.petals.binding.rest.exchange.outgoing.onhttpstatus.ProcessHttpResponseAs;
import org.ow2.petals.binding.rest.utils.BooleanWithPlaceholder;
import org.ow2.petals.binding.rest.utils.DOMUtils;
import org.ow2.petals.binding.rest.utils.HttpHeadersBuilder;
import org.ow2.petals.binding.rest.utils.HttpStatusBuilder;
import org.ow2.petals.binding.rest.utils.JsonXMLConfigBuilder;
import org.ow2.petals.binding.rest.utils.RESTUriTemplate;
import org.ow2.petals.binding.rest.utils.extractor.value.XMLPayloadValueExtractor;
import org.ow2.petals.component.framework.api.exception.PEtALSCDKException;
import org.ow2.petals.component.framework.jbidescriptor.generated.Provides;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.ebmwebsourcing.easycommons.properties.PropertiesException;
import com.ebmwebsourcing.easycommons.xml.XMLHelper;

import de.odysseus.staxon.json.JsonXMLInputFactory;
import de.odysseus.staxon.json.JsonXMLOutputFactory;

public class RESTProvidesConfigurationBuilder extends RESTSUConfiguration {

    public static Map getRESTMessages(final Logger logger, final Document wsdlDoc,
            final String suName, final String installRoot, final Provides provides,
            final Properties componentPlaceholders) throws PEtALSCDKException {

        try {
            Map operations = null;
            final Description wsdl = WSDL4ComplexWsdlFactory.newInstance().newWSDLReader().read(wsdlDoc);

            if (wsdl != null) {
                final WSDLVersionConstants wsdlVersion = wsdl.getVersion();
                if (wsdlVersion == WSDLVersionConstants.WSDL20) {
                    // operations = processWSDL20(wsdl);
                } else {
                    // it is a WSDL 1.1, use the SU parameters
                    operations = processSUProvidesMapping(logger, suName, installRoot, provides, componentPlaceholders);
                }
            } else {
                RESTConfiguration.handleMissingMandatoryParameterError(WSDL);
            }

            return operations;

        } catch (final WSDLException | URISyntaxException e) {
            throw new PEtALSCDKException(e);
        }
    }

    // private Map processWSDL20(Description wsdl)
    // throws PEtALSCDKException {
    // Map operations = new HashMap();
    //
    // List services = wsdl.getServices();
    // for (Service service : services) {
    //
    // List endpoints = service.getEndpoints();
    // for (Endpoint endpoint : endpoints) {
    //
    // String address = endpoint.getAddress();
    //
    // Binding binding = endpoint.getBinding();
    // BindingConstants bindingType = binding.getTypeOfBinding();
    // if (bindingType == BindingConstants.HTTP_BINDING4WSDL20) {
    // List bindingOperations =
    // binding.getBindingOperations();
    // for (BindingOperation bindingOperation : bindingOperations) {
    // Operation operation = bindingOperation.getOperation();
    // QName operationName = operation.getQName();
    // String httpLocation = bindingOperation.getHttpLocation();
    // String httpMethod = bindingOperation.getHttpMethod();
    //
    // Templates uriXSL = createURIXSL(address, httpLocation);
    //
    // RESTRequest restRequest = new RESTRequest(uriXSL, httpMethod);
    //
    // Templates httpBodyXSL = createBodyXSL();
    // if(httpBodyXSL != null) {
    // restRequest.setHTTPBodyXSL(httpBodyXSL);
    // }
    //
    // operations.put(operationName, restRequest);
    // }
    // }
    // }
    // }
    //
    // return operations;
    // }
    //
    // private Templates createURIXSL(String address, String httpLocation)
    // throws PEtALSCDKException {
    // // TODO Support of WSDL 2.0
    // throw new NotImplementedException();
    // }
    //
    // private Templates createBodyXSL() {
    // // TODO Support of WSDL 2.0
    // throw new NotImplementedException();
    // }

    private static final Map processSUProvidesMapping(final Logger logger,
            final String suName, final String installRoot, final Provides provides,
            final Properties componentPlaceholders) throws PEtALSCDKException {

        final LogErrorListener xslLogErrorListener = new LogErrorListener(logger, suName);
        final Map operations = new HashMap<>();

        final NodeList operationNodes = getSUOperationMappingNodes(provides.getAny());
        final int operationNb = operationNodes.getLength();
        for (int i = 0; i < operationNb; i++) {
            final Node operationNode = operationNodes.item(i);
            final Element operationElt = (Element) operationNode;

            final QName jbiOperation = DOMUtils.getAttributeAsQName(operationElt, OPERATION_NAME);
            final String httpMethod = DOMUtils.getSubElementTextContent(operationElt, HTTP_METHOD, true);
            final String uriStr = DOMUtils.getSubElementTextContent(operationElt, URI, true);
            RESTUriTemplate uri;
            try {
                uri = new RESTUriTemplate(uriStr, componentPlaceholders, logger);
            } catch (final IllegalArgumentException | PropertiesException e) {
                throw new PEtALSCDKException("A problem occurs creating the URI template from '" + uriStr + "'", e);
            }
            final String httpBodyTypeStr = DOMUtils.getSubElementTextContent(operationElt, HTTP_BODY_TYPE, true);
            final HTTPBodyType httpBodyType;
            try {
                httpBodyType = HTTPBodyType.valueOf(HTTPBodyType.class, httpBodyTypeStr);
            } catch (final IllegalArgumentException e) {
                throw new PEtALSCDKException(httpBodyTypeStr + " is not a valid HTTP Body type.");
            }

            try {
                final XPathFactory xpathFactory = XPathFactory.newInstance();
                final XPath xPathEvaluator = xpathFactory.newXPath();

                final Map xPathParamExprs = getXPathParams(operationElt, xPathEvaluator);

                final Map headers = HttpHeadersBuilder.build(operationElt,
                        xPathEvaluator, componentPlaceholders, logger);

                final Authentication authentication = getAuthentication(operationElt, jbiOperation, xPathEvaluator,
                        componentPlaceholders, logger);

                final List formDataExprs = getFormDataParams(operationElt, xPathEvaluator,
                        componentPlaceholders, logger);

                final RESTProvidesConfigurationInputTransformation xslOnIncomingRequest = getXslOnIncomingRequest(
                        operationElt, installRoot, xslLogErrorListener);
                if (xslOnIncomingRequest != null && xslOnIncomingRequest.isJsonResult()
                        && httpBodyType != HTTPBodyType.JSON) {
                    throw new PEtALSCDKException(
                            "The XSL can generate JSON directly only if the HTTP body type is set to JSON.");
                }
                
                final CookiePolicy cookiePolicy = getCookiePolicy(operationElt);

                final boolean bufferRequest = getBufferRequestParam(operationElt);
                final BooleanWithPlaceholder trustAllCertificates = getTrustAllCertificatesParam(operationElt,
                        componentPlaceholders, logger);

                // Note: this will only be used when we retrieve a json response!
                final XMLInputFactory responseConverterFactory = new JsonXMLInputFactory(
                        getInputJsonXMLConfig(operationElt));

                final OnHttpStatusTransformation hardcodedDefaultTransformation = new DefaultResponseTransformation(
                        ProcessHttpResponseAs.AUTO, null, responseConverterFactory, componentPlaceholders, logger);

                final Map onHttpStatus = getOnHttpStatus(operationElt, xPathEvaluator,
                        installRoot, xslLogErrorListener, componentPlaceholders, responseConverterFactory,
                        hardcodedDefaultTransformation, logger);

                final RESTRequestConfiguration restRequest;
                switch (httpBodyType) {
                    case NO_BODY:
                        restRequest = new NoBodyRequestConfiguration(logger, jbiOperation, authentication, headers,
                                httpMethod, uri, xPathParamExprs, cookiePolicy, onHttpStatus, bufferRequest,
                                trustAllCertificates, hardcodedDefaultTransformation);
                        break;
                    case XML:
                        restRequest = new XMLRequestConfiguration(logger, jbiOperation, componentPlaceholders,
                                authentication, headers, httpMethod, uri, xPathParamExprs, cookiePolicy, onHttpStatus,
                                xslOnIncomingRequest != null ? xslOnIncomingRequest.getXslTemplate() : null,
                                bufferRequest, trustAllCertificates, hardcodedDefaultTransformation);
                        break;
                    case JSON:
                        final XMLOutputFactory requestConverterFactory = new JsonXMLOutputFactory(
                                JsonXMLConfigBuilder.build(operationElt));
                        restRequest = new JSONRequestConfiguration(logger, jbiOperation, componentPlaceholders,
                                authentication, headers, httpMethod, uri, xPathParamExprs, xslOnIncomingRequest,
                                requestConverterFactory, cookiePolicy, onHttpStatus, bufferRequest,
                                trustAllCertificates, hardcodedDefaultTransformation);
                        break;
                    case POST_QUERY_STRING:
                        final String postQueryStr = DOMUtils.getSubElementTextContent(operationElt, POST_QUERY, true);
                        final UriTemplate postQuery = new UriTemplate(postQueryStr);
                        restRequest = new PostQueryRequestConfiguration(logger, jbiOperation, authentication, headers,
                                httpMethod, uri, postQuery, xPathParamExprs, cookiePolicy, onHttpStatus, bufferRequest,
                                trustAllCertificates, hardcodedDefaultTransformation);
                        break;
                    case MULTIPART_FORMDATA:
                        restRequest = new MultipartFormDataRequestConfiguration(logger, jbiOperation, authentication,
                                headers, httpMethod, uri, xPathParamExprs, formDataExprs, cookiePolicy, onHttpStatus,
                                bufferRequest, trustAllCertificates, hardcodedDefaultTransformation);
                        break;
                    case ATTACHMENT:
                        restRequest = new AttachementRequestConfiguration(logger, jbiOperation, authentication, headers,
                                httpMethod, uri, xPathParamExprs, cookiePolicy, onHttpStatus, bufferRequest,
                                trustAllCertificates, hardcodedDefaultTransformation);
                        break;
                    default:
                        throw new PEtALSCDKException(httpBodyType + " is not an implemented HTTP Body type.");
                }

                restRequest.log(logger);

                operations.put(jbiOperation, restRequest);
            } catch (final XPathExpressionException xpee) {
                throw new PEtALSCDKException(xpee);
            }
        }

        return operations;
    }

    private static Map getXPathParams(final Element operationElt, final XPath xPathEvaluator)
            throws XPathExpressionException {
        final Map xPathParams = new HashMap<>();

        final String namespaceURI = operationElt.getNamespaceURI();
        final NodeList xPathParamElements = operationElt.getElementsByTagNameNS(namespaceURI, XPATH_PARAM);
        final int xPathParamElementsNb = xPathParamElements.getLength();
        for (int i = 0; i < xPathParamElementsNb; i++) {
            final Node xPathParamNode = xPathParamElements.item(i);
            final Element xPathParamElt = (Element) xPathParamNode;
            final String paramName = xPathParamElt.getAttribute(XPATH_PARAM_NAME);
            final String paramValue = xPathParamElt.getTextContent();
            final XPathExpression xPathExpression = xPathEvaluator.compile(paramValue);
            xPathParams.put(paramName, xPathExpression);
        }

        return xPathParams;
    }

    private static boolean getBufferRequestParam(final Element operationElt) throws PEtALSCDKException {
        final String text = DOMUtils.getSubElementTextContent(operationElt, BUFFER_REQUEST, false);
        if (text == null) {
            return false;
        } else {
            return Boolean.parseBoolean(text);
        }
    }

    private static CookiePolicy getCookiePolicy(final Element operationElt) throws PEtALSCDKException {
        final String text = DOMUtils.getSubElementTextContent(operationElt, COOKIE_POLICY, false);
        if (text == null) {
            return CookiePolicy.IGNORE;
        } else {
            final CookiePolicy cookiePolicy = CookiePolicy.parse(text);
            return cookiePolicy == null ? CookiePolicy.IGNORE : cookiePolicy;
        }
    }

    private static BooleanWithPlaceholder getTrustAllCertificatesParam(final Element operationElt,
            final Properties componentPlaceholders, final Logger logger) throws PEtALSCDKException {
        final String text = DOMUtils.getSubElementTextContent(operationElt, TRUST_ALL_CERTIFICATES, false);
        if (text == null || text.trim().isEmpty()) {
            return new BooleanWithPlaceholder(Boolean.FALSE.toString(), componentPlaceholders, logger);
        } else {
            return new BooleanWithPlaceholder(text, componentPlaceholders, logger);
        }
    }

    private static Authentication getAuthentication(final Element operationElt, final QName operationName,
            final XPath xPathEvaluator, final Properties componentPlaceholders, final Logger logger)
            throws PEtALSCDKException {

        final String namespaceURI = operationElt.getNamespaceURI();
        final NodeList authElements = operationElt.getElementsByTagNameNS(namespaceURI, AUTHENTICATION);
        if (authElements.getLength() == 0) {
            return new NoAuthentication(logger);
        } else if (authElements.getLength() > 1) {
            throw new PEtALSCDKException(String.format(
                    "Only one authentication configuration can be set for operation '%s'.", operationName.toString()));
        } else {
            return AuthenticationBuilder.build((Element) authElements.item(0), operationName, xPathEvaluator,
                    componentPlaceholders, logger);
        }
    }

    private static List getFormDataParams(final Element operationElt, final XPath xpathEvaluator,
            final Properties componentPlaceholders, final Logger logger) throws PEtALSCDKException {
        final List formDatas = new ArrayList();

        final String namespaceURI = operationElt.getNamespaceURI();
        final NodeList formDataElements = operationElt.getElementsByTagNameNS(namespaceURI, FORM_DATA_PARAM);
        for (int i = 0; i < formDataElements.getLength(); i++) {
            final Node formDataNode = formDataElements.item(i);
            final Element formDataElt = (Element) formDataNode;

            formDatas.add(FormDataBuilder.build(formDataElt, xpathEvaluator, componentPlaceholders, logger));
        }

        return formDatas;
    }

    private static Map getOnHttpStatus(final Element operationElt, final XPath xpathBuilder,
            final String suRootPath, final ErrorListener logErrorListener, final Properties componentPlaceholders,
            final XMLInputFactory responseConverterFactory,
            final OnHttpStatusTransformation hardcodedDefaultTransformation, final Logger logger)
            throws PEtALSCDKException {
        final Map onHttpStatus = new HashMap<>();

        final String namespaceURI = operationElt.getNamespaceURI();
        final NodeList onHttpStatusElements = operationElt.getElementsByTagNameNS(namespaceURI, ON_HTTP_STATUS);
        for (int i = 0; i < onHttpStatusElements.getLength(); i++) {
            final Node onHttpStatusNode = onHttpStatusElements.item(i);
            final Element onHttpStatusElt = (Element) onHttpStatusNode;

            final int httpCode = HttpStatusBuilder.build(onHttpStatusElt, HTTP_CODE);

            final SortedSet conditionalTransformations = onHttpStatusGetConditionalTransformations(
                    onHttpStatusElt, xpathBuilder, suRootPath, logErrorListener, componentPlaceholders,
                    responseConverterFactory, logger);

            final OnHttpStatusTransformation otherwiseTransformation;
            final List otherwiseTransformations = onHttpStatusGetOtherwiseTransformations(
                    onHttpStatusElt, suRootPath, logErrorListener, responseConverterFactory, componentPlaceholders,
                    logger);
            if (otherwiseTransformations.size() > 1) {
                throw new PEtALSCDKException("Only one clause 'otherwise-xxx' is required.");
            } else if (otherwiseTransformations.size() == 1) {
                otherwiseTransformation = otherwiseTransformations.get(0);
            } else {
                otherwiseTransformation = null;
            }

            onHttpStatus.put(httpCode, new OnHttpStatus(httpCode, conditionalTransformations, otherwiseTransformation,
                    hardcodedDefaultTransformation, responseConverterFactory, logger));
        }

        return onHttpStatus;
    }

    private static SortedSet onHttpStatusGetConditionalTransformations(
            final Element onHttpStatusElt, final XPath xpathBuilder, final String suRootPath,
            final ErrorListener logErrorListener, final Properties componentPlaceholders,
            final XMLInputFactory responseConverterFactory, final Logger logger) throws PEtALSCDKException {

        final SortedSet conditionalTransformations = new TreeSet<>();
        final NodeList children = onHttpStatusElt.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            final Node child = children.item(i);
            if (child instanceof Element) {
                final OnHttpStatusConditionalTransformation conditionalTransformation;

                final Element elt = (Element) child;
                if (Out.XML_TAG_NAME.equals(elt.getLocalName())) {
                    conditionalTransformation = Out.build(elt, xpathBuilder, suRootPath, logErrorListener,
                            componentPlaceholders, responseConverterFactory, logger);
                } else if (Fault.XML_TAG_NAME.equals(elt.getLocalName())) {
                    conditionalTransformation = Fault.build(elt, xpathBuilder, suRootPath, logErrorListener,
                            componentPlaceholders, responseConverterFactory, logger);
                } else if (Error.XML_TAG_NAME.equals(elt.getLocalName())) {
                    conditionalTransformation = Error.build(elt, xpathBuilder, suRootPath, logErrorListener,
                            componentPlaceholders, responseConverterFactory, logger);
                } else {
                    // Children that are not conditional transformation are processed elsewhere
                    conditionalTransformation = null;
                }

                if (conditionalTransformation != null) {
                    conditionalTransformation.verify();
                    conditionalTransformations.add(conditionalTransformation);
                }
            }
        }

        return conditionalTransformations;
    }

    private static List onHttpStatusGetOtherwiseTransformations(
            final Element onHttpStatusElt, final String suRootPath, final ErrorListener logErrorListener,
            final XMLInputFactory responseConverterFactory, final Properties componentPlaceholders, final Logger logger)
            throws PEtALSCDKException {

        final List otherwiseTransformations = new ArrayList<>();
        final NodeList children = onHttpStatusElt.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            final Node child = children.item(i);
            if (child instanceof Element) {
                final Element elt = (Element) child;
                if (OtherwiseOut.XML_TAG_NAME.equals(elt.getLocalName())) {
                    otherwiseTransformations.add(
                            OtherwiseOut.build(elt, suRootPath, logErrorListener, responseConverterFactory,
                                    componentPlaceholders, logger));
                } else if (OtherwiseFault.XML_TAG_NAME.equals(elt.getLocalName())) {
                    otherwiseTransformations.add(
                            OtherwiseFault.build(elt, suRootPath, logErrorListener, responseConverterFactory,
                                    componentPlaceholders, logger));
                } else if (OtherwiseError.XML_TAG_NAME.equals(elt.getLocalName())) {
                    otherwiseTransformations.add(
                            OtherwiseError.build(elt, suRootPath, logErrorListener, responseConverterFactory,
                                    componentPlaceholders, logger));
                } else {
                    // Children that are not otherwise transformation are processed elsewhere
                }
            }
        }

        return otherwiseTransformations;
    }

    private static RESTProvidesConfigurationInputTransformation getXslOnIncomingRequest(final Element operationElt,
            final String suRootPath, final LogErrorListener logErrorListener) throws PEtALSCDKException {

        final String namespaceURI = operationElt.getNamespaceURI();
        final List xslOnIncomingReqElts = XMLHelper.getChildrenElementNS(operationElt, namespaceURI, XSL);
        if (xslOnIncomingReqElts.size() > 1) {
            throw new PEtALSCDKException("Only one XSL can be applied on the incoming request !");
        } else if (xslOnIncomingReqElts.isEmpty()) {
            return null;
        } else {
            final Element xslElt = xslOnIncomingReqElts.get(0);

            final String xslFileName = xslElt.getTextContent();
            // The XSL style-sheet file must exist
            final File xslFile = new File(suRootPath, xslFileName);
            if (!xslFile.exists()) {
                throw new PEtALSCDKException("XSL file does not exist: " + xslFile.getAbsolutePath());
            }

            // The XSL style-sheet file must be a regular file
            if (!xslFile.isFile()) {
                throw new PEtALSCDKException("XSL file is not a file: " + xslFile.getAbsolutePath());
            }

            // The XSL style-sheet file must be a buildable XSL
            final Source xslSource = new StreamSource(xslFile);
            final TransformerFactory transformerFactory = TransformerFactory.newInstance();
            transformerFactory.setErrorListener(logErrorListener);
            final Templates xslTemplate;
            try {
                xslTemplate = transformerFactory.newTemplates(xslSource);
            } catch (final TransformerConfigurationException e) {
                throw new PEtALSCDKException("Error compiling the XSL file: " + xslFile.getAbsolutePath(), e);
            }

            final String isJsonResultStr = xslElt.getAttribute(IS_JSON_RESULT);
            final boolean isJsonResult;
            if (isJsonResultStr == null || isJsonResultStr.trim().isEmpty()) {
                isJsonResult = false;
            } else {
                isJsonResult = Boolean.parseBoolean(isJsonResultStr.trim());
            }

            return new RESTProvidesConfigurationInputTransformation(xslTemplate, isJsonResult);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy