package org.openrosa.client.util; import java.util.HashMap; import java.util.Vector; import org.openrosa.client.Context; import org.openrosa.client.xforms.XformConstants; import org.openrosa.client.xforms.XformParser; import org.openrosa.client.xforms.XmlUtil; import org.openrosa.client.xpath.XPathExpression; import com.google.gwt.xml.client.Document; import com.google.gwt.xml.client.Element; import com.google.gwt.xml.client.Node; import com.google.gwt.xml.client.NodeList; import com.google.gwt.xml.client.XMLParser; /** * This class is responsible for the translation of xforms and layout xml * files in various locales. * * @author daniel * */ public class LanguageUtil { public static final String NODE_NAME_XFORM = "xform"; public static final String NODE_NAME_FORM = "Form"; public static final String NODE_NAME_LANGUAGE_TEXT = "LanguageText"; /** * Translates xforms or layout text into a locale or language as in the locale xml. * * @param srcXml the text to be translated into another locale. * @param languageXml the locale xml. * @param xform set to true if translating an xform, else false. * @return */ public static String translate(String srcXml, String languageXml, boolean xform){ if(srcXml == null || srcXml.trim().length() == 0 || languageXml == null || languageXml.trim().length() == 0) return null; return translate(XMLParser.parse(srcXml),languageXml,xform); } public static String translate(Document doc, String languageXml, boolean xform){ if(doc == null) return null; Document lngDoc = XMLParser.parse(languageXml); NodeList nodes = lngDoc.getDocumentElement().getChildNodes(); if(nodes == null) return null; for(int index = 0; index < nodes.getLength(); index++){ Node node = nodes.item(index); if(node.getNodeType() != Node.ELEMENT_NODE) continue; if((xform && node.getNodeName().equalsIgnoreCase(NODE_NAME_XFORM)) || (!xform && node.getNodeName().equalsIgnoreCase(NODE_NAME_FORM))) return translate(doc,node); } return null; } public static String translate(Document doc, Node parent){ NodeList nodes = parent.getChildNodes(); for(int index = 0; index < nodes.getLength(); index++){ Node node = nodes.item(index); if(node.getNodeType() != Node.ELEMENT_NODE) continue; String xpath = ((Element)node).getAttribute(XformConstants.ATTRIBUTE_NAME_XPATH); String value = ((Element)node).getAttribute(XformConstants.ATTRIBUTE_NAME_VALUE); if(xpath == null || value == null) continue; Vector<?> result = new XPathExpression(doc, xpath).getResult(); if(result != null){ //TODO We need to uniquely identify nodes and so each xpath should //point to no more than one node. if(result.size() > 1){ ;//Window.alert(result.size()+"..........."+xpath+"............"+value); continue; } else if(result.size() == 0) ;//Window.alert(result.size()+"..........."+xpath+"............"+value); for(int item = 0; item < result.size(); item++){ Element targetNode = (Element)result.get(item); int pos = xpath.lastIndexOf('@'); if(pos > 0 && xpath.indexOf('=',pos) < 0){ String attributeName = xpath.substring(pos + 1, xpath.indexOf(']',pos)); targetNode.setAttribute(attributeName, value); } else XmlUtil.setTextNodeValue(targetNode, value); } } } return doc.toString(); } /*public static String translate(String srcXml, String langXml){ if(srcXml == null || srcXml.trim().length() == 0 || langXml == null || langXml.trim().length() == 0) return srcXml; Document doc = XMLParser.parse(srcXml); Element parentLangNode = XMLParser.parse(langXml).getDocumentElement(); NodeList nodes = parentLangNode.getChildNodes(); for(int index = 0; index < nodes.getLength(); index++){ Node node = nodes.item(index); if(node.getNodeType() != Node.ELEMENT_NODE) continue; String xpath = ((Element)node).getAttribute(XformConstants.ATTRIBUTE_NAME_XPATH); String value = ((Element)node).getAttribute(XformConstants.ATTRIBUTE_NAME_VALUE); if(xpath == null || value == null) continue; Vector result = new XPathExpression(doc, xpath).getResult(); if(result != null && result.size() > 0){ //TODO We need to uniquely identify nodes and so each xpath should //point to no more than one node. if(result.size() > 1){ Window.alert(result.size()+"..........."+xpath+"............"+value); continue; } else if(result.size() == 0) Window.alert(result.size()+"..........."+xpath+"............"+value); Element targetNode = (Element)result.get(0); int pos = xpath.lastIndexOf('@'); if(pos > 0 && xpath.indexOf('=',pos) < 0){ String attributeName = xpath.substring(pos + 1, xpath.indexOf(']',pos)); targetNode.setAttribute(attributeName, value); } else XmlUtil.setTextNodeValue(targetNode, value); } } return doc.toString(); }*/ /** * Extracts xforms locale text from a combined locale document. * * @param doc the locale document. * @return the xforms locale text. */ public static String getXformsLocaleText(Document doc){ return getNodeText(doc, NODE_NAME_XFORM); } /** * Extracts layout locale text from a combined locale document. * * @param doc the locale document. * @return the layout locale text. */ public static String getLayoutLocaleText(Document doc){ return getNodeText(doc, NODE_NAME_FORM); } // // /** // * Creates a new language of locale document. // * // * @return the new language document. // */ // public static Document createNewLanguageDoc(){ // com.google.gwt.xml.client.Document doc = XMLParser.createDocument(); // doc.appendChild(doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"")); // Element rootNode = doc.createElement("LanguageText"); // rootNode.setAttribute("lang", Context.getLocale().getKey()); // doc.appendChild(rootNode); // return doc; // } // // /** // * Gets an xml text which combines locale text for the xform and layout text. // * // * @param xform the xform locale text. // * @param layout the layout locale text. // * @return the combined text. // */ // public static String getLocaleText(String xform, String layout){ // Document doc = createNewLanguageDoc(); // // if(xform != null && xform.trim().length() > 0) // doc.getDocumentElement().appendChild(doc.importNode(XMLParser.parse(xform).getDocumentElement(),true)); // // if(layout != null && layout.trim().length() > 0) // doc.getDocumentElement().appendChild(doc.importNode(XMLParser.parse(layout).getDocumentElement(),true)); // // return doc.toString(); // } /** * Extracts text for a given node name from a document. * * @param doc the document. * @param nodeName the node name. * @return the node text. */ private static String getNodeText(Document doc, String nodeName){ NodeList nodes = doc.getDocumentElement().getChildNodes(); for(int index = 0; index < nodes.getLength(); index++){ Node node = nodes.item(index); if(node.getNodeType() != Node.ELEMENT_NODE) continue; if(node.getNodeName().equalsIgnoreCase(nodeName)) return node.toString(); } return null; } public static void loadLanguageText(Integer formId, String xml, HashMap<Integer,HashMap<String,String>> languageText){ if(xml == null || xml.trim().length() == 0) return; NodeList nodes = XmlUtil.getDocument(xml).getDocumentElement().getElementsByTagName(NODE_NAME_LANGUAGE_TEXT); if(nodes != null) XformParser.loadLanguageText(formId, nodes, languageText); } }