/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999-2009 Bull S.A.S.
 * Contact: jonas-team@ow2.org
 *
 * This 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 any later version.
 *
 * This 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 library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.ws.publish.internal.manager;

import java.util.ArrayList;
import java.util.List;

import org.ow2.jonas.jmx.JmxService;
import org.ow2.jonas.lib.service.AbsServiceImpl;
import org.ow2.jonas.lib.util.JonasObjectName;
import org.ow2.jonas.service.ServiceException;
import org.ow2.jonas.ws.publish.PublishableDefinition;
import org.ow2.jonas.ws.publish.WSDLPublisher;
import org.ow2.jonas.ws.publish.WSDLPublisherException;
import org.ow2.jonas.ws.publish.WSDLPublisherManager;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;

/**
 * Delegate publishing to all added WSDL Publishers.
 * @author Xavier Delplanque
 * @author Guillaume Sauthier
 */
public class DefaultWSDLPublisherManager extends AbsServiceImpl implements WSDLPublisherManager {

    /**
     * Logger.
     */
    private static Log logger = LogFactory.getLog(DefaultWSDLPublisherManager.class);

    /**
     * List of WSDL Publishers in charge of WSDL Publication
     */
    private List<WSDLPublisher> publishers;

    /**
     * JMX Service.
     */
    private JmxService jmxService = null;

    /**
     * Get a new instance of WSDLManager.
     */
    public DefaultWSDLPublisherManager() {
        publishers = new ArrayList<WSDLPublisher>();
    }

    /**
     * @param param List of WSDL Publishers to create.
     */
    public void setPublishers(final String param) {
        List<String> handlers = convertToList(param);

        WSDLPublisherFactory factory = WSDLPublisherFactory.newInstance();
        for (String name : handlers) {
            // Create the publisher
            WSDLPublisher publisher = null;
            try {
                publisher = factory.newPublisher(name);
            } catch (WSDLPublisherException e) {
                logger.info("Cannot add the new WSDLPublisher '{0}'", name, e);
            }

            logger.debug("Adding WSDLPublisher ''{0}''", name);

            // Add the created Handler
            this.addPublisher(publisher);
        }
    }

    /**
     * Add a new publisher in this manager.
     * @param publisher new WSDLPublisher
     */
    public void addPublisher(final WSDLPublisher publisher) {
        publishers.add(publisher);
    }

    /**
     * Remove an already registered publisher.
     * @param publisher WSDLPublisher to be removed
     */
    public void removePublisher(final WSDLPublisher publisher) {
        publishers.remove(publisher);
    }

    /**
     * Delegate publishing to all added WSDL Publishers.
     * @param publishableDefinition the data containing the WSDL file to be published and the publication info
     * @throws WSDLPublisherException if an error occurs at the publishing.
     */
    public void publish(final PublishableDefinition publishableDefinition) throws WSDLPublisherException {
        for (WSDLPublisher publisher : publishers) {
            publisher.publish(publishableDefinition);
        }
    }

    /**
     * Delegate publishing to all added WSDL Publishers.
     * @param publishableDefinitionList a list of data containing the WSDL file to be published and the publication info
     * @throws WSDLPublisherException if an error occurs at the publishing.
     */
    public void publish(final List<PublishableDefinition> publishableDefinitionList) throws WSDLPublisherException {
        if (publishableDefinitionList != null) {
            for (PublishableDefinition publishableDefinition : publishableDefinitionList) {
                for (WSDLPublisher publisher : publishers) {
                    publisher.publish(publishableDefinition);
                }
            }
        }
    }

    /**
     * Abstract start-up method to be implemented by sub-classes.
     * @throws org.ow2.jonas.service.ServiceException service start-up failed
     */
    @Override
    protected void doStart() throws ServiceException {
        // Load the Descriptors
        jmxService.loadDescriptors(getClass().getPackage().getName(), getClass().getClassLoader());

        // And register MBean
        try {
            jmxService.registerModelMBean(this, JonasObjectName.wsdlPublisherService(getDomainName()));
        } catch (Exception e) {
            logger.warn("Cannot register MBean for Deployable Monitor service", e);
        }
    }

    /**
     * Abstract method for service stopping to be implemented by sub-classes.
     * @throws org.ow2.jonas.service.ServiceException service stopping failed
     */
    @Override
    protected void doStop() throws ServiceException {
        // Unregister MBean
        if (jmxService != null) {
            try {
                jmxService.unregisterModelMBean(JonasObjectName.wsdlPublisherService(getDomainName()));
            } catch (Exception e) {
                logger.warn("Cannot unregister MBean for Deployable Monitor service", e);
            }
        }
    }

    /**
     * @param jmxService the jmxService to set
     */
    public void setJmxService(final JmxService jmxService) {
        this.jmxService = jmxService;
    }
}
