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.text.xml.XMLCaster; 010 import railo.runtime.type.Array; 011 import railo.runtime.type.Collection; 012 import railo.runtime.type.KeyImpl; 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 /** 055 * 056 * @see railo.runtime.text.xml.struct.XMLNodeStruct#removeEL(railo.runtime.type.Collection.Key) 057 */ 058 public Object removeEL(Collection.Key key) { 059 int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); 060 if(index==Integer.MIN_VALUE)return super.removeEL (key); 061 return removeEL(index); 062 } 063 064 /** 065 * @see railo.runtime.type.Array#removeEL(int) 066 */ 067 public Object removeEL(int index) { 068 Object o=array.removeEL(index); 069 if(o instanceof Element) { 070 Element el=(Element) o; 071 //try { 072 Node n = XMLCaster.toRawNode(el); 073 el.getParentNode().removeChild(n); 074 //} catch (PageException e) {} 075 } 076 return o; 077 } 078 079 080 /** 081 * @see railo.runtime.type.Collection#remove(java.lang.String) 082 */ 083 public Object remove(String key) throws PageException { 084 int index=Caster.toIntValue(key,Integer.MIN_VALUE); 085 if(index==Integer.MIN_VALUE)return super.remove (KeyImpl.init(key)); 086 return remove(index); 087 } 088 089 /** 090 * @see railo.runtime.text.xml.struct.XMLNodeStruct#remove(railo.runtime.type.Collection.Key) 091 */ 092 public Object remove(Collection.Key key) throws PageException { 093 int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); 094 if(index==Integer.MIN_VALUE)return super.remove (key); 095 return remove(index); 096 } 097 098 /** 099 * @see railo.runtime.type.Array#removeE(int) 100 */ 101 public Object remove(int index) throws PageException { 102 Object o=array.removeE(index); 103 if(o instanceof Element) { 104 Element el=(Element) o; 105 el.getParentNode().removeChild(XMLCaster.toRawNode(el)); 106 } 107 return o; 108 } 109 110 /** 111 * @see railo.runtime.text.xml.struct.XMLNodeStruct#get(railo.runtime.type.Collection.Key) 112 */ 113 public Object get(Collection.Key key) throws PageException { 114 int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); 115 if(index==Integer.MIN_VALUE)return super.get(key); 116 return get(index); 117 } 118 119 /** 120 * 121 * @see railo.runtime.type.Array#getE(int) 122 */ 123 public Object get(int index) throws PageException { 124 return array.getE(index); 125 } 126 127 /** 128 * 129 * @see railo.runtime.type.Collection#get(java.lang.String, java.lang.Object) 130 */ 131 public Object get(Collection.Key key, Object defaultValue) { 132 int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); 133 if(index==Integer.MIN_VALUE)return super.get(key,defaultValue); 134 return get(index,defaultValue); 135 } 136 137 /** 138 * @see railo.runtime.type.Array#get(int, java.lang.Object) 139 */ 140 public Object get(int index, Object defaultValue) { 141 return array.get(index,defaultValue); 142 } 143 144 /** 145 * 146 * @see railo.runtime.text.xml.struct.XMLNodeStruct#setEL(railo.runtime.type.Collection.Key, java.lang.Object) 147 */ 148 public Object setEL(Collection.Key key, Object value) { 149 try { 150 return set(key,value); 151 } catch (PageException e1) { 152 return null; 153 } 154 } 155 156 /** 157 * @param index 158 * @param value 159 * @return 160 */ 161 public Object setEL(int index, Object value) { 162 try { 163 return set(index, value); 164 } catch (PageException e) { 165 return null; 166 } 167 } 168 169 /** 170 * @see railo.runtime.text.xml.struct.XMLNodeStruct#set(railo.runtime.type.Collection.Key, java.lang.Object) 171 */ 172 public Object set(Collection.Key key, Object value) throws PageException { 173 int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); 174 if(index==Integer.MIN_VALUE){ 175 return super.set (key,value); 176 } 177 return set(index,value); 178 } 179 180 /** 181 * @see railo.runtime.type.Array#setE(int, java.lang.Object) 182 */ 183 public Object set(int index, Object value) throws PageException { 184 Element element=XMLCaster.toElement(getOwnerDocument(),value); 185 Object obj = array.get(index,null); 186 187 if(obj instanceof Element) { 188 Element el = ((Element)obj); 189 el.getParentNode().replaceChild(XMLCaster.toRawNode(element), XMLCaster.toRawNode(el)); 190 } 191 else if(array.size()+1==index) { 192 getParentNode().appendChild(XMLCaster.toRawNode(element)); 193 } 194 else { 195 throw new ExpressionException("the index for child node is out of range","valid range is from 1 to "+(array.size()+1)); 196 } 197 return array.setE(index,element); 198 } 199 200 201 /** 202 * 203 * @see railo.runtime.text.xml.struct.XMLNodeStruct#containsKey(railo.runtime.type.Collection.Key) 204 */ 205 public boolean containsKey(Collection.Key key) { 206 return get(key,null)!=null; 207 } 208 209 Array getInnerArray() { 210 return array; 211 } 212 213 214 public Collection duplicate(boolean deepCopy) { 215 try { 216 return new XMLMultiElementStruct((Array) array.duplicate(deepCopy),getCaseSensitive()); 217 } catch (PageException e) { 218 return null; 219 } 220 } 221 222 /** 223 * @see org.w3c.dom.Node#cloneNode(boolean) 224 */ 225 public Node cloneNode(boolean deep) { 226 try { 227 return new XMLMultiElementStruct((Array) array.duplicate(deep),getCaseSensitive()); 228 } catch (PageException e) { 229 return null; 230 } 231 } 232 }