001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019/** 020 * Implements the CFML Function xmlelemnew 021 */ 022package lucee.runtime.functions.xml; 023 024import lucee.commons.lang.StringUtil; 025import lucee.runtime.PageContext; 026import lucee.runtime.exp.FunctionException; 027import lucee.runtime.ext.function.Function; 028import lucee.runtime.text.xml.XMLUtil; 029import lucee.runtime.text.xml.struct.XMLStructFactory; 030import lucee.runtime.type.util.ListUtil; 031 032import org.w3c.dom.Document; 033import org.w3c.dom.Element; 034import org.w3c.dom.NamedNodeMap; 035import org.w3c.dom.Node; 036 037public final class XmlElemNew implements Function { 038 039 private static final long serialVersionUID = -2601887739406776466L; 040 041 public static Element call(PageContext pc , Node node, String childname) throws FunctionException { 042 return call(pc, node, null, childname); 043 } 044 045 public static Element call(PageContext pc , Node node, String namespace, String childname) throws FunctionException { 046 Document doc=XMLUtil.getDocument(node); 047 048 if(StringUtil.isEmpty(childname)) { 049 if(!StringUtil.isEmpty(namespace)) { 050 childname=namespace; 051 namespace=null; 052 } 053 else throw new FunctionException(pc, "XmlElemNew", 3, "childname", "argument is required"); 054 } 055 056 Element el = null; 057 058 // without namespace 059 if(StringUtil.isEmpty(namespace)){ 060 if(childname.indexOf(':')!=-1) { 061 String[] parts = ListUtil.listToStringArray(childname, ':'); 062 childname = parts[1]; 063 String prefix = parts[0]; 064 namespace = getNamespaceForPrefix(doc.getDocumentElement(),prefix); 065 if(StringUtil.isEmpty(namespace)) { 066 el=doc.createElement(childname); 067 } else { 068 el=doc.createElementNS(namespace,childname); 069 el.setPrefix(prefix); 070 } 071 072 } else { 073 el=doc.createElement(childname); 074 } 075 } 076 // with namespace 077 else { 078 el=doc.createElementNS(namespace, childname); 079 } 080 return (Element)XMLStructFactory.newInstance(el,false); 081 } 082 083 private static String getNamespaceForPrefix(Node node,String prefix) { 084 if (node==null) return null; 085 NamedNodeMap atts = node.getAttributes(); 086 087 if (atts != null) { 088 String currLocalName,currPrefix; 089 int len=atts.getLength(); 090 for (int i = 0; i < len; i++) { 091 Node currAttr = atts.item(i); 092 currLocalName = currAttr.getLocalName(); 093 currPrefix = currAttr.getPrefix(); 094 if (prefix.equals(currLocalName) && "xmlns".equals(currPrefix)) { 095 return currAttr.getNodeValue(); 096 } 097 else if (StringUtil.isEmpty(prefix) && "xmlns".equals(currLocalName) 098 && StringUtil.isEmpty(currPrefix)) { 099 return currAttr.getNodeValue(); 100 } 101 } 102 } 103 return null; 104 } 105 106 107}