/*******************************************************************************
* Copyright (c) 2006-2013, Cloudsmith Inc.
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the copyright holder
* listed above, as the Initial Contributor under such license. The text or
* such license is available at www.eclipse.org.
******************************************************************************/
package org.eclipse.buckminster.osgi.filter.impl;
import java.util.ArrayList;
import java.util.Map;
import org.eclipse.buckminster.osgi.filter.Filter;
class AndOrFilterImpl extends FilterImpl {
private final FilterImpl[] filters;
AndOrFilterImpl(int operation, FilterImpl[] filters) {
super(operation, null);
this.filters = filters;
}
@Override
public void addConsultedAttributes(Map<String, String[]> propertyChoices) {
for (int i = 0; i < filters.length; i++)
filters[i].addConsultedAttributes(propertyChoices);
}
@Override
public int compareTo(FilterImpl o) {
int cmp = internalCompareTo(o);
if (cmp != 0)
return cmp;
FilterImpl[] o_filters = ((AndOrFilterImpl) o).filters;
int top = filters.length;
if (top > o_filters.length)
return 1;
if (top < o_filters.length)
return -1;
for (int idx = 0; idx < top; ++idx) {
cmp = filters[idx].compareTo(o_filters[idx]);
if (cmp != 0)
return cmp;
}
return 0;
}
@Override
public FilterImpl stripFilter(Filter subFilter) {
ArrayList<FilterImpl> newList = new ArrayList<FilterImpl>(filters.length);
boolean change = false;
for (int idx = 0; idx < filters.length; ++idx) {
FilterImpl child = filters[idx];
if (child.equals(subFilter)) {
change = true;
continue;
}
if (child instanceof AndOrFilterImpl) {
FilterImpl newChild = ((AndOrFilterImpl) child).stripFilter(subFilter);
if (child != newChild)
change = true;
if (newChild != null)
newList.add(newChild);
} else
newList.add(child);
}
return change ? Parser.normalize(newList, getOp()) : this;
}
@Override
FilterImpl addFilter(FilterImpl subFilter, int op) {
FilterImpl result;
if (getOp() == op) {
int top = filters.length;
// Prevent that the same filter is concatenated twice.
for (int idx = 0; idx < top; ++idx)
if (filters[idx].equals(subFilter))
return this;
ArrayList<FilterImpl> filterList = new ArrayList<FilterImpl>(top + 1);
for (int idx = 0; idx < top; ++idx)
filterList.add(filters[idx]);
filterList.add(subFilter);
result = Parser.normalize(filterList, getOp());
} else
result = super.addFilter(subFilter, op);
return result;
}
@Override
FilterImpl[] getFilterImpls() {
return filters;
}
@Override
boolean match0(Map<String, ? extends Object> properties) {
switch (getOp()) {
case AND:
for (int i = 0, size = filters.length; i < size; i++)
if (!filters[i].match0(properties))
return false;
return true;
case OR:
for (int i = 0, size = filters.length; i < size; i++)
if (filters[i].match0(properties))
return true;
return false;
}
return false;
}
@Override
void toString(StringBuilder sb) {
sb.append('(');
if (getOp() == AND)
sb.append('&');
else
sb.append('|');
for (int i = 0, size = filters.length; i < size; i++)
sb.append(filters[i].toString());
sb.append(')');
}
}