package com.omatech.utils;

// Copyright (c) 05/2005 Agusti Pons
// Parser de microcalls, implementat amb JDOM
// Inclou lazy evaluation dels contents de tipus text/xml
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URLConnection;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.jdom.Element;
import org.jdom.Document;
import java.net.URL;
import java.io.OutputStreamWriter;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import org.jdom.transform.JDOMResult;
import org.jdom.transform.JDOMSource;
import org.jdom.output.Format;

public class MicrocallerJDOM extends Object
{

 String call;
 String procedure;
 String retcode;
 String errbuf;
 boolean bExistRetVal;
 boolean bOK;
 private Long lonRetCode; 
 private boolean debug;
 private PrintStream debug_output;

 private Hashtable<String, String> retvalues;
 private Hashtable<String, ContentElement> hashContents;
 private Hashtable<String, Cjt> hashCjt;
 private Document doc_total;

 private Hashtable transformParameters = new Hashtable();

 public void clearTransformParameters()
 {
   transformParameters.clear();
 }

 public void setTransformParameter(String name, String value){
     if (transformParameters.containsKey(name)){
         transformParameters.remove(name);
     }
     transformParameters.put(name,value);
 }

 public class Cjt
 {
   private String name;
   private Hashtable<String, CjtElement> hashCjts;
     public void init()
   {
     hashCjts = new Hashtable<String, CjtElement>();
   }
     public Cjt()
   {
     init();
   }
     public Cjt(String p_name)
   {
     init();
     this.name=p_name;
   }

   public CjtElement get(String p_name)
   {
     return((CjtElement)hashCjts.get(p_name));
   }

   public void put(String p_name, CjtElement p_cjtelement)
   {
     hashCjts.put(p_name, p_cjtelement);
   }
         public String getName()
   {
     return this.name;
   }
     public Enumeration getElements()
   {
     return(this.hashCjts.keys());
   }

   /**
   * Mčtode per obtenir el nombre d'elements d'un conjunt donat.
   */
   public int getSize()
   {
     return this.hashCjts.size();
   }
   }


 public class CjtElement
 {
   private String id;
   private Hashtable<String, ContentElement> hashContents;
     public void init()
   {
     hashContents = new Hashtable<String, ContentElement>();
   }
     public CjtElement()
   {
     init();
   }
     public CjtElement(String p_id)
   {
     init();
     this.id=p_id;
   }
     public void setID(String p_id)
   {
     this.id=p_id;
   }
     public void put(ContentElement p_content)
   {
     hashContents.put(p_content.getName(), p_content);
   }
     public ContentElement get(String p_name)
   {
     return((ContentElement)hashContents.get(p_name));
   }
     public Enumeration getContents()
   {
     return(this.hashContents.keys());
   }
     public String toHTML()
   {
     String l_str="Element ID="+this.id+"<br/>";
     Enumeration en = this.hashContents.keys();
     while (en.hasMoreElements())
     {
       String l_content_name=(String)en.nextElement();
       ContentElement ce = (ContentElement)this.hashContents.get(l_content_name);
       l_str=l_str+ce.toHTML();
     }
     return l_str;
   }
     public String toString()
   {
     String l_str="Element ID="+this.id+"\n";
     Enumeration en = this.hashContents.keys();
     while (en.hasMoreElements())
     {
       String l_content_name=(String)en.nextElement();
       ContentElement ce = (ContentElement)this.hashContents.get(l_content_name);
       l_str=l_str+ce.toString();
     }
     return l_str;
   }
 }


 public class ContentElement
 {
   private String name;
   private String cdata;
   private String contentType;
   private String transformation;
   private Document doc;
   private boolean bIsXML;

   public ContentElement()
   {
   }

   public ContentElement(String p_name, String p_cdata, String p_contentType, String p_transformation, Document p_doc)
   {
     this.name=p_name;
     setContentType(p_contentType);
     this.cdata=p_cdata;
     this.transformation=p_transformation;
     this.doc = p_doc;
   }

   public String getName()
   {
     return(this.name);
   }

   public boolean isXML()
   {
     return(this.bIsXML);
   }

   public String getCdata()
   {
     return(this.cdata);        }

   public Document getXMLdata()
   {
     return(this.doc);        }

   public String getContentType()
   {
     return(this.contentType);
   }

   public String getTransformation()
   {
     return(this.transformation);
   }

   public void setCdata(String cdata)
   {
     this.cdata=cdata;
   }

   public void setXMLdata(Document p_doc)
   {
     this.doc=p_doc;
   }

   public void setContentType(String p_contentType)
   {
     this.contentType=p_contentType;
     if (p_contentType.equalsIgnoreCase("text/xml"))
     {
       this.bIsXML=true;
     }
     else
     {
       this.bIsXML=false;
     }
   }

   public void setName(String p_name)
   {
     this.name = p_name;
   }

   public void setTransformation(String p_transformation)
   {
     this.transformation = p_transformation;
   }

   public String toString()
   {
     if (bIsXML)
     {
       return "Name="+name+" Type="+contentType+" Transformation="+transformation+" XML=XML\n";
     }
     else
     {
       return "Name="+name+" Type="+contentType+" Transformation="+transformation+" CDATA="+cdata+"\n";
     }
   }

   public String toHTML()
   {
     return toString()+"<br>";
   }
 }



 public void init()
 {
   retvalues = new Hashtable<String, String>();
   hashContents = new Hashtable<String, ContentElement>();
   hashCjt = new Hashtable<String, Cjt>();
 }

 public MicrocallerJDOM()
 {
   init();
 }

 public void setDebugOn(PrintStream p_out)
 {
   this.debug=true;
   this.debug_output = p_out;
 }

 public void setDebugOff()
 {
   this.debug=false;
   this.debug_output.close();
 }

 public void debug(String p_message)
 {
   try
   {
     if (this.debug && this.debug_output!=null)
     {
       this.debug_output.println(p_message);
     }
   }
   catch (Exception e)
   {// No diem res, no pot ser que el debug casqui !
   }
 }

 public boolean allRight ()
 {
   return(bOK);
 }

 public boolean anyProblem ()
 {
   return(!bOK);
 }

 public int getIntReturnCode ()
 {
   Integer intRetCode=null;
   if (lonRetCode.longValue() < new Integer(Integer.MAX_VALUE).longValue()
   && lonRetCode.longValue() > new Integer(Integer.MIN_VALUE).longValue())
   {
     intRetCode = new Integer(retcode);
   }
   return(intRetCode.intValue());
 }

 public long getLonReturnCode ()
 {
   return(this.lonRetCode.longValue());
 }

 public String getProcedure()
 {
   return(this.procedure);
 }

 public String getStringReturnCode ()
 {
   return(this.retcode);
 }

 public String getErrBuf ()
 {
   return(this.errbuf);
 }

 public boolean existsContent ()
 {
   return(existsContent("default"));
 }

 public boolean existsRetValues ()
 {
   return(bExistRetVal);
 }

 public String getRetValue (String p_name)
 {
   return((String)retvalues.get(p_name));
 }


 public ContentElement getContentElement (String p_name)
 {// Retorna el ContentElement con name=p_name
   try
   {
     return(((ContentElement)hashContents.get(p_name)));
   }
   catch(Exception e)
   {
     return(null);
   }
 }

 public String getContentType ()
 {// Retorna el content type con name=default
   return(getContentType("default"));
 }

 public String getContentTransformation ()
 {// Retorna la transformacion del content con name=default
   return(getContentTransformation("default"));
 }
 public String getContent ()
 {// Retorna el content con name=default
   return(getContent("default"));
 }


 public String getContentType (String p_name)
 {// Retorna el content type con name=p_name
   ContentElement ce = getContentElement(p_name);
   if (ce!=null)
   {
     return (ce.getContentType());
   }
   else
   {
     return null;
   }
 }

 public String getContentTransformation (String p_name)
 {// Retorna la transformacion del content con name=p_name
   ContentElement ce = getContentElement(p_name);
   if (ce!=null)
   {
     return (ce.getTransformation());
   }
   else
   {
     return null;
   }
 }

 public Enumeration getContents()
 {
   return(hashContents.keys());
 }

 public Enumeration getRetValues()
 {
   return(retvalues.keys());
 }

 public Enumeration getCjts()
 {
   return(hashCjt.keys());
 }

 public boolean existsContent (String p_name)
 {// Retorna true si existeix el content
   try
   {
     ContentElement ce = getContentElement(p_name);
     return (ce!=null);
   }
   catch(Exception e)
   {
     return(false);
   }
 }

 public boolean existsCjt (String p_name)
 {// Retorna true si existeix el content
   return(hashCjt.containsKey(p_name));
 }

 public String getContent (String p_name)
 {// Retorna el content con name=p_name
debug("Entro en getContent");    ContentElement ce = getContentElement(p_name);
     if (ce!=null)
   {
debug("ce no es null"); debug(ce.getCdata());      return (ce.getCdata());
   }
   else
   {
debug("ce ES null");      return null;
   }
 }

 public Cjt getCjt (String p_name)
 {// Retorna el content con name=p_name
   return((Cjt)this.hashCjt.get(p_name));
 }

 private void setError (int p_error_code, String p_errbuf)
 {
   this.lonRetCode=new Long(p_error_code);
   this.retcode=lonRetCode.toString();
   this.bOK=false;
   errbuf=p_errbuf;
   debug(p_errbuf);
 }

 public ContentElement getContentElement (Element p_e)
 {
   ContentElement ce = new ContentElement();
   ce.setName(p_e.getAttributeValue("name"));
   String l_type = p_e.getAttributeValue("type");
   if (l_type.equalsIgnoreCase("text/xml"))
   {
     ce.setTransformation(p_e.getAttributeValue("transformation"));
     List l_fills = p_e.getChildren();
     Iterator itr_fills = l_fills.iterator();
     Element l_xml_root=null;
     if (itr_fills.hasNext())
     {
       l_xml_root = (Element)itr_fills.next();
     }
     if (l_xml_root!=null)
     {//Si tenim root element, actualitzem la informacio associada
       Document l_xml_doc = new Document((Element)l_xml_root.clone());
       ce.setXMLdata(l_xml_doc);
     }
debug("Creando content: "+ce.getName()+" "+ce.getContentType());        }
   else
   {
     //ce.setCdata(e.getText());
     ce.setCdata(p_e.getTextTrim());
     debug("TEXT:"+p_e.getText());              
     debug("TEXT NORMALIZE:"+p_e.getTextNormalize());
     debug("TEXT TRIM:"+p_e.getTextTrim());              debug("Creando content: "+ce.getName()+" "+l_type+"\n"+p_e.getTextTrim());        
   }
   ce.setContentType(l_type);
   return ce;
 }


 public synchronized void parse(Document p_doc)
 {
   Element root=null;
   try
   {
     if (p_doc!=null)
     {
       root = p_doc.getRootElement();
     }
     else
     {
       debug("Estic a parse i el p_doc es null!");
       this.bOK=false;
       setError(-6, "Estic a parse i el p_doc es null!");
       return;
     }
   }
   catch(IllegalStateException e)
   {
     debug(e.getMessage());
     this.bOK=false;
     setError(-5, e.getMessage());
     return;
   }
     if (root.getAttributeValue("value").equalsIgnoreCase("OK"))
   {
     this.bOK=true;
   }
   else
   {// If the value is not OK then it's ERROR
     this.bOK=false;
   }
     this.retcode=root.getAttributeValue("retcode");
   this.procedure=root.getAttributeValue("procedure");
   this.errbuf=root.getAttributeValue("errbuf");

   lonRetCode = new Long(retcode);
     if (!this.bOK)
   {// We don't need to continue parsing if there was an error.
     setError(new Integer(root.getAttributeValue("retcode")).intValue(), root.getAttributeValue("errbuf"));
     return;
   }
     List retvalues_list = root.getChildren("retvalues");
   Iterator itr_retvalues = retvalues_list.iterator();
   while (itr_retvalues.hasNext())
   {
     Element e_retvalues = (Element)itr_retvalues.next();
     List retvalue_list = e_retvalues.getChildren("retvalue");
     Iterator itr_retvalue = retvalue_list.iterator();
     while (itr_retvalue.hasNext())
     {
       Object o2 = itr_retvalue.next();        if (o2 instanceof Element)
       {// In this level, we only accept revalue elements
         Element e = (Element)o2;
         String l_name = e.getAttributeValue("name");
         String l_val  = e.getAttributeValue("value");
         retvalues.put(l_name, l_val);                  }
     }
   }


   List contents_list = root.getChildren("content");
   Iterator itr_contents = contents_list.iterator();
   while (itr_contents.hasNext())
   {
     Object o = itr_contents.next();
     if (o instanceof Element)
     {
       ContentElement ce=getContentElement((Element)o);              this.hashContents.put(ce.getName(), ce);
     }
   }
     List cjt_list = root.getChildren("cjt");
   Iterator itr_cjts = cjt_list.iterator();
   while (itr_cjts.hasNext())
   {
     Object o = itr_cjts.next();
     if (o instanceof Element)
     {
       Element e = (Element)o;
       String l_cjt_name = e.getAttributeValue("name");
       Cjt l_cjt = new Cjt(l_cjt_name);
       List element_list = e.getChildren("element");
       Iterator itr_elements = element_list.iterator();
       while (itr_elements.hasNext())
       {
         Object o2 = itr_elements.next();
         if (o2 instanceof Element)
         {
           Element e2 = (Element)o2;
           String l_element_id = e2.getAttributeValue("id");
                     CjtElement l_cjtElement = new CjtElement(l_element_id);
           List cjtelementcontents_list = e2.getChildren("content");
           Iterator itr_cjtelementcontents = cjtelementcontents_list.iterator();
           while (itr_cjtelementcontents.hasNext())
           {
             Object o3 = itr_cjtelementcontents.next();
             if (o3 instanceof Element)
             {
               ContentElement ce=getContentElement((Element)o3);
               l_cjtElement.put(ce);
             }
           }
           l_cjt.put(l_element_id, l_cjtElement);
         }
       }
       this.hashCjt.put(l_cjt_name, l_cjt);
     }
   }
   }



 public Document callGET(String p_url)
 {
   Document l_doc=null;
debug("Entro en callGET");
   try
   {
     init();
     try
     {
debug("MICROCALLER: Abans de fer el get");
       SAXBuilder builder = new SAXBuilder();
       builder.setValidation(false);
       builder.setIgnoringElementContentWhitespace(false);
       l_doc = builder.build(new URL(p_url));
       return l_doc;
     }
     catch (Exception e)
     {            setError(-2, "Error inesperado en la evaluacion del microCall "+p_url+": "+e.getMessage());
     }
   }
   catch (Exception e)
   {
     setError(-3, "Error inesperado en la evaluacion del microCall "+p_url+": "+e.getMessage());
   }
   return null;
 }




 public Document callPOST(String p_url)
 {
   String tmp_url;
   String tmp_params;
   int interr;
   URL l_urlCall;
   Document l_doc=null;

debug("Entro en callPOST");
   /* Tractament inicial dels parametres, conversio de GET virtual a POST */
   interr=p_url.indexOf("?");
   if (interr >= 0)
   {
     tmp_url=p_url.substring(0,interr);
     tmp_params=p_url.substring(interr+1);
   }
   else
   {
     tmp_url = p_url;
     tmp_params = "";
   }
   /* Fi del tractament inicial dels parametres */  
   try
   {
     init();
     try
     {
       l_urlCall = new URL(tmp_url);                      URLConnection conn = l_urlCall.openConnection();
       conn.setDoInput(true);
       conn.setUseCaches(false);
debug("MICROCALLER: Abans de fer el post");
       if(!tmp_params.equalsIgnoreCase(""))
       {
debug("MICROCALLER: Abans d'enviar el content type");
         conn.setDoOutput(true);
         conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
         OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
debug("MICROCALLER envio els parametres: "+tmp_params);           wr.write(tmp_params);
         wr.flush();
         wr.close();
       }
       if (p_url.startsWith("http://"))
       {// It's a HTTP URL Connection
         HttpURLConnection http_conn=(HttpURLConnection)conn;
         if (http_conn.getResponseCode()!=200)
         {// Cas en que la url no contesti un codi 200
           setError(-1, "URL connection error in "+tmp_url+tmp_params+" - "+http_conn.getResponseMessage());
         }
       }
       SAXBuilder builder;
       builder = new SAXBuilder();
       builder.setValidation(false);
       builder.setIgnoringElementContentWhitespace(false);
       l_doc = builder.build(new InputStreamReader(conn.getInputStream()));
         return l_doc;
     }
     catch (Exception e)
     {            setError(-2, "Error inesperado en la evaluacion del microCall "+p_url+": "+e.getMessage());
     }
   }
   catch (Exception e)
   {
     setError(-3, "Error inesperado en la evaluacion del microCall "+p_url+": "+e.getMessage());
   }
   return null;
 }

 /**
  * Main method, used to call the url, obtain the result in microcall format
  * and parse it, it's the first method to call after creation.
  * @param p_url URL String file:// or http:// or whatever
  */
 public synchronized void call(String p_url)
 {
   Document l_doc=null;

/*
   if (p_url.length()>250)
   {
     l_doc = callPOST(p_url);
   }
   else
   {
     l_doc = callGET(p_url);
   }
*/

   l_doc=callPOST(p_url);
   this.doc_total=l_doc;          
   parse(l_doc);

/*
       if (this.debug)
       {
         debug("RETORNAT !!!:");
         XMLOutputter xo = new XMLOutputter();
         xo.output(this.doc_total, this.debug_output);
       }
*/        
  }

 public String getTransformedContent (String p_name, String p_xsl)
 {
   return getTransformedContent(p_name, p_xsl, "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl", "org.apache.xalan.processor.TransformerFactoryImpl");
 }

 public String getTransformedContent (String p_name, String p_xsl, String p_parser_xml, String p_parser_xsl)
 {
   String l_ret = null;
   String l_dbf = System.getProperty("javax.xml.parsers.DocumentBuilderFactory");    String l_tf = System.getProperty("javax.xml.transform.TransformerFactory");
   debug("MICROCALLER:: Properties de transformacio que teniem originalment:");
   debug("MICROCALLER:: "+l_dbf);
   debug("MICROCALLER:: "+l_tf);

   System.setProperty("javax.xml.parsers.DocumentBuilderFactory", p_parser_xml);
   System.setProperty("javax.xml.transform.TransformerFactory", p_parser_xsl);
   try
   {
     ContentElement ce = getContentElement(p_name);
         if (ce.isXML())
     {
       Document l_doc = ce.getXMLdata();
       XMLOutputter xo = new XMLOutputter();
       Format fxo = xo.getFormat();
       fxo.setEncoding("ISO-8859-1");
       xo.setFormat(fxo);

if (this.debug)
{
 xo.output(l_doc, this.debug_output);
}
       JDOMSource source = new JDOMSource(ce.getXMLdata());
debug("Vaig a crear el transformer amb el xsl: "+p_xsl);
       Transformer t = TransformerFactory.newInstance().newTransformer(new StreamSource(p_xsl));
debug("Despres de crear el transformer amb el xsl: "+p_xsl);
       StringWriter l_out = new StringWriter();

/*
       JDOMResult result = new JDOMResult();
       t.transform(source, result);
       Document l_doc2 = result.getDocument();
       l_ret = xo.outputString(l_doc2);
*/

       StreamResult result = new StreamResult(l_out);

       if(!transformParameters.isEmpty())
       {
         Enumeration e = transformParameters.keys();
         while (e.hasMoreElements())
         {
           String key = e.nextElement().toString();
           //System.out.println("nombre=:" + key);
           //System.out.println("valor=:" + transformParameters.get(key).toString());
           t.setParameter(key, transformParameters.get(key).toString());
          }
        }

        t.transform(source, result);

debug("l_out==="+new String(l_out.getBuffer()));
       l_ret=new String(l_out.getBuffer());       
/*
       List list_result = result.getResult();
       l_ret = xo.outputString(list_result);
       debug("result to string:"+result.toString());
       debug("l_out to string:"+l_out.toString());
       l_ret = result.toString();
*/

     }
     else
     {
       debug("Thats not an XML Content");            // Tornem als transformers que teniem originalment
       System.setProperty("javax.xml.parsers.DocumentBuilderFactory",l_dbf);
       System.setProperty("javax.xml.transform.TransformerFactory",l_tf);        
       l_ret = null;
     }
   }
   catch (Exception e)
   {// unexpected exception
     debug("Error in getTransformedContent("+p_name+", "+p_xsl+") -> "+e.getMessage()+" "+e.getCause()+" "+e.getClass());
     // Tornem als transformers que teniem originalment
     l_ret=null;
   }

   // Tornem als transformers que teniem originalment
   if (l_dbf!=null)
   {
     System.setProperty("javax.xml.parsers.DocumentBuilderFactory",l_dbf);
   }
   if (l_tf!=null)
   {
     System.setProperty("javax.xml.transform.TransformerFactory",l_tf);    
   }
   return l_ret;

 }




 public String getTransformedContent ()
 {
   return(getTransformedContent("default", getContentTransformation("default")));
 }

 public String getTransformedContent (String p_name)
 {
   return(getTransformedContent(p_name, getContentTransformation(p_name)));
 }


 public String getAllTransformed(String urlXSL)  {
   return getAllTransformed(urlXSL, "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl", "org.apache.xalan.processor.TransformerFactoryImpl");
 }

 public String getAllTransformed(String urlXSL, String p_parser_xml, String p_parser_xsl)
 {// Retorna el resultado de realizar la transformacion de todo el xml usando la transformacion de la URL psXSLT
     String l_ret = null;
   String l_dbf = System.getProperty("javax.xml.parsers.DocumentBuilderFactory");    String l_tf = System.getProperty("javax.xml.transform.TransformerFactory");
   debug("MICROCALLER:: Properties de transformacio que teniem originalment:");
   debug("MICROCALLER:: "+l_dbf);
   debug("MICROCALLER:: "+l_tf);

   System.setProperty("javax.xml.parsers.DocumentBuilderFactory",p_parser_xml);
   System.setProperty("javax.xml.transform.TransformerFactory",p_parser_xsl);
   XMLOutputter xo = new XMLOutputter();
   JDOMSource source = new JDOMSource(this.doc_total);
this.debug("Abans de transformar "+urlXSL);
   try
   {
     Transformer t = TransformerFactory.newInstance().newTransformer(new StreamSource(urlXSL));
     //StringWriter l_out = new StringWriter();
     JDOMResult result = new JDOMResult();
     t.transform(source, result);
     Document l_doc2 = result.getDocument();
     l_ret = xo.outputString(l_doc2);
   }
   catch (Exception e)
   {
     this.setError(-4, "Error al transformar "+e.getMessage());    }
       // Tornem als transformers que teniem originalment
   if (l_dbf!=null)
   {
     System.setProperty("javax.xml.parsers.DocumentBuilderFactory",l_dbf);
   }
   if (l_tf!=null)
   {
     System.setProperty("javax.xml.transform.TransformerFactory",l_tf);    }
   return l_ret;
 }


 public String getAll()
 {
   XMLOutputter xo = new XMLOutputter();
   return(xo.outputString(this.doc_total));
 }



 public Document getXML()
 {
   return doc_total;
 }


 public String toHTML ()
 {
   String l_strRetorno;
   int l_cont;
   Enumeration en;
     l_strRetorno="Microcall "+this.call;
   l_strRetorno=l_strRetorno+"\n<br>Resultado de la ejecución del procedimiento: "+getProcedure()+"\n<br>";
   if (allRight())
   {
     l_strRetorno=l_strRetorno+"<font class=\"cosok\">Resultado Correcto<br/>";
     l_strRetorno=l_strRetorno+"Codigo Retorno: "+getStringReturnCode()+"<br/>";
     l_strRetorno=l_strRetorno+"</font>";

     l_strRetorno=l_strRetorno+"Contents:\n<br>";
     l_cont=0;
     en = getContents();
     while (en.hasMoreElements())
     {
       ContentElement ce = getContentElement((String)en.nextElement());
       l_strRetorno=l_strRetorno+ce.toHTML();
       l_cont++;                        }
     l_strRetorno=l_strRetorno+"\n<br/>"+l_cont+" contents encontrados.";


     l_strRetorno=l_strRetorno+"\n\n<br><br>RetVals:\n<br>";
     l_cont=0;
     en = getRetValues();
     while (en.hasMoreElements())
     {
       String l_nom=(String)en.nextElement();
       String l_valor=(String)retvalues.get(l_nom);
       l_strRetorno=l_strRetorno+l_nom+"="+l_valor+"\n<br/>";
       l_cont++;                        }
     l_strRetorno=l_strRetorno+"\n<br/>"+l_cont+" retvals encontrados.";

     l_strRetorno=l_strRetorno+"\n\n<br><br>Cjts:\n<br>";
     l_cont=0;
     Enumeration encjts = getCjts();
     while (encjts.hasMoreElements())
     {
       String l_cjtname=(String)encjts.nextElement();
       Cjt l_cjt=(Cjt)this.hashCjt.get(l_cjtname);
       l_strRetorno=l_strRetorno+"\n\n<br><br>Cjt name="+l_cjt.getName()+":\n<br>";
       Enumeration enelements = l_cjt.getElements();
       while (enelements.hasMoreElements())
       {
         String l_element_name = (String)enelements.nextElement();
         CjtElement cjtelement = l_cjt.get(l_element_name);
         l_strRetorno=l_strRetorno+cjtelement.toHTML();              }
       l_cont++;                        }
     l_strRetorno=l_strRetorno+"\n<br/>"+l_cont+" cjts encontrados.";
   }
   else
   {
     l_strRetorno=l_strRetorno+"<font class=\"coserror\">Resultado Erroneo !!!<br/>";
     l_strRetorno=l_strRetorno+"Codigo Retorno: "+getStringReturnCode()+"<br/>";
     l_strRetorno=l_strRetorno+"Mensaje: "+getErrBuf()+"<br/>";
     l_strRetorno=l_strRetorno+"</font>";
   }



   return(l_strRetorno);
 }

 public String toString ()
 {
   String l_strRetorno;
   int l_cont;
   Enumeration en;

   l_strRetorno="Microcall "+this.call;
   l_strRetorno=l_strRetorno+"\nResultado de la ejecución del procedimiento: "+getProcedure()+"\n";
   if (allRight())
   {
     l_strRetorno=l_strRetorno+"Resultado Correcto\n";
     l_strRetorno=l_strRetorno+"Codigo Retorno: "+getStringReturnCode()+"\n";
         l_strRetorno=l_strRetorno+"Contents:\n";
     l_cont=0;
     en = getContents();
     while (en.hasMoreElements())
     {
       ContentElement ce = getContentElement((String)en.nextElement());
       l_strRetorno=l_strRetorno+ce.toString();
       l_cont++;                        }
     l_strRetorno=l_strRetorno+"\n"+l_cont+" contents encontrados.";

     l_strRetorno=l_strRetorno+"\n\nRetVals:\n";
     l_cont=0;
     en = getRetValues();
     while (en.hasMoreElements())
     {
       String l_nom=(String)en.nextElement();
       String l_valor=(String)retvalues.get(l_nom);
       l_strRetorno=l_strRetorno+l_nom+"="+l_valor+"\n";
       l_cont++;                        }
     l_strRetorno=l_strRetorno+"\n"+l_cont+" retvals encontrados.";


     l_strRetorno=l_strRetorno+"\n\nCjts:\n";
     l_cont=0;
     Enumeration encjts = getCjts();
     while (encjts.hasMoreElements())
     {
       String l_cjtname=(String)encjts.nextElement();
       Cjt l_cjt=(Cjt)this.hashCjt.get(l_cjtname);
       l_strRetorno=l_strRetorno+"\n\nCjt name="+l_cjt.getName()+":\n";
       Enumeration enelements = l_cjt.getElements();
       while (enelements.hasMoreElements())
       {
         String l_element_name = (String)enelements.nextElement();
         CjtElement cjtelement = l_cjt.get(l_element_name);
         l_strRetorno=l_strRetorno+cjtelement.toString();              }
       l_cont++;                        }
     l_strRetorno=l_strRetorno+"\n"+l_cont+" cjts encontrados.";


   }
   else
   {
     l_strRetorno=l_strRetorno+"<Resultado Erroneo !!!\n";
     l_strRetorno=l_strRetorno+"Codigo Retorno: "+getStringReturnCode()+"\n";
     l_strRetorno=l_strRetorno+"Mensaje: "+getErrBuf()+"\n";
   }
   return(l_strRetorno);
 }

}

