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.functions.other;
020
021
022import java.util.HashSet;
023import java.util.Iterator;
024import java.util.Map.Entry;
025
026import lucee.runtime.Component;
027import lucee.runtime.PageContext;
028import lucee.runtime.converter.LazyConverter;
029import lucee.runtime.op.Operator;
030import lucee.runtime.type.Collection;
031import lucee.runtime.type.Collection.Key;
032import lucee.runtime.type.UDF;
033
034public class ObjectEquals {
035        public static boolean call(PageContext pc , Object left, Object right) {
036                return Operator.equalsComplexEL(left, right, false, false);
037                //return _equals(new HashSet<Object>(), left, right);
038        }
039        
040        private static boolean _equals(HashSet<Object> done,Object left, Object right) {
041                // null
042                if(left==null) {
043                        return right==null;
044                }
045                if(left==right) return true;
046                
047                Object rawLeft = LazyConverter.toRaw(left);
048                Object rawRight = LazyConverter.toRaw(right);
049                
050                if(done.contains(rawLeft)) return done.contains(rawRight);
051                done.add(rawLeft);
052                done.add(rawRight);
053                try{
054                
055                        // Components
056                        if(left instanceof Component){
057                                if(!(right instanceof Component)) return false;
058                                return _equals(done,(Component)left, (Component)right);
059                        }
060                        
061                        // Collection
062                        if(left instanceof Collection){
063                                if(!(right instanceof Collection)) return false;
064                                return _equals(done,(Collection)left, (Collection)right);
065                        }
066                        
067                        if(left instanceof UDF) {
068                                if(!(right instanceof UDF)) return false;
069                                
070                                
071                        }
072                        
073                        // other
074                        return left.equals(right);
075                }
076                finally {
077                        done.remove(rawLeft);
078                        done.remove(rawRight);
079                }
080        }
081        
082        private static boolean _equals(HashSet<Object> done,Collection left, Collection right) {
083                if(left.size()!=right.size()) return false;
084                Iterator<Entry<Key, Object>> it = left.entryIterator();
085                Entry<Key, Object> e;
086                Object l,r;
087                while(it.hasNext()){
088                        e = it.next();
089                        l=e.getValue();
090                        r=right.get(e.getKey(),null);
091                        if(r==null || !_equals(done,l, r)) return false;
092                }
093                return true;
094        }
095        
096        private static boolean _equals(HashSet<Object> done,Component left, Component right) {
097                if(left==null || right==null) return false;
098                
099                if(!left.getPageSource().equals(right.getPageSource())) return false;
100                
101                if(!_equals(done,left.getComponentScope(),right.getComponentScope())) return false;
102                
103                if(!_equals(done,(Collection)left,(Collection)right)) return false;
104
105                return true;
106        }
107}