}
private Class[] validateContextDesc(ContextDetailPartitioned segmentedSpec) throws ExprValidationException {
if (segmentedSpec.getItems().isEmpty()) {
throw new ExprValidationException("Empty list of partition items");
}
// verify properties exist
for (ContextDetailPartitionItem item : segmentedSpec.getItems()) {
EventType type = item.getFilterSpecCompiled().getFilterForEventType();
for (String property : item.getPropertyNames()) {
EventPropertyGetter getter = type.getGetter(property);
if (getter == null) {
throw new ExprValidationException("Property name '" + property + "' not found on type " + type.getName());
}
}
}
// verify property number and types compatible
ContextDetailPartitionItem firstItem = segmentedSpec.getItems().get(0);
if (segmentedSpec.getItems().size() > 1) {
// verify the same filter event type is only listed once
for (int i = 0; i < segmentedSpec.getItems().size(); i++) {
EventType compareTo = segmentedSpec.getItems().get(i).getFilterSpecCompiled().getFilterForEventType();
for (int j = 0; j < segmentedSpec.getItems().size(); j++) {
if (i == j) {
continue;
}
EventType compareFrom = segmentedSpec.getItems().get(j).getFilterSpecCompiled().getFilterForEventType();
if (compareFrom == compareTo) {
throw new ExprValidationException("The event type '" + compareFrom.getName() + "' is listed twice");
}
if (EventTypeUtility.isTypeOrSubTypeOf(compareFrom, compareTo) || EventTypeUtility.isTypeOrSubTypeOf(compareTo, compareFrom)) {
throw new ExprValidationException("The event type '" + compareFrom.getName() + "' is listed twice: Event type '" +
compareFrom.getName() + "' is a subtype or supertype of event type '" + compareTo.getName() + "'");
}
}
}
// build property type information
String[] names = new String[firstItem.getPropertyNames().size()];
Class[] types = new Class[firstItem.getPropertyNames().size()];
Class[] typesBoxed = new Class[firstItem.getPropertyNames().size()];
for (int i = 0; i < firstItem.getPropertyNames().size(); i++) {
String property = firstItem.getPropertyNames().get(i);
names[i] = property;
types[i] = firstItem.getFilterSpecCompiled().getFilterForEventType().getPropertyType(property);
typesBoxed[i] = JavaClassHelper.getBoxedType(types[i]);
}
// compare property types and numbers
for (int item = 1; item < segmentedSpec.getItems().size(); item++) {
ContextDetailPartitionItem nextItem = segmentedSpec.getItems().get(item);
// compare number of properties
if (nextItem.getPropertyNames().size() != types.length) {
throw new ExprValidationException("Expected the same number of property names for each event type, found " +
types.length + " properties for event type '" + firstItem.getFilterSpecCompiled().getFilterForEventType().getName() +
"' and " + nextItem.getPropertyNames().size() + " properties for event type '" + nextItem.getFilterSpecCompiled().getFilterForEventType().getName() + "'");
}
// compare property types
for (int i = 0; i < nextItem.getPropertyNames().size(); i++) {
String property = nextItem.getPropertyNames().get(i);
Class type = JavaClassHelper.getBoxedType(nextItem.getFilterSpecCompiled().getFilterForEventType().getPropertyType(property));
Class typeBoxed = JavaClassHelper.getBoxedType(type);
boolean left = JavaClassHelper.isSubclassOrImplementsInterface(typeBoxed, typesBoxed[i]);
boolean right = JavaClassHelper.isSubclassOrImplementsInterface(typesBoxed[i], typeBoxed);
if (typeBoxed != typesBoxed[i] && !left && !right) {
throw new ExprValidationException("Found mismatch of property types, property '" + names[i] +
"' of type '" + JavaClassHelper.getClassNameFullyQualPretty(types[i]) +
"' compared to property '" + property +
"' of type '" + JavaClassHelper.getClassNameFullyQualPretty(typeBoxed) + "'");
}
}