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

org.ow2.petals.bc.mail.MailSuManager Maven / Gradle / Ivy

/**
 * Copyright (c) 2016-2023 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.bc.mail;

import static org.ow2.petals.bc.mail.MailConstants.IntegrationService.OP_SENDMAIL;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;

import javax.xml.namespace.QName;

import org.ow2.petals.bc.mail.exception.MailDeclarationException;
import org.ow2.petals.bc.mail.listeners.ExternalListener;
import org.ow2.petals.bc.mail.service.provide.AbstractSendService;
import org.ow2.petals.bc.mail.service.provide.integration.SendMailOperation;
import org.ow2.petals.bc.mail.service.provide.pivot.annotated.AnnotatedMailOperation;
import org.ow2.petals.bc.mail.service.provide.pivot.annotated.AnnotatedWsdlParser;
import org.ow2.petals.bc.mail.service.provide.pivot.annotated.exception.InvalidAnnotationException;
import org.ow2.petals.bc.mail.service.provide.pivot.annotated.exception.UnsupportedAnnotatedOperationException;
import org.ow2.petals.component.framework.api.configuration.SuConfigurationParameters;
import org.ow2.petals.component.framework.api.exception.PEtALSCDKException;
import org.ow2.petals.component.framework.bc.AbstractBindingComponent;
import org.ow2.petals.component.framework.bc.BindingComponentServiceUnitManager;
import org.ow2.petals.component.framework.jbidescriptor.generated.Jbi;
import org.ow2.petals.component.framework.jbidescriptor.generated.Provides;
import org.ow2.petals.component.framework.listener.AbstractExternalListener;
import org.ow2.petals.component.framework.su.ServiceUnitDataHandler;
import org.ow2.petals.component.framework.util.ServiceEndpointOperationKey;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * @author Christophe DENEUX - Linagora
 */
public class MailSuManager extends BindingComponentServiceUnitManager {

    /**
     * Default constructor.
     * 
     * @param component
     *            the Mail component
     */
    public MailSuManager(final AbstractBindingComponent component) {
        super(component);
    }

    @Override
    protected AbstractExternalListener createExternalListener() {
        return new ExternalListener();
    }

    /**
     * {@inheritDoc}
     * 
     * We override the deployment processing for nodes 'provides' to be able to manage distinctly: static SU and SU in
     * mode 'service'.
     */
    @Override
    protected void doDeploy(final ServiceUnitDataHandler suDH) throws PEtALSCDKException {
        if (this.logger.isLoggable(Level.FINE)) {
            this.logger.fine("Start MailSuManager.doDeploy(SU =" + suDH.getName() + ")");
        }

        final Jbi jbiDescriptor = suDH.getDescriptor();

        // Process section 'provides'
        for (final Provides provide : jbiDescriptor.getServices().getProvides()) {
            final String edptName = provide.getEndpointName();
            final QName interfaceName = provide.getInterfaceName();
            final QName serviceName = provide.getServiceName();
            final SuConfigurationParameters extensions = suDH.getConfigurationExtensions(provide);
            if (extensions == null) {
                throw new PEtALSCDKException("Invalid JBI descriptor: it does not contain any component extension.");
            }

            // Create processing operations
            final Document wsdl = suDH.getEndpointDescription(provide);
            final List operations = this.createMailOperations(wsdl, extensions,
                    suDH.getInstallRoot());
            if (operations == null) {
                // No annotation exists in the WSDL, it's a section providing an integration service provider

                // Retrieve the operation from WSDL. The operation should be alone
                final QName wsdlOperation;
                final NodeList portTypes = wsdl.getElementsByTagNameNS(AnnotatedWsdlParser.SCHEMA_WSDL, "portType");
                if (portTypes.getLength() == 0) {
                    this.logger.warning("No port type defined in the WSDL of service " + serviceName.toString()
                            + ". We use the default operation name.");
                    wsdlOperation = OP_SENDMAIL;
                } else {
                    final String targetNamespace = wsdl.getDocumentElement().getAttribute("targetNamespace");
                    QName tmpWsdlOperation = null;
                    for (int i = 0; i < portTypes.getLength(); i++) {
                        final Element portType = (Element) portTypes.item(i);
                        final Attr portTypeName = portType.getAttributeNode("name");
                        // TODO: Manage the use case where no attribute "name" is set
                        if (portTypeName.getValue().equals(interfaceName.getLocalPart())
                                && interfaceName.getNamespaceURI().equals(targetNamespace)) {
                            // Port type associated to the provide section is found
                            final NodeList wsdlOperations = portType
                                    .getElementsByTagNameNS(AnnotatedWsdlParser.SCHEMA_WSDL, "operation");
                            if (wsdlOperations.getLength() == 0) {
                                this.logger.warning("No operation defined in port type " + interfaceName.toString()
                                        + ". We use the default operation name.");
                                tmpWsdlOperation = OP_SENDMAIL;
                            } else if (wsdlOperations.getLength() == 1) {
                                final Element operation = (Element) wsdlOperations.item(0);
                                final Attr operationName = operation.getAttributeNode("name");
                                // TODO: Manage the use case where no attribute "name" is set
                                tmpWsdlOperation = new QName(targetNamespace, operationName.getValue());
                            } else {
                                this.logger.warning("Several operations defined in port type "
                                        + interfaceName.toString() + ". We use the first one.");
                                final Element operation = (Element) wsdlOperations.item(0);
                                final Attr operationName = operation.getAttributeNode("name");
                                // TODO: Manage the use case where no attribute "name" is set
                                tmpWsdlOperation = new QName(targetNamespace, operationName.getValue());
                            }
                        }
                    }
                    if (tmpWsdlOperation == null) {
                        this.logger.warning("No port type associated to the interface '" + interfaceName.toString()
                                + "' was found. We use the default operation name.");
                        wsdlOperation = OP_SENDMAIL;
                    } else {
                        wsdlOperation = tmpWsdlOperation;
                    }
                }

                final AbstractSendService operation = new SendMailOperation(this.getComponent().getMailSessionManager(),
                        this.getComponent().getMimeMessageManager(), this.logger, extensions, wsdlOperation);
                final ServiceEndpointOperationKey eptAndOperation = new ServiceEndpointOperationKey(serviceName,
                        edptName, operation.getWsdlOperation());
                this.getComponent().registerMailOperation(eptAndOperation, operation);
                this.logEptOperationToMailOperation(eptAndOperation, operation);
            } else {
                // Annotation exists in the WSDL, it's a section providing a pivot service provider

                // Enable processing operations
                for (final AbstractSendService operation : operations) {
                    // Store the AbstractSendService in the map with the corresponding end-point
                    final ServiceEndpointOperationKey eptAndOperation = new ServiceEndpointOperationKey(serviceName,
                            edptName, operation.getWsdlOperation());
                    this.getComponent().registerMailOperation(eptAndOperation, operation);
                    this.logEptOperationToMailOperation(eptAndOperation, operation);
                }
            }
        }



        if (this.logger.isLoggable(Level.FINE)) {
            this.logger.fine("End MailSuManager.doDeploy()");
        }
    }

