001    package railo.runtime.text.xml.struct;
002    
003    import org.w3c.dom.Element;
004    import org.w3c.dom.Node;
005    
006    import railo.runtime.exp.ExpressionException;
007    import railo.runtime.exp.PageException;
008    import railo.runtime.op.Caster;
009    import railo.runtime.op.Duplicator;
010    import railo.runtime.text.xml.XMLCaster;
011    import railo.runtime.type.Array;
012    import railo.runtime.type.Collection;
013    
014    /**
015     * Element that can contain more than one Element
016     */
017    public final class XMLMultiElementStruct extends XMLElementStruct {
018    
019            private static final long serialVersionUID = -4921231279765525776L;
020            private Array array;
021        
022        /**
023         * Constructor of the class
024         * @param array
025         * @param caseSensitive
026         * @throws PageException
027         */
028        public XMLMultiElementStruct(Array array, boolean caseSensitive) throws PageException {
029            super(getFirstRaw(array),caseSensitive);
030            this.array=array;
031            
032            if(array.size()==0)
033                throw new ExpressionException("Array must have one Element at least");
034            
035            int[] ints=array.intKeys();
036            for(int i=0;i<ints.length;i++) {
037                Object o=array.get(ints[i],null);
038                if(!(o instanceof Element)) {
039                    throw new ExpressionException("all Element in the Array must be of type Element");
040                }
041            }
042        }
043    
044            private static Element getFirstRaw(Array array) throws PageException {
045            if(array.size()==0)
046                throw new ExpressionException("Array must have one Element at least");
047            Element el=(Element) array.getE(1);
048            if(el instanceof XMLElementStruct)
049                    el=(Element) XMLCaster.toRawNode(((XMLElementStruct)el).getElement());
050            return el;
051            //return (Element)XMLCaster.toRawNode(array.getE(1));
052        }
053    
054        @Override
055        public Object removeEL(Collection.Key key) {
056            int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE);
057            if(index==Integer.MIN_VALUE)return super.removeEL (key);
058            return removeEL(index);
059        }
060    
061            public Object removeEL(int index) {
062                    Object o=array.removeEL(index);
063                    if(o instanceof Element) {
064                            Element el=(Element) o;
065                            //try {
066                                    Node n = XMLCaster.toRawNode(el);
067                                    el.getParentNode().removeChild(n);
068                            //} catch (PageException e) {}
069                    }
070                    return o;
071            }
072            
073        @Override
074        public Object remove(Collection.Key key) throws PageException {
075            int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE);
076            if(index==Integer.MIN_VALUE)return super.remove (key);
077            return remove(index);
078        }
079    
080            public Object remove(int index) throws PageException {
081                    Object o=array.removeE(index);
082                    if(o instanceof Element) {
083                            Element el=(Element) o;
084                            el.getParentNode().removeChild(XMLCaster.toRawNode(el));
085                    }
086                    return o;
087            }
088    
089        @Override
090        public Object get(Collection.Key key) throws PageException  {
091            int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE);
092            if(index==Integer.MIN_VALUE)return super.get(key);
093            return get(index);
094        }
095    
096            public Object get(int index) throws PageException {
097                    return array.getE(index);
098            }
099        
100        @Override
101        public Object get(Collection.Key key, Object defaultValue) {
102            int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE);
103            if(index==Integer.MIN_VALUE)return super.get(key,defaultValue);
104            return get(index,defaultValue);
105        }
106    
107            public Object get(int index, Object defaultValue) {
108                    return array.get(index,defaultValue);
109            }
110    
111        @Override
112        public Object setEL(Collection.Key key, Object value) {
113            try {
114                            return set(key,value);
115                    } catch (PageException e1) {
116                            return null;
117                    }
118        }
119    
120            /**
121             * @param index
122             * @param value
123             * @return
124             */
125            public Object setEL(int index, Object value) {
126                    try {
127                            return set(index, value);
128                    } catch (PageException e) {
129                            return null;
130                    }
131            }
132    
133            @Override
134            public Object set(Collection.Key key, Object value) throws PageException {
135            int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE);
136            if(index==Integer.MIN_VALUE){
137                    return super.set (key,value);
138            }
139            return set(index,value);
140        }
141    
142            public Object set(int index, Object value) throws PageException {
143                    Element element=XMLCaster.toElement(getOwnerDocument(),value);
144            Object obj = array.get(index,null);
145            
146            if(obj instanceof Element) {
147                    Element el = ((Element)obj);
148                    el.getParentNode().replaceChild(XMLCaster.toRawNode(element), XMLCaster.toRawNode(el));
149            }
150            else if(array.size()+1==index) {
151                    getParentNode().appendChild(XMLCaster.toRawNode(element));
152            }
153            else {
154                    throw new ExpressionException("the index for child node is out of range","valid range is from 1 to "+(array.size()+1));
155            }
156            return array.setE(index,element);
157            }
158        
159    
160        @Override
161        public boolean containsKey(Collection.Key key) {
162            return get(key,null)!=null;
163        }
164    
165            Array getInnerArray() {
166                    return array;
167            }
168            
169    
170        public Collection duplicate(boolean deepCopy) {
171            try {
172                return new XMLMultiElementStruct((Array) Duplicator.duplicate(array,deepCopy),getCaseSensitive());
173            } catch (PageException e) {
174                return null;
175            }
176        }
177    
178            @Override
179            public Node cloneNode(boolean deep) {
180                    try {
181                return new XMLMultiElementStruct((Array) Duplicator.duplicate(array,deep),getCaseSensitive());
182            } catch (PageException e) {
183                return null;
184            }
185            }
186    }