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.converter; 020 021import java.io.IOException; 022import java.io.Writer; 023import java.util.HashSet; 024import java.util.Iterator; 025import java.util.Set; 026 027import lucee.runtime.PageContext; 028import lucee.runtime.op.Caster; 029import lucee.runtime.text.xml.struct.XMLStruct; 030import lucee.runtime.type.Array; 031import lucee.runtime.type.Collection.Key; 032import lucee.runtime.type.SimpleValue; 033import lucee.runtime.type.Struct; 034 035public class LazyConverter extends ConverterSupport { 036 037 public static String serialize(Object o) { 038 return serialize(o,new HashSet<Object>()); 039 } 040 041 @Override 042 public void writeOut(PageContext pc, Object source, Writer writer) throws ConverterException, IOException { 043 writer.write(serialize(source)); 044 writer.flush(); 045 } 046 047 048 private static String serialize(Object o,Set<Object> done) { 049 050 if(o==null) return "null"; 051 Object raw=toRaw(o); 052 053 if(done.contains(raw)) return "parent reference"; 054 done.add(raw); 055 try{ 056 if(o instanceof Array)return serializeArray((Array)o,done); 057 if(o instanceof Struct){ 058 return serializeStruct((Struct)o,done); 059 } 060 if(o instanceof SimpleValue || o instanceof Number || o instanceof Boolean)return Caster.toString(o,null); 061 return o.toString(); 062 } 063 finally { 064 done.remove(raw); 065 } 066 } 067 068 public static Object toRaw(Object o) { 069 if(o instanceof XMLStruct)return ((XMLStruct)o).toNode(); 070 return o; 071 } 072 073 074 private static String serializeStruct(Struct struct, Set<Object> done) { 075 StringBuilder sb=new StringBuilder("{"); 076 Iterator<Key> it = struct.keyIterator(); 077 Key key; 078 boolean notFirst=false; 079 while(it.hasNext()) { 080 if(notFirst)sb.append(", "); 081 key=it.next(); 082 sb.append(key); 083 sb.append("={"); 084 sb.append(serialize(struct.get(key,null),done)); 085 sb.append("}"); 086 notFirst=true; 087 } 088 089 return sb.append("}").toString(); 090 } 091 092 private static String serializeArray(Array array, Set<Object> done) { 093 StringBuilder sb=new StringBuilder("["); 094 int len=array.size(); 095 for(int i=1;i<=len;i++){ 096 if(i>1)sb.append(", "); 097 sb.append(serialize(array.get(i,null),done)); 098 } 099 return sb.append("]").toString(); 100 } 101}