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

import org.jboss.logging.Logger;
import org.jboss.xb.binding.ObjectModelFactory;
import org.jboss.xb.binding.UnmarshallingContext;
import org.xml.sax.Attributes;

/**
 * Represents the jboss.xml deployment descriptor for the 2.1 schema
 *
 * @author <a href="mailto:bdecoste@jboss.com">William DeCoste</a>
 * @version <tt>$Revision: 1.5.2.5 $</tt>
 */
public class JBossDDObjectFactory implements ObjectModelFactory
{
   private static final Logger log = Logger
           .getLogger(JBossDDObjectFactory.class);

   private EjbJarDD dd;

   public JBossDDObjectFactory(EjbJarDD dd)
   {
      super();
      this.dd = dd;
   }

   /**
    * Return the root.
    */
   public Object newRoot(Object root, UnmarshallingContext navigator,
                         String namespaceURI, String localName, Attributes attrs)
   {
      return dd;
   }

   public Object completeRoot(Object root, UnmarshallingContext ctx,
                              String uri, String name)
   {
      return root;
   }

   // Methods discovered by introspection

   /**
    * Called when parsing of a new element started.
    */
   public Object newChild(EjbJarDD dd, UnmarshallingContext navigator,
                          String namespaceURI, String localName, Attributes attrs)
   {
      Object child = null;

      if (localName.equals("enterprise-beans"))
      {
         child = dd.getEnterpriseBeans();
      }
      else if (localName.equals("loader-repository"))
      {
         child = new LoaderRepository();
         for (int i = 0; i < attrs.getLength(); ++i)
         {
            if (attrs.getLocalName(i).equals("loaderRepositoryClass"))
               ((LoaderRepository) child).setLoaderRepositoryClass(attrs.getValue(i));
         }
      } 
      else if (localName.equals("invoker-proxy-bindings"))
      {
         child = dd;
      }
      else if (localName.equals("invoker-proxy-binding"))
      {
         child = new InvokerProxyBinding();
      }

      return child;
   }

   /**
    * Called when parsing of a new element started.
    */
   public Object newChild(LoaderRepository repository, UnmarshallingContext navigator,
                          String namespaceURI, String localName, Attributes attrs)
   {
      Object child = null;

      if (localName.equals("loader-repository-config"))
      {
         child = new LoaderRepositoryConfig();
         for (int i = 0; i < attrs.getLength(); ++i)
         {
            if (attrs.getLocalName(i).equals("configParserClass"))
               ((LoaderRepositoryConfig) child).setConfigParserClass(attrs.getValue(i));
         }
      }

      return child;
   }
   
   /**
    * Called when parsing of a new element started.
    */
   public Object newChild(InvokerProxyBinding binding, UnmarshallingContext navigator,
                          String namespaceURI, String localName, Attributes attrs)
   {
      Object child = null;

      if (localName.equals("bean"))
      {
         child = new ClientBeanInterceptors();
      }

      return child;
   }

   /**
    * Called when parsing of a new element started.
    */
   public Object newChild(LoaderRepositoryConfig config, UnmarshallingContext navigator,
                          String namespaceURI, String localName, Attributes attrs)
   {
      Object child = null;

      return child;
   }

   /**
    * Called when parsing of a new element started.
    */
   public Object newChild(EnterpriseBeans ejbs, UnmarshallingContext navigator,
                          String namespaceURI, String localName, Attributes attrs)
   {
      Object child = null;

      if (localName.equals("session"))
      {
         child = ejbs;
      }
      else if (localName.equals("ejb-ref"))
      {
         child = new EjbRef();
      }
      else if (localName.equals("ejb-local-ref"))
      {
         child = new EjbLocalRef();
      }
      else if (localName.equals("resource-ref"))
      {
         child = new ResourceRef();
      }
      else if (localName.equals("call-by-value"))
      {
         ejbs.setCallByValue(true);
      }
      else if (localName.equals("clustered"))
      {
         child = new ClusterConfig();
      }
      else if (localName.equals("invoker-bindings"))
      {
         child = ejbs;
      }
      else if (localName.equals("invoker"))
      {
         child = new Invoker();
      }

      return child;
   }
   
   /**
    * Called when parsing character is complete.
    */
   public void addChild(EnterpriseBeans parent, Invoker invoker,
                        UnmarshallingContext navigator, String namespaceURI, String localName)
   {
      parent.addInvoker(invoker);
   }
   
   /**
    * Called when parsing character is complete.
    */
   public void addChild(EjbJarDD parent, InvokerProxyBinding binding,
                        UnmarshallingContext navigator, String namespaceURI, String localName)
   {
      parent.addInvokerProxyBinding(binding);
   }
   
   /**
    * Called when parsing character is complete.
    */
   public void addChild(InvokerProxyBinding parent, ClientBeanInterceptors interceptors,
                        UnmarshallingContext navigator, String namespaceURI, String localName)
   {
      parent.setClientBeanInterceptors(interceptors);
   }

   /**
    * Called when parsing character is complete.
    */
   public void addChild(EjbJarDD parent, LoaderRepository repository,
                        UnmarshallingContext navigator, String namespaceURI, String localName)
   {
      parent.setLoaderRepository(repository);
   }

   /**
    * Called when parsing character is complete.
    */
   public void addChild(LoaderRepository parent, LoaderRepositoryConfig config,
                        UnmarshallingContext navigator, String namespaceURI, String localName)
   {
      parent.setLoaderRepositoryConfig(config);
   }

   /**
    * Called when parsing character is complete.
    */
   public void addChild(EnterpriseBeans parent, EnterpriseBeans ejbs,
                        UnmarshallingContext navigator, String namespaceURI, String localName)
   {

   }

   /**
    * Called when parsing character is complete.
    */
   public void addChild(EnterpriseBeans parent, EjbRef ref,
                        UnmarshallingContext navigator, String namespaceURI, String localName)
   {
      parent.updateEjbRef(ref);
   }

   /**
    * Called when parsing character is complete.
    */
   public void addChild(EnterpriseBeans parent, EjbLocalRef ref,
                        UnmarshallingContext navigator, String namespaceURI, String localName)
   {
      parent.updateEjbLocalRef(ref);
   }

   /**
    * Called when parsing character is complete.
    */
   public void addChild(EnterpriseBeans parent, ResourceRef ref,
                        UnmarshallingContext navigator, String namespaceURI, String localName)
   {
      parent.updateResourceRef(ref);
   }

   /**
    * Called when parsing character is complete.
    */
   public void addChild(EnterpriseBeans parent, ClusterConfig config,
                        UnmarshallingContext navigator, String namespaceURI, String localName)
   {
      parent.setClusterConfig(config);
   }

   /**
    * Called when a child element with simple content is read for DD.
    */
   public void setValue(EnterpriseBeans ejbs, UnmarshallingContext navigator,
                        String namespaceURI, String localName, String value)
   {
      if (localName.equals("ejb-name"))
      {
         ejbs.setCurrentEjbName(value);
      }
      else if (localName.equals("jndi-name"))
      {
         ejbs.setJndiName(value);
      }
      else if (localName.equals("local-jndi-name"))
      {
         ejbs.setLocalJndiName(value);
      }
      else if (localName.equals("security-domain"))
      {
         ejbs.setSecurityDomain(value);
      }
      else if (localName.equals("call-by-value"))
      {
         ejbs.setCallByValue(true);
      }
      else if (localName.equals("run-as-principal"))
      {
         ejbs.setRunAsPrincipal(value);
      }
      else if (localName.equals("aop-domain-name"))
      {
         ejbs.setAopDomainName(value);
      }
   }

   /**
    * Called when a child element with simple content is read for DD.
    */
   public void setValue(ClusterConfig config, UnmarshallingContext navigator,
                        String namespaceURI, String localName, String value)
   {
      if (localName.equals("load-balance-policy"))
      {
         config.setLoadBalancePolicy(value);
      }
      else if (localName.equals("partition-name"))
      {
         config.setPartition(value);
      }
   }

   /**
    * Called when a child element with simple content is read for DD.
    */
   public void setValue(EjbRef ref, UnmarshallingContext navigator,
                        String namespaceURI, String localName, String value)
   {
      if (localName.equals("ejb-ref-name"))
      {
         ref.setEjbRefName(value);
      }
      else if (localName.equals("jndi-name"))
      {
         ref.setJndiName(value);
      }
   }
   
   /**
    * Called when a child element with simple content is read for DD.
    */
   public void setValue(ClientBeanInterceptors interceptors, UnmarshallingContext navigator,
                        String namespaceURI, String localName, String value)
   {
      if (localName.equals("interceptor"))
      {
         interceptors.addInterceptor(value);
      }
   }
   
   /**
    * Called when a child element with simple content is read for DD.
    */
   public void setValue(Invoker invoker, UnmarshallingContext navigator,
                        String namespaceURI, String localName, String value)
   {
      if (localName.equals("invoker-proxy-binding-name"))
      {
         invoker.setInvokerProxyBindingName(value);
      }
   }
   
   /**
    * Called when a child element with simple content is read for DD.
    */
   public void setValue(InvokerProxyBinding binding, UnmarshallingContext navigator,
                        String namespaceURI, String localName, String value)
   {
      if (localName.equals("name"))
      {
         binding.setName(value);
      }
      else if (localName.equals("proxy-factory"))
      {
         binding.setProxyFactory(value);
      }
   }

   /**
    * Called when a child element with simple content is read for DD.
    */
   public void setValue(EjbLocalRef ref, UnmarshallingContext navigator,
                        String namespaceURI, String localName, String value)
   {
      if (localName.equals("ejb-ref-name"))
      {
         ref.setEjbRefName(value);
      }
      else if (localName.equals("jndi-name"))
      {
         ref.setJndiName(value);
      }
   }

   /**
    * Called when a child element with simple content is read for DD.
    */
   public void setValue(ResourceRef ref, UnmarshallingContext navigator,
                        String namespaceURI, String localName, String value)
   {
      if (localName.equals("res-ref-name"))
      {
         ref.setResRefName(value);
      }
      else if (localName.equals("jndi-name"))
      {
         ref.setJndiName(value);
      }
      else if (localName.equals("resource-name"))
      {
         ref.setResourceName(value);
      }
   }

   /**
    * Called when a child element with simple content is read for DD.
    */
   public void setValue(EjbJarDD dd, UnmarshallingContext navigator,
                        String namespaceURI, String localName, String value)
   {
      if (localName.equals("security-domain"))
      {
         dd.setSecurityDomain(value);
      }

   }

   /**
    * Called when a child element with simple content is read for DD.
    */
   public void setValue(LoaderRepository repository, UnmarshallingContext navigator,
                        String namespaceURI, String localName, String value)
   {
      if (localName.equals("value"))
      {
         repository.setValue(value);
      }
      else if (localName.equals("loader-repository"))
      {
         repository.setValue(value);
      }
   }

   /**
    * Called when a child element with simple content is read for DD.
    */
   public void setValue(LoaderRepositoryConfig config, UnmarshallingContext navigator,
                        String namespaceURI, String localName, String value)
   {
      if (localName.equals("value"))
      {
         config.setValue(value);
      }
      else if (localName.equals("loader-repository-config"))
      {
         config.setValue(value);
      }
   }

}
