/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.servicemix.jbi.container;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Collection;
import java.util.EventListener;
import java.util.MissingResourceException;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.jbi.JBIException;
import javax.jbi.component.Component;
import javax.jbi.component.ComponentLifeCycle;
import javax.jbi.component.ServiceUnitManager;
import javax.jbi.management.DeploymentException;
import javax.jbi.management.LifeCycleMBean;
import javax.jbi.messaging.ExchangeStatus;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.MessagingException;
import javax.jbi.servicedesc.ServiceEndpoint;
import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.swing.event.EventListenerList;
import javax.transaction.TransactionManager;
import javax.xml.namespace.QName;

import org.w3c.dom.DocumentFragment;

import org.apache.servicemix.JbiConstants;
import org.apache.servicemix.components.util.ComponentAdaptor;
import org.apache.servicemix.components.util.ComponentAdaptorMEListener;
import org.apache.servicemix.components.util.ComponentSupport;
import org.apache.servicemix.components.util.PojoLifecycleAdaptor;
import org.apache.servicemix.components.util.PojoSupport;
import org.apache.servicemix.executors.ExecutorFactory;
import org.apache.servicemix.id.IdGenerator;
import org.apache.servicemix.jbi.api.Container;
import org.apache.servicemix.jbi.event.ComponentListener;
import org.apache.servicemix.jbi.event.ContainerAware;
import org.apache.servicemix.jbi.event.DeploymentListener;
import org.apache.servicemix.jbi.event.EndpointListener;
import org.apache.servicemix.jbi.event.ExchangeEvent;
import org.apache.servicemix.jbi.event.ExchangeListener;
import org.apache.servicemix.jbi.event.ServiceAssemblyListener;
import org.apache.servicemix.jbi.event.ServiceUnitListener;
import org.apache.servicemix.jbi.framework.AdminCommandsService;
import org.apache.servicemix.jbi.framework.AutoDeploymentService;
import org.apache.servicemix.jbi.framework.ClientFactory;
import org.apache.servicemix.jbi.framework.ComponentContextImpl;
import org.apache.servicemix.jbi.framework.ComponentMBeanImpl;
import org.apache.servicemix.jbi.framework.ComponentNameSpace;
import org.apache.servicemix.jbi.framework.DeploymentService;
import org.apache.servicemix.jbi.framework.InstallationService;
import org.apache.servicemix.jbi.framework.Registry;
import org.apache.servicemix.jbi.listener.MessageExchangeListener;
import org.apache.servicemix.jbi.management.BaseLifeCycle;
import org.apache.servicemix.jbi.management.BaseSystemService;
import org.apache.servicemix.jbi.management.ManagementContext;
import org.apache.servicemix.jbi.messaging.MessageExchangeImpl;
import org.apache.servicemix.jbi.nmr.Broker;
import org.apache.servicemix.jbi.nmr.DefaultBroker;
import org.apache.servicemix.jbi.nmr.flow.Flow;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The main container
 *
 * @version $Revision$
 */
public class JBIContainer extends BaseLifeCycle implements Container {

    /**
     * Default Container name - must be unique if used in a cluster
     */
    public static final String DEFAULT_NAME = "ServiceMix";

    private static final Logger LOGGER = LoggerFactory.getLogger(JBIContainer.class);

    protected Broker broker = new DefaultBroker();
    protected ServiceUnitManager serviceManager;
    protected ManagementContext managementContext = new ManagementContext();
    protected EnvironmentContext environmentContext = new EnvironmentContext();
    protected InstallationService installationService = new InstallationService();
    protected DeploymentService deploymentService = new DeploymentService();
    protected AutoDeploymentService autoDeployService = new AutoDeploymentService();
    protected AdminCommandsService adminCommandsService = new AdminCommandsService();
    protected BaseSystemService[] services;
    protected ClientFactory clientFactory = new ClientFactory();
    protected Registry registry = new Registry();
    protected boolean autoEnlistInTransaction;
    protected boolean persistent;
    protected boolean embedded;
    protected boolean notifyStatistics;
    protected EventListenerList listeners = new EventListenerList();
    protected EventListener[] configuredListeners;
    protected boolean useShutdownHook = true;
    protected boolean useNewTransactionModel;
    protected transient Thread shutdownHook;
    protected ExecutorFactory executorFactory;
    private String name = DEFAULT_NAME;
    private InitialContext namingContext;
    private MBeanServer mbeanServer;
    private String completeStartMarkupFileName;
    private TransactionManager transactionManager;
    private String rootDir;
    private String generatedRootDirPrefix = "target/rootDirs/rootDir";
    private boolean generateRootDir;
    private AtomicBoolean started = new AtomicBoolean(false);
    private AtomicBoolean containerInitialized = new AtomicBoolean(false);
    private IdGenerator idGenerator = new IdGenerator();
    private long forceShutdown;
    private boolean optimizedDelivery = true;

    /**
     * Default Constructor
     */
    public JBIContainer() {
    }

    /**
     * @return Returns the unique nam for the Container
     */
    public String getName() {
        return name;
    }

    /**
     * @param name The name to set (must be unique within a cluster)
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Get the description
     *
     * @return descrption
     */
    public String getDescription() {
        return "ServiceMix JBI Container";
    }

    /**
     * @return Returns the flowName.
     */
    public String getFlowName() {
        String flowNames = getDefaultBroker().getFlowNames();
        if (flowNames == null) {
            return null;
        }
        String[] flows = flowNames.split(",");
        if (flows.length > 1) {
            throw new IllegalStateException("Multiple flows have been defined");
        }
        return flows[0];
    }

