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 **/ 019package lucee.runtime.cache.tag.udf; 020 021import java.util.HashSet; 022import java.util.Iterator; 023import java.util.Map.Entry; 024import java.util.Set; 025 026import lucee.commons.lang.StringUtil; 027import lucee.runtime.exp.PageException; 028import lucee.runtime.op.Caster; 029import lucee.runtime.text.xml.struct.XMLStruct; 030import lucee.runtime.type.Collection; 031import lucee.runtime.type.Collection.Key; 032import lucee.runtime.type.Query; 033import lucee.runtime.type.SimpleValue; 034 035public class UDFArgConverter { 036 037 public static String serialize(Object o) { 038 return serialize(o,new HashSet<Object>()); 039 } 040 041 042 private static String serialize(Object o,Set<Object> done) { 043 044 if(o==null) return "null"; 045 Object raw=toRaw(o); 046 047 if(done.contains(raw)) return "parent reference"; 048 done.add(raw); 049 Collection c=null; 050 Object other=null; 051 try{ 052 if((c=Caster.toCollection(o,null))!=null) { 053 if(o!=c){ 054 done.add(c); 055 other=c; 056 } 057 return serializeCollection(c,done); 058 } 059 if(o instanceof String) { 060 return "'"+escape((String)o)+"'"; 061 } 062 if(o instanceof SimpleValue || o instanceof Number || o instanceof Boolean) 063 return Caster.toString(o,""); 064 065 return o.toString(); 066 } 067 finally { 068 if(other!=null) done.remove(other); 069 done.remove(raw); 070 } 071 } 072 073 private static Object toRaw(Object o) { 074 if(o instanceof XMLStruct)return ((XMLStruct)o).toNode(); 075 return o; 076 } 077 078 079 private static String serializeCollection(Collection coll, Set<Object> done) { 080 if(coll instanceof Query) { 081 Query qry=(Query) coll; 082 StringBuilder sb=new StringBuilder(); 083 084 Iterator<Key> it = qry.keyIterator(); 085 Key k; 086 sb.append("{"); 087 boolean oDoIt=false; 088 int len=qry.getRecordcount(); 089 while(it.hasNext()) { 090 k = it.next(); 091 if(oDoIt)sb.append(','); 092 oDoIt=true; 093 sb.append(k.getLowerString()); 094 sb.append(":["); 095 boolean doIt=false; 096 for(int y=1;y<=len;y++) { 097 if(doIt)sb.append(','); 098 doIt=true; 099 try { 100 sb.append(serialize(qry.getAt(k,y),done)); 101 } catch (PageException e) { 102 sb.append(serialize(e.getMessage(),done)); 103 } 104 } 105 sb.append(']'); 106 } 107 108 sb.append('}'); 109 return sb.toString(); 110 } 111 112 113 StringBuilder sb=new StringBuilder("{"); 114 Iterator<Entry<Key, Object>> it = coll.entryIterator(); 115 Entry<Key, Object> e; 116 boolean notFirst=false; 117 while(it.hasNext()) { 118 if(notFirst)sb.append(","); 119 e=it.next(); 120 sb.append(e.getKey().getLowerString()); 121 sb.append(":"); 122 sb.append(serialize(e.getValue(),done)); 123 notFirst=true; 124 } 125 126 return sb.append("}").toString(); 127 } 128 129 private static String escape(String str) { 130 return StringUtil.replace(str,"'","''",false); 131 } 132}