package railo.runtime.converter;
import java.io.IOException;
import java.io.Writer;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import railo.runtime.PageContext;
import railo.runtime.op.Caster;
import railo.runtime.text.xml.struct.XMLStruct;
import railo.runtime.type.Array;
import railo.runtime.type.Collection;
import railo.runtime.type.SimpleValue;
import railo.runtime.type.Struct;
public class LazyConverter extends ConverterSupport {
public static String serialize(Object o) {
return serialize(o,new HashSet<Object>());
}
@Override
public void writeOut(PageContext pc, Object source, Writer writer) throws ConverterException, IOException {
writer.write(serialize(source));
writer.flush();
}
private static String serialize(Object o,Set<Object> done) {
if(o==null) return "null";
Object raw=toRaw(o);
if(done.contains(raw)) return "parent reference";
done.add(raw);
try{
if(o instanceof Array)return serializeArray((Array)o,done);
if(o instanceof Struct){
return serializeStruct((Struct)o,done);
}
if(o instanceof SimpleValue || o instanceof Number || o instanceof Boolean)return Caster.toString(o,null);
return o.toString();
}
finally {
done.remove(raw);
}
}
public static Object toRaw(Object o) {
if(o instanceof XMLStruct)return ((XMLStruct)o).toNode();
return o;
}
private static String serializeStruct(Struct struct, Set<Object> done) {
StringBuffer sb=new StringBuffer("{");
Iterator it = struct.keyIterator();
Object key;
boolean notFirst=false;
while(it.hasNext()) {
if(notFirst)sb.append(", ");
key=it.next();
sb.append(key);
sb.append("={");
if(key instanceof String)
sb.append(serialize(struct.get((String)key,null),done));
else
sb.append(serialize(struct.get((Collection.Key)key,null),done));
sb.append("}");
notFirst=true;
}
return sb.append("}").toString();
}
private static String serializeArray(Array array, Set<Object> done) {
StringBuffer sb=new StringBuffer("[");
int len=array.size();
for(int i=1;i<=len;i++){
if(i>1)sb.append(", ");
sb.append(serialize(array.get(i,null),done));
}
return sb.append("]").toString();
}
}