    private void logEptOperationToMailOperation(final ServiceEndpointOperationKey svcEdpKey,
            final AbstractSendService operation) {
        if (this.logger.isLoggable(Level.CONFIG)) {
            this.logger.config("*** Endpoint Operation ");
            this.logger.config(svcEdpKey.toString());
            operation.log();
        }
    }

    @Override
    protected void doStart(final ServiceUnitDataHandler suDH) throws PEtALSCDKException {
        this.logger.fine("Start MailSuManager.doStart(SU =" + suDH.getName() + ")");

        // TODO Have we something to do here ?

        this.logger.fine("End MailSuManager.doStart()");
    }

    @Override
    protected void doStop(final ServiceUnitDataHandler suDH) throws PEtALSCDKException {
        this.logger.fine("Start MailSuManager.doStop(SU =" + suDH.getName() + ")");

        // TODO Have we something to do here ?

        this.logger.fine("End MailSuManager.doStop()");
    }

    @Override
    protected void doUndeploy(final ServiceUnitDataHandler suDH) throws PEtALSCDKException {
        this.logger.fine("Start MailSuManager.doUndeploy(SU =" + suDH.getName() + ")");
        try {
            // Process section 'provides'
            for (final Provides provide : suDH.getDescriptor().getServices().getProvides()) {
                // Remove the mail operation in the map with the corresponding end-point
                this.getComponent().removeMailOperations(provide.getEndpointName());

            }
        } finally {
            this.logger.fine("End MailSuManager.doUndeploy()");
        }
    }

    @Override
    protected MailComponent getComponent() {
        return (MailComponent) super.getComponent();
    }

    /**
     * Create the mail operations ({@link AbstractSendService}) reading BC Mail annotations from the WSDL
     * 
     * @param wsdlDocument
     *            The WSDL to parse to create mail operations
     * @param extensions
     *            BC Mail extensions of the JBI descriptor of the current provider
     * @param suRootPath
     *            The root directory of the service unit
     * @return The list of {@link AbstractSendService} created from WSDL, or {@code null} if no annotation exists in the
     *         WSDL
     * @throws MailDeclarationException
     *             An error was detected about annotations
     */
    private List createMailOperations(final Document wsdlDocument,
            final SuConfigurationParameters extensions, final String suRootPath) throws MailDeclarationException {

        final AnnotatedWsdlParser annotatedWdslParser = new AnnotatedWsdlParser(this.logger);

        final List annotatedOperations = annotatedWdslParser.parse(wsdlDocument, extensions,
                suRootPath);
        if (annotatedOperations.isEmpty()) {
            // No annotated operation was correctly read from the WSDL, or no annotated operation is declared in the
            // WSDL
            return null;
        } else {
            // Log all WSDL errors before to process each annotated operations
            if (this.logger.isLoggable(Level.WARNING)) {
                for (final InvalidAnnotationException encounteredError : annotatedWdslParser.getEncounteredErrors()) {
                    this.logger.warning(encounteredError.getMessage());
                }
            }

            final List operations = new ArrayList<>(annotatedOperations.size());
            for (final AnnotatedMailOperation annotatedOperation : annotatedOperations) {

                final QName wsdlOperation = annotatedOperation.getWsdlOperation();
                this.logger.fine("Processing WSDL annotated operation: " + wsdlOperation);

                // create the right mail operation according to its type
                if (annotatedOperation instanceof org.ow2.petals.bc.mail.service.provide.pivot.annotated.SendMailOperation) {
                    operations.add(new org.ow2.petals.bc.mail.service.provide.pivot.SendMailOperation(
                            (org.ow2.petals.bc.mail.service.provide.pivot.annotated.SendMailOperation) annotatedOperation,
                            this.getComponent().getMailSessionManager(), this.getComponent().getMimeMessageManager(),
                            extensions, this.logger));
                } else {
                    // This case is a bug case, as the annotated operation is known by the parser, it must be supported
                    // here.
                    throw new MailDeclarationException(new UnsupportedAnnotatedOperationException(wsdlOperation,
                            annotatedOperation.getClass().getSimpleName()));
                }
            }

            return operations;
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy