package railo.runtime.text.xml.struct; import org.w3c.dom.Element; import org.w3c.dom.Node; import railo.runtime.exp.ExpressionException; import railo.runtime.exp.PageException; import railo.runtime.op.Caster; import railo.runtime.op.Duplicator; import railo.runtime.text.xml.XMLCaster; import railo.runtime.type.Array; import railo.runtime.type.Collection; /** * Element that can contain more than one Element */ public final class XMLMultiElementStruct extends XMLElementStruct { private static final long serialVersionUID = -4921231279765525776L; private Array array; /** * Constructor of the class * @param array * @param caseSensitive * @throws PageException */ public XMLMultiElementStruct(Array array, boolean caseSensitive) throws PageException { super(getFirstRaw(array),caseSensitive); this.array=array; if(array.size()==0) throw new ExpressionException("Array must have one Element at least"); int[] ints=array.intKeys(); for(int i=0;i<ints.length;i++) { Object o=array.get(ints[i],null); if(!(o instanceof Element)) { throw new ExpressionException("all Element in the Array must be of type Element"); } } } private static Element getFirstRaw(Array array) throws PageException { if(array.size()==0) throw new ExpressionException("Array must have one Element at least"); Element el=(Element) array.getE(1); if(el instanceof XMLElementStruct) el=(Element) XMLCaster.toRawNode(((XMLElementStruct)el).getElement()); return el; //return (Element)XMLCaster.toRawNode(array.getE(1)); } @Override public Object removeEL(Collection.Key key) { int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); if(index==Integer.MIN_VALUE)return super.removeEL (key); return removeEL(index); } public Object removeEL(int index) { Object o=array.removeEL(index); if(o instanceof Element) { Element el=(Element) o; //try { Node n = XMLCaster.toRawNode(el); el.getParentNode().removeChild(n); //} catch (PageException e) {} } return o; } @Override public Object remove(Collection.Key key) throws PageException { int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); if(index==Integer.MIN_VALUE)return super.remove (key); return remove(index); } public Object remove(int index) throws PageException { Object o=array.removeE(index); if(o instanceof Element) { Element el=(Element) o; el.getParentNode().removeChild(XMLCaster.toRawNode(el)); } return o; } @Override public Object get(Collection.Key key) throws PageException { int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); if(index==Integer.MIN_VALUE)return super.get(key); return get(index); } public Object get(int index) throws PageException { return array.getE(index); } @Override public Object get(Collection.Key key, Object defaultValue) { int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); if(index==Integer.MIN_VALUE)return super.get(key,defaultValue); return get(index,defaultValue); } public Object get(int index, Object defaultValue) { return array.get(index,defaultValue); } @Override public Object setEL(Collection.Key key, Object value) { try { return set(key,value); } catch (PageException e1) { return null; } } /** * @param index * @param value * @return */ public Object setEL(int index, Object value) { try { return set(index, value); } catch (PageException e) { return null; } } @Override public Object set(Collection.Key key, Object value) throws PageException { int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); if(index==Integer.MIN_VALUE){ return super.set (key,value); } return set(index,value); } public Object set(int index, Object value) throws PageException { Element element=XMLCaster.toElement(getOwnerDocument(),value); Object obj = array.get(index,null); if(obj instanceof Element) { Element el = ((Element)obj); el.getParentNode().replaceChild(XMLCaster.toRawNode(element), XMLCaster.toRawNode(el)); } else if(array.size()+1==index) { getParentNode().appendChild(XMLCaster.toRawNode(element)); } else { throw new ExpressionException("the index for child node is out of range","valid range is from 1 to "+(array.size()+1)); } return array.setE(index,element); } @Override public boolean containsKey(Collection.Key key) { return get(key,null)!=null; } Array getInnerArray() { return array; } public Collection duplicate(boolean deepCopy) { try { return new XMLMultiElementStruct((Array) Duplicator.duplicate(array,deepCopy),getCaseSensitive()); } catch (PageException e) { return null; } } @Override public Node cloneNode(boolean deep) { try { return new XMLMultiElementStruct((Array) Duplicator.duplicate(array,deep),getCaseSensitive()); } catch (PageException e) { return null; } } }