/**
 * JBoss, the OpenSource J2EE webOS
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.deployment.spi.factories;

import org.jboss.deployment.spi.DeploymentManagerImpl;
import org.jboss.logging.Logger;

import javax.enterprise.deploy.spi.DeploymentManager;
import javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException;
import javax.enterprise.deploy.spi.factories.DeploymentFactory;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;

// $Id: DeploymentFactoryImpl.java,v 1.1.1.1.4.1 2005/04/08 18:26:47 tdiesler Exp $

/**
 * The DeploymentFactory interface is a deployment driver for a J2EE plaform product.
 * It returns a DeploymentManager object which represents a connection to a specific J2EE platform product.
 * 
 * @author thomas.diesler@jboss.org
 * @author Scott.Stark@jboss.com
 * @version $Revision: 1.1.1.1.4.1 $
 */
public class DeploymentFactoryImpl implements DeploymentFactory
{
   // deployment logging
   private static final Logger log = Logger.getLogger(DeploymentFactoryImpl.class);

   // The name of the JBoss DeploymentFactory
   private static String DISPLAY_NAME;
   // The product version
   private static String PRODUCT_VERSION;

   /* Obtain the display name and version from the Package object for
      org.jboss.deploy.spi.factories
    */
   static
   {
      Package pkg = Package.getPackage("org.jboss.deploy.spi.factories");
      if (pkg != null)
      {
         DISPLAY_NAME = pkg.getImplementationVendor();
         PRODUCT_VERSION = pkg.getImplementationVersion();
      }
      if (DISPLAY_NAME == null || PRODUCT_VERSION == null)
      {
         DISPLAY_NAME = "DeploymentFactoryImpl";
         PRODUCT_VERSION = "1.1";
      }
   }

   /**
    * Look for jboss-deployer:.... URIs. Returns true if uri is has a
    * scheme of jboss-deployer, false otherwise.
    *
    * @param uri the uri
    * @return true for jboss-deployer schemes, false otherwise.
    */
   public boolean handlesURI(String uri)
   {
      boolean handlesURI = false;
      try
      {
         URI deployURI = parseURI(uri);
         String scheme = deployURI.getScheme();
         if (scheme.equals(DeploymentManagerImpl.DEPLOYER_SCHEME))
            handlesURI = true;
      }
      catch (URISyntaxException e)
      {
         log.warn("Failed to parse uri: " + uri, e);
      }

      log.debug("handlesURI [" + uri + "]: " + handlesURI);
      return handlesURI;
   }

   /**
    * Get a connected deployment manager
    * 
    * @param uri      the uri of the deployment manager
    * @param userName the user name
    * @param password the password
    * @return the deployment manager
    * @throws javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException
    *          
    */
   public DeploymentManager getDeploymentManager(String uri, String userName, String password)
           throws DeploymentManagerCreationException
   {
      log.debug("getDeploymentManager (uri=" + uri + ")");

      if (handlesURI(uri) == false)
         throw new DeploymentManagerCreationException("Cannot handle URI: " + uri);

      DeploymentManager mgr = null;
      try
      {
         URI deployURI = parseURI(uri);
         mgr = new DeploymentManagerImpl(deployURI, true, userName, password);
      }
      catch (URISyntaxException e)
      {
         DeploymentManagerCreationException ex =
                 new DeploymentManagerCreationException("Failed to create DeploymentManagerImpl");
         ex.initCause(e);
         throw ex;
      }
      return mgr;
   }

   /**
    * Get a disconnected version of the deployment manager
    * 
    * @param uri the uri to connect to
    * @return the disconnected deployment manager
    * @throws javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException
    *          
    */
   public DeploymentManager getDisconnectedDeploymentManager(String uri)
           throws DeploymentManagerCreationException
   {
      log.debug("getDisconnectedDeploymentManager (uri=" + uri + ")");

      if (handlesURI(uri) == false)
         throw new DeploymentManagerCreationException("Cannot handle URI: " + uri);

      DeploymentManager mgr = null;
      try
      {
         URI deployURI = parseURI(uri);
         mgr = new DeploymentManagerImpl(deployURI, false);
      }
      catch (URISyntaxException e)
      {
         DeploymentManagerCreationException ex =
                 new DeploymentManagerCreationException("Failed to create DeploymentManagerImpl");
         ex.initCause(e);
         throw ex;
      }
      return mgr;
   }

   /**
    * The name of the JBoss DeploymentFactory.
    * 
    * @return the vendor name
    */
   public String getDisplayName()
   {
      return DISPLAY_NAME;
   }

   /**
    * The version of the deployment manager
    * 
    * @return the version
    */
   public String getProductVersion()
   {
      return PRODUCT_VERSION;
   }

   private URI parseURI(String uri) throws URISyntaxException
   {
      URI deployURI;
      try
      {
         if (uri.equals(DeploymentManagerImpl.DEPLOYER_SCHEME))
            deployURI = new URI(uri + "://" + InetAddress.getLocalHost().getHostName());
         else
            deployURI = new URI(uri);
      }
      catch (UnknownHostException e)
      {
         throw new URISyntaxException(uri, e.toString());
      }

      return deployURI;
   }
}