/*
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@objectweb.org
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.objectweb.jonas.container;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URLClassLoader;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.Set;
import java.util.HashSet;
import java.util.Vector;
import java.util.Iterator;
import java.util.Properties;
import java.rmi.RemoteException;
import java.security.Guard;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.transaction.TransactionManager;
import org.objectweb.jonas.common.JProp;
import org.objectweb.jonas.common.Log;
import org.objectweb.jonas_ejb.container.BeanFactory;
import org.objectweb.jonas_ejb.container.Container;
import org.objectweb.jonas_ejb.container.JContainer;
import org.objectweb.jonas_ejb.container.JFactory;
import org.objectweb.jonas_ejb.container.JMdbFactory;
import org.objectweb.jonas_ejb.container.JEntityFactory;
import org.objectweb.jonas_ejb.container.JSessionFactory;
import org.objectweb.jonas_ejb.deployment.api.BeanDesc;
import org.objectweb.jonas_ejb.deployment.api.DeploymentDesc;
import org.objectweb.jonas_ejb.deployment.api.DeploymentDescException;
import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
import org.objectweb.jonas_ejb.deployment.api.EntityJdbcCmpDesc;
import org.objectweb.jonas_ejb.deployment.api.SessionDesc;
import org.objectweb.jonas_ejb.deployment.api.ResourceRefDesc;
import org.objectweb.jonas_ejb.deployment.api.SessionStatefulDesc;
import org.objectweb.jonas_ejb.deployment.api.SessionStatelessDesc;
import org.objectweb.jonas_ejb.deployment.api.EntityBmpDesc;
import org.objectweb.jonas_ejb.deployment.api.EntityCmpDesc;
import org.objectweb.jonas_ejb.deployment.api.EntityJdbcCmpDesc;
import org.objectweb.jonas_ejb.deployment.api.MessageDrivenDesc;
import org.objectweb.jonas_ejb.lib.BeanNaming;
import org.objectweb.jonas.jmx.JmxService;
import org.objectweb.jonas_jms.api.JmsManager;
import org.objectweb.jonas.jtm.TransactionService;
import org.objectweb.jonas.jms.JmsService;
import org.objectweb.jonas.jmx.JmxService;
import org.objectweb.jonas.jmx.JonasObjectName;
import org.objectweb.jonas.naming.CompNamingContext;
import org.objectweb.jonas.naming.NamingManager;
import org.objectweb.jonas.security.SecurityService;
import org.objectweb.jonas.service.ServiceManager;
import org.objectweb.jonas.service.AbsServiceImpl;
import org.objectweb.jonas.service.ServiceException;
import org.objectweb.util.monolog.api.Logger;
import org.objectweb.util.monolog.api.BasicLevel;

/**
 * EJBService implementation for JOnAS EJBServer
 * This class works only with jonas_ejb classes.
 * @author Philippe Coq
 * Contributor(s): 
 * Jeff Mesnil: Security
 * Markus Karg: Novell port
 * Christophe Ney: for making easier Enhydra integration
 */
public class EJBServiceImpl extends AbsServiceImpl implements EJBService, EJBServiceImplMBean {

    static private Logger logger = null;

    // Transaction manager reference
    // (tm can be accessed directly from everywhere in the package.)
    private TransactionManager tm = null;
    // JMS manager reference
    private JmsManager jms = null;
    // JMX Server
    private MBeanServer mbeanServer = null;

    // Security service reference
    private SecurityService securityService = null;

    // List of the ejb names to load when starting the EJBService
    private Vector ejbNames = new Vector();

    // We have a Container by ejb-jar file.
    private Vector containers = new Vector();

    // default thread pool size
    int threadPoolSize = 0;

    // -------------------------------------------------------------------
    // JOnAS Service Implementation
    // -------------------------------------------------------------------

    /**
     * Init the Service.
     * Configuration information is passed thru a Context object.
     */
    public void doInit(Context ctx) throws ServiceException {
	logger = Log.getLogger(Log.JONAS_SERVER_PREFIX);
	// Get the used services
	try {
	    // Get the Transaction Manager via the jtm service
	    TransactionService jtmService =
		(TransactionService)ServiceManager.getInstance().getTransactionService();
	    tm = jtmService.getTransactionManager();

	} catch (ServiceException e) {
	    logger.log(BasicLevel.ERROR, "Cannot initialize the EJBService: "+e);
	    throw new ServiceException("Cannot initialize the EJBService", e);
	}

	try {
	    // Get the Security service
	    securityService =
		(SecurityService)ServiceManager.getInstance().getSecurityService();
	} catch (ServiceException e) {
	    // The Security service may not be started
	    securityService = null;
	}
	try {
	    // Get the JMS manager via the JMS service
	    JmsService jmsService = (JmsService)ServiceManager.getInstance().getJmsService();
	    jms = jmsService.getJmsManager();
	} catch (ServiceException e) {
	    // the JMS service may not be started
	    jms = null;
	}

	try {
	    // Get the JMX Server via JMX Service
	    mbeanServer = ((JmxService)ServiceManager.getJmxService()).getJmxServer();
	} catch (ServiceException e) {
	    // the JMX service may not be started
	    mbeanServer = null;
	}

	// Set the XML parsing mode to no validation
	String parsingMode = "false";
	try {
	    parsingMode = (String) ctx.lookup("parsingwithvalidation");
	} catch (NamingException e) {
	    // No problem if there is no value for 'parsingwithvalidation' (false by default)
	}
	if ("false".equalsIgnoreCase(parsingMode)) {
	    DeploymentDesc.setParsingWithValidation(false);
	    logger.log(BasicLevel.DEBUG, "XML parsing without validation");
	} else {
	    logger.log(BasicLevel.DEBUG, "XML parsing with validation");
	}

	// Init the ejb names to be loaded when starting
	String descsValue = null;
	try {
	    descsValue = (String) ctx.lookup("descriptors");
	} catch (NamingException e) {
	    // No problem if there is no value for 'descriptors' (no ejb to load)
	}
	if (descsValue != null) {
	    StringTokenizer st = new StringTokenizer(descsValue, ",");
	    while (st.hasMoreTokens()) {
		String fileName = st.nextToken().trim();
		ejbNames.add(fileName);
	    }
	}

	// MDB thread pool size
	try {
	    String plz = (String) ctx.lookup("mdbthreadpoolsize");
	    threadPoolSize = (new Integer(plz)).intValue();
	} catch (NamingException e) {
	    // default value will be used.
	}

	logger.log(BasicLevel.DEBUG, "EJBService initialized");
    }

    /**
     * Start the Service
     * Initialization of the service is already done.
     */
    public void doStart() throws ServiceException {

	try {
	    // Creates all predefined containers
	    // 1 container per ejbjar file.
	    for (int i = 0; i < ejbNames.size(); i++) {
		String fileName = (String) ejbNames.elementAt(i);
		Context contctx = new CompNamingContext(fileName);
		contctx.rebind("filename", fileName);
		createContainer(contctx);
	    }

	    // Register EJBService MBean : EJBServiceImplMBean
	    if (mbeanServer != null) {
		mbeanServer.registerMBean(this, JonasObjectName.ejbService());
	    }
	} catch (Exception e) {
	    throw new ServiceException("Cannot start the EJBService", e);
	}
	
    }

    /**
     * Stop the service:
     * - Remove all JOnAS Containers.
     * - Unbinds all the EJBHome names from JNDI
     */
    public void doStop() {

	Enumeration lc = containers.elements();
	while (lc.hasMoreElements()) {
	    Container cont = (Container) lc.nextElement();
	    removeContainer(cont);
	}
	if (mbeanServer != null) {
	    try {
		// unregister EJBService MBean : EJBServiceImplMBean 
		mbeanServer.unregisterMBean(JonasObjectName.ejbService());
	    } catch (Exception e) {
		logger.log(BasicLevel.ERROR, "Cannot stop the EJBService: "+e);
	    }
	}

	logger.log(BasicLevel.DEBUG, "EJBService stopped");
    }

    // -------------------------------------------------------------------
    // EJBService Implementation
    // -------------------------------------------------------------------

    /**
     * Add beans from a .xml or a .jar file
     */
    public Container  createContainer(Context ctx) throws Exception {
	logger.log(BasicLevel.DEBUG, "entering");

	// Get the file name and check if file exists
	String fileName = (String) ctx.lookup("filename");
	File f = new File(fileName);
	if (!f.exists()) {
	    boolean found = false;
	    String ejbjarFileName = null;
	    if (fileName.endsWith(".jar")) {
		// In case of the name is a ejb-jar file name, check also in
		// the JONAS_ROOT/ejbjars directory
		String jonasRoot = JProp.getInstallRoot();
		ejbjarFileName = jonasRoot+File.separator+"ejbjars"+File.separator+fileName;
		File fj = new File(ejbjarFileName);
		found = fj.exists();
	    }
	    if (found) {
		fileName = ejbjarFileName;
	    } else {
		logger.log(BasicLevel.ERROR, "createContainer: "+fileName+" not found");
		Exception e = new NamingException(fileName+" not found");
		throw e;
	    }
	}

	// Check if container already exists
	if (getContainer(fileName) != null) {
	    logger.log(BasicLevel.ERROR, "createContainer: "+fileName+" already exists");
	    throw new RemoteException("Container already exists");
	}

	// Classloader
	URLClassLoader loader = null;
	URLClassLoader loaderForDD = null;
	try {
	    URL url[] = null;
	    if (fileName.endsWith(".jar")) {
		url = new URL[1];
		url[0] = (new File(fileName)).toURL();
	    } else {
		url = new URL[0];
	    }
	    loader = new URLClassLoader(url);
	    loaderForDD = new URLClassLoader(url, null);
	} catch (MalformedURLException e) {
	    logger.log(BasicLevel.ERROR, "Invalid ejb-jar file name '" + fileName + "': " + e);
	}
	// Get the deployment descriptor from file
	DeploymentDesc dd = null;
	try {
	    if (fileName.endsWith(".jar")) {
		// ejb-jar file
		// The loader used to get the DDs has no parent, to avoid to get wrong DDs
		// (ie META-INF/ejb-jar.xml resource accessible via the classpath)
		dd = DeploymentDesc.getInstance(loaderForDD, loader);
	    } else {
		// xml file
		dd = DeploymentDesc.getInstance(fileName, BeanNaming.getJonasXmlName(fileName));
	    }
	} catch (DeploymentDescException e) {
	    logger.log(BasicLevel.ERROR, "Cannot read the deployment descriptors '" + fileName + "': " + e);
	    throw new NamingException(e.toString());
	}

	// container name: displayName
	String cname = "EJB container ";
	if (dd.getDisplayName() != null) {
	    cname += dd.getDisplayName();
	}

	// only container with ressource available:
	String unUsedR = UseUnExistingResourceJdbc(dd);
	if (unUsedR != null) {
	    throw new Exception("Error when deploying container: use un-existing resource: "+unUsedR);
	}

	JContainer cont = new JContainer(cname, fileName, loader);
	cont.setContainerNaming(NamingManager.getInstance());
	cont.setTransactionManager(tm);
	cont.setPrincipalFactory(new PrincipalFactoryImpl());
	cont.setEjbDescriptor(dd);
	if (securityService != null) {
	    cont.setMethodGuard(securityService.getMethodGuard(fileName));
	    Guard rg = securityService.getRoleGuard(fileName);
	    cont.setRoleGuard(rg);
	} else {
	    logger.log(BasicLevel.DEBUG, "EJBService: working without Security Service");
	}
	cont.setJmsManager(jms);

	// Set thread pool size if it has been set in properties
	// Note that this ThreadPool is used only for MDB (jms), but it could
	// be used for other purpose later.
	if (threadPoolSize > 0) {
	    cont.setThreadPoolSize(threadPoolSize);
	}

	// Process each bean from the DD
	BeanDesc[] beans = dd.getBeanDesc();
	for (int i = 0; i < beans.length; i++) {
	    BeanFactory bf = cont.addBean(beans[i]);	    
	    if (mbeanServer != null) {
		try {
		    // register MBean for this ejb

		    if (beans[i] instanceof EntityBmpDesc) {
                        JEntityFactory _bf = (JEntityFactory)bf;
			mbeanServer.registerMBean(new JmxEntityFactory(_bf),
						  JonasObjectName.ejbbmp(fileName, beans[i].getEjbName()));
		    } else if (beans[i] instanceof EntityCmpDesc) {
                        JEntityFactory _bf = (JEntityFactory)bf;
			mbeanServer.registerMBean(new JmxEntityFactory(_bf),
						  JonasObjectName.ejbcmp(fileName, beans[i].getEjbName()));
		    } else if (beans[i] instanceof SessionStatefulDesc) {
                        JSessionFactory _bf = (JSessionFactory)bf;
			mbeanServer.registerMBean(new JmxSbfFactory(_bf),
						  JonasObjectName.ejbsbf(fileName, beans[i].getEjbName()));
		    } else if (beans[i] instanceof SessionStatelessDesc) {
                        JSessionFactory _bf = (JSessionFactory)bf;
			mbeanServer.registerMBean(new JmxSblFactory(_bf),
						  JonasObjectName.ejbsbl(fileName, beans[i].getEjbName()));
		    } else {
			JMdbFactory _bf = (JMdbFactory)bf;
			mbeanServer.registerMBean(new JmxMdbFactory(_bf),
						  JonasObjectName.ejbmdb(fileName, beans[i].getEjbName()));
		    }
		   
		} catch (Exception e) {
		    logger.log(BasicLevel.ERROR, "Cannot create container: "+e);
		}
	    }
	    if (securityService != null)
		securityService.deployBean(fileName,beans[i]);
	}
	containers.addElement(cont);

	// Container MBean registering
	if (mbeanServer != null) {
            mbeanServer.registerMBean(new JmxContainer(cont), JonasObjectName.container(cont.getFileName()));
	}

	logger.log(BasicLevel.DEBUG, "created container for "+fileName);
	return cont;
    }

    /**
     * Get the Container by its file name (.xml or .jar)
     */
    public Container getContainer(String fileName) {
	logger.log(BasicLevel.DEBUG, "entering for ejbjar= "+fileName);
	Enumeration lc = containers.elements();
	while (lc.hasMoreElements()) {
	    Container cont  = (JContainer) lc.nextElement();
	    if (cont.getFileName().equals(fileName)) {
		return cont;
	    }
	}
	if (fileName.endsWith(".jar")) {
	    // In case of the name is a ejb-jar file name, check also in
	    // the JONAS_ROOT/ejbjars directory
	    String jonasRoot = JProp.getInstallRoot();
	    String ejbjarFileName = jonasRoot+File.separator+"ejbjars"+File.separator+fileName;
	    lc = containers.elements();
	    while (lc.hasMoreElements()) {
		Container cont  = (JContainer) lc.nextElement();
		if (cont.getFileName().equals(ejbjarFileName)) {
		    return cont;
		}
	    }
	}
	return null;
    }

    /**
     * Remove a JOnAS container
     */
    public void removeContainer(Container cont) {
	logger.log(BasicLevel.DEBUG, "entering for "+cont.getName());

	if (mbeanServer != null) {
	    try {
		// remove Container MBean and all mbeans of this container (ejb)
		Set objectNames = mbeanServer.queryNames(JonasObjectName.allInContainer(cont.getFileName()), null) ;
		Iterator it  = objectNames.iterator();
		while (it.hasNext()) {
		    mbeanServer.unregisterMBean((ObjectName)it.next());
		}
	    } catch (Exception e) {
		logger.log(BasicLevel.ERROR, "Cannot remove container: "+e);
	    }
	} 
	cont.remove();
	containers.removeElement(cont);

    }

    /**
     * List JOnAS container created by  EJB Service
     */
    public Container[] listContainers() {
	logger.log(BasicLevel.DEBUG, "entering for size= "+ containers.size());

	Container ret[] = new Container[containers.size()];
	containers.copyInto(ret);
	return ret;
    }

    /**
     * Synchronized all entity bean containers
     */
    public void syncAllEntities() {
	logger.log(BasicLevel.DEBUG, "entering");

	Enumeration lc = containers.elements();
	while (lc.hasMoreElements()) {
	    JContainer cont = (JContainer) lc.nextElement();
	    cont.syncAll();
	}
    }

    /**
     * MBean method
     * @return Integer Total Number of Container currently in JOnAS
     */ 
     public Integer getCurrentNumberOfContainer(){
	return new Integer(containers.size());
    }

    /**
     * MBean method
     * @return Integer Total Number of Bean Type currently in JOnAS
     */ 
    public Integer getTotalCurrentNumberOfBeanType(){
	int count = 0;
	Enumeration lc = containers.elements();
	while (lc.hasMoreElements()) {
	    JContainer cont = (JContainer) lc.nextElement();
	    count += cont.getBeanNb();
	}
	return new Integer(count);
    }

    /**
     * MBean method
     * @return Integer Total Number of Bmp Type currently in JOnAS
     */
    public Integer getTotalCurrentNumberOfBMPType(){
	int count = 0;
	Enumeration lc = containers.elements();
	while (lc.hasMoreElements()) {
	    JContainer cont = (JContainer) lc.nextElement();
	    count += cont.getEntityBMPNb();
	}
	return new Integer(count);
    }

    /**
     * MBean method
     * @return Integer Total Number of Cmp Type currently in JOnAS
     */
    public Integer getTotalCurrentNumberOfCMPType(){
	int count = 0;
	Enumeration lc = containers.elements();
	while (lc.hasMoreElements()) {
	    JContainer cont = (JContainer) lc.nextElement();
	    count += cont.getEntityCMPNb();
	}
	return new Integer(count);
    }

    /**
     * MBean method
     * @return Integer Total Number of Sbf Type currently in JOnAS
     */
    public Integer getTotalCurrentNumberOfSBFType(){
	int count = 0;
	Enumeration lc = containers.elements();
	while (lc.hasMoreElements()) {
	    JContainer cont = (JContainer) lc.nextElement();
	    count += cont.getStatefulSessionNb();
	}
	return new Integer(count);
    }

    /**
     * MBean method
     * @return Integer Total Number of Sbl Type currently in JOnAS
     */
    public Integer getTotalCurrentNumberOfSBLType(){
	int count = 0;
	Enumeration lc = containers.elements();
	while (lc.hasMoreElements()) {
	    JContainer cont = (JContainer) lc.nextElement();
	    count += cont.getStatelessSessionNb();
	}
	return new Integer(count);
    }

    /**
     * MBean method
     * @return Integer Total Number of Mdb Type currently in JOnAS
     */
    public Integer getTotalCurrentNumberOfMDBType(){
	int count = 0;
	Enumeration lc = containers.elements();
	while (lc.hasMoreElements()) {
	    JContainer cont = (JContainer) lc.nextElement();
	    count += cont.getMessageDrivenNb();
	}
	return new Integer(count);
    }

    /**
     * MBean method
     * remove a container application
     * @param String ContainerName, the Name of this container
     */
    public void removeContainer(String fileName) {
	Container cont = getContainer(fileName);
	if (cont!=null) {
	    removeContainer(cont);
	} else {
	    logger.log(BasicLevel.ERROR, "Cannot remove the non-existant container '"+fileName+"'");
	}
    }

    /**
     * MBean method
     * Start (or restart if already start) a new container application
     * @param String ejbJarFile, the Name of the ejbJarFile for this container application
     */
    public void createContainer(String ejbJarFile) throws RemoteException {
	try {
	    Context contctx = new CompNamingContext(ejbJarFile);
	    contctx.rebind("filename", ejbJarFile);
	    createContainer(contctx);
	} catch (Exception e) {
	    e.printStackTrace();
	    throw new RemoteException(""+e.getMessage(), e);
	}
    }

    /**
     * MBean method
     * @return all ejb ObjectName using this datasource (with  there container name)
     */
    public Set getDataSourceDependence(String dsName) {
	HashSet resultProperties = new HashSet();
	HashSet resultObjectName = new HashSet();
	Enumeration lc = containers.elements();
	try {
	    Context ctx_ds = new InitialContext();
	    ctx_ds.lookup(dsName);
	    ctx_ds.close();
	    // this ds is rebind
	    while (lc.hasMoreElements()) {
		JContainer cont = (JContainer) lc.nextElement();
		//TODO
		//resultProperties.addAll(cont.getDataSourceDependence(dsName));
	    }
	    // change string to ObjectName
	    Iterator it = resultProperties.iterator();
	    while (it.hasNext()) {
		try {
		    resultObjectName.add(JonasObjectName.genericEjbObjectName((Properties)it.next()));
		} catch (Exception e) {
		    logger.log(BasicLevel.ERROR, "EjbServiceImpl: Object Name Error:" +e);
		}  
	    }
	} catch (NamingException ne) {
	    // unexisting ds so 
	    resultObjectName = new HashSet();
	}
	return resultObjectName;	
    }

    /**
     * Manangement method
     * @return all ejb ObjectName using this destination (with  there container name)
     */
    public Set getJmsDestinationDependence(String dsName) {
	HashSet resultProperties = new HashSet();
	HashSet resultObjectName = new HashSet();
	Enumeration lc = containers.elements();
	try {
	    Context ctx_ds = new InitialContext();
	    ctx_ds.lookup(dsName);
	    ctx_ds.close();
	    // this ds is rebind
	    while (lc.hasMoreElements()) {
		JContainer cont = (JContainer) lc.nextElement();
		//TODO
		//resultProperties.addAll(cont.getJmsDestinationDependence(dsName));
	    }
	    // change string to ObjectName
	    Iterator it = resultProperties.iterator();
	    while (it.hasNext()) {
		try {
		    resultObjectName.add(JonasObjectName.genericEjbObjectName((Properties)it.next()));
		} catch (Exception e) {
		    logger.log(BasicLevel.ERROR, "EjbServiceImpl: Object Name Error:" +e);
		}  
	    }
	} catch (NamingException ne) {
	    // unexisting ds so 
	    resultObjectName = new HashSet();
	}
	return resultObjectName;	
    }

    /**
     * Management method
     * @return all ejb ObjectName using this Connection Factory (with  there container name)
     */
    public Set getJmsConnectionFactoryDependence(String cfName) {
	HashSet resultProperties = new HashSet();
	HashSet resultObjectName = new HashSet();
	Enumeration lc = containers.elements();
	try {
	    Context ctx_ds = new InitialContext();
	    ctx_ds.lookup(cfName);
	    ctx_ds.close();
	    // this cf is rebind
	    while (lc.hasMoreElements()) {
		JContainer cont = (JContainer) lc.nextElement();
		//TODO
		//resultProperties.addAll(cont.getJmsConnectionFactoryDependence(cfName));
	    }
	    // change string to ObjectName
	    Iterator it = resultProperties.iterator();
	    while (it.hasNext()) {
		try {
		    resultObjectName.add(JonasObjectName.genericEjbObjectName((Properties)it.next()));
		} catch (Exception e) {
		    logger.log(BasicLevel.ERROR, "EjbServiceImpl: Object Name Error:" +e);
		}  
	    }
	} catch (NamingException ne) {
	    // unexisting cf so 
	    resultObjectName = new HashSet();
	}
	return resultObjectName;	
    }
    
    
    /**
     * Management method
     * @return null if all resource in the deployement descriptor existe or return resource name
     */
    public String UseUnExistingResourceJdbc(DeploymentDesc dd) {
	String result = null;
	BeanDesc[] beans = dd.getBeanDesc();
	int j = 0;
	while ((j < beans.length) && (result == null)) {
	    ResourceRefDesc[] rrDesc = beans[j].getResourceRefDesc();
	    int i = 0;
	    while ((i < rrDesc.length) && (result == null)) {
		if (rrDesc[i].isJdbc()) {
		    try {
			new InitialContext().lookup(rrDesc[i].getJndiName());
		    } catch (NamingException ne) {
			result = rrDesc[i].getName(); 
			logger.log(BasicLevel.ERROR, "UseUnExistingResourceJdbc '"+rrDesc[i].getJndiName()+"'");
		    }
		}
		i++;
	    }
	    j++;
	}
	return result;
    }

}
