package io.ebeaninternal.api;
import io.ebean.Pairs;
import io.ebeaninternal.server.deploy.BeanNaturalKey;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class NaturalKeyQueryData<T> {
private final BeanNaturalKey naturalKey;
private boolean hasIn;
private String inProperty0, inProperty1;
private List<Pairs.Entry> inPairs;
private List<Object> inValues;
private String inProperty;
private List<NaturalKeyEq> eqList;
private NaturalKeySet set;
private int hitCount;
public NaturalKeyQueryData(BeanNaturalKey naturalKey) {
this.naturalKey = naturalKey;
}
private boolean matchProperty(String propName) {
return naturalKey.matchProperty(propName);
}
public List<Pairs.Entry> matchInPairs(String property0, String property1, List<Pairs.Entry> inPairs) {
if (hasIn) {
return null;
}
if (matchProperty(property0) && matchProperty(property1)) {
this.hasIn = true;
this.inProperty0 = property0;
this.inProperty1 = property1;
this.inPairs = new ArrayList<>(inPairs);
return this.inPairs;
}
return null;
}
public boolean matchIn(String propName, List<Object> inValues) {
if (hasIn) {
return false;
}
if (matchProperty(propName)) {
this.hasIn = true;
this.inProperty = propName;
this.inValues = inValues;
return true;
}
return false;
}
public boolean matchEq(String propName, Object bindValue) {
if (matchProperty(propName)) {
if (eqList == null) {
eqList = new ArrayList<>();
}
eqList.add(new NaturalKeyEq(propName, bindValue));
return true;
}
return false;
}
public NaturalKeySet buildKeys() {
if (!expressionCount() || !matchProperties()) {
return null;
}
this.set = new NaturalKeySet();
if (inValues != null) {
addInValues();
} else if (inPairs != null) {
addInPairs();
} else {
addEqualsKey();
}
return set;
}
private void addInPairs() {
for (Pairs.Entry entry : inPairs) {
set.add(new NaturalKeyEntryBasic(naturalKey, eqList, inProperty0, inProperty1, entry));
}
}
private void addInValues() {
if (eqList == null) {
for (Object inValue : inValues) {
set.add(new NaturalKeyEntrySimple(inValue));
}
} else {
for (Object inValue : inValues) {
set.add(new NaturalKeyEntryBasic(naturalKey, eqList, inProperty, inValue));
}
}
}
private void addEqualsKey() {
if (eqList.size() == 1) {
set.add(new NaturalKeyEntrySimple(eqList.get(0).value));
} else {
set.add(new NaturalKeyEntryBasic(naturalKey, eqList));
}
}
private boolean matchProperties() {
if (naturalKey.isSingleProperty()) {
naturalKey.matchSingleProperty((inProperty != null) ? inProperty : eqList.get(0).property);
}
Set<String> exprProps = new HashSet<>();
if (inProperty != null) {
exprProps.add(inProperty);
}
if (inProperty0 != null) {
exprProps.add(inProperty0);
}
if (inProperty1 != null) {
exprProps.add(inProperty1);
}
if (eqList != null) {
for (NaturalKeyEq eq : eqList) {
exprProps.add(eq.property);
}
}
return naturalKey.matchMultiProperties(exprProps);
}
private boolean expressionCount() {
int defined = (inValues == null) ? 0 : 1;
defined += (inPairs == null) ? 0 : 2;
defined += (eqList == null) ? 0 : eqList.size();
return defined == naturalKey.length();
}
public boolean allHits() {
return hitCount > 0
&& hitCount == set.size()
&& (inValues == null || inValues.isEmpty());
}
public List<T> removeHits(BeanCacheResult<T> cacheResult) {
List<BeanCacheResult.Entry<T>> hits = cacheResult.hits();
this.hitCount = hits.size();
List<T> beans = new ArrayList<>(hitCount);
for (BeanCacheResult.Entry<T> hit : hits) {
removeKey(set.getInValue(hit.getKey()));
beans.add(hit.getBean());
}
return beans;
}
private void removeKey(Object inValue) {
if (inValues != null) {
inValues.remove(inValue);
} else if (inPairs != null) {
inPairs.remove(inValue);
}
}
}