/*
* *************************************************************************************
* Copyright (C) 2008 EsperTech, Inc. All rights reserved. *
* http://esper.codehaus.org *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
* *************************************************************************************
*/
package com.espertech.esper.epl.join.hint;
import com.espertech.esper.client.EPException;
import com.espertech.esper.client.annotation.HintEnum;
import com.espertech.esper.collection.Pair;
import com.espertech.esper.epl.annotation.AnnotationException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class IndexHint {
private final List<SelectorInstructionPair> pairs;
public IndexHint(List<SelectorInstructionPair> pairs) {
this.pairs = pairs;
}
public static IndexHint getIndexHint(Annotation[] annotations) {
List<String> hints = HintEnum.INDEX.getHintAssignedValues(annotations);
if (hints == null) {
return null;
}
List<SelectorInstructionPair> pairs = new ArrayList<SelectorInstructionPair>();
for (String hint : hints) {
String[] hintAtoms = HintEnum.splitCommaUnlessInParen(hint);
List<IndexHintSelector> selectors = new ArrayList<IndexHintSelector>();
List<IndexHintInstruction> instructions = new ArrayList<IndexHintInstruction>();
for (int i = 0; i < hintAtoms.length; i++) {
String hintAtom = hintAtoms[i];
if (hintAtom.toLowerCase().trim().equals("bust")) {
instructions.add(new IndexHintInstructionBust());
}
else if (hintAtom.toLowerCase().trim().equals("explicit")) {
instructions.add(new IndexHintInstructionExplicit());
}
else if (checkValue("subquery", hintAtom.toLowerCase())) {
int subqueryNum = extractValue(hintAtom);
selectors.add(new IndexHintSelectorSubquery(subqueryNum));
}
else {
instructions.add(new IndexHintInstructionIndexName(hintAtom.trim()));
}
}
pairs.add(new SelectorInstructionPair(selectors, instructions));
}
return new IndexHint(pairs);
}
public List<IndexHintInstruction> getInstructionsSubquery(int subqueryNumber) {
for (SelectorInstructionPair pair : pairs) {
if (pair.getSelector().isEmpty()) { // empty selector mean hint applies to all
return pair.getInstructions();
}
for (IndexHintSelector selector : pair.getSelector()) {
if (selector.matchesSubquery(subqueryNumber)) {
return pair.getInstructions();
}
}
}
return Collections.emptyList();
}
public List<IndexHintInstruction> getInstructionsFireAndForget() {
for (SelectorInstructionPair pair : pairs) {
if (pair.getSelector().isEmpty()) { // empty selector mean hint applies to all
return pair.getInstructions();
}
}
return Collections.emptyList();
}
private static boolean checkValue(String type, String value) {
int indexOpen = value.indexOf('(');
if (indexOpen != -1) {
String noparen = value.substring(0, indexOpen);
if (type.equals(noparen)) {
return true;
}
}
return false;
}
private static int extractValue(String text) {
int indexOpen = text.indexOf('(');
int indexClosed = text.lastIndexOf(')');
if (indexOpen != -1) {
String value = text.substring(indexOpen + 1, indexClosed);
try {
return Integer.parseInt(value);
}
catch (Exception ex) {
throw new EPException("Failed to parse '" + value + "' as an index hint integer value");
}
}
throw new IllegalStateException("Not a parentheses value");
}
}