001 /** 002 * Implements the CFML Function xmlelemnew 003 */ 004 package railo.runtime.functions.xml; 005 006 import org.w3c.dom.Document; 007 import org.w3c.dom.Element; 008 import org.w3c.dom.NamedNodeMap; 009 import org.w3c.dom.Node; 010 011 import railo.commons.lang.StringUtil; 012 import railo.runtime.PageContext; 013 import railo.runtime.exp.FunctionException; 014 import railo.runtime.ext.function.Function; 015 import railo.runtime.text.xml.XMLUtil; 016 import railo.runtime.text.xml.struct.XMLStructFactory; 017 import railo.runtime.type.util.ListUtil; 018 019 public final class XmlElemNew implements Function { 020 021 private static final long serialVersionUID = -2601887739406776466L; 022 023 public static Element call(PageContext pc , Node node, String childname) throws FunctionException { 024 return call(pc, node, null, childname); 025 } 026 027 public static Element call(PageContext pc , Node node, String namespace, String childname) throws FunctionException { 028 Document doc=XMLUtil.getDocument(node); 029 030 if(StringUtil.isEmpty(childname)) { 031 if(!StringUtil.isEmpty(namespace)) { 032 childname=namespace; 033 namespace=null; 034 } 035 else throw new FunctionException(pc, "XmlElemNew", 3, "childname", "argument is required"); 036 } 037 038 Element el = null; 039 040 // without namespace 041 if(StringUtil.isEmpty(namespace)){ 042 if(childname.indexOf(':')!=-1) { 043 String[] parts = ListUtil.listToStringArray(childname, ':'); 044 childname = parts[1]; 045 String prefix = parts[0]; 046 namespace = getNamespaceForPrefix(doc.getDocumentElement(),prefix); 047 if(StringUtil.isEmpty(namespace)) { 048 el=doc.createElement(childname); 049 } else { 050 el=doc.createElementNS(namespace,childname); 051 el.setPrefix(prefix); 052 } 053 054 } else { 055 el=doc.createElement(childname); 056 } 057 } 058 // with namespace 059 else { 060 el=doc.createElementNS(namespace, childname); 061 } 062 return (Element)XMLStructFactory.newInstance(el,false); 063 } 064 065 private static String getNamespaceForPrefix(Node node,String prefix) { 066 if (node==null) return null; 067 NamedNodeMap atts = node.getAttributes(); 068 069 if (atts != null) { 070 String currLocalName,currPrefix; 071 int len=atts.getLength(); 072 for (int i = 0; i < len; i++) { 073 Node currAttr = atts.item(i); 074 currLocalName = currAttr.getLocalName(); 075 currPrefix = currAttr.getPrefix(); 076 if (prefix.equals(currLocalName) && "xmlns".equals(currPrefix)) { 077 return currAttr.getNodeValue(); 078 } 079 else if (StringUtil.isEmpty(prefix) && "xmlns".equals(currLocalName) 080 && StringUtil.isEmpty(currPrefix)) { 081 return currAttr.getNodeValue(); 082 } 083 } 084 } 085 return null; 086 } 087 088 089 }