package com.bagri.core.model;
import java.util.Collection;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
import com.bagri.core.query.Comparison;
import com.bagri.core.query.PathExpression;
/**
* Container for XDM elements.
*
* @author Denis Sukhoroslov
* @since 06.2014
*/
public class Elements {
private int pathId;
private Object elementRef;
/**
* default constructor
*/
public Elements() {
//
}
/**
*
* @param pathId the path id
* @param elements the Map of elements
*/
public Elements(int pathId, Collection<Element> elements) {
this.pathId = pathId;
setElements(elements);
}
/**
*
* @param element the element to add into container
*/
@SuppressWarnings("unchecked")
public void addElement(Element element) {
if (elementRef == null) {
elementRef = element;
return;
}
if (elementRef instanceof Element) {
Element oldElement = (Element) elementRef;
elementRef = new ArrayList<>();
((List<Element>) elementRef).add(oldElement);
}
((List<Element>) elementRef).add(element);
}
/**
*
* @return container elements
*/
@SuppressWarnings("unchecked")
public Collection<Element> getElements() {
if (elementRef == null) {
return Collections.emptyList();
}
if (elementRef instanceof Element) {
// wouldn't be better to keep it in the Set then?
ArrayList<Element> elements = new ArrayList<>();
elements.add((Element) elementRef);
return elements;
}
return (List<Element>) elementRef;
}
/**
*
* @return element's path id
*/
public int getPathId() {
return pathId;
}
/**
*
* @param elements elements to set
*/
public void setElements(Collection<Element> elements) {
elementRef = null;
if (elements != null && elements.size() > 0) {
for (Element elt : elements) {
addElement(elt);
}
}
}
/**
* performs comparison with expression
*
* @param pex the expression
* @param value the value to compare with
* @return true if comparison satisfies, false otherwise
*/
public boolean apply(PathExpression pex, Object value) {
if (value instanceof Collection) {
for (Object val: (Collection) value) {
if (applyValue(pex, val)) {
return true;
}
}
return false;
} else {
return applyValue(pex, value);
}
}
@SuppressWarnings("unchecked")
private boolean applyValue(PathExpression pex, Object value) {
if (elementRef instanceof Element) {
return compareValue(pex.getCompType(), value, ((Element) elementRef).getValue());
} else {
return compareValues(pex.getCompType(), value, (List<Element>) elementRef);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private boolean compareValue(Comparison comp, Object value1, Object value2) {
int result = ((Comparable) value2).compareTo((Comparable) value1);
switch (comp) {
case EQ: return result == 0;
case NE: return result != 0;
case LE: return result <= 0;
case LT: return result < 0;
case GE: return result >= 0;
case GT: return result > 0;
default: return false;
}
}
@SuppressWarnings("unchecked")
private boolean compareValues(Comparison comp, Object value, List<Element> elements) {
for (Element element : elements) {
if (element.getValue() != null) {
if (compareValue(comp, value, element.getValue())) {
return true;
}
}
}
return false;
//switch (comp) {
// case EQ: return values.contains(value);
// case NE: return !values.contains(value);
// case LE: return values.floor(value) != null;
// case LT: return values.lower(value) != null;
// case GE: return values.ceiling(value) != null;
// case GT: return values.higher(value) != null;
// default: return false;
//}
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Elements [pathId=" + pathId + ", elementRef=" + elementRef + "]";
}
}