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.text.xml.struct;
020
021import java.util.ArrayList;
022import java.util.Comparator;
023import java.util.Iterator;
024import java.util.List;
025import java.util.Map.Entry;
026
027import lucee.runtime.PageContext;
028import lucee.runtime.dump.DumpData;
029import lucee.runtime.dump.DumpProperties;
030import lucee.runtime.exp.PageException;
031import lucee.runtime.exp.PageRuntimeException;
032import lucee.runtime.op.Duplicator;
033import lucee.runtime.text.xml.XMLCaster;
034import lucee.runtime.type.Collection;
035import lucee.runtime.type.dt.DateTime;
036import lucee.runtime.type.it.EntryIterator;
037import lucee.runtime.type.it.KeyIterator;
038import lucee.runtime.type.it.StringIterator;
039import lucee.runtime.type.util.ArraySupport;
040import lucee.runtime.type.util.ArrayUtil;
041import lucee.runtime.type.wrap.ArrayAsArrayList;
042
043import org.w3c.dom.Element;
044import org.w3c.dom.Node;
045
046public class XMLMultiElementArray extends ArraySupport {
047
048        private static final long serialVersionUID = -2673749147723742450L;
049        private XMLMultiElementStruct struct;
050
051        public XMLMultiElementArray(XMLMultiElementStruct struct) {
052                this.struct=struct;
053        }
054
055        @Override
056        public Object append(Object o) throws PageException {
057                return setE(size()+1,o);
058        }
059
060        @Override
061        public Object appendEL(Object o) {
062                return setEL(size()+1,o);
063        }
064
065
066        @Override
067        public boolean containsKey(int key) {
068                return get(key,null)!=null;
069        }
070
071        @Override
072        public Object get(int key, Object defaultValue) {
073                return struct.get(key,defaultValue);
074        }
075
076        @Override
077        public Object getE(int key) throws PageException {
078                return struct.get(key);
079        }
080
081
082        @Override
083        public int getDimension() {
084                return struct.getInnerArray().getDimension();
085        }
086
087        @Override
088        public boolean insert(int index, Object value) throws PageException {
089        Element element=XMLCaster.toElement(struct.getOwnerDocument(),value);
090        boolean rtn = struct.getInnerArray().insert(index, element);
091        Object obj = struct.getInnerArray().get(index,null);
092        
093        if(obj instanceof Element) {
094                Element el = ((Element)obj);
095                el.getParentNode().insertBefore(XMLCaster.toRawNode(element), el);
096        }
097        else  {
098                struct.getParentNode().appendChild(XMLCaster.toRawNode(element));
099        }
100        return rtn;
101        }
102
103        @Override
104        public int[] intKeys() {
105                return struct.getInnerArray().intKeys();
106        }
107
108        @Override
109        public Object prepend(Object value) throws PageException {
110        Element element=XMLCaster.toElement(struct.getOwnerDocument(),value);
111        Object obj = struct.getInnerArray().get(1,null);
112        
113        if(obj instanceof Element) {
114                Element el = ((Element)obj);
115                el.getParentNode().insertBefore(XMLCaster.toRawNode(element), el);
116        }
117        else  {
118                struct.getParentNode().appendChild(XMLCaster.toRawNode(element));
119        }
120        return struct.getInnerArray().prepend(element);
121        }
122
123        @Override
124        public Object removeE(int key) throws PageException {
125                return struct.remove(key);
126        }
127
128        @Override
129        public Object removeEL(int key) {
130                return struct.removeEL(key);
131        }
132
133        @Override
134        public void resize(int to) throws PageException {
135                throw new PageRuntimeException("resizing of xml nodelist not allowed");
136        }
137
138        @Override
139        public Object setE(int key, Object value) throws PageException {
140                return struct.set(key, value);
141        }
142
143        @Override
144        public Object setEL(int key, Object value) {
145                return struct.setEL(key, value);
146        }
147
148        @Override
149        public void sort(String sortType, String sortOrder) throws PageException {
150                if(size()<=1) return;
151                
152                struct.getInnerArray().sort(sortType, sortOrder);
153                
154                Object[] nodes = struct.getInnerArray().toArray();
155                Node last=(Node) nodes[nodes.length-1],current;
156                Node parent=last.getParentNode();
157                for(int i=nodes.length-2;i>=0;i--) {
158                        current=(Node) nodes[i];
159                        parent.insertBefore(current, last);
160                        last=current;
161                }// MUST testen
162        }
163
164        public void sort(Comparator comp) {
165                if(size()<=1) return;
166                
167                struct.getInnerArray().sort(comp);
168                
169                Object[] nodes = struct.getInnerArray().toArray();
170                Node last=(Node) nodes[nodes.length-1],current;
171                Node parent=last.getParentNode();
172                for(int i=nodes.length-2;i>=0;i--) {
173                        current=(Node) nodes[i];
174                        parent.insertBefore(current, last);
175                        last=current;
176                }// MUST testen
177        }
178        
179        
180        @Override
181        public Object[] toArray() {
182                return struct.getInnerArray().toArray();
183        }
184
185        public ArrayList toArrayList() {
186                return ArrayAsArrayList.toArrayList(this);
187        }
188
189        @Override
190        public void clear() {//MUST
191        }
192
193        @Override
194        public boolean containsKey(String key) {
195                return struct.containsKey(key);
196        }
197
198        @Override
199        public boolean containsKey(Key key) {
200                return struct.containsKey(key);
201        }
202
203        @Override
204        public Collection duplicate(boolean deepCopy) {
205                return new XMLMultiElementArray((XMLMultiElementStruct)Duplicator.duplicate(struct,deepCopy));
206        }
207        
208
209        @Override
210        public Object get(String key) throws PageException {
211                return struct.get(key);
212        }
213
214        @Override
215        public Object get(Key key) throws PageException {
216                return struct.get(key);
217        }
218
219        @Override
220        public Object get(String key, Object defaultValue) {
221                return struct.get(key,defaultValue);
222        }
223
224        @Override
225        public Object get(Key key, Object defaultValue) {
226                return struct.get(key,defaultValue);
227        }
228
229        @Override
230        public Key[] keys() {
231                return struct.getInnerArray().keys();
232        }
233
234        @Override
235        public Object remove(Key key) throws PageException {
236                return struct.remove(key);
237        }
238
239        @Override
240        public Object removeEL(Key key) {
241                return struct.removeEL(key);
242        }
243
244        @Override
245        public Object set(String key, Object value) throws PageException {
246                return struct.set(key, value);
247        }
248
249        @Override
250        public Object set(Key key, Object value) throws PageException {
251                return struct.set(key, value);
252        }
253
254        @Override
255        public Object setEL(String key, Object value) {
256                return struct.setEL(key, value);
257        }
258
259        @Override
260        public Object setEL(Key key, Object value) {
261                return struct.setEL(key, value);
262        }
263
264        @Override
265        public int size() {
266                return struct.getInnerArray().size();
267        }
268
269        @Override
270        public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) {
271                return struct.toDumpData(pageContext, maxlevel,dp);
272        }
273
274        @Override
275        public Iterator<Collection.Key> keyIterator() {
276                return new KeyIterator(keys());
277        }
278    
279    @Override
280        public Iterator<String> keysAsStringIterator() {
281        return new StringIterator(keys());
282    }
283        
284        @Override
285        public Iterator<Entry<Key, Object>> entryIterator() {
286                return new EntryIterator(this,keys());
287        }
288
289        @Override
290        public boolean castToBooleanValue() throws PageException {
291                return struct.castToBooleanValue();
292        }
293    
294    @Override
295    public Boolean castToBoolean(Boolean defaultValue) {
296        return struct.castToBoolean(defaultValue);
297    }
298
299        @Override
300        public DateTime castToDateTime() throws PageException {
301                return struct.castToDateTime();
302        }
303    
304    @Override
305    public DateTime castToDateTime(DateTime defaultValue) {
306        return struct.castToDateTime(defaultValue);
307    }
308
309        @Override
310        public double castToDoubleValue() throws PageException {
311                return struct.castToDoubleValue();
312        }
313    
314    @Override
315    public double castToDoubleValue(double defaultValue) {
316        return struct.castToDoubleValue(defaultValue);
317    }
318
319        @Override
320        public String castToString() throws PageException {
321                return struct.castToString();
322        }
323        
324        @Override
325        public String castToString(String defaultValue) {
326                return struct.castToString(defaultValue);
327        }
328
329        @Override
330        public int compareTo(String str) throws PageException {
331                return struct.compareTo(str);
332        }
333
334        @Override
335        public int compareTo(boolean b) throws PageException {
336                return struct.compareTo(b);
337        }
338
339        @Override
340        public int compareTo(double d) throws PageException {
341                return struct.compareTo(d);
342        }
343
344        @Override
345        public int compareTo(DateTime dt) throws PageException {
346                return struct.compareTo(dt);
347        }
348        
349        @Override
350        public Object clone() {
351                return duplicate(true);
352        }
353
354        public boolean add(Object o) {
355                // TODO Auto-generated method stub
356                return false;
357        }
358
359        @Override
360        public long sizeOf() {
361                return ArrayUtil.sizeOf((List)this);
362        }
363
364}