    /**
     * @param flowName The flow to set.
     */
    public void setFlowName(String flowName) {
        getDefaultBroker().setFlowNames(flowName);
    }

    /**
     * @return Returns the flowNames.
     */
    public String getFlowNames() {
        return getDefaultBroker().getFlowNames();
    }

    /**
     * @param flowNames The flows to set.
     */
    public void setFlowNames(String flowNames) {
        getDefaultBroker().setFlowNames(flowNames);
    }

    /**
     * @return the subscriptionFlowName
     */
    public String getSubscriptionFlowName() {
        return getDefaultBroker().getSubscriptionFlowName();
    }

    /**
     * Set the subscription flow name
     *
     * @param subscriptionFlowName
     */
    public void setSubscriptionFlowName(String subscriptionFlowName) {
        getDefaultBroker().setSubscriptionFlowName(subscriptionFlowName);
    }

    /**
     * Set the broker message flow
     *
     * @param flow
     */
    public void setFlow(Flow flow) {
        getDefaultBroker().setFlows(new Flow[]{flow});
    }

    /**
     * @return the broker message Flow
     */
    public Flow getFlow() {
        Flow[] flows = getDefaultBroker().getFlows();
        if (flows == null || flows.length == 0) {
            return null;
        } else if (flows.length > 1) {
            throw new IllegalStateException("Multiple flows have been defined");
        } else {
            return flows[0];
        }
    }

    /**
     * Set the broker message flows
     *
     * @param flows
     */
    public void setFlows(Flow[] flows) {
        getDefaultBroker().setFlows(flows);
    }

    /**
     * @return the broker message Flows
     */
    public Flow[] getFlows() {
        return getDefaultBroker().getFlows();
    }

    public boolean isUseShutdownHook() {
        return useShutdownHook;
    }

    /**
     * Sets whether or not we should use a shutdown handler to close down the
     * broker cleanly if the JVM is terminated. It is recommended you leave this
     * enabled.
     */
    public void setUseShutdownHook(boolean useShutdownHook) {
        this.useShutdownHook = useShutdownHook;
    }

    public boolean isUseNewTransactionModel() {
        return useNewTransactionModel;
    }

    /**
     * Sets whether the new transaction model should be used.
     *
     * @param useNewTransactionModel
     */
    public void setUseNewTransactionModel(boolean useNewTransactionModel) {
        this.useNewTransactionModel = useNewTransactionModel;
    }

    /**
     * @return the services
     */
    public BaseSystemService[] getServices() {
        return services;
    }

    /**
     * @param services the services to set
     */
    public void setServices(BaseSystemService[] services) {
        this.services = services;
    }

    /**
     * Gets name of file that is created when container finished starting.
     *
     * @return the name of the markup file in container root directory.
     */
    public String getCompleteStartMarkupFileName() {
        return this.completeStartMarkupFileName;
    }

    /**
     * Sets name of file that is created when container finishes starting.
     *
     * @param completeStartMarkupFileName name of the marker file in container root directory.
     */
    public void setCompleteStartMarkupFileName(String completeStartMarkupFileName) {
        this.completeStartMarkupFileName = completeStartMarkupFileName;
    }

    /**
     * Get the ManagementContext
     *
     * @return the ManagementContext
     */
    public ManagementContext getManagementContext() {
        return managementContext;
    }

    /**
     * @return Return the EnvironmentContext
     */
    public EnvironmentContext getEnvironmentContext() {
        return environmentContext;
    }

    /**
     * @return Return the registry
     */
    public Registry getRegistry() {
        return registry;
    }

    /**
     * Return the DefaultBroker instance
     */
    public DefaultBroker getDefaultBroker() {
        if (!(broker instanceof DefaultBroker)) {
            throw new IllegalStateException("Broker is not a DefaultBroker");
        }
        return (DefaultBroker) broker;
    }

    /**
     * @return Return the NMR broker
     */
    public Broker getBroker() {
        return broker;
    }

    /**
     * Set the Broker to use
     */
    public void setBroker(Broker broker) {
        this.broker = broker;
    }

    /**
     * @return true if creates own MBeanServer if none supplied
     */
    public boolean isCreateMBeanServer() {
        return managementContext.isCreateMBeanServer();
    }

    /**
     * Set the flag to create own MBeanServer if none supplied
     *
     * @param enableJMX
     */
    public void setCreateMBeanServer(boolean enableJMX) {
        managementContext.setCreateMBeanServer(enableJMX);
    }

    /**
     * @return Returns the useMBeanServer.
     */
    public boolean isUseMBeanServer() {
        return managementContext.isUseMBeanServer();
    }

    /**
     * @param useMBeanServer The useMBeanServer to set.
     */
    public void setUseMBeanServer(boolean useMBeanServer) {
        managementContext.setUseMBeanServer(useMBeanServer);
    }

    /**
     * @return Returns the useMBeanServer.
     */
    public boolean isCreateJmxConnector() {
        return managementContext.isCreateJmxConnector();
    }

    /**
     * @param createJmxConnector The createJmxConnector to set.
     */
    public void setCreateJmxConnector(boolean createJmxConnector) {
        managementContext.setCreateJmxConnector(createJmxConnector);
    }

    /**
     * @return Returns the monitorInstallationDirectory.
     */
    public boolean isMonitorInstallationDirectory() {
        return autoDeployService.isMonitorInstallationDirectory();
    }

    /**
     * @param monitorInstallationDirectory The monitorInstallationDirectory to set.
     */
    public void setMonitorInstallationDirectory(boolean monitorInstallationDirectory) {
        autoDeployService.setMonitorInstallationDirectory(monitorInstallationDirectory);
    }

    /**
     * @return Returns the monitorDeploymentDirectory.
     */
    public boolean isMonitorDeploymentDirectory() {
        return autoDeployService.isMonitorDeploymentDirectory();
    }

    /**
     * @param monitorDeploymentDirectory The monitorDeploymentDirectory to set.
     */
    public void setMonitorDeploymentDirectory(boolean monitorDeploymentDirectory) {
        autoDeployService.setMonitorDeploymentDirectory(monitorDeploymentDirectory);
    }

    /**
     * @return Returns the installationDir.
     */
    public String getInstallationDirPath() {
        File dir = environmentContext.getInstallationDir();
        return dir != null ? dir.getAbsolutePath() : "";
    }

    /**
     * Set the installationDir - rge default location is root/<container name>/installation
     *
     * @param installationDir
     */
    public void setInstallationDirPath(String installationDir) {
        if (installationDir != null && installationDir.length() > 0) {
            environmentContext.setInstallationDir(new File(installationDir));
        }
    }

    /**
     * @return Returns the deploymentDir.
     */
    public String getDeploymentDirPath() {
        File dir = environmentContext.getDeploymentDir();
        return dir != null ? dir.getAbsolutePath() : "";
    }

    /**
     * @param deploymentDir The deploymentDir to set.
     */
    public void setDeploymentDirPath(String deploymentDir) {
        if (deploymentDir != null && deploymentDir.length() > 0) {
            environmentContext.setDeploymentDir(new File(deploymentDir));
        }
    }

    /**
     * @return Returns the monitorInterval (in secs).
     */
    public int getMonitorInterval() {
        return autoDeployService.getMonitorInterval();
    }

    /**
     * @param monitorInterval The monitorInterval to set (in secs).
     */
    public void setMonitorInterval(int monitorInterval) {
        autoDeployService.setMonitorInterval(monitorInterval);
    }

    /**
     * @return the deploymentExtensions
     */
    public String getDeploymentExtensions() {
        return autoDeployService.getExtensions();
    }

    /**
     * @param deploymentExtensions the deploymentExtensions to set
     */
    public void setDeploymentExtensions(String deploymentExtensions) {
        autoDeployService.setExtensions(deploymentExtensions);
    }

    /**
     * Install an component from a url
     *
     * @param url
     * @throws DeploymentException
     */
    public void installArchive(String url) throws DeploymentException {
        installationService.install(url, null, true);
    }

    /**
     * load an archive from an external location.
     * The archive can be a Component, Service Assembly or Shared Library.
     *
     * @param location  - can either be a url or filename (if relative - must be relative to the container)
     * @param autoStart - if true will start the component/service assembly
     * @throws DeploymentException
     */
    public void updateExternalArchive(String location, boolean autoStart) throws DeploymentException {
        autoDeployService.updateExternalArchive(location, autoStart);
    }

    /**
     * load an archive from an external location and starts it
     * The archive can be a Component, Service Assembly or Shared Library.
     *
     * @param location - can either be a url or filename (if relative - must be relative to the container)
     * @throws DeploymentException
     */
    public void updateExternalArchive(String location) throws DeploymentException {
        updateExternalArchive(location, true);
    }

    /**
     * @return Returns the deploymentService.
     */
    public DeploymentService getDeploymentService() {
        return deploymentService;
    }

    /**
     * @return Returns the installationService.
     */
    public InstallationService getInstallationService() {
        return installationService;
    }

    /**
     * @return the AutomDeploymentService
     */
    public AutoDeploymentService getAutoDeploymentService() {
        return autoDeployService;
    }

    /**
     * @return the AdminCommandsService
     */
    public AdminCommandsService getAdminCommandsService() {
        return adminCommandsService;
    }

    public ClientFactory getClientFactory() {
        return clientFactory;
    }

    public String getGeneratedRootDirPrefix() {
        return generatedRootDirPrefix;
    }

    /**
     * Sets the prefix used when auto-creating a rootDir property value
     * which is useful for integration testing inside JUnit test cases
     * letting each test case create its own empty servicemix install
     *
     * @param generatedRootDirPrefix the prefix used to auto-create the
     *                               rootDir
     * @see #setRootDir(String)
     * @see #setGeneratedRootDirPrefix(String)
     */
    public void setGeneratedRootDirPrefix(String generatedRootDirPrefix) {
        this.generatedRootDirPrefix = generatedRootDirPrefix;
    }

    public boolean isGenerateRootDir() {
        return generateRootDir;
    }

    public long getForceShutdown() {
        return forceShutdown;
    }

    /**
     * Set the timeout (in ms) before a shutdown is forced by cancelling all pending exchanges.
     * The default value is 0 -- no forced shutdown
     *
     * @param forceShutdown the timeout in ms
     */
    public void setForceShutdown(long forceShutdown) {
        this.forceShutdown = forceShutdown;
    }

    /**
     * Creates an auto-generated rootDir which is useful for integration testing
     * in JUnit test cases allowing installations of deployments inside an empty
     * installation of ServiceMix
     *
     * @param generateRootDir if true this will enable the auto-generation of the rootDir
     *                        if the rootDir property is not configured
     * @see #setRootDir(String)
     * @see #setGeneratedRootDirPrefix(String)
     */
    public void setGenerateRootDir(boolean generateRootDir) {
        this.generateRootDir = generateRootDir;
    }

    /**
     * light weight initialization - default values for mbeanServer, TransactionManager etc are null
     *
     * @throws JBIException
     */
    public void init() throws JBIException {
        if (containerInitialized.compareAndSet(false, true)) {
            LOGGER.info("ServiceMix {} JBI Container ({}) is starting", EnvironmentContext.getVersion(), getName());
            LOGGER.info("For help or more information please see: http://servicemix.apache.org/");
            addShutdownHook();
            if (this.executorFactory == null) {
                this.executorFactory = createExecutorFactory();
            }
            if (this.namingContext == null) {
                try {
                    this.namingContext = new InitialContext();
                } catch (NamingException e) {
                    // Log a warning, with exception only in debug
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.warn("Failed to set InitialContext", e);
                    } else {
                        LOGGER.warn("Failed to set InitialContext");
                    }
                }
            }
            managementContext.init(this, getMBeanServer());
            mbeanServer = this.managementContext.getMBeanServer(); // just in case ManagementContext creates it
            environmentContext.init(this, getRootDir());
            clientFactory.init(this);
            if (services != null) {
                for (int i = 0; i < services.length; i++) {
                    services[i].init(this);
                }
            }
            registry.init(this);
            broker.init(this);
            installationService.init(this);
            deploymentService.init(this);
            autoDeployService.init(this);
            adminCommandsService.init(this);

            // register self with the ManagementContext
            try {
                managementContext.registerMBean(ManagementContext.getContainerObjectName(managementContext.getJmxDomainName(), getName()),
                        this, LifeCycleMBean.class);
            } catch (JMException e) {
                throw new JBIException(e);
            }

            // Initialize listeners after the whole container has been initialized
            // so that they can register themselves as JMX mbeans for example
            if (configuredListeners != null) {
                for (int i = 0; i < configuredListeners.length; i++) {
                    EventListener listener = configuredListeners[i];
                    addListener(listener);
                }
            }
        }
    }

    /**
     * start processing
     *
     * @throws JBIException
     */
    public void start() throws JBIException {
        checkInitialized();
        if (started.compareAndSet(false, true)) {
            managementContext.start();
            environmentContext.start();
            clientFactory.start();
            if (services != null) {
                for (int i = 0; i < services.length; i++) {
                    services[i].start();
                }
            }
            broker.start();
            registry.start();
            installationService.start();
            deploymentService.start();
            autoDeployService.start();
            adminCommandsService.start();
            super.start();
            this.notifyContainerStarted();
        }
    }

    private void notifyContainerStarted() throws JBIException {
        if (completeStartMarkupFileName != null) {
            File startMarkupFile = new File(rootDir, completeStartMarkupFileName);
            try {
                if (!startMarkupFile.exists()) {
                    File parent = startMarkupFile.getParentFile();
                    if (parent != null && !parent.exists()) {
                        parent.mkdirs();
                    }
                    startMarkupFile.createNewFile();
                }
                startMarkupFile.setLastModified(System.currentTimeMillis());
            } catch (IOException ioException) {
                throw new JBIException("Cannot create startup markup file " + startMarkupFile.getAbsolutePath(), ioException);
            }
        }
        LOGGER.info("ServiceMix JBI Container (" + this.getName() + ") started");
    }

    /**
     * stop the container from processing
     *
     * @throws JBIException
     */
    public void stop() throws JBIException {
        checkInitialized();
        if (started.compareAndSet(true, false)) {
            LOGGER.info("ServiceMix JBI Container ({})", getName());
            adminCommandsService.stop();
            autoDeployService.stop();
            deploymentService.stop();
            installationService.stop();
            registry.stop();
            broker.stop();
            if (services != null) {
                for (int i = services.length - 1; i >= 0; i--) {
                    services[i].stop();
                }
            }
            clientFactory.stop();
            environmentContext.stop();
            managementContext.stop();
            super.stop();
        }
    }

    /**
     * After a shutdown the container will require an init before a start ...
     *
     * @throws JBIException
     */
    public void shutDown() throws JBIException {
        if (containerInitialized.compareAndSet(true, false)) {
            LOGGER.info("Shutting down ServiceMix JBI Container ({})", getName());
            removeShutdownHook();
            adminCommandsService.shutDown();
            autoDeployService.shutDown();
            deploymentService.shutDown();
            installationService.shutDown();
            shutdownRegistry();
            broker.shutDown();
            shutdownServices();
            clientFactory.shutDown();
            environmentContext.shutDown();
            // shutdown the management context last, because it will close the mbean server
            super.shutDown();
            managementContext.unregisterMBean(this);
            managementContext.shutDown();
            LOGGER.info("ServiceMix JBI Container ({})", getName());
        }
    }

    private void shutdownServices() throws JBIException {
        if (services != null) {
            for (int i = services.length - 1; i >= 0; i--) {
                services[i].shutDown();
            }
        }
    }

    private void shutdownRegistry() throws JBIException {
        FutureTask<Boolean> shutdown = new FutureTask<Boolean>(new Callable<Boolean>() {
            public Boolean call() throws Exception {
                registry.shutDown();
                return true;
            }
        });

        //use daemon thread to run this shutdown task
        //fix the container hang when shutdown container from the jmx console
        Thread daemonShutDownThread = new Thread(shutdown);
        daemonShutDownThread.setDaemon(true);
        daemonShutDownThread.start();

        try {
            if (forceShutdown > 0) {
                LOGGER.info("Waiting another {} ms for complete shutdown of the components and service assemblies", forceShutdown);
                shutdown.get(forceShutdown, TimeUnit.MILLISECONDS);
            } else {
                LOGGER.info("Waiting for complete shutdown of the components and service assemblies");
                shutdown.get();
            }
            LOGGER.info("Components and service assemblies have been shut down");
        } catch (Exception e) {
            forceShutdown(e);
        }
    }

    /**
     * Force a container shutdown by canceling all pending exchanges
     *
     * @param e the exception that caused the forced container shutdown
     */
    protected void forceShutdown(Exception e) {
        LOGGER.warn("Unable to shutdown components and service assemblies normally: {}", e, e);
        LOGGER.warn("Forcing shutdown by cancelling all pending exchanges");
        registry.cancelPendingExchanges();
    }

    protected void addShutdownHook() {
        if (useShutdownHook) {
            shutdownHook = new Thread("ServiceMix ShutdownHook") {
                public void run() {
                    containerShutdown();
                }
            };
            Runtime.getRuntime().addShutdownHook(shutdownHook);
        }
    }

    protected void removeShutdownHook() {
        if (shutdownHook != null) {
            try {
                Runtime.getRuntime().removeShutdownHook(shutdownHook);
            } catch (Exception e) {
                LOGGER.debug("Caught exception, must be shutting down: {}", e, e);
            }
        }
    }

    /**
     * Causes a clean shutdown of the container when the VM is being shut down
     */
    protected void containerShutdown() {
        try {
            shutDown();
        } catch (Throwable e) {
            System.err.println("Failed to shut down: " + e);
        }
    }

    /**
     * @return theMBean server assocated with the JBI
     */
    public synchronized MBeanServer getMBeanServer() {
        return mbeanServer;
    }

    /**
     * Set the MBeanServer
     *
     * @param mbs
     */
    public synchronized void setMBeanServer(MBeanServer mbs) {
        this.mbeanServer = mbs;
        if (this.mbeanServer != null
                && this.executorFactory != null
                && this.executorFactory instanceof org.apache.servicemix.executors.impl.ExecutorFactoryImpl) {
            ((org.apache.servicemix.executors.impl.ExecutorFactoryImpl) this.executorFactory).setMbeanServer(this.mbeanServer);
        }
    }

    /**
     * @return the naming context
     */
    public synchronized InitialContext getNamingContext() {
        return namingContext;
    }

    /**
     * Set the naming context
     *
     * @param ic
     */
    public synchronized void setNamingContext(InitialContext ic) {
        this.namingContext = ic;
    }

    /**
     * @return the TransactionManager for this implementation
     */
    public synchronized Object getTransactionManager() {
        if (transactionManager == null && namingContext != null) {
            try {
                transactionManager = (TransactionManager) namingContext.lookup("java:appserver/TransactionManager");
            } catch (NamingException e) {
                LOGGER.debug("No transaction manager found from naming context: {}", e.getMessage());
                try {
                    transactionManager = (TransactionManager) namingContext.lookup("javax.transaction.TransactionManager");
                } catch (NamingException e1) {
                    LOGGER.debug("No transaction manager found from naming context: {}", e1.getMessage());
                }
            }
        }
        return transactionManager;
    }

    /**
     * Set the transaction manager
     *
     * @param tm
     */
    public synchronized void setTransactionManager(Object tm) {
        this.transactionManager = (TransactionManager) tm;
    }

    /**
     * @return the root directory path
     */
    public synchronized String getRootDir() {
        if (rootDir == null) {
            if (isGenerateRootDir()) {
                rootDir = createRootDir();
            } else {
                rootDir = "." + File.separator + "rootDir";
            }
            LOGGER.debug("Defaulting to rootDir: {}", rootDir);
        }
        return this.rootDir;
    }


    /**
     * Set the workspace root
     *
     * @param root
     */
    public synchronized void setRootDir(String root) {
        this.rootDir = root;
    }

    /**
     * Route an ExchangePacket to a destination
     *
     * @param exchange
     * @throws MessagingException
     */
    public void sendExchange(MessageExchangeImpl exchange) throws MessagingException {
        try {
            broker.sendExchangePacket(exchange);
        } catch (MessagingException e) {
            throw e;
        } catch (JBIException e) {
            throw new MessagingException(e);
        }
    }

    /**
     * @param cns
     * @param externalEndpoint
     * @throws JBIException
     */
    public void registerExternalEndpoint(ComponentNameSpace cns, ServiceEndpoint externalEndpoint) throws JBIException {
        registry.registerExternalEndpoint(cns, externalEndpoint);
    }

    /**
     * @param cns
     * @param externalEndpoint
     * @throws JBIException
     */
    public void deregisterExternalEndpoint(ComponentNameSpace cns, ServiceEndpoint externalEndpoint) throws JBIException {
        registry.deregisterExternalEndpoint(cns, externalEndpoint);
    }

    /**
     * @param context
     * @param epr
     * @return matching endpoint or null
     */
    public ServiceEndpoint resolveEndpointReference(ComponentContextImpl context, DocumentFragment epr) {
        return registry.resolveEndpointReference(epr);
    }

    /**
     * @param context
     * @param service
     * @param endpointName
     * @return the matching endpoint
     */
    public ServiceEndpoint getEndpoint(ComponentContextImpl context, QName service, String endpointName) {
        return registry.getEndpoint(service, endpointName);
    }

    /**
     * @param context
     * @param interfaceName
     * @return endpoints that match the interface name
     */
    public ServiceEndpoint[] getEndpoints(ComponentContextImpl context, QName interfaceName) {
        return registry.getEndpointsForInterface(interfaceName);
    }

    /**
     * @param context
     * @param serviceName
     * @return endpoints for a given service
     */
    public ServiceEndpoint[] getEndpointsForService(ComponentContextImpl context, QName serviceName) {
        return registry.getEndpointsForService(serviceName);
    }

    /**
     * @param context
     * @param interfaceName
     * @return endpoints matching the interface name
     */
    public ServiceEndpoint[] getExternalEndpoints(ComponentContextImpl context, QName interfaceName) {
        return registry.getExternalEndpoints(interfaceName);
    }

    /**
     * @param context
     * @param serviceName
     * @return external endpoints
     */
    public ServiceEndpoint[] getExternalEndpointsForService(ComponentContextImpl context, QName serviceName) {
        return registry.getExternalEndpointsForService(serviceName);
    }

    /**
     * @param suffix
     * @param resourceBundleName
     * @return the Logger
     * @throws MissingResourceException
     * @throws JBIException
     */
    public java.util.logging.Logger getLogger(String suffix, String resourceBundleName) throws MissingResourceException, JBIException {
        try {
            return java.util.logging.Logger.getLogger(suffix, resourceBundleName);
        } catch (IllegalArgumentException e) {
            throw new JBIException("A LOGGER can not be created using resource bundle " + resourceBundleName);
        }
    }

    /**
     * Used for Simple POJO's
     *
     * @param componentName - the unique component ID
     * @throws JBIException
     */
    public void deactivateComponent(String componentName) throws JBIException {
        ComponentMBeanImpl component = registry.getComponent(componentName);
        if (component != null) {
            component.doShutDown();
            component.unregisterMbeans(managementContext);
            registry.deregisterComponent(component);
            environmentContext.unreregister(component);
            component.dispose();
            LOGGER.info("Deactivating component {}", componentName);
        } else {
            throw new JBIException("Could not find component " + componentName);
        }
    }

    /**
     * Delete a Component
     *
     * @param id
     * @throws JBIException
     */
    public void deleteComponent(String id) throws JBIException {
        deactivateComponent(id);
        environmentContext.removeComponentRootDirectory(id);
    }

    /**
     * Get the component associated with the given component ID
     *
     * @param componentName
     * @return the component
     */
    public ComponentMBeanImpl getComponent(String componentName) {
        return registry.getComponent(componentName);
    }

    /**
     * @return all local ComponentConnectors
     */
    public Collection getLocalComponentConnectors() {
        return registry.getComponents();
    }

    /**
     * Activates a new component
     *
     * @param activationSpec
     * @return Component
     * @throws JBIException
     */
    public Component activateComponent(ActivationSpec activationSpec) throws JBIException {
        if (activationSpec.getId() == null) {
            if (activationSpec.getComponentName() == null) {
                // lets generate one
                activationSpec.setId(createComponentID());
            } else {
                activationSpec.setId(activationSpec.getComponentName());
            }
        }
        String id = activationSpec.getId();
        if (id == null) {
            throw new IllegalArgumentException("A Registration must have an ID");
        }
        if (activationSpec.getEndpoint() == null && activationSpec.getService() != null) {
            // lets default to the ID
            activationSpec.setEndpoint(id);
        }
        if (activationSpec.getComponentName() == null) {
            activationSpec.setComponentName(id);
        }
        Object bean = activationSpec.getComponent();
        if (bean == null) {
            throw new IllegalArgumentException("A Registration must have a component associated with it");
        }
        if (bean instanceof Component) {
            Component component = (Component) bean;
            if (component instanceof ComponentSupport) {
                defaultComponentServiceAndEndpoint((ComponentSupport) component, activationSpec);
            }
            activateComponent(component, activationSpec);
            return component;
        } else if (bean instanceof ComponentLifeCycle) {
            // lets support just plain lifecycle pojos
            ComponentLifeCycle lifeCycle = (ComponentLifeCycle) bean;
            if (bean instanceof PojoSupport) {
                defaultComponentServiceAndEndpoint((PojoSupport) bean, activationSpec);
            }
            Component adaptor = createComponentAdaptor(lifeCycle, activationSpec);
            activateComponent(adaptor, activationSpec);
            return adaptor;
        } else if (bean instanceof MessageExchangeListener) {
            // lets support just plain listener pojos
            MessageExchangeListener listener = (MessageExchangeListener) bean;
            Component adaptor = createComponentAdaptor(listener, activationSpec);
            activateComponent(adaptor, activationSpec);
            return adaptor;
        } else {
            throw new IllegalArgumentException("Component name: " + id
                    + " is bound to an object which is not a JBI component, it is of type: " + bean.getClass().getName());
        }
    }

    /**
     * Activate a POJO Component
     *
     * @param component
     * @param componentName
     * @return the ObjectName of the MBean for the Component
     * @throws JBIException
     */
    public ObjectName activateComponent(Component component, String componentName) throws JBIException {
        ActivationSpec activationSpec = new ActivationSpec();
        ComponentNameSpace cns = new ComponentNameSpace(getName(), componentName);
        activationSpec.setComponent(component);
        activationSpec.setComponentName(cns.getName());
        return activateComponent(component, activationSpec);
    }

    /**
     * Activate A POJO Component
     *
     * @param component
     * @param activationSpec
     * @return the ObjectName of the MBean for the Component
     * @throws JBIException
     */
    public ObjectName activateComponent(Component component, ActivationSpec activationSpec) throws JBIException {
        return activateComponent(component, "POJO Component", activationSpec, true, false, false, null);
    }

    /**
     * Called by the Installer MBean
     *
     * @param installDir
     * @param component
     * @param description
     * @param context
     * @param binding
     * @param service
     * @return the ObjectName of the Component's MBean
     * @throws JBIException
     */
    public ObjectName activateComponent(File installDir, Component component, String description, ComponentContextImpl context,
                                        boolean binding, boolean service, String[] sharedLibraries) throws JBIException {
        ComponentNameSpace cns = context.getComponentNameSpace();
        ActivationSpec activationSpec = new ActivationSpec();
        activationSpec.setComponent(component);
        activationSpec.setComponentName(cns.getName());
        return activateComponent(installDir, component, description, context, activationSpec, false, binding, service, sharedLibraries);
    }

    /**
     * @param component
     * @param description
     * @param activationSpec
     * @param pojo
     * @param binding
     * @param service
     * @return the ObjectName of the Component's MBean
     * @throws JBIException
     */
    public ObjectName activateComponent(Component component, String description, ActivationSpec activationSpec, boolean pojo,
                                        boolean binding, boolean service, String[] sharedLibraries) throws JBIException {
        ComponentNameSpace cns = new ComponentNameSpace(getName(), activationSpec.getComponentName());
        if (registry.getComponent(cns) != null) {
            throw new JBIException("A component is already registered for " + cns);
        }
        ComponentContextImpl context = new ComponentContextImpl(this, cns);
        return activateComponent(new File("."), component, description, context, activationSpec, pojo, binding, service, sharedLibraries);
    }

    /**
     * @param installationDir
     * @param component
     * @param description
     * @param context
     * @param activationSpec
     * @param pojo
     * @param binding
     * @param service
     * @return the ObjectName of the Component's MBean
     * @throws JBIException
     */
    public ObjectName activateComponent(File installationDir, Component component,
                                        String description, ComponentContextImpl context,
                                        ActivationSpec activationSpec, boolean pojo,
                                        boolean binding, boolean service, String[] sharedLibraries) throws JBIException {
        ObjectName result = null;
        ComponentNameSpace cns = new ComponentNameSpace(getName(), activationSpec.getComponentName());
        LOGGER.info("Activating component {}", cns);
        ComponentMBeanImpl lcc = registry.registerComponent(cns, description, component, binding, service, sharedLibraries);
        if (lcc != null) {
            lcc.setPojo(pojo);
            ComponentEnvironment env = environmentContext.registerComponent(context.getEnvironment(), lcc);
            if (env.getInstallRoot() == null) {
                env.setInstallRoot(installationDir);
            }
            context.activate(component, env, activationSpec);
            lcc.setContext(context);
            lcc.setActivationSpec(activationSpec);

            if (lcc.isPojo()) {
                //non-pojo's are either started by the auto deployer
                //or manually
                lcc.init();
            } else {
                lcc.doShutDown();
            }
            result = lcc.registerMBeans(managementContext);
            // Start the component after mbeans have been registered
            // This can be usefull if listeners use them
            if (lcc.isPojo() && started.get()) {
                lcc.start();
            }
        }
        return result;
    }

    /**
     * Allow the service and endpoint name to be configured from the registration, to reduce the amount of XML which is
     * required to configure a ServiceMix component
     *
     * @param component
     * @param activationSpec
     */
    protected void defaultComponentServiceAndEndpoint(PojoSupport component, ActivationSpec activationSpec) {
        if (activationSpec.getService() != null) {
            component.setService(activationSpec.getService());
        }
        if (activationSpec.getEndpoint() != null) {
            component.setEndpoint(activationSpec.getEndpoint());
        }
    }

    protected ExecutorFactory createExecutorFactory() throws JBIException {
        return getExecutorFactory() != null ? getExecutorFactory() : new org.apache.servicemix.executors.impl.ExecutorFactoryImpl();
    }

    /**
     * Factory method to create a new component adaptor from the given lifecycle
     *
     * @param lifeCycle
     * @param activationSpec
     * @return Component
     */
    protected Component createComponentAdaptor(ComponentLifeCycle lifeCycle, ActivationSpec activationSpec) {
        ComponentAdaptor answer = null;
        if (lifeCycle instanceof MessageExchangeListener) {
            answer = new ComponentAdaptorMEListener(lifeCycle, activationSpec.getService(), activationSpec.getEndpoint(),
                    (MessageExchangeListener) lifeCycle);
        } else {
            answer = new ComponentAdaptor(lifeCycle, activationSpec.getService(), activationSpec.getEndpoint());
        }
        answer.setServiceManager(serviceManager);
        return answer;
    }

    protected Component createComponentAdaptor(MessageExchangeListener listener, ActivationSpec activationSpec) {
        ComponentLifeCycle lifecCycle = new PojoLifecycleAdaptor(listener, activationSpec.getService(), activationSpec.getEndpoint());
        return new ComponentAdaptorMEListener(lifecCycle, listener);
    }

    /**
     * Factory method to create a new component ID if none is specified
     *
     * @return uniqueId
     */
    protected String createComponentID() {
        return idGenerator.generateId();
    }

    protected void checkInitialized() throws JBIException {
        if (!containerInitialized.get()) {
            throw new JBIException("The Container is not initialized - please call init(...)");
        }
    }

    /**
     * Retrieve the value for automatic transaction enlistment.
     *
     * @return
     */
    public boolean isAutoEnlistInTransaction() {
        return autoEnlistInTransaction;
    }

    /**
     * Set the new value for automatic transaction enlistment.
     * When this parameter is set to <code>true</code> and a transaction
     * is running when sending / receiving an exchange, this operation will
     * automatically be done in the current transaction.
     *
     * @param autoEnlistInTransaction
     */
    public void setAutoEnlistInTransaction(boolean autoEnlistInTransaction) {
        this.autoEnlistInTransaction = autoEnlistInTransaction;
    }

    public boolean isPersistent() {
        return persistent;
    }

    /**
     * Set the new default value for exchange persistence.
     * This value will be the default if none is configured on
     * the activation spec of the component or on the message.
     *
     * @param persistent
     */
    public void setPersistent(boolean persistent) {
        this.persistent = persistent;
    }

    public void addListener(EventListener listener) {
        LOGGER.debug("Adding listener: {}", listener.getClass());
        if (listener instanceof ContainerAware) {
            ContainerAware containerAware = (ContainerAware) listener;
            containerAware.setContainer(this);
        }
        if (listener instanceof ExchangeListener) {
            listeners.add(ExchangeListener.class, (ExchangeListener) listener);
        }
        if (listener instanceof ComponentListener) {
            listeners.add(ComponentListener.class, (ComponentListener) listener);
        }
        if (listener instanceof ServiceAssemblyListener) {
            listeners.add(ServiceAssemblyListener.class, (ServiceAssemblyListener) listener);
        }
        if (listener instanceof ServiceUnitListener) {
            listeners.add(ServiceUnitListener.class, (ServiceUnitListener) listener);
        }
        if (listener instanceof EndpointListener) {
            listeners.add(EndpointListener.class, (EndpointListener) listener);
        }
        if (listener instanceof DeploymentListener) {
            listeners.add(DeploymentListener.class, (DeploymentListener) listener);
        }
    }

    public void removeListener(EventListener listener) {
        LOGGER.debug("Removing listener: {}", listener.getClass());
        if (listener instanceof ExchangeListener) {
            listeners.remove(ExchangeListener.class, (ExchangeListener) listener);
        }
        if (listener instanceof ComponentListener) {
            listeners.remove(ComponentListener.class, (ComponentListener) listener);
        }
        if (listener instanceof ServiceAssemblyListener) {
            listeners.remove(ServiceAssemblyListener.class, (ServiceAssemblyListener) listener);
        }
        if (listener instanceof ServiceUnitListener) {
            listeners.remove(ServiceUnitListener.class, (ServiceUnitListener) listener);
        }
        if (listener instanceof EndpointListener) {
            listeners.remove(EndpointListener.class, (EndpointListener) listener);
        }
        if (listener instanceof DeploymentListener) {
            listeners.remove(DeploymentListener.class, (DeploymentListener) listener);
        }
    }

    public Object[] getListeners(Class lc) {
        return listeners.getListeners(lc);
    }

    public void setListeners(EventListener[] listeners) {
        configuredListeners = listeners;
    }

    public void resendExchange(MessageExchange exchange) throws JBIException {
        if (!(exchange instanceof MessageExchangeImpl)) {
            throw new IllegalArgumentException("exchange should be a MessageExchangeImpl");
        }
        MessageExchangeImpl me = (MessageExchangeImpl) exchange;
        me.getPacket().setExchangeId(new IdGenerator().generateId());
        me.getPacket().setOut(null);
        me.getPacket().setFault(null);
        me.getPacket().setError(null);
        me.getPacket().setStatus(ExchangeStatus.ACTIVE);
        me.getPacket().setProperty(JbiConstants.DATESTAMP_PROPERTY_NAME, Calendar.getInstance());
        ExchangeListener[] l = (ExchangeListener[]) listeners.getListeners(ExchangeListener.class);
        ExchangeEvent event = new ExchangeEvent(me, ExchangeEvent.EXCHANGE_SENT);
        for (int i = 0; i < l.length; i++) {
            try {
                l[i].exchangeSent(event);
            } catch (Exception e) {
                LOGGER.warn("Error calling listener: {}", e.getMessage(), e);
            }
        }
        me.handleSend(false);
        sendExchange(me.getMirror());
    }

    public boolean isEmbedded() {
        return embedded;
    }

    public void setEmbedded(boolean embedded) {
        this.embedded = embedded;
    }

    public void setRmiPort(int portNum) {
        getManagementContext().setNamingPort(portNum);
    }

    public int getRmiPort() {
        return getManagementContext().getNamingPort();
    }

    /**
     * @return Returns the notifyStatistics.
     */
    public boolean isNotifyStatistics() {
        return notifyStatistics;
    }

    /**
     * @param notifyStatistics The notifyStatistics to set.
     */
    public void setNotifyStatistics(boolean notifyStatistics) {
        this.notifyStatistics = notifyStatistics;
    }

    /**
     * @return the executorFactory
     */
    public ExecutorFactory getExecutorFactory() {
        return executorFactory;
    }

    /**
     * @param executorFactory the executorFactory to set
     */
    public void setExecutorFactory(ExecutorFactory executorFactory) {
        this.executorFactory = executorFactory;
        if (this.executorFactory != null && this.executorFactory instanceof org.apache.servicemix.executors.impl.ExecutorFactoryImpl) {
            ((org.apache.servicemix.executors.impl.ExecutorFactoryImpl) this.executorFactory).setMbeanServer(getMBeanServer());
        }
    }


    /**
     * Creates a new rootDir
     */
    protected String createRootDir() {
        String prefix = getGeneratedRootDirPrefix();
        for (int i = 1; true; i++) {
            File file = new File(prefix + i);
            if (!file.exists()) {
                file.mkdirs();
                return file.getAbsolutePath();
            }
        }
    }

    public boolean isOptimizedDelivery() {
        return optimizedDelivery;
    }

    public void setOptimizedDelivery(boolean optimizedDelivery) {
        this.optimizedDelivery = optimizedDelivery;
    }

}
