/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package clips.directory.editors.mkb10;
import beans.directory.mkb10.MKBCode;
import beans.directory.mkb10.MKBCode.CompareResould;
import cli_fmw.main.ClipsException;
import cli_fmw.utils.Selector;
import clips.delegate.directory.complex.DirectoryMKB10;
import clips.delegate.directory.complex.DirectoryMKB10Item;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
/**
*
* @author finder
*/
public class MKbSelector {
private DirectoryMKB10 dir;
private SelectType selectType;
private ArrayList<DirectoryMKB10Item> tmp = new ArrayList<DirectoryMKB10Item>();
public enum SelectType{
inclusive,
single,
oneToOne,
}
public MKbSelector(DirectoryMKB10 dir, SelectType selectType) {
if (dir == null){
throw new IllegalArgumentException();
}
this.dir = dir;
this.selectType = selectType;
}
public ArrayList<DirectoryMKB10Item> getSelectedItem(Collection<MKBCode> codes) throws ParseException, ClipsException{
HashMap<Integer, DirectoryMKB10Item> target = new HashMap<Integer, DirectoryMKB10Item>();
for (MKBCode mKBCode : codes) {
getSelectedItem(mKBCode, tmp);
if (tmp.size() > 1 && selectType == SelectType.oneToOne){
throw new ClipsException("Код " + mKBCode + " встречается в базе данных дважды");
}
for (int i = 0; i < tmp.size(); i++) {
DirectoryMKB10Item item = tmp.get(i);
if (target.put(item.getID(), item) != null){
throw new ClipsException("Попытка добавть элемент " + mKBCode + " дважды");
}
}
tmp.clear();
}
ArrayList<DirectoryMKB10Item> targetList = new ArrayList<DirectoryMKB10Item>(target.values());
if (selectType == SelectType.inclusive){
for (DirectoryMKB10Item item : targetList) {
if (isContainRecursive(target, item)){
throw new ClipsException("В списке находится как элемент " + item.getDiseaseCode() + " так и его предок");
}
}
}
Collections.sort(targetList);
return targetList;
}
private boolean isContainRecursive(HashMap<Integer, DirectoryMKB10Item> map, DirectoryMKB10Item item){
item = item.getParent();
while (item != null){
if (map.get(item.getID()) != null){
return true;
}
item = item.getParent();
}
return false;
}
private void getSelectedItem(MKBCode code, ArrayList<DirectoryMKB10Item> target) throws ParseException, ClipsException{
dirScanRecursive(dir.getItems(), target, code);
}
private void dirScanRecursive(Selector<DirectoryMKB10Item> selector, ArrayList<DirectoryMKB10Item> items, MKBCode code) throws ParseException, ClipsException{
int size = selector.size();
for (int i = 0; i < size; i++){
DirectoryMKB10Item item = selector.get(i);
if (item.getID() == 0){
continue;
}
MKBCode itemCode = item.getDecodedCode();
CompareResould res = code.advanceCompare(itemCode);
switch (res){
case less:
break;
case more:
break;
case contains:
if (selectType == SelectType.oneToOne){
throw new ClipsException("Код " + code + " не соотведстует не одному коду в базе данных");
}
items.add(item);
break;
case equal:
items.add(item);
return;
case cross:
if (selectType == SelectType.oneToOne){
throw new ClipsException("Код " + code + " не соотведстует не одному коду в базе данных");
}
dirScanRecursive(item.getItems(), items, code);
break;
case inside:
dirScanRecursive(item.getItems(), items, code);
break;
default:
throw new RuntimeException("Unsupported CompareResould");
}
}
}
public DirectoryMKB10Item getSingleItem(MKBCode code) throws ParseException, ClipsException{
if (selectType != SelectType.oneToOne){
throw new IllegalStateException("Incorrect selectType");
}
getSelectedItem(code, tmp);
if (tmp.size() == 0){
return null;
}
if (tmp.size() > 1){
throw new ClipsException("Код " + code + " встречается в базе данных дважды");
}
DirectoryMKB10Item target = tmp.get(0);
tmp.clear();
return target;
}
}