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-sdk-ext. 005 * 006 * Dicoogle/dicoogle-sdk-ext 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-sdk-ext 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.sdk.p2p.Messages.Handlers; 020 021import java.io.ByteArrayInputStream; 022import java.io.IOException; 023import java.util.ArrayList; 024import java.util.HashMap; 025import java.util.List; 026import java.util.Map; 027import java.util.Observable; 028import java.util.Observer; 029import org.slf4j.LoggerFactory; 030import org.dom4j.Document; 031import org.dom4j.DocumentException; 032import org.dom4j.Element; 033import org.dom4j.io.SAXReader; 034import pt.ua.dicoogle.sdk.NetworkPluginAdapter; 035import pt.ua.dicoogle.sdk.Utils.TaskRequest; 036import pt.ua.dicoogle.sdk.Utils.TaskRequestsConstants; 037import pt.ua.dicoogle.sdk.datastructs.SearchResult; 038import pt.ua.dicoogle.sdk.p2p.Messages.Builders.MessageBuilder; 039import pt.ua.dicoogle.sdk.p2p.Messages.MessageFields; 040import pt.ua.dicoogle.sdk.p2p.Messages.MessageI; 041import pt.ua.dicoogle.sdk.p2p.Messages.MessageXML; 042 043/** 044 * 045 * @author Carlos Ferreira 046 * @author Pedro Bento 047 */ 048public class QueryHandler implements MessageHandler, Observer 049{ 050 051 private int maxResultsPerMessage; 052 //private ListObservable<TaskRequest> tasks; 053 private NetworkPluginAdapter plugin; 054 055 public QueryHandler(int maxResultsPerMessage, NetworkPluginAdapter plugin) 056 { 057 this.plugin = plugin; 058 this.maxResultsPerMessage = maxResultsPerMessage; 059 } 060 061 public void handleMessage(MessageI message, String sender) 062 { 063 if (!MessageXML.class.isInstance(message)) 064 { 065 return; 066 } 067 068 byte[] msg = (byte[]) message.getMessage(); 069 070 SAXReader saxReader = new SAXReader(); 071 072 Document document = null; 073 try 074 { 075 document = saxReader.read(new ByteArrayInputStream(msg)); 076 } catch (DocumentException ex) 077 { 078 ex.printStackTrace(System.out); 079 } 080 081 /** 082 * Reading the message XML, getting the necessary fields. 083 */ 084 Element root = document.getRootElement(); 085 String query; 086 Element queryNumber = root.element(MessageFields.QUERY_NUMBER); 087 List<String> extra = new ArrayList(); 088 Element queryE = root.element(MessageFields.QUERY); 089 /** 090 * If the message has not the query element, then it is an invalid message 091 * ignore it. 092 */ 093 if (queryE == null) 094 { 095 return; 096 } 097 query = queryE.getText(); 098 List<Element> extrafields = root.elements(MessageFields.EXTRAFIELD); 099 if (extrafields == null) 100 { 101 extrafields = new ArrayList(); 102 } 103 for (Element extrafield : extrafields) 104 { 105 extra.add(extrafield.getText()); 106 } 107 108 /** 109 * Local search. 110 */ 111 Map<Integer, Object> parameters = new HashMap<Integer, Object>(); 112 parameters.put(TaskRequestsConstants.P_QUERY, query); 113 parameters.put(TaskRequestsConstants.P_EXTRAFIELDS, extra); 114 parameters.put(TaskRequestsConstants.P_REQUESTER_ADDRESS, sender); 115 parameters.put(TaskRequestsConstants.P_QUERY_NUMBER, queryNumber.getText()); 116 117 TaskRequest task = new TaskRequest(TaskRequestsConstants.T_QUERY_LOCALLY, 118 this.plugin.getName(), parameters); 119 task.addObserver(this); 120 121 this.plugin.getTaskRequestsList().addTask(task); 122 123 124 // ArrayList<SearchResult> resultsAll = IndexEngine.getInstance().search(query, extra); 125 // 126 } 127 128 public void update(Observable o, Object arg) 129 { 130 131 if (!TaskRequest.class.isInstance(o)) 132 { 133 return; 134 } 135 136 TaskRequest task = (TaskRequest) o; 137 138 139 Map<Integer, Object> res = task.getResults(); 140 Object SR = res.get(TaskRequestsConstants.R_SEARCH_RESULTS); 141 if ((SR == null) || (!ArrayList.class.isInstance(SR))) 142 { 143 return; 144 } 145 146 ArrayList<SearchResult> resultsAll = (ArrayList<SearchResult>) SR; 147 List<SearchResult> results; 148 /** 149 * Build of the response for the query 150 */ 151 MessageBuilder builder = new MessageBuilder(); 152 MessageI newMessage = null; 153 for (int i = 0; i < resultsAll.size(); i += maxResultsPerMessage) 154 { 155 int size = maxResultsPerMessage; 156 if (i + maxResultsPerMessage > resultsAll.size()) 157 { 158 size = resultsAll.size() - i; 159 } 160 161 results = resultsAll.subList(i, i + size); 162 try 163 { 164 newMessage = builder.buildQueryResponse(results, (String) task.getParameters().get(TaskRequestsConstants.P_QUERY_NUMBER), this.plugin.getName()); 165 } catch (IOException ex) 166 { 167 LoggerFactory.getLogger(QueryHandler.class).error(ex.getMessage(), ex); 168 } 169 170 /** 171 * Sending the response 172 */ 173 if (newMessage != null) 174 { 175 176 this.plugin.send(newMessage, (String) task.getParameters().get(TaskRequestsConstants.P_REQUESTER_ADDRESS)); 177 } 178 } 179 } 180}