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.intergral.fusiondebug.server.type.coll;
020
021import java.util.ArrayList;
022import java.util.Arrays;
023import java.util.List;
024
025import lucee.intergral.fusiondebug.server.type.FDValueSupport;
026import lucee.intergral.fusiondebug.server.type.FDVariable;
027import lucee.intergral.fusiondebug.server.util.FDCaster;
028import lucee.runtime.Component;
029import lucee.runtime.type.Array;
030import lucee.runtime.type.Collection;
031import lucee.runtime.type.Collection.Key;
032import lucee.runtime.type.Struct;
033import lucee.runtime.type.comparator.TextComparator;
034import lucee.runtime.type.util.CollectionUtil;
035
036import com.intergral.fusiondebug.server.FDLanguageException;
037import com.intergral.fusiondebug.server.FDMutabilityException;
038import com.intergral.fusiondebug.server.IFDStackFrame;
039
040public class FDCollection extends FDValueSupport {
041
042        private static final int INTERVAL = 10;
043        private ArrayList children;
044        private Collection coll;
045        private String name;
046        private Key[] keys;
047
048        /**
049         * Constructor of the class
050         * @param frame 
051         * @param name 
052         * @param name
053         * @param coll
054         */
055        
056
057        public FDCollection(IFDStackFrame frame, String name, Collection coll) {
058                this(frame,name,coll,keys(coll));
059        }
060
061        public FDCollection(IFDStackFrame frame, String name, Collection coll, Key[] keys) {
062                
063                this.name=name;
064                this.coll=coll;
065                this.keys=keys;
066                //Key[] keys = coll.keys();
067                children=new ArrayList();
068                
069                int interval=INTERVAL;
070                while(interval*interval<keys.length)
071                        interval*=interval;
072                
073                if(keys.length>interval){
074                        FDCollection node;
075                        
076                        
077                        int len=keys.length;
078                        
079                        int max;
080                        for(int i=0;i<len;i+=interval)       {
081                                max=(i+(interval))<len?(interval):len-i;
082                                Key[] skeys=new Key[max];
083                                for(int y=0;y<max;y++)       {
084                                        skeys[y]=keys[i+y];
085                                }                               
086                                node = new FDCollection(frame,"Rows",coll,skeys);
087                                children.add(new FDVariable(frame,node.getName(),node));
088                        }
089                }
090                else {
091                        FDCollectionNode node;
092                        for(int i=0;i<keys.length;i++){
093                                node = new FDCollectionNode(frame,coll,keys[i]);
094                                children.add(new FDVariable(frame,node.getName(),node));
095                        }
096                }
097        }
098        
099        private static Key[] keys(Collection coll) {
100                Key[] keys=CollectionUtil.keys(coll);
101                if(coll instanceof Array) return keys;
102                TextComparator comp=new TextComparator(true,true);
103                Arrays.sort(keys,comp);
104                return keys;
105        }
106
107        @Override
108        public List getChildren() {
109                return children;
110        }
111
112 
113        public IFDStackFrame getStackFrame() {
114                // TODO Auto-generated method stub
115                return null;
116        }
117
118        @Override
119        public boolean isMutable() {
120                return false;
121        }
122
123        public void set(String arg0) throws FDMutabilityException,FDLanguageException {
124                throw new FDMutabilityException();
125        }
126
127        @Override
128        public boolean hasChildren() {
129                return true;
130        }
131        
132
133        @Override
134        public String toString() {
135                if(coll instanceof Array)
136                        return "["+fromto()+"]";
137                if(coll instanceof Component){
138                        Component c=(Component) coll;
139                        return "Component "+c.getName()+"("+c.getPageSource().getDisplayPath()+")";
140                }
141                if(coll instanceof Struct)
142                        return "{"+fromto()+"}";
143                return FDCaster.serialize(coll);
144        }
145        
146
147        private String fromto() {
148                StringBuffer sb=new StringBuffer();
149                for(int i=0;i<keys.length;i++){
150                        if(i!=0)sb.append(",");
151                        sb.append(keys[i].toString());
152                }
153                return keys[0]+" ... "+keys[keys.length-1];
154        }
155
156
157        @Override
158        public String getName() {
159                return name;
160        }
161}