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;
}
}
}