001    package railo.runtime.converter;
002    
003    import java.io.IOException;
004    import java.io.Writer;
005    import java.util.HashSet;
006    import java.util.Iterator;
007    import java.util.Set;
008    
009    import railo.runtime.PageContext;
010    import railo.runtime.op.Caster;
011    import railo.runtime.text.xml.struct.XMLStruct;
012    import railo.runtime.type.Array;
013    import railo.runtime.type.Collection;
014    import railo.runtime.type.SimpleValue;
015    import railo.runtime.type.Struct;
016    
017    public class LazyConverter extends ConverterSupport {
018    
019            public static String serialize(Object o)  {
020                    return serialize(o,new HashSet<Object>());
021            }
022    
023            @Override
024            public void writeOut(PageContext pc, Object source, Writer writer) throws ConverterException, IOException {
025                    writer.write(serialize(source));
026                    writer.flush();
027            }
028            
029            
030            private static String serialize(Object o,Set<Object> done)  {
031                    
032                    if(o==null) return "null";
033                    Object raw=toRaw(o);
034                    
035                    if(done.contains(raw)) return "parent reference";
036                    done.add(raw);
037                    try{
038                             if(o instanceof Array)return serializeArray((Array)o,done);
039                             if(o instanceof Struct){
040                                     return serializeStruct((Struct)o,done);
041                             }
042                             if(o instanceof SimpleValue || o instanceof Number || o instanceof Boolean)return Caster.toString(o,null);
043                             return o.toString();
044                    }
045                    finally {
046                            done.remove(raw);
047                    }
048            }
049    
050            public static Object toRaw(Object o) {
051                    if(o instanceof XMLStruct)return ((XMLStruct)o).toNode();
052                    return o;
053            }
054    
055    
056            private static String serializeStruct(Struct struct, Set<Object> done) {
057                    StringBuffer sb=new StringBuffer("{");
058                    Iterator it = struct.keyIterator();
059                    Object key;
060                    boolean notFirst=false;
061                    while(it.hasNext()) {
062                            if(notFirst)sb.append(", ");
063                            key=it.next();
064                            sb.append(key);
065                            sb.append("={");
066                            if(key instanceof String)
067                                    sb.append(serialize(struct.get((String)key,null),done));
068                            else
069                                    sb.append(serialize(struct.get((Collection.Key)key,null),done));
070                            sb.append("}");
071                            notFirst=true;
072                    }
073                    
074                    return sb.append("}").toString();
075            }
076    
077            private static String serializeArray(Array array, Set<Object> done) {
078                    StringBuffer sb=new StringBuffer("[");
079                    int len=array.size();
080                    for(int i=1;i<=len;i++){
081                            if(i>1)sb.append(", ");
082                            sb.append(serialize(array.get(i,null),done));
083                    }
084                    return sb.append("]").toString();
085            }
086    }