001    package railo.runtime.functions.other;
002    
003    
004    import java.util.HashSet;
005    import java.util.Iterator;
006    import java.util.Map.Entry;
007    
008    import railo.runtime.Component;
009    import railo.runtime.PageContext;
010    import railo.runtime.converter.LazyConverter;
011    import railo.runtime.type.Collection;
012    import railo.runtime.type.Collection.Key;
013    
014    public class ObjectEquals {
015            public static boolean call(PageContext pc , Object left, Object right) {
016                    return _equals(new HashSet<Object>(), left, right);
017            }
018            
019            private static boolean _equals(HashSet<Object> done,Object left, Object right) {
020                    // null
021                    if(left==null) {
022                            return right==null;
023                    }
024                    if(left==right) return true;
025                    
026                    Object rawLeft = LazyConverter.toRaw(left);
027                    Object rawRight = LazyConverter.toRaw(right);
028                    
029                    if(done.contains(rawLeft)) return done.contains(rawRight);
030                    done.add(rawLeft);
031                    done.add(rawRight);
032                    try{
033                    
034                            // Components
035                            if(left instanceof Component){
036                                    if(!(right instanceof Component)) return false;
037                                    return _equals(done,(Component)left, (Component)right);
038                            }
039                            
040                            // Collection
041                            if(left instanceof Collection){
042                                    if(!(right instanceof Collection)) return false;
043                                    return _equals(done,(Collection)left, (Collection)right);
044                            }
045                            
046                            // other
047                            return left.equals(right);
048                    }
049                    finally {
050                            done.remove(rawLeft);
051                            done.remove(rawRight);
052                    }
053            }
054            
055            private static boolean _equals(HashSet<Object> done,Collection left, Collection right) {
056                    if(left.size()!=right.size()) return false;
057                    Iterator<Entry<Key, Object>> it = left.entryIterator();
058                    Entry<Key, Object> e;
059                    Object l,r;
060                    while(it.hasNext()){
061                            e = it.next();
062                            l=e.getValue();
063                            r=right.get(e.getKey(),null);
064                            if(r==null || !_equals(done,l, r)) return false;
065                    }
066                    return true;
067            }
068            
069            private static boolean _equals(HashSet<Object> done,Component left, Component right) {
070                    if(left==null || right==null) return false;
071                    if(!left.getPageSource().equals(right.getPageSource())) return false;
072                    
073                    if(!_equals(done,left.getComponentScope(),right.getComponentScope())) return false;
074                    if(!_equals(done,(Collection)left,(Collection)right)) return false;
075    
076                    return true;
077            }
078    }