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 }