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 retvalues; private Hashtable hashContents; private Hashtable 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 hashCjts; public void init() { hashCjts = new Hashtable(); } 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 hashContents; public void init() { hashContents = new Hashtable(); } 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+"
"; 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()+"
"; } } public void init() { retvalues = new Hashtable(); hashContents = new Hashtable(); hashCjt = new Hashtable(); } 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
Resultado de la ejecución del procedimiento: "+getProcedure()+"\n
"; if (allRight()) { l_strRetorno=l_strRetorno+"Resultado Correcto
"; l_strRetorno=l_strRetorno+"Codigo Retorno: "+getStringReturnCode()+"
"; l_strRetorno=l_strRetorno+"
"; 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.toHTML(); l_cont++; } l_strRetorno=l_strRetorno+"\n
"+l_cont+" contents encontrados."; l_strRetorno=l_strRetorno+"\n\n

RetVals:\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\n

Cjts:\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\n

Cjt 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.toHTML(); } l_cont++; } l_strRetorno=l_strRetorno+"\n
"+l_cont+" cjts encontrados."; } else { l_strRetorno=l_strRetorno+"Resultado Erroneo !!!
"; l_strRetorno=l_strRetorno+"Codigo Retorno: "+getStringReturnCode()+"
"; l_strRetorno=l_strRetorno+"Mensaje: "+getErrBuf()+"
"; l_strRetorno=l_strRetorno+"
"; } 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+"