001/** 002 * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/ 003 * 004 * This file is part of Dicoogle/dicoogle. 005 * 006 * Dicoogle/dicoogle is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Dicoogle/dicoogle is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Dicoogle. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package pt.ua.dicoogle.server.web.dicom; 020 021import java.util.ArrayList; 022import java.util.HashMap; 023import java.util.Iterator; 024import java.util.List; 025import java.util.Map; 026import java.util.concurrent.ExecutionException; 027 028import org.apache.commons.collections.Buffer; 029import org.apache.commons.collections.BufferUtils; 030import org.apache.commons.collections.KeyValue; 031import org.apache.commons.collections.buffer.UnboundedFifoBuffer; 032import org.apache.commons.collections.keyvalue.DefaultKeyValue; 033 034import pt.ua.dicoogle.plugins.PluginController; 035import pt.ua.dicoogle.sdk.datastructs.SearchResult; 036import pt.ua.dicoogle.sdk.task.JointQueryTask; 037import pt.ua.dicoogle.sdk.task.Task; 038 039public class SearchHolder { 040 041 @SuppressWarnings("unused") //TODO: IMPLEMENT THIS 042 private static int maxNumberOfTasks = 3; 043 private Map<Integer, QueryHandler> tasks; 044 045 public SearchHolder() { 046 tasks = new HashMap<Integer, SearchHolder.QueryHandler>(); 047 } 048 049 public synchronized int registerNewQuery(List<String> providers, String query, Object searchParam){ 050 QueryHandler task = new QueryHandler(); 051 052 task = (QueryHandler) PluginController.getInstance().query(task, providers, query, searchParam); 053 if(task == null) 054 return -1; 055 056 tasks.put(task.hashCode(), task); 057 return task.hashCode(); 058 } 059 060 public synchronized void removeQuery(int id){ 061 tasks.remove(id); 062 } 063 064 public synchronized Iterable<KeyValue> retrieveQueryOutput(int id){ 065 QueryHandler task = tasks.get(id); 066 067 if(task == null) 068 return null; 069 070 return task; 071 } 072 073 private class QueryHandler extends JointQueryTask implements Iterable<KeyValue>{ 074 075 private StringBuffer buffer; 076 private List<KeyValue> tempResults; 077 private List<InnerIterator> currentIterators; 078 079 public QueryHandler() { 080 super(); 081 buffer = new StringBuffer(); 082 currentIterators = new ArrayList<InnerIterator>(); 083 tempResults = new ArrayList<>(); 084 } 085 086 @Override 087 public void onCompletion() { 088 // TODO Auto-generated method stub 089 System.out.println("Completed Query"); 090 } 091 092 @Override 093 public void onReceive(Task<Iterable<SearchResult>> e) { 094 // TODO Auto-generated method stub 095 try { 096 System.out.println("RECEIVED NEW ITERATION: "); 097 098 Iterable<SearchResult> results = e.get(); 099 DefaultKeyValue keyValue = new DefaultKeyValue(e.getName(), results); 100 101 appendResult(keyValue); 102 103 /*for(SearchResult res : results ){ 104 105 }*/ 106 } catch (InterruptedException | ExecutionException e1) { 107 // TODO Auto-generated catch block 108 //e1.printStackTrace(); 109 } 110 111 buffer.append("Received Query: "+e.getName()); 112 } 113 114 @SuppressWarnings("unchecked") 115 private synchronized void appendResult(DefaultKeyValue keyValue) { 116 tempResults.add(keyValue); 117 118 for(InnerIterator it : currentIterators){ 119 it.resultBuffer.add(keyValue); 120 } 121 } 122 123 private synchronized InnerIterator createIterator(){ 124 InnerIterator it = new InnerIterator(tempResults); 125 currentIterators.add(it); 126 127 return it; 128 } 129 130 @Override 131 public Iterator<KeyValue> iterator() { 132 if(isDone() || isCancelled()) 133 return tempResults.iterator(); 134 135 return createIterator(); 136 } 137 138 private class InnerIterator implements Iterator<KeyValue>{ 139 140 private Buffer resultBuffer; 141 142 @SuppressWarnings("unchecked") 143 public InnerIterator(List<KeyValue> tempResults) { 144 int size = tempResults.size(); 145 if(size <= 0) 146 size = 1; 147 resultBuffer = BufferUtils.blockingBuffer( new UnboundedFifoBuffer(size) ); 148 resultBuffer.addAll(tempResults); 149 } 150 151 @Override 152 public boolean hasNext() { 153 if(!(isCancelled() || isDone())) 154 return true; 155 156 return !resultBuffer.isEmpty(); 157 } 158 159 @Override 160 public KeyValue next() { 161 return (KeyValue) resultBuffer.remove(); 162 } 163 164 @Override 165 public void remove() { 166 } 167 168 } 169 170 } 171 172 public boolean isDone(int id) { 173 QueryHandler task = tasks.get(id); 174 175 if(task == null) 176 return true; 177 178 return task.isDone() || task.isCancelled(); 179 } 180 181}