Package org.cafesip.jiplet

Source Code of org.cafesip.jiplet.JipletContainer

/*
* Created on Nov 8, 2004
*
* Copyright 2005 CafeSip.org
*
* Licensed 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.cafesip.jiplet;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
import javax.management.ObjectName;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import org.cafesip.jiplet.config.jip.ContextMapping;
import org.cafesip.jiplet.config.jip.JipletContextMappings;
import org.cafesip.jiplet.config.jip.ObjectFactory;
import org.cafesip.jiplet.config.server.JipConnector;
import org.cafesip.jiplet.config.server.JipRealm;
import org.cafesip.jiplet.config.server.JipRealmParam;
import org.cafesip.jiplet.config.server.JipRealms;
import org.cafesip.jiplet.config.server.JipServer;
import org.cafesip.jiplet.jmxbeans.ConnectorElement;
import org.cafesip.jiplet.jmxbeans.ContextElement;
import org.cafesip.jiplet.jmxbeans.RealmElement;
import org.cafesip.jiplet.utils.FileUtils;
import org.xml.sax.InputSource;

/**
* This class represents the Jiplet Container. The jiplet container hosts
* multiple contexts. Each context is a separate application that has its own
* class loader and therefore completely isolated from each other. Each context
* may contain one or more jiplets. The container exposes a JMX management
* interface for managing the contexts. Using this interface, a context may be
* added or removed from the container. Alternatively, a container may be
* deployed by simply adding the content of the context to the deploy directory
* of the container and re-starting the jilet container application. Unlike most
* servlet container and J2EE server applications, the container does not
* periodically check its deploy directory to determine if a new context has
* been added.
*
* <p>
* The contexts may be deployed either in the "spr" format or in "exploded"
* format. The spr format consist of a single file that packs all the classes,
* data files and descriptors beloging to a context. The files are packed using
* the jar/zip utility. A custom ant task has been provided to zip the content
* of a context directory. A spr is equivalent to a "war" file in the
* servlet/JSP world.
*
* The jiplet container server application can either run as a Java standalone
* application similar to Apache Tomcat. But it can also be deployed as a JBOSS
* service (incidentally Tomcat can also be run as a JBOSS service). When
* running as a JBOSS service, it can be managed from the JBOSS management
* console and it also supports deployment of spr files using the JBOSS
* deployment infrastructure.
*
* @author Becky McElroy & Amit Chatterjee
*
*/
public class JipletContainer extends NotificationBroadcasterSupport implements
        JipletContainerMBean
{
    private static final int REALM_DEPLOYED = 0;

    private static final int REALM_J2EE = 1;

    private static JipletContainer instance = null;

    private static File deployDir;

    private static File confDir;

    private JipServer config;

    private HashMap connectors = new HashMap();

    private String defaultConnectorName;

    private HashMap deployedContexts = new HashMap();

    private static MBeanServer jmxAgent;

    private ArrayList realms = new ArrayList();

    private HashMap dirRealmsMap = new HashMap();

    // key = path, value=Realm object

    private HashMap realmsDirMap = new HashMap();

    // key= realm name, value = path

    public static ObjectName MBEAN_NAME = null;
    static
    {
        try
        {
            MBEAN_NAME = new ObjectName(
                    "org.cafesip.jiplet:type=JipletContainer");
        }
        catch (MalformedObjectNameException e)
        {
            // should not happen
        }
    }

    private long seqNum = 0;

    private String defaultRealm;

    private long authCachePeriod = 0L;

    private boolean authOnLogout = true;

    private JipletContextMappings contextMappings = null;

    private static VendorDescriptorFactory vendorDeploymentFactory = null;

    /**
     * Constructor for the class.
     */
    public JipletContainer() throws JipletException
    {
        if (instance != null)
        {
            throw new JipletException(
                    "Jiplet container is already instantiated. Use getInstance() instead");
        }
        instance = this;
    }

    public void init() throws Exception
    {
        JipletLogger.info("Jiplet container started");

        // parse the server.xml
        File serverxml = new File(confDir, "server.xml");
        FileInputStream istream = new FileInputStream(serverxml);
        config = (JipServer) JAXBContext.newInstance(
                "org.cafesip.jiplet.config.server",
                this.getClass().getClassLoader()).createUnmarshaller()
                .unmarshal(istream);
        istream.close();

        File mappingxml = new File(confDir, "mapping.xml");
        if (mappingxml.exists() == true)
        {
            istream = new FileInputStream(mappingxml);
            contextMappings = (JipletContextMappings) JAXBContext.newInstance(
                    "org.cafesip.jiplet.config.jip",
                    this.getClass().getClassLoader()).createUnmarshaller()
                    .unmarshal(istream);
            istream.close();
        }

        // initialize the SIP Connectors from server.xml
        initConfiguredSipConnectors();

        // initialize the realms from server.xml
        initRealms();

        // next, initialize the contexts present in the deploy
        // directory
        initContexts();

        // finally, initialize the JMX services
        initJmxServices();
    }

    private void initRealms() throws Exception
    {
        // first, configure the realms based on the server.xml config file.
        JipRealms realms = config.getRealms();
        if (realms == null)
        {
            return;
        }

        int cache_period = realms.getAuthCachePeriod().intValue();
        if (cache_period > 0)
        {
            authCachePeriod = cache_period * 1000L;
        }

        authOnLogout = realms.isAuthOnLogout();

        Iterator iter = realms.getRealm().iterator();
        while (iter.hasNext() == true)
        {
            JipRealm realm = (JipRealm) iter.next();
            startRealm(realm, null, null);
        }

        // next initiate the SRR realms based on the deployment directory
        if (deployDir.exists() == false)
        {
            return;
        }

        File[] files = deployDir.listFiles(new FilenameFilter()
        {
            public boolean accept(File dir, String name)
            {
                if ((name.equals(".") == true) || (name.equals("..") == true))
                {
                    return false;
                }

                File f = new File(dir, name);
                if (FileUtils.validDeployableRealmDir(f.getAbsolutePath()) == true)
                {
                    // if the srr exists, then return false because the srr will
                    // be found
                    File srr = new File(f.getAbsolutePath()
                            + FileUtils.SRR_EXTENSION);
                    if (FileUtils.validDeployableSrr(srr.getAbsolutePath()) == true)
                    {
                        return false;
                    }
                }
                else if (FileUtils.validDeployableSrr(f.getAbsolutePath()) == false)
                {
                    return false;
                }
                return true;
            }
        });

        for (int i = 0; i < files.length; i++)
        {
            String err = deployRealm(files[i].getAbsolutePath(),
                    REALM_DEPLOYED, null);
            if (err.length() > 0)
            {
                JipletLogger.error("Error deploying realm "
                        + files[i].getAbsolutePath() + ". Error message: "
                        + err);
                continue;
            }
        }
    }

    private void initJmxServices() throws InstanceAlreadyExistsException,
            MBeanRegistrationException, NotCompliantMBeanException
    {
        if (jmxAgent != null)
        {
            JipletLogger.info("Registering MBEAN JipletContainer");
            jmxAgent.registerMBean(this, MBEAN_NAME);
        }
        else
        {
            JipletLogger
                    .info("No JMX agent found. JMX services will not be initialized");
        }
    }

    private void initConfiguredSipConnectors() throws Exception
    {
        List list = config.getConnectors().getConnector();
        Iterator iter = list.iterator();
        while (iter.hasNext() == true)
        {
            JipConnector c = (JipConnector) iter.next();

            initSipConnector(c);
        }
    }

    private void initContexts()
    {
        if (deployDir.exists() == false)
        {
            return;
        }

        File[] files = deployDir.listFiles(new FilenameFilter()
        {
            public boolean accept(File dir, String name)
            {
                if ((name.equals(".") == true) || (name.equals("..") == true))
                {
                    return false;
                }

                File f = new File(dir, name);
                if (FileUtils.validDeployableJipletDir(f.getAbsolutePath()) == true)
                {
                    // if the spr exists, then return false because the spr will
                    // be found
                    File spr = new File(f.getAbsolutePath()
                            + FileUtils.SPR_EXTENSION);
                    if (FileUtils.validDeployableSpr(spr.getAbsolutePath()) == true)
                    {
                        return false;
                    }
                }
                else if (FileUtils.validDeployableSpr(f.getAbsolutePath()) == false)
                {
                    return false;
                }
                return true;
            }
        });

        for (int i = 0; i < files.length; i++)
        {
            String err = deployContext(files[i].getAbsolutePath(),
                    JipletContext.CONTEXT_DEPLOYED, null, null);
            if (err.length() > 0)
            {
                JipletLogger.error("Error deploying context "
                        + files[i].getAbsolutePath() + ". Error message: "
                        + err);
            }
        }
    }

    private void startContext(String name, String path, int type,
            ClassLoader loader) throws Exception
    {
        JipletLogger.info("Initializing context: " + name);
        JipletContext context = new JipletContext(name, new File(path), type,
                loader);
        context.init();

        synchronized (deployedContexts)
        {
            deployedContexts.put(name, context);
        }
    }

    /**
     * This method returns a context given its name.
     *
     * @param name
     *            name of the context.
     * @return the JipletContext object, null if the context is not found.
     */
    private JipletContext findContext(String name)
    {
        synchronized (deployedContexts)
        {
            return (JipletContext) deployedContexts.get(name);
        }
    }

    private void initSipConnector(JipConnector c) throws Exception
    {
        SipConnector sc = new SipConnector(c);
        sc.init(c);

        synchronized (connectors)
        {
            connectors.put(c.getName(), sc);
        }
        if (c.isDefault() == true)
        {
            if (JipletLogger.isDebugEnabled() == true)
            {
                JipletLogger.debug("Connector " + c.getName()
                        + " being set to default");
            }

            defaultConnectorName = c.getName();
        }
        else if (defaultConnectorName == null)
        {
            if (JipletLogger.isDebugEnabled() == true)
            {
                JipletLogger.debug("Connector " + c.getName()
                        + " being set to default");
            }
            defaultConnectorName = c.getName();
        }
    }

    /**
     * The JipletContainer is a singleton class. This static method is used to
     * get the instance of the class. If the class has not already been
     * instantiated, the class is instantiated inside this method and the
     * reference is returned.
     *
     * @return Returns the instance.
     */
    public static JipletContainer getInstance() throws Exception
    {
        if (instance == null)
        {
            new JipletContainer();
        }
        return instance;
    }

    /**
     * Sets the deploy directory. By default, the deploy directory is located
     * under the home directory of the container. However, an application
     * instantiating this class can set a different directory.
     *
     * @param dir
     */
    public static void setDeployDir(File dir)
    {
        deployDir = dir;
    }

    /**
     * Returns a list of the connectors. Each element of the returned HashMap
     * object contains a key-value pair. The key is the connector name and the
     * value is an object of type SipConnector.
     *
     * @see SipConnector for more details.
     *
     * @return Returns the connectors.
     */
    public HashMap getConnectors()
    {
        return connectors;
    }

    /**
     * @return Returns the defaultConnectorName.
     */
    public String getDefaultConnectorName()
    {
        return defaultConnectorName;
    }

    /**
     * Returns a SipConnector object of a given connector name.
     *
     * @param name
     *            name of the connector
     * @return a SipConnector object, null if the name does not match.
     */
    public SipConnector findConnector(String name)
    {
        synchronized (connectors)
        {
            return (SipConnector) connectors.get(name);
        }
    }

    /**
     * This method is called when the application disposes off the container.
     */
    public void destroy()
    {
        if (jmxAgent != null)
        {
            try
            {
                jmxAgent.unregisterMBean(MBEAN_NAME);
            }
            catch (Exception e)
            {
                JipletLogger
                        .error("Error occured while unregistering JipletContainer MBEAN: "
                                + e.getClass().getName()
                                + ": "
                                + e.getMessage()
                                + "\n"
                                + JipletLogger.getStackTrace(e));
            }
        }

        // first, shutdown all the contexts
        synchronized (deployedContexts)
        {
            Iterator iter = deployedContexts.entrySet().iterator();
            while (iter.hasNext() == true)
            {
                Map.Entry element = (Map.Entry) iter.next();
                JipletContext context = (JipletContext) element.getValue();

                JipletLogger.info("Destroying jiplet context: "
                        + (String) element.getKey());
                context.destroy();
                iter.remove();
            }
        }

        // next shutdown all the connectors
        synchronized (connectors)
        {
            Iterator iter = connectors.entrySet().iterator();
            while (iter.hasNext() == true)
            {
                Map.Entry element = (Map.Entry) iter.next();
                SipConnector connector = (SipConnector) element.getValue();

                JipletLogger.info("Destroying connector: "
                        + (String) element.getKey());
                connector.destroy();
                iter.remove();
            }
        }

        // next shutdown the realms
        synchronized (realms)
        {
            Iterator iter = realms.iterator();
            while (iter.hasNext() == true)
            {
                Realm realm = (Realm) iter.next();
                JipletLogger.info("Destroying realm " + realm.getRealmName());

                ClassLoader cl = Thread.currentThread().getContextClassLoader();

                try
                {
                    Thread.currentThread().setContextClassLoader(
                            realm.getClass().getClassLoader());
                    realm.destroy();
                }
                finally
                {
                    Thread.currentThread().setContextClassLoader(cl);
                }
                iter.remove();
            }
        }
    }

    private boolean deployDirExists(File deploy, String path)
    {
        try
        {
            File f = new File(path);

            if (deploy.exists() == false)
            {
                return false;
            }

            if (deploy.compareTo(f.getParentFile()) == 0)
            {
                return true;
            }
        }
        catch (Exception ex)
        {
            return false;
        }

        return false;
    }

    /*
     * @see
     * org.cafesip.jiplet.JipletContainerMBean#startContext(java.lang.String,
     * java.lang.String)
     */
    public String createContext(String path, String overriddenName)
    {
        JipletLogger
                .info("Received a request from JMX agent to add a context with path: "
                        + path
                        + ((overriddenName != null) ? (", name: " + overriddenName)
                                : ""));

        String err = deployContext(path, JipletContext.CONTEXT_DEPLOYED,
                overriddenName, null);

        if (err.length() > 0)
        {
            return err;
        }

        String name = FileUtils.parseContextNameFromSpr(new File(path));
        if (overriddenName != null)
        {
            name = overriddenName;
        }

        JipletLogger.info("Context " + name + " created based on JMX request");

        Notification n = new Notification("Container", this.getClass()
                .getName(), seqNum++, System.currentTimeMillis(), "Context: "
                + name + " added with path: " + path);
        sendNotification(n);
        return "";
    }

    private String deployContext(String path, int type, String overriddenName,
            ClassLoader loader)
    {
        String name = null;
        File f = new File(path);

        try
        {
            boolean internal = deployDirExists(deployDir, path);

            boolean spr = false;
            if (FileUtils.validDeployableSpr(path) == true)
            {
                if (overriddenName != null)
                {
                    if (internal == true)
                    {
                        // This is because when the system is re-started, the
                        // container will try to
                        // deploy the spr with the parsed name instead of the
                        // overridden name
                        return "This context with path " + path
                                + " is internal. The name cannot be overidden";
                    }

                    name = overriddenName;
                }
                else
                {
                    name = FileUtils.parseContextNameFromSpr(f);
                }
                spr = true;
            }
            else if (FileUtils.validDeployableJipletDir(path) == true)
            {
                name = f.getName();
                spr = false;
            }
            else
            {
                return "The context could not be created because the path does not have a valid signature";
            }

            if (findContext(name) != null)
            {
                return "The context could not be created because a context with the same name already exists";
            }

            FileUtils ant = new FileUtils();

            File exploded = new File(deployDir, name);

            boolean extr = false;
            if ((spr == true) || (internal == false))
            {
                if (FileUtils.validDeployableJipletDir(exploded
                        .getAbsolutePath()) == true)
                {
                    if (f.lastModified() > exploded.lastModified())
                    {
                        if (JipletLogger.isDebugEnabled() == true)
                        {
                            JipletLogger
                                    .info("Found older exploded context entry "
                                            + exploded.getAbsolutePath()
                                            + " while creating the context "
                                            + name + ". Deleting the directory");
                        }

                        ant.deleteDir(exploded.getAbsolutePath());
                        extr = true;
                    }
                }
                else
                {
                    if (exploded.isDirectory() == true)
                    {
                        ant.deleteDir(exploded.getAbsolutePath());
                    }
                    extr = true;
                }
            }

            if (extr == true)
            {
                if (spr == true)
                {
                    if (ant.extractSpr(f.getAbsolutePath(), deployDir
                            .getAbsolutePath(), name) == false)
                    {
                        JipletLogger.error("Error extracting context " + name
                                + " from the corresponding spr file");
                        return "The zipped context could not be extracted";
                    }
                }
                else
                // exploded
                {
                    if (ant.copy(path, deployDir.getAbsolutePath()) == false)
                    {
                        JipletLogger.error("Error copying exploded context "
                                + name + " file: " + path
                                + " to deploy directory");
                        return "The exploded context could not be copied to the deploy dir";
                    }
                }
            }

            startContext(name, exploded.getAbsolutePath(), type, loader);
        }
        catch (Exception ex)
        {
            JipletLogger.error("Error creating context: "
                    + ex.getClass().getName() + ": " + ex.getMessage() + "\n"
                    + JipletLogger.getStackTrace(ex));
            return "Context: " + name + " could not be created. Message: "
                    + ex.getMessage() + ". See log for details";
        }

        return "";
    }

    /*
     * @see
     * org.cafesip.jiplet.JipletContainerMBean#deleteContext(java.lang.String)
     */
    public String deleteContext(String name)
    {
        JipletLogger
                .info("Received a request from JMX agent to delete a context: "
                        + name);

        synchronized (deployedContexts)
        {
            JipletContext context = findContext(name);
            if (context == null)
            {
                return "The context " + name + " does not exist";
            }

            if (context.getContextType() == JipletContext.CONTEXT_J2EE)
            {
                return "The context " + name
                        + " is a J2EE-deployed context. It cannot be deleted";
            }

            context.destroy();

            if (JipletLogger.isDebugEnabled() == true)
            {
                JipletLogger.debug("Removing entry for context " + name
                        + " from deploy directory");
            }

            deployedContexts.remove(name);

            FileUtils ant = new FileUtils();
            File exploded = new File(deployDir, name);

            // if a spr file exists, delete the spr
            File spr_file = new File(deployDir, name + FileUtils.SPR_EXTENSION);

            // Delete the contexts so that the contexts wont be started during
            // server re-start
            if (spr_file.exists() == true)
            {
                JipletLogger.info("Deleting deployment spr file "
                        + spr_file.getAbsolutePath());

                if (spr_file.delete() == false)
                {
                    // this can happen in a windoze environment because the file
                    // may be in use
                    JipletLogger.error("The context spr file "
                            + spr_file.getAbsolutePath()
                            + ". could not be deleted.");
                }
            }

            JipletLogger.info("Deleting deployment directory "
                    + exploded.getAbsolutePath());
            if (ant.deleteDir(exploded.getAbsolutePath()) == false)
            {
                JipletLogger
                        .warn("The context  directory   "
                                + exploded.getAbsolutePath()
                                + ". Could not be deleted. We will try again during server restart");
                // this can happen in a windoze environment because the file may
                // be in use
                markContextAsDeleted(exploded);
            }
        }

        JipletLogger.info("Context " + name + " deleted based on JMX request");

        Notification n = new Notification("Container", this.getClass()
                .getName(), seqNum++, System.currentTimeMillis(), "Context: "
                + name + " deleted");
        sendNotification(n);

        return "";
    }

    private void markContextAsDeleted(File dir)
    {
        File jip = new File(dir, "JIP-INF/jip.xml");
        if (jip.exists() == true)
        {
            File rename = new File(jip.getAbsolutePath() + ".deleted");
            jip.renameTo(rename);
        }
    }

    /*
     * @see org.cafesip.jiplet.JipletContainerMBean#listContexts()
     */
    public String[] listContexts()
    {
        JipletLogger.info("Received a JMX request for listing contexts");
        synchronized (deployedContexts)
        {
            String[] ret = new String[deployedContexts.size()];
            deployedContexts.keySet().toArray(ret);
            return ret;
        }
    }

    /**
     * Returns the JMX MBeanServer object. Jiplet applications can call this
     * method to retrieve the MBeanServer object. This object can then be used
     * to provide management interface for the jiplet application.
     *
     * @return Returns the jmxAgent.
     */
    protected static MBeanServer getJmxAgent()
    {
        return jmxAgent;
    }

    /**
     * @param jmxAgent
     *            The jmxAgent to set.
     */
    public static void setJmxAgent(MBeanServer jmxAgent)
    {
        JipletContainer.jmxAgent = jmxAgent;
    }

    /*
     * @see org.cafesip.jiplet.JipletContainerMBean#getContextProperty()
     */
    public ContextElement getContextProperty(String name)
    {
        if (JipletLogger.isDebugEnabled() == true)
        {
            JipletLogger
                    .debug("Received a request from JMX agent to view the context: "
                            + name);
        }

        JipletContext context = findContext(name);
        if (context == null)
        {
            if (JipletLogger.isDebugEnabled() == true)
            {
                JipletLogger.debug("Context: " + name + " was not found");
            }
            return null;
        }

        ContextElement element = new ContextElement();
        ArrayList criteria = context.getContextSelectionCriteria();
        ArrayList scriteria = new ArrayList(criteria.size());

        for (int i = 0; i < criteria.size(); i++)
        {
            Pair p = (Pair) criteria.get(i);
            String connector = (String) p.getFirst();
            String exp = (String) p.getSecond();
            scriteria.add(connector + ":" + exp);
        }
        element.setSelectionCriteria(scriteria);
        element.setName(name);
        element.setDisplayName(context.getDisplayName());
        element.setPath(context.getContextRoot().getAbsolutePath());
        element.setTypeDescription(context.getContextTypeDescription());
        return element;
    }

    /*
     * @see org.cafesip.jiplet.JipletContainerMBean#getDeployDir()
     */
    public String getDeployDir()
    {
        return deployDir.getAbsolutePath();
    }

    /**
     * Create a J2EE context. The Jboss wrapper application for the jiplet
     * container uses this method to register spr files deployed in the JBOSS
     * deploy directory.
     *
     * @param path
     *            the path of the SPR file
     * @param loader
     *            - the J2EE classloader
     * @return
     */
    public String createJ2eeContext(String path, ClassLoader loader)
    {
        JipletLogger
                .info("Received a request from J2EE deployer to add a context  with path: "
                        + path);

        String err = deployContext(path, JipletContext.CONTEXT_J2EE, null,
                loader);

        if (err.length() > 0)
        {
            return err;
        }

        String name = FileUtils.parseContextNameFromSpr(new File(path));
        JipletLogger.info("Context " + name
                + " created based on J2EE deployer request");

        Notification n = new Notification("Container", this.getClass()
                .getName(), seqNum++, System.currentTimeMillis(), "Context: "
                + name + " added with path: " + path);
        sendNotification(n);
        return "";
    }

    /**
     * The JBOSS wrapper application uses this method to delete a context when
     * it has been removed from the JBOSS deploy directory.
     *
     * @param path
     * @return
     */
    public String deleteJ2eeContext(String path)
    {
        String name = null;
        File f = new File(path);
        if (path.endsWith(FileUtils.SPR_EXTENSION) == true)
        {
            name = FileUtils.parseContextNameFromSpr(f);
        }
        else
        {
            name = f.getName();
            File deploy = new File(deployDir, name);
            if (deploy.isDirectory() == false)
            {
                return "The context could not be removed because the deployment does not exist";
            }
        }

        JipletLogger
                .info("Received a request from the J2ee server to delete a context: "
                        + name);

        synchronized (deployedContexts)
        {
            JipletContext context = findContext(name);
            if (context == null)
            {
                return "The context " + name + " does not exist";
            }

            if (context.getContextType() != JipletContext.CONTEXT_J2EE)
            {
                return "The context "
                        + name
                        + " is not a J2EE-deployed context. It cannot be deleted";
            }

            context.destroy();
            deployedContexts.remove(name);
        }

        JipletLogger.info("Context " + name
                + " deleted based on J2EE deployer request");

        Notification n = new Notification("Container", this.getClass()
                .getName(), seqNum++, System.currentTimeMillis(), "Context: "
                + name + " deleted");
        sendNotification(n);

        return "";
    }

    /**
     * @return Returns the realms.
     */
    protected ArrayList getRealms()
    {
        return realms;
    }

    public Realm findRealm(String name)
    {
        synchronized (realms)
        {
            Iterator iter = realms.iterator();
            while (iter.hasNext() == true)
            {
                Realm r = (Realm) iter.next();
                String rname = null;
                ClassLoader cl = Thread.currentThread().getContextClassLoader();
                try
                {
                    Thread.currentThread().setContextClassLoader(
                            r.getClass().getClassLoader());
                    rname = r.getRealmName();
                }
                finally
                {
                    Thread.currentThread().setContextClassLoader(cl);
                }
                if (rname.equals(name) == true)
                {
                    return r;
                }
            }
        }

        return null;
    }

    /**
     * @return Returns the defaultRealm.
     */
    public String getDefaultRealm()
    {
        return defaultRealm;
    }

    /**
     * @return Returns the authCachePeriod.
     */
    protected long getAuthCachePeriod()
    {
        return authCachePeriod;
    }

    /*
     * @see org.cafesip.jiplet.JipletContainerMBean#listRealms()
     */
    public String[] listRealms()
    {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();

        JipletLogger.info("Received a JMX request for listing realms");
        String[] ret = null;
        synchronized (realms)
        {
            int size = realms.size();
            ret = new String[size];

            for (int i = 0; i < size; i++)
            {
                Realm realm = (Realm) realms.get(i);

                try
                {
                    Thread.currentThread().setContextClassLoader(
                            realm.getClass().getClassLoader());
                    ret[i] = realm.getRealmName();
                }
                finally
                {
                    Thread.currentThread().setContextClassLoader(cl);
                }
            }
        }
        return ret;
    }

    /*
     * @see
     * org.cafesip.jiplet.JipletContainerMBean#createRealmUser(java.lang.String,
     * java.lang.String, java.lang.String, java.lang.String[])
     */
    public String createRealmUser(String name, String user, String password,
            String[] roles)
    {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();

        JipletLogger.info("Received a JMX request for creating user " + user
                + " for domain " + name);
        synchronized (realms)
        {
            int size = realms.size();
            for (int i = 0; i < size; i++)
            {
                Realm realm = (Realm) realms.get(i);
                String realm_name = null;
                boolean supports_prov = false;

                try
                {
                    Thread.currentThread().setContextClassLoader(
                            realm.getClass().getClassLoader());
                    realm_name = realm.getRealmName();
                    supports_prov = realm.supportsProvisioning();
                }
                finally
                {
                    Thread.currentThread().setContextClassLoader(cl);
                }

                if (name.equals(realm_name) == true)
                {
                    if (supports_prov == false)
                    {
                        return "This realm does not support provisioning";
                    }

                    boolean ret;
                    try
                    {
                        Thread.currentThread().setContextClassLoader(
                                realm.getClass().getClassLoader());
                        ret = realm.addUser(user, password, roles);
                    }
                    finally
                    {
                        Thread.currentThread().setContextClassLoader(cl);
                    }

                    if (ret == false)
                    {
                        return "The user already exists";
                    }

                    Notification n = new Notification("Container", this
                            .getClass().getName(), seqNum++, System
                            .currentTimeMillis(), "Added user " + user
                            + " to realm  " + name);
                    sendNotification(n);
                    return "";
                }
            }

            return "The realm could not be found";
        }
    }

    /*
     * @see
     * org.cafesip.jiplet.JipletContainerMBean#modifyRealmUser(java.lang.String,
     * java.lang.String, java.lang.String, java.lang.String[])
     */
    public String modifyRealmUser(String name, String user, String password,
            String[] roles)
    {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();

        JipletLogger.info("Received a JMX request for modifying user " + user
                + " for domain " + name);
        synchronized (realms)
        {
            int size = realms.size();
            for (int i = 0; i < size; i++)
            {
                Realm realm = (Realm) realms.get(i);
                String realm_name = null;
                boolean supports_prov = false;

                try
                {
                    Thread.currentThread().setContextClassLoader(
                            realm.getClass().getClassLoader());
                    realm_name = realm.getRealmName();
                    supports_prov = realm.supportsProvisioning();
                }
                finally
                {
                    Thread.currentThread().setContextClassLoader(cl);
                }

                if (name.equals(realm_name) == true)
                {
                    if (supports_prov == false)
                    {
                        return "This realm does not support provisioning";
                    }

                    boolean ret;
                    try
                    {
                        Thread.currentThread().setContextClassLoader(
                                realm.getClass().getClassLoader());
                        ret = realm.modifyUser(user, password, roles);
                    }
                    finally
                    {
                        Thread.currentThread().setContextClassLoader(cl);
                    }

                    if (ret == false)
                    {
                        return "The user already exists";
                    }

                    if (ret == false)
                    {
                        return "The user could not be found";
                    }

                    Notification n = new Notification("Container", this
                            .getClass().getName(), seqNum++, System
                            .currentTimeMillis(), "Modified user " + user
                            + " belonging to realm  " + name);
                    sendNotification(n);
                    return "";
                }
            }
            return "The realm could not be found";
        }
    }

    /*
     * @see
     * org.cafesip.jiplet.JipletContainerMBean#deleteRealmUser(java.lang.String,
     * java.lang.String)
     */
    public String deleteRealmUser(String name, String user)
    {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();

        JipletLogger.info("Received a JMX request for deleting user " + user
                + " from domain " + name);
        synchronized (realms)
        {
            int size = realms.size();
            for (int i = 0; i < size; i++)
            {
                Realm realm = (Realm) realms.get(i);
                String realm_name = null;
                boolean supports_prov = false;

                try
                {
                    Thread.currentThread().setContextClassLoader(
                            realm.getClass().getClassLoader());
                    realm_name = realm.getRealmName();
                    supports_prov = realm.supportsProvisioning();
                }
                finally
                {
                    Thread.currentThread().setContextClassLoader(cl);
                }

                if (name.equals(realm_name) == true)
                {
                    if (supports_prov == false)
                    {
                        return "This realm does not support provisioning";
                    }

                    boolean ret;
                    try
                    {
                        Thread.currentThread().setContextClassLoader(
                                realm.getClass().getClassLoader());
                        ret = realm.deleteUser(user);
                    }
                    finally
                    {
                        Thread.currentThread().setContextClassLoader(cl);
                    }

                    if (ret == false)
                    {
                        return "The user does not exist";
                    }

                    Notification n = new Notification("Container", this
                            .getClass().getName(), seqNum++, System
                            .currentTimeMillis(), "User " + user
                            + " deleted from realm  " + name);
                    sendNotification(n);
                    return "";
                }
            }
            return "The realm could not be found";
        }
    }

    /*
     * @see
     * org.cafesip.jiplet.JipletContainerMBean#getRealmUser(java.lang.String,
     * java.lang.String)
     */
    public String[] getRealmUser(String name, String user)
    {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();

        synchronized (realms)
        {
            int size = realms.size();
            for (int i = 0; i < size; i++)
            {
                Realm realm = (Realm) realms.get(i);
                String realm_name = null;
                boolean supports_prov = false;

                try
                {
                    Thread.currentThread().setContextClassLoader(
                            realm.getClass().getClassLoader());
                    realm_name = realm.getRealmName();
                    supports_prov = realm.supportsProvisioning();
                }
                finally
                {
                    Thread.currentThread().setContextClassLoader(cl);
                }

                if (name.equals(realm_name) == true)
                {
                    if (supports_prov == false)
                    {
                        return null;
                    }

                    try
                    {
                        Thread.currentThread().setContextClassLoader(
                                realm.getClass().getClassLoader());
                        return realm.getRoles(user);
                    }
                    finally
                    {
                        Thread.currentThread().setContextClassLoader(cl);
                    }
                }
            }

            return null;
        }
    }

    protected boolean isAuthOnLogout()
    {
        return authOnLogout;
    }

    private String deployRealm(String path, int type, ClassLoader cl)
    {
        File f = new File(path);
        String name = null;

        try
        {
            boolean srr = false;
            if (FileUtils.validDeployableSrr(path))
            {
                srr = true;
                name = FileUtils.parseRealmDirNameFromSrr(f);
            }
            else if (FileUtils.validDeployableRealmDir(path))
            {
                srr = false;
                name = f.getName();
            }
            else
            {
                return "The realm could not be created because the path does not have a valid signature";
            }

            FileUtils ant = new FileUtils();
            File exploded = new File(deployDir, name);

            boolean extr = false;
            if (srr)
            {
                if (FileUtils.validDeployableRealmDir(exploded
                        .getAbsolutePath()))
                {
                    if (f.lastModified() > exploded.lastModified())
                    {
                        if (JipletLogger.isDebugEnabled())
                        {
                            JipletLogger
                                    .info("Found older exploded realm entry "
                                            + exploded.getAbsolutePath()
                                            + " while creating the realm on directory "
                                            + name + ". Deleting the directory");
                        }

                        ant.deleteDir(exploded.getAbsolutePath());
                        extr = true;
                    }
                }
                else
                {
                    if (exploded.isDirectory())
                    {
                        ant.deleteDir(exploded.getAbsolutePath());
                    }
                    extr = true;
                }
            }

            // new code
            boolean internal = deployDirExists(deployDir, path);
            if (srr || !internal)
            {
                if (FileUtils.validDeployableRealmDir(exploded
                        .getAbsolutePath()))
                {
                    if (f.lastModified() > exploded.lastModified())
                    {
                        if (JipletLogger.isDebugEnabled())
                        {
                            JipletLogger
                                    .info("Found older exploded context entry "
                                            + exploded.getAbsolutePath()
                                            + " while creating the realm "
                                            + name + ". Deleting the directory");
                        }

                        ant.deleteDir(exploded.getAbsolutePath());
                        extr = true;
                    }
                }
                else
                {
                    if (exploded.isDirectory())
                    {
                        ant.deleteDir(exploded.getAbsolutePath());
                    }
                    extr = true;
                }
            }
            // new code ends

            if (extr)
            {
                if (srr)
                {
                    if (!ant.extractSpr(f.getAbsolutePath(), deployDir
                            .getAbsolutePath(), name))
                    {
                        JipletLogger
                                .error("Error extracting realm with directory "
                                        + name
                                        + " from the corresponding srr file");
                        return "The zipped context could not be extracted";
                    }
                }
                else
                // exploded
                {
                    if (!ant.copy(path, deployDir.getAbsolutePath()))
                    {
                        JipletLogger.error("Error copying exploded realm "
                                + name + " file: " + path
                                + " to deploy directory");
                        return "The exploded realm could not be copied to the deploy dir";
                    }
                }
            }

            File realmxml = new File(exploded, "META-INF/realm.xml");
            FileInputStream istream = new FileInputStream(realmxml);
            JipRealm realm = (JipRealm) JAXBContext.newInstance(
                    "org.cafesip.jiplet.config.server",
                    this.getClass().getClassLoader()).createUnmarshaller()
                    .unmarshal(istream);
            istream.close();

            if (findRealm(realm.getName()) != null)
            {
                return "The realm could not be created because a realm with the same name already exists";
            }

            // create a classloader for this realm

            // add the classes directory
            File c = new File(exploded, "classes");
            if (!c.isDirectory())
            {
                // does not exist or is not a directory
                c = null;
            }

            // next, add all the jars under the lib directory
            File j = new File(exploded, "lib");
            if (!j.isDirectory())
            {
                j = null;
            }

            ClassLoader pcl = getClass().getClassLoader();
            if (cl != null)
            {
                pcl = cl;
            }

            ClassLoader loader = JipletClassLoader.getClassLoader(pcl, c, j);

            startRealm(realm, loader, exploded.getAbsolutePath());
        }
        catch (Exception e)
        {
            JipletLogger.error("Error creating realm: "
                    + e.getClass().getName() + ": " + e.getMessage() + "\n"
                    + JipletLogger.getStackTrace(e));
            return "Realm: " + name + " could not be created. Message: "
                    + e.getMessage() + ". See log for details";
        }

        return "";
    }

    private void startRealm(JipRealm realm, ClassLoader loader,
            String deployPath) throws Exception
    {
        Iterator i = realm.getRealmParams().getRealmParam().iterator();
        HashMap map = new HashMap();
        while (i.hasNext() == true)
        {
            JipRealmParam param = (JipRealmParam) i.next();
            map.put(param.getRealmParamName(), param.getRealmParamValue());
        }

        if (loader == null)
        {
            loader = this.getClass().getClassLoader();
        }

        Class cl = Class.forName(realm.getClassname(), true, loader);
        Class[] interfaces = cl.getInterfaces();
        boolean found = false;
        for (int j = 0; j < interfaces.length; j++)
        {
            if (interfaces[j].equals(Realm.class) == true)
            {
                found = true;
                break;
            }
        }

        if (found == false)
        {
            throw new JipletException("Realm " + realm.getName()
                    + " does not implement the interface "
                    + Realm.class.getName());
        }

        Realm r = null;
        ClassLoader tcl = Thread.currentThread().getContextClassLoader();
        try
        {
            Thread.currentThread().setContextClassLoader(loader);
            r = (Realm) cl.newInstance();
            r.init(realm.getName(), confDir, map, realm.isDefault());
        }
        finally
        {
            Thread.currentThread().setContextClassLoader(tcl);
        }
        JipletLogger.info("Realm " + realm.getName() + " started");

        if (realm.isDefault() == true)
        {
            defaultRealm = realm.getName();
        }

        if (defaultRealm == null)
        {
            defaultRealm = realm.getName();
        }

        synchronized (this.realms)
        {
            this.realms.add(r);
        }

        if (deployPath != null)
        {
            synchronized (dirRealmsMap)
            {
                dirRealmsMap.put(deployPath, r);
                realmsDirMap.put(r.getRealmName(), deployPath);
            }
        }
    }

    /**
     * Create a J2EE realm. The Jboss wrapper application for the jiplet
     * container uses this method to register srr files deployed in the JBOSS
     * deploy directory.
     *
     * @param path
     * @param loader
     * @return
     */
    public String createJ2eeRealm(String path, ClassLoader loader)
    {
        JipletLogger
                .info("Received a request from J2EE deployer to add a realm  with path: "
                        + path);

        String err = deployRealm(path, REALM_J2EE, loader);

        if (err.length() > 0)
        {
            JipletLogger.error("Error creating J2EE realm: " + err);
            return err;
        }

        String name = FileUtils.parseRealmDirNameFromSrr(new File(path));
        JipletLogger.info("Realm " + name
                + " created based on J2EE deployer request");

        Notification n = new Notification("Container", this.getClass()
                .getName(), seqNum++, System.currentTimeMillis(), "Realm: "
                + name + " added with path: " + path);
        sendNotification(n);
        return "";
    }

    /**
     * The JBOSS wrapper application uses this method to delete a realm when it
     * has been removed from the JBOSS deploy directory.
     *
     * @param path
     * @return
     */
    public String deleteJ2eeRealm(String path)
    {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        String name = null;
        File f = new File(path);
        if (path.endsWith(FileUtils.SRR_EXTENSION) == true)
        {
            name = FileUtils.parseRealmDirNameFromSrr(f);
        }
        else
        {
            name = f.getName();
        }

        File deploy = new File(deployDir, name);
        if (deploy.isDirectory() == false)
        {
            return "The realm could not be remove because the deployment does not exist";
        }

        JipletLogger
                .info("Received a request from the J2EE server to delete a realm with directory name: "
                        + name);

        Realm realm = null;
        synchronized (dirRealmsMap)
        {
            realm = (Realm) dirRealmsMap.get(deploy.getAbsolutePath());
            if (realm == null)
            {
                return "The realm with deployment directory "
                        + deployDir.getAbsolutePath()
                        + " does not have an entry in the realms map. Aborting.";
            }

            synchronized (deployedContexts)
            {
                Iterator i = deployedContexts.entrySet().iterator();
                while (i.hasNext() == true)
                {
                    Map.Entry entry = (Map.Entry) i.next();
                    JipletContext context = (JipletContext) entry.getValue();
                    context.getSecurityManager().removeRealm(realm);
                }
            }

            String realm_name = null;
            try
            {
                Thread.currentThread().setContextClassLoader(
                        realm.getClass().getClassLoader());
                realm_name = realm.getRealmName();
            }
            finally
            {
                Thread.currentThread().setContextClassLoader(cl);
            }

            dirRealmsMap.remove(deploy.getAbsolutePath());
            realmsDirMap.remove(realm_name);

            synchronized (realms)
            {
                realms.remove(realm);
            }

            // tell the realm to clean up
            try
            {
                Thread.currentThread().setContextClassLoader(
                        realm.getClass().getClassLoader());
                realm.destroy();
            }
            finally
            {
                Thread.currentThread().setContextClassLoader(cl);
            }
        }

        JipletLogger.info("Realm  " + realm.getRealmName()
                + " deleted based on J2EE deployer request");

        Notification n = new Notification("Container", this.getClass()
                .getName(), seqNum++, System.currentTimeMillis(), "Realm: "
                + realm.getRealmName() + " deleted");
        sendNotification(n);

        return "";
    }

    /*
     * @see
     * org.cafesip.jiplet.JipletContainerMBean#createRealm(java.lang.String)
     */
    public String createRealm(String path)
    {
        JipletLogger
                .info("Received a request from the JMX agent to add a realm with path: "
                        + path);

        String err = deployRealm(path, REALM_DEPLOYED, null);

        if (err.length() > 0)
        {
            return err;
        }

        String name = FileUtils.parseContextNameFromSpr(new File(path));

        JipletLogger.info("Realm with directory " + name
                + " created based on JMX request");

        Notification n = new Notification("Container", this.getClass()
                .getName(), seqNum++, System.currentTimeMillis(),
                "Context with directory name: " + name + " added with path: "
                        + path);
        sendNotification(n);
        return "";
    }

    /*
     * @see
     * org.cafesip.jiplet.JipletContainerMBean#deleteRealm(java.lang.String)
     */
    public String deleteRealm(String realmName)
    {
        JipletLogger
                .info("Received a request from the JMX agent to delete a realm with name: "
                        + realmName);

        synchronized (dirRealmsMap)
        {
            String path = (String) realmsDirMap.get(realmName);
            if (path == null)
            {
                return "The path was not found for the given realm name."
                        + " Either the realm does not exist or the realm is not a deployed realm (is a part of the server.xml)";
            }

            Realm realm = (Realm) dirRealmsMap.get(path);
            if (realm == null)
            {
                return "The realm " + realmName
                        + " could not be mapped to a realm object. Aborting.";
            }

            synchronized (deployedContexts)
            {
                Iterator i = deployedContexts.entrySet().iterator();
                while (i.hasNext() == true)
                {
                    Map.Entry entry = (Map.Entry) i.next();
                    JipletContext context = (JipletContext) entry.getValue();
                    context.getSecurityManager().removeRealm(realm);
                }
            }

            dirRealmsMap.remove(path);
            realmsDirMap.remove(realmName);

            synchronized (realms)
            {
                realms.remove(realm);
            }

            // tell the realm to clean up
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            try
            {
                Thread.currentThread().setContextClassLoader(
                        realm.getClass().getClassLoader());
                realm.destroy();
            }
            finally
            {
                Thread.currentThread().setContextClassLoader(cl);
            }
            // remove the directories and files
            File spr_file = new File(path + FileUtils.SPR_EXTENSION);
            if (spr_file.exists() == true)
            {
                if (spr_file.delete() == false)
                {
                    JipletLogger
                            .error("While deleting realm "
                                    + realmName
                                    + ", the realm file "
                                    + spr_file.getAbsolutePath()
                                    + " could not be deleted. On re-start, the realm will get started up.");
                }
            }

            FileUtils futils = new FileUtils();
            if (futils.deleteDir(path) == false)
            {
                JipletLogger.warn("While deleting realm " + realmName
                        + ", the realm directory " + path
                        + " could not be deleted.");

                // mess up the deployment descriptor name so that it does not
                // get recorgnized
                // as a valid srr deployment during startup.
                File realmxml = new File(path, "META-INF/realm.xml");
                File mess_name = new File(path, "META-INF/realm.xml.deleted");
                if (realmxml.renameTo(mess_name) == false)
                {
                    JipletLogger
                            .error("While deleting realm "
                                    + realmName
                                    + ", the realm directory "
                                    + path
                                    + " could not be mangled. On re-start, the realm will get started up.");
                }
            }
        }

        JipletLogger.info("Realm  " + realmName
                + " deleted based on JMX request");

        Notification n = new Notification("Container", this.getClass()
                .getName(), seqNum++, System.currentTimeMillis(), "Realm: "
                + realmName + " deleted");
        sendNotification(n);
        return "";
    }

    /*
     * @see
     * org.cafesip.jiplet.JipletContainerMBean#getRealmDirName(java.lang.String)
     */
    public String getRealmDirName(String realmName)
    {
        synchronized (dirRealmsMap)
        {
            String path = (String) realmsDirMap.get(realmName);
            if (path == null)
            {
                return null;
            }

            File f = new File(path);
            return f.getName();
        }
    }

    /*
     * @see
     * org.cafesip.jiplet.JipletContainerMBean#getRealmProperty(java.lang.String
     * )
     */
    public RealmElement getRealmProperty(String realmName)
    {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        synchronized (realms)
        {
            Iterator i = realms.iterator();
            while (i.hasNext() == true)
            {
                Realm realm = (Realm) i.next();

                String rname = null;
                try
                {
                    Thread.currentThread().setContextClassLoader(
                            realm.getClass().getClassLoader());
                    rname = realm.getRealmName();
                }
                finally
                {
                    Thread.currentThread().setContextClassLoader(cl);
                }

                if (rname.equals(realmName) == true)
                {
                    RealmElement element = new RealmElement();
                    element.setName(realmName);
                    element.setDefaultRealm(realm.isDefaultRealm());
                    element.setParams(realm.getParams());
                    element.setDeployDir((String) realmsDirMap.get(realmName));
                    return element;
                }
            }
        }
        return null;
    }

    protected ArrayList getContextMapping(String context)
    {
        ArrayList list = new ArrayList();
        if (contextMappings == null)
        {
            return list;
        }

        Iterator i = contextMappings.getContextMapping().iterator();
        while (i.hasNext() == true)
        {
            ContextMapping cmap = (ContextMapping) i.next();
            if (cmap.getContext().equals(context) == true)
            {
                list.add(cmap);
            }
        }
        return list;
    }

    /*
     * @see
     * org.cafesip.jiplet.JipletContainerMBean#addContextMapping(java.lang.String
     * )
     */
    public String addContextMapping(String context, String mapping)
    {
        try
        {
            ObjectFactory factory = new ObjectFactory();

            if (contextMappings == null)
            {
                contextMappings = factory.createContextMappings();
            }

            synchronized (contextMappings)
            {
                // next, unmarshall the mapping object
                JipletContextMappings rmappings = (JipletContextMappings) JAXBContext
                        .newInstance("org.cafesip.jiplet.config.jip",
                                this.getClass().getClassLoader())
                        .createUnmarshaller().unmarshal(
                                new InputSource(new StringReader(mapping)));

                // next remove any references to the context left from earlier
                // deployment
                Iterator i = contextMappings.getContextMapping().iterator();
                while (i.hasNext() == true)
                {
                    ContextMapping cmap = (ContextMapping) i.next();
                    if (cmap.getContext().equals(context) == true)
                    {
                        i.remove();
                    }
                }

                // copy the received map object into the cloned map object
                i = rmappings.getContextMapping().iterator();
                while (i.hasNext() == true)
                {
                    ContextMapping m = (ContextMapping) i.next();
                    contextMappings.getContextMapping().add(m);
                }

                // everything looks good. Marshall the content to the
                // mapping.xml file.
                saveMappingXml();
            }

            return "";
        }
        catch (Exception e)
        {
            JipletLogger.error("Exception " + e.getClass().getName()
                    + " occured while adding context mapping: "
                    + e.getMessage() + "\n" + JipletLogger.getStackTrace(e));
            return e.getClass().getName()
                    + " occured while adding context mapping: "
                    + e.getMessage();
        }
    }

    /*
     * @see
     * org.cafesip.jiplet.JipletContainerMBean#removeContextMapping(java.lang
     * .String)
     */
    public String removeContextMapping(String context)
    {
        try
        {
            if (contextMappings == null)
            {
                return "";
            }

            boolean removed = false;
            synchronized (contextMappings)
            {
                Iterator i = contextMappings.getContextMapping().iterator();
                while (i.hasNext() == true)
                {
                    ContextMapping cmap = (ContextMapping) i.next();
                    if (cmap.getContext().equals(context) == true)
                    {
                        i.remove();
                        removed = true;
                    }
                }
            }

            if (removed == true)
            {
                // everything looks good. Marshall the content to the
                // mapping.xml file.
                saveMappingXml();
            }

            return "";
        }
        catch (Exception e)
        {
            JipletLogger.error("Exception " + e.getClass().getName()
                    + " occured while removing context mapping: "
                    + e.getMessage() + "\n" + JipletLogger.getStackTrace(e));
            return e.getClass().getName()
                    + " occured while removing context mapping: "
                    + e.getMessage();
        }
    }

    private void saveMappingXml() throws JAXBException, IOException
    {
        File f = new File(confDir, "mapping.xml");
        FileOutputStream os = new FileOutputStream(f);
        Marshaller m = JAXBContext.newInstance("org.cafesip.jiplet.config.jip",
                this.getClass().getClassLoader()).createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true));
        m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,
                "context-mappings_2.0.xsd");
        m.marshal(contextMappings, os);
        os.close();
    }

    /*
     * @see org.cafesip.jiplet.JipletContainerMBean#listConnectors()
     */
    public String[] listConnectors()
    {
        JipletLogger.info("Received a JMX request for listing connectors");
        ArrayList list = new ArrayList();
        synchronized (connectors)
        {
            Iterator i = connectors.keySet().iterator();
            while (i.hasNext() == true)
            {
                String name = (String) i.next();
                list.add(name);
            }

            String[] ret = new String[list.size()];
            list.toArray(ret);
            return ret;
        }
    }

    /*
     * @see
     * org.cafesip.jiplet.JipletContainerMBean#getConnectorProperty(java.lang
     * .String)
     */
    public ConnectorElement getConnectorProperty(String connectorName)
    {
        JipletLogger
                .info("Received a JMX request for getting connector property for "
                        + connectorName);
        synchronized (connectors)
        {
            SipConnector connector = (SipConnector) connectors
                    .get(connectorName);
            if (connector == null)
            {
                return null;
            }

            ConnectorElement element = new ConnectorElement();
            element.setName(connectorName);
            element.setDefaultConnector(defaultConnectorName
                    .equals(connectorName));
            element.setPorts(connector.getPortInfo());
            element.setStack(connector.getStackImpl());
            element.setProperties(connector.getProperties());
            element.setMaxThreads(connector.getMaxThreadCount());
            element.setMinThreads(connector.getMinThreadCount());
            return element;
        }
    }

    /**
     * @return Returns the confDir.
     */
    public static File getConfDir()
    {
        return confDir;
    }

    /**
     * @param confDir
     *            The confDir to set.
     */
    public static void setConfDir(File confDir)
    {
        JipletContainer.confDir = confDir;
    }

    /**
     * @return Returns the vendorDeploymentFactory.
     */
    public static VendorDescriptorFactory getVendorDeploymentFactory()
    {
        return vendorDeploymentFactory;
    }

    /**
     * @param vendorDeploymentFactory
     *            The vendorDeploymentFactory to set.
     */
    public static void setVendorDeploymentFactory(
            VendorDescriptorFactory vendorDeploymentFactory)
    {
        JipletContainer.vendorDeploymentFactory = vendorDeploymentFactory;
    }
}
TOP

Related Classes of org.cafesip.jiplet.JipletContainer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.