/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package beans.directory.mkb10;
import beans.UserRightsSet;
import beans.directory.mkb10.entity.Mkb10Details;
import framework.beans.directory.DirectoryBean;
import beans.cec.entity.CommitteeResolution;
import beans.directory.mkb10.entity.Mkb10;
import beans.directory.vidal.entities.mkb10.VidalMkb10;
import beans.directory.vidal.entities.mkb10.VidalMkb10PK;
import beans.doctor.diagnosis.Diagnosis;
import beans.doctor.direction.Direction;
import beans.followup.entity.Followup;
import framework.generic.ClipsServerException;
import framework.generic.EDataIntegrity;
import framework.generic.EMoveToTrash;
import framework.security.UserRight;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;
import javax.ejb.Stateful;
import java.util.HashMap;
/**
* @security ok
* @author axe
* Security - Ok.
*/
@Stateful(mappedName="clips-beans/DirectoryMKB10Bean")
public class DirectoryMKB10Bean extends DirectoryBean<Mkb10, Mkb10Details>
implements DirectoryMKB10BeanRemote {
public DirectoryMKB10Bean() {
super(Mkb10.class, "диагноз");
}
@Override
protected UserRight getRightForCreateDirectoryItem() {
return UserRightsSet.WRITE_REGION_ADMIN_DIRECTORY;
}
@Override
protected UserRight getRightForWriteToDirectory() {
return UserRightsSet.WRITE_REGION_ADMIN_DIRECTORY;
}
protected void checkForNotLatin(String str) throws EDataIntegrity{
for (int i = 0; i < str.length(); i++){
char ch = str.charAt(i);
if (ch >= 0x80) {
throw new EDataIntegrity("Код MKB10 содержит не латинские буквы!");
}
}
}
@Override
protected void set(Mkb10 mkb10, Mkb10Details d) throws ClipsServerException {
mkb10.setTitle(d.title);
//mkb10.setDirty(details.dirty);
checkForNotLatin(d.code);
mkb10.setCode(d.code);
mkb10.setMustNotify(d.mustNotify);
mkb10.setInfectious(d.infectious);
mkb10.setShortTitle(d.shortTitle);
if(d.parentItem > 0) {
Mkb10 mkb10Parent = findEntity(Mkb10.class, d.parentItem);
mkb10.setRef(mkb10Parent);
}
}
@Override
protected void onRemove(Mkb10 entity) throws ClipsServerException {
Field f1[] = { new Field("mkbRef", entity) };
// Field parent[] = { new Field("mkbRef", entity) };
if(getEntityCount(Mkb10.class, f1) > 0) {
throw new EMoveToTrash("Существуют подчиненные диагнозы, удаление невозможно");
}
Field f2[] = { new Field("mkb10", entity) };
if(getEntityCount(Followup.class, f2) > 0) {
throw new EMoveToTrash("Существует диспансеризация с данным диагнозом, удаление невозможно");
}
if(getEntityCount(CommitteeResolution.class, f2) > 0) {
throw new EMoveToTrash("Существует решение КЭК с данным диагнозом, удаление невозможно");
}
if(getEntityCount(Diagnosis.class, f2) > 0) {
throw new EMoveToTrash("Данная болезнь была использована в ЭМК при постановке диагноза, удаление невозможно");
}
if(getEntityCount(Direction.class, f2) > 0) {
throw new EMoveToTrash("Существует направление с данным диагнозом, удаление невозможно");
}
}
@Override
public Set<Integer> getVidals(int mkb10) throws ClipsServerException {
if(mkb10 == 0) {
throw new EDataIntegrity("");
}
Iterator<VidalMkb10> list = findEntityList(VidalMkb10.class, "key.mkb10", mkb10).iterator();
Set<Integer> res = new HashSet<Integer>();
while(list.hasNext()) {
VidalMkb10 vidal = (VidalMkb10)list.next();
res.add(vidal.getKey().getVidal());
}
return res;
}
@Override
public void setVidals(int mkb10, Set<Integer> vidals) throws ClipsServerException {
if(mkb10 == 0) {
throw new EDataIntegrity("");
}
checkCommandAccessibility(COMMAND_WRITE);
Set<Integer> backup = new HashSet<Integer>(vidals);
Set<Integer> oldVidals = getVidals(mkb10);
vidals.removeAll(oldVidals);
oldVidals.removeAll(backup);
if(oldVidals.size() > 0) {
@SuppressWarnings("unchecked")
Field f[] = {
new Field("key.mkb10", mkb10),
new Field("key.vidal", oldVidals, Field.OPERATOR_IN)
};
deleteEntityList(VidalMkb10.class, f);
}
Iterator<Integer> addNew = vidals.iterator();
while(addNew.hasNext()) {
VidalMkb10 res = new VidalMkb10();
res.setKey(new VidalMkb10PK(mkb10, addNew.next()));
System.out.println("Added new:" + res);
manager.persist(res);
}
}
ArrayList<MkbItem> buildTree(List<MkbItem> newTree) throws ClipsServerException{
TreeMap<Object, MkbItem> map = new TreeMap<Object, MkbItem>();
for (MkbItem item : newTree) {
if (map.containsKey(item.getId())) {
throw new ClipsServerException("Новая коллекция содержит два элемента с одинаковым идентификатором");
}
map.put(item.getId(), item);
}
ArrayList<MkbItem> target = new ArrayList<MkbItem>();
for (MkbItem mkbItem : newTree) {
if (mkbItem.getParentId() == null) {
target.add(mkbItem);
}
else {
MkbItem newParent = map.get(mkbItem.getParentId());
if (newParent == null) {
throw new ClipsServerException("Новая коллекция не содержит элемента с идентификатором "
+ mkbItem.getParentId() + " являющегося предком элемента " + mkbItem.toString());
}
mkbItem.setParent(newParent);
}
}
return target;
}
LinkedList<Mkb10> remap(List<Mkb10> entityList, List<MkbItem> newTree) throws ClipsServerException{
TreeMap<String, MkbItem> nameMap = new TreeMap<String, MkbItem>();
for (MkbItem mkbItem : newTree) {
mkbItem.setMKB10Item(null);
if (nameMap.containsKey(mkbItem.getMkbCode())) {
throw new ClipsServerException("Попытка загрузить два элемента с одним кодом MKB! (" + mkbItem.getMkbCode() + ")");
}
nameMap.put(mkbItem.getMkbCode(), mkbItem);
}
HashMap<String, Mkb10> droped = new HashMap<String, Mkb10>();
for (Mkb10 entity: entityList){
MkbItem item = nameMap.get(entity.getCode());
if (item == null) {
if (droped.put(entity.getCode(), entity) != null){
throw new ClipsServerException("В базе присутствуют два элемента с одинаковым кодом (" + entity.getCode() + ")");
}
}
else {
if (item.getMKB10Item() != null){
throw new ClipsServerException("В базе присутствуют два элемента с одинаковым кодом (" + entity.getCode() + ")");
}
item.setMKB10Item(entity);
}
}
return new LinkedList<Mkb10>(droped.values());
}
// Уже не быстрое
Mkb10 fastSaveEntity(Mkb10 entity){
if(entity.getId() != 0) {
entity = manager.merge(entity);
} else {
manager.persist(entity);
manager.flush();
manager.refresh(entity);
}
return entity;
}
int counter = 0;
void saveItem(Mkb10 parent, MkbItem item){
Mkb10 entity = item.getMKB10Item();
if (entity == null){
entity = new Mkb10();
}
entity.setCode(item.getMkbCode());
entity.setTitle(item.getTitle());
entity.setRef(parent);
entity.setTrash(false);
entity = fastSaveEntity(entity);
if (counter++ % 100 == 0) {
System.err.println(counter + " : " + item.getId());
}
Iterator<MkbItem> itr = item.getChildrens();
while (itr.hasNext()) {
MkbItem child = itr.next();
saveItem(entity, child);
}
}
void saveTree(ArrayList<MkbItem> roots){
for (MkbItem mkbItem : roots) {
saveItem(null, mkbItem);
}
//manager.flush();
}
boolean deepMkbStrEqual(String str1, String str2){
if (str1.equalsIgnoreCase(str2)) {
return true;
}
if (str1.equalsIgnoreCase(str2 + "*") || (str1 + "*").equalsIgnoreCase(str2)){
return true;
}
if (str1.equalsIgnoreCase(str2 + "+") || (str1 + "+").equalsIgnoreCase(str2)){
return true;
}
return false;
}
void tryToDeepRemap(LinkedList<Mkb10> droppedList, List<MkbItem> newTree){
for (Iterator<Mkb10> it = droppedList.iterator(); it.hasNext();) {
Mkb10 entity = it.next();
if (!entity.isTrash()){
for (MkbItem mkbItem : newTree) {
if (mkbItem.getMKB10Item() == null) {
if (deepMkbStrEqual(entity.getCode(), mkbItem.getMkbCode())) {
mkbItem.setMKB10Item(entity);
it.remove();
break;
}
}
}
}
}
}
@Override
public void synchronize(List<MkbItem> newlist) throws ClipsServerException{
checkCommandAccessibility(COMMAND_CREATE);
checkCommandAccessibility(COMMAND_WRITE);
ArrayList<MkbItem> roots = buildTree(newlist);
@SuppressWarnings("unchecked")
List<Mkb10> items = findEntityList(Mkb10.class, new Field[0]);
LinkedList<Mkb10> droppedList = remap(items, newlist);
tryToDeepRemap(droppedList, newlist);
saveTree(roots);
for (Mkb10 mkb10 : droppedList) {
if (!mkb10.isTrash()) {
remove(mkb10.getId());
manager.flush();
}
}
}
/**
* Обновляет названия элементов справочника МКБ. Элементы, с кодами,
* отсутсвующими в списке игнорируются
* @param newlist
* @return
* @throws framework.generic.ClipsServerException
*/
@SuppressWarnings("unchecked")
@Override
public void updateTitle(List<MkbItem> newlist) throws ClipsServerException{
checkCommandAccessibility(COMMAND_WRITE);
HashMap<String, MkbItem> nameMap = new HashMap<String, MkbItem>();
for (MkbItem mkbItem : newlist) {
mkbItem.setMKB10Item(null);
if (nameMap.containsKey(mkbItem.getMkbCode())) {
throw new ClipsServerException("Попытка загрузить два элемента с одним кодом MKB! (" + mkbItem.getMkbCode() + ")");
}
nameMap.put(mkbItem.getMkbCode(), mkbItem);
}
@SuppressWarnings("unchecked")
/**Все мкб итемы*/
List<Mkb10> items = findEntityList(Mkb10.class, new Field[0]);
/**Мап код - сущность*/
HashMap<String, Mkb10> hashItems = new HashMap<String, Mkb10>();
ArrayList<Mkb10> change = new ArrayList<Mkb10>(items.size());
//идем по всем существующим итемам, заполняем мап, выявляем новые и выявляем измененные
for (Mkb10 mkb10 : items) {
//Добавляем в хэш, заодно проверка вдруг есть двойные
if (hashItems.containsKey(mkb10.getCode())) {
throw new ClipsServerException("В базе существуют два элемента с одним кодом MKB! (" + mkb10.getCode() + ")");
}
hashItems.put(mkb10.getCode(),mkb10);
MkbItem item = nameMap.remove(mkb10.getCode());
if (item == null) {
String s = mkb10.getCode();
s = s.replace("+", "");
s = s.replace("*", "");
item = nameMap.remove(s);
}
if (item != null){
if (!mkb10.getTitle().equals(item.getTitle())){
mkb10.setTitle(item.getTitle());
change.add(mkb10);
}
}
}
for (Mkb10 mkb10 : change) {
manager.merge(mkb10);
}
}
}