package org.jfox.ejb.meta;

import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * @author <a href="mailto:yangyong@ufsoft.com.cn">Young Yang</a>
 */

public class EJBDescriptor extends EJBDescriptorBase {
  private EJBBundle bundle;
  private String displayName;
  private String smallIcon;
  private String largeIcon;
  private String ejbClassName;
  private List containerTransactions = new ArrayList();
  private List methodPermissions = new ArrayList();
  private List environmentEntries = new ArrayList();
  private List ejbReferences = new ArrayList();
  private List resourceReferences = new ArrayList();
  private List roleReferences = new ArrayList();

  private String remoteProtocol="jrmp";
  private String localProtocol="local";

  public EJBDescriptor() {

  }

  public void processXML(Node node) throws EJBDescriptionException {
    super.processXML(node);
    setDisplayName(XmlUtil.getChildNodeValueOf(node,"display-name"));
    setSmallIcon(XmlUtil.getChildNodeValueOf(node,"small-icon"));
    setLargeIcon(XmlUtil.getChildNodeValueOf(node,"large-icon"));
    setEjbName(XmlUtil.getChildNodeValueOf(node,"ejb-name"));
    setHomeClassName(XmlUtil.getChildNodeValueOf(node,"home"));
    setRemoteClassName(XmlUtil.getChildNodeValueOf(node,"remote"));
    setEjbClassName(XmlUtil.getChildNodeValueOf(node,"ejb-class"));

    Iterator envEntries = XmlUtil.getElementsByTagName((Element)node,"env-entry");
    while(envEntries.hasNext()){
      Element envEntry = (Element)envEntries.next();
      EnvEntryDescriptor eed = new EnvEntryDescriptor();
      eed.processXML(envEntry);
      addEnvironmentEntry(eed);
    }

    Iterator ejbRefs = XmlUtil.getElementsByTagName((Element)node,"ejb-ref");
    while(ejbRefs.hasNext()){
      Element ejbRef = (Element)ejbRefs.next();
      EJBReferenceDescriptor erd = new EJBReferenceDescriptor();
      erd.processXML(ejbRef);
      addEJBReference(erd);
    }

    Iterator resRefs = XmlUtil.getElementsByTagName((Element)node,"resource-ref");
    while(resRefs.hasNext()){
      Element resRef = (Element)resRefs.next();
      ResourceRefDescriptor rrd = new ResourceRefDescriptor();
      rrd.processXML(resRef);
      addResourceRef(rrd);
    }

    // security-role-ref not support now
/*
    Iterator secRefs = XmlUtil.getElementsByTagName((Element)node,"security-role-ref");
    while(secRefs.hasNext()){
      Element secRef = (Element)secRefs.next();
    }
*/
  }

  public String getType() {
    return "Session";
  }

  public String getJndiName() {
    if (jndiName == null)
      jndiName = homeClassName.replace('.','/');
    return jndiName;
  }

  public EJBBundle getEJBBundle() {
    return bundle;
  }

  public void setEJBBundle(EJBBundle bundle) {
    this.bundle = bundle;
  }

  public boolean isBeanManagedTransaction() {
    return false;
  }

  public String getDisplayName() {
    return displayName;
  }

  public void setDisplayName(String displayName) {
    this.displayName = displayName;
  }

  public String getSmallIcon() {
    return smallIcon;
  }

  public void setSmallIcon(String smallIcon) {
    this.smallIcon = smallIcon;
  }

  public String getLargeIcon() {
    return largeIcon;
  }

  public void setLargeIcon(String largeIcon) {
    this.largeIcon = largeIcon;
  }

  public String getEjbClassName() {
    return ejbClassName;
  }

  public void setEjbClassName(String ejbClassName) {
    this.ejbClassName = ejbClassName;
  }

  public List getContainerTransactions() {
    return containerTransactions;
  }

  public void setContainerTransactions(List containerTransactions) {
    this.containerTransactions = containerTransactions;
  }

  public List getMethodPermissions() {
    return methodPermissions;
  }

  public void setMethodPermissions(List methodPermissions) {
    this.methodPermissions = methodPermissions;
  }

  public List getEnvironmentEntries() {
    return environmentEntries;
  }

  public void setEnvironmentEntries(List environmentEntries) {
    this.environmentEntries = environmentEntries;
  }

  public List getEjbReferences() {
    return ejbReferences;
  }

  public void setEjbReferences(List ejbReferences) {
    this.ejbReferences = ejbReferences;
  }

  public List getResourceReferences() {
    return resourceReferences;
  }

  public void setResourceReferences(List resourceReferences) {
    this.resourceReferences = resourceReferences;
  }

  public List getRoleReferences() {
    return roleReferences;
  }

  public void setRoleReferences(List roleReferences) {
    this.roleReferences = roleReferences;
  }


  // TODO: performance !!!
  /**
   * get the Transaction Attribute of the method
   * @param method
   * @return
   */
  public byte getMethodTransactionAttribute(Method method) {
    for(int i=0; i<containerTransactions.size(); i++) {
      MethodTransaction mt = (MethodTransaction)containerTransactions.get(i);
      if(mt.getMethod().match(method)) {
        return mt.getTransactionAttr();
      }
    }
    return TransactionAttribute.TX_REQUIRED;
  }

  void addMethodTransaction(MethodTransaction mt) {
    containerTransactions.add(mt);
  }

  void addEnvironmentEntry(EnvEntryDescriptor eed) {
    environmentEntries.add(eed);
  }

  void addEJBReference(EJBReferenceDescriptor erd) {
    ejbReferences.add(erd);
  }

  void addResourceRef(ResourceRefDescriptor rrd) {
    resourceReferences.add(rrd);
  }

  public String getRemoteProtocol() {
    return remoteProtocol;
  }

  public void setRemoteProtocol(String remoteProtocol) {
    this.remoteProtocol = remoteProtocol;
  }

  public String getLocalProtocol() {
    return localProtocol;
  }

  public void setLocalProtocol(String localProtocol) {
    this.localProtocol = localProtocol;
  }

  public static void main(String[] args) {

  }

}