/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package clips.dicom.model;
import clips.dicom.Image.DICOMImage;
import clips.dicom.Image.DICOMImageEventsHandler;
import clips.dicom.dicombaseclass.DICOMChekup;
import clips.dicom.dicombaseclass.DICOMDeviceParam;
import clips.dicom.dicombaseclass.DICOMException;
import clips.dicom.dicomdataimpl.DICOMDataInput;
import clips.dicom.waveform.DICOMWaveformEventHandler;
import clips.dicom.waveform.DICOMWaveformGroup;
import cli_fmw.utils.MessageBox;
import java.awt.EventQueue;
import java.io.IOException;
import java.net.BindException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.event.EventListenerList;
/**
*
* @author finder
*/
final public class Agregator implements DICOMImageEventsHandler, DICOMWaveformEventHandler{
private LinkedList<AgregatorItem> items = new LinkedList<AgregatorItem>();
private LinkedList<Collection<? extends DICOMChekup>>buff = null;
private EventListenerList listenerList = new EventListenerList();
Runnable newItemsPorcessor = new Runnable() {
@Override
public void run() {
processAccept();
}
};
public void onAcceptImp(Collection<? extends DICOMChekup> chekups){
if (chekups.size() <= 0) {
return;
}
synchronized(this){
if (buff == null) {
buff = new LinkedList<Collection<? extends DICOMChekup>>();
}
buff.add(chekups);
}
EventQueue.invokeLater(newItemsPorcessor);
}
@Override
public void onImageAccept(Collection<DICOMImage> images, DICOMDeviceParam device) {
onAcceptImp(images);
}
@Override
public void onWaveAccept(Collection<DICOMWaveformGroup> waves, DICOMDeviceParam device) {
onAcceptImp(waves);
}
private AgregatorItem findItemBySeriesImp(String uid){
for (AgregatorItem agrItem : items) {
if (agrItem.getSeriesUID() != null && agrItem.getSeriesUID().equals(uid)) {
return agrItem;
}
}
return null;
}
private AgregatorItem findItemBySeriesImp(String uid, AgregatorItem.ItemsType type){
for (AgregatorItem agrItem : items) {
if (agrItem.getSeriesUID() != null && agrItem.getSeriesUID().equals(uid) && agrItem.getItemsType().equals(type)) {
return agrItem;
}
}
return null;
}
private void processAccept(){
LinkedList<Collection<? extends DICOMChekup>> newimages;
synchronized(this){
newimages = buff;
buff = null;
}
if (newimages == null) {
return;
}
ChangeType ctype = null;
for (Collection<? extends DICOMChekup> collection: newimages) {
if (collection.size() > 0){
DICOMChekup cu = collection.iterator().next();
String series = cu.getSeriesUID();
AgregatorItem.ItemsType type = AgregatorItem.ItemsType.indefine(cu);
AgregatorItem agrItem;
if (series != null) {
agrItem = findItemBySeriesImp(series, type);
}
else {
agrItem = null;
}
if (agrItem != null){
agrItem.addItemsWithCheck(collection);
ctype = ChangeType.modifedItems;
}
else{
items.add(new AgregatorItem(collection, type));
ctype = ChangeType.addedItems;
}
}
}
if (ctype != null){
notifyListeners(new ItemEvent(this, ctype));
}
}
protected void notifyListeners(ItemEvent e){
AgregatorListener[] listeners = listenerList.getListeners(AgregatorListener.class);
for (AgregatorListener listener : listeners) {
listener.agregatorItemsChanged(e);
}
}
protected void addListenerInt(AgregatorListener listener){
listenerList.add(AgregatorListener.class, listener);
}
protected void removeListenerInt(AgregatorListener listener){
listenerList.remove(AgregatorListener.class, listener);
}
protected int getListenerCountInt(){
return listenerList.getListenerCount(AgregatorListener.class);
}
protected Iterator<AgregatorItem> iteratorInt() {
return items.iterator();
}
protected ArrayList<AgregatorItem> getItemsInt(){
return new ArrayList<AgregatorItem>(items);
}
protected boolean removeItemInt(AgregatorItem item){
for (Iterator<AgregatorItem> it = items.iterator(); it.hasNext();) {
AgregatorItem agregatorItem = it.next();
if (agregatorItem == item){
it.remove();
notifyListeners(new ItemEvent(this, ChangeType.deletedItems));
return true;
}
}
return false;
}
private void finallyRemoveItemImp(AgregatorItem item) {
for (AgregatorItem item1 : items) {
if (item == item1){
return;
}
}
try {
item.clearSafeStore();
} catch (IOException ex) {
MessageBox.showExceptionOnly(ex);
}
}
private void saveItemOrFinallyRemoveImp(AgregatorItem item) {
for (AgregatorItem item1 : items) {
if (item == item1){
item.saveToSafeStore();
return;
}
}
try {
item.clearSafeStore();
} catch (IOException ex) {
MessageBox.showExceptionOnly(ex);
}
}
protected void addItemInt(AgregatorItem item){
AgregatorItem agregatorItem = findItemBySeriesImp(item.getSeriesUID(), item.getItemsType());
if (agregatorItem != null){
if (agregatorItem != item){
agregatorItem.addItemsWithCheck(item.getItems());
notifyListeners(new ItemEvent(this, ChangeType.modifedItems));
}
}
else{
items.add(item);
notifyListeners(new ItemEvent(this, ChangeType.addedItems));
}
}
void dispose(){
}
// --- singleton interface
static protected Agregator agregator = null;
static protected Thread dumpLoaderThread = null;
static public void start() throws DICOMException, IOException{
if (agregator != null) {
throw new DICOMException("Попытка повторного запуска!");
}
agregator = new Agregator();
try{
DICOMDataInput.addEventHandler((DICOMImageEventsHandler)agregator);
DICOMDataInput.addEventHandler((DICOMWaveformEventHandler)agregator);
DICOMDataInput.start(new ClipsDicomConfigStore());
// если сокет забиндин, то летит BindException и не чего не грузится
dumpLoaderThread = new Thread(new DumpLoader());
dumpLoaderThread.start();
}
catch (RuntimeException ex){
stop();
throw ex;
}
catch (DICOMException ex){
stop();
throw ex;
}
catch (BindException ex){
MessageBox.printStackTrace(ex);
}
catch (IOException ex){
stop();
throw ex;
}
}
static public void stop() throws DICOMException{
if (agregator == null) {
throw new DICOMException("Попытка останова незапущенного сервиса!");
}
if (dumpLoaderThread != null && dumpLoaderThread.isAlive()){
try {
dumpLoaderThread.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
throw new RuntimeException("Непредвиденна ошибка", ex);
}
}
dumpLoaderThread = null;
if (DICOMDataInput.started()){
DICOMDataInput.stop();
DICOMDataInput.removeEventHandler((DICOMImageEventsHandler)agregator);
DICOMDataInput.removeEventHandler((DICOMWaveformEventHandler)agregator);
}
agregator.dispose();
agregator = null;
}
static public void removeListener(AgregatorListener listener) {
agregator.removeListenerInt(listener);
}
static public boolean removeItem(AgregatorItem item) {
return agregator.removeItemInt(item);
}
/**
* Удаляет элемент из из безопастного хранилища, если он уже удален из агрегатора
* @param item - элемент который необходимо удалить
*/
static public void finallyRemoveItem(AgregatorItem item) {
agregator.finallyRemoveItemImp(item);
}
/**
* Удаляет элемент из из безопастного хранилища, если он уже удален из агрегатора,
* или сохраняет его, если нет
* @param item - элемент который необходимо сохранить или удалить
*/
static public void saveItemOrFinallyRemove(AgregatorItem item) {
agregator.saveItemOrFinallyRemoveImp(item);
}
static public Iterator<AgregatorItem> iterator() {
return agregator.iteratorInt();
}
static public ArrayList<AgregatorItem> getItems() {
return agregator.getItemsInt();
}
static public void addListener(AgregatorListener listener) {
agregator.addListenerInt(listener);
}
static public int getListenerCount() {
return agregator.getListenerCountInt();
}
static public void addItem(AgregatorItem item) {
agregator.addItemInt(item);
}
static public void onAccept(Collection<? extends DICOMChekup> chekups) {
agregator.onAcceptImp(chekups);
}
}