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.util.ArrayList;
023import java.util.HashMap;
024import java.util.List;
025import org.dom4j.Document;
026import org.dom4j.DocumentException;
027import org.dom4j.Element;
028import org.dom4j.io.SAXReader;
029import pt.ua.dicoogle.sdk.NetworkPluginAdapter;
030import pt.ua.dicoogle.sdk.observables.ListObservable;
031import pt.ua.dicoogle.sdk.p2p.Messages.MessageFields;
032import pt.ua.dicoogle.sdk.p2p.Messages.MessageI;
033import pt.ua.dicoogle.sdk.p2p.Messages.MessageXML;
034import pt.ua.dicoogle.sdk.p2p.Messages.SearchResultFields;
035import pt.ua.dicoogle.sdk.Utils.QueryNumber;
036import pt.ua.dicoogle.sdk.datastructs.SearchResult;
037
038/**
039 *
040 * @author Carlos Ferreira
041 * @author Pedro Bento
042 */
043public class QueryResponseHandler implements MessageHandler
044{
045
046    private NetworkPluginAdapter NPA;
047    private ListObservable<SearchResult> results;
048
049    public QueryResponseHandler(NetworkPluginAdapter NPA, ListObservable<SearchResult> results)
050    {
051        this.NPA = NPA;
052        this.results = results;
053    }
054
055    public void handleMessage(MessageI message, String sender)
056    {
057        if (!MessageXML.class.isInstance(message))
058        {
059            return;
060        }
061
062        MessageXML msg = (MessageXML) message;
063
064        /**
065         * leitura do pacote.
066         */
067        byte[] xml = msg.getMessage();
068        SAXReader saxReader = new SAXReader();
069
070        Document document = null;
071        try
072        {
073            document = saxReader.read(new ByteArrayInputStream(xml));
074        } catch (DocumentException ex)
075        {
076            ex.printStackTrace(System.out);
077        }
078
079        Element root = document.getRootElement();
080
081        /**
082         * Verification of the validity of the message
083         */
084        if (!root.getName().equals(MessageFields.MESSAGE))
085        {
086            return;
087        }
088
089        Element tmp = root.element(MessageFields.QUERY_NUMBER);
090        if (tmp == null)
091        {
092            return;
093        }
094
095        Integer queryNumber = null;
096        try
097        {
098            queryNumber = Integer.parseInt(tmp.getText());
099        } catch (Exception ex)
100        {
101            return;
102        }
103
104        /**
105         * if the queryNumber is not the most recent query's number, then ignore the message
106         * It is the response for a search deprecated.
107         * This will be checked again, nevertheless here it is checked to save time 
108         * with avoidable XML processing in case of the deprecation of the message received
109         */
110        if (queryNumber != QueryNumber.getInstance().getQueryNumber())
111        {
112            return;
113        }
114
115        tmp = root.element(MessageFields.SEARCH_RESULTS);
116        List<Element> Results = tmp.elements(MessageFields.SEARCH_RESULT);
117        List<SearchResult> res = new ArrayList<SearchResult>();
118        Element tmp2;
119        for (Element result : Results)
120        {
121            String Filename = null, FileHash = null, FileSize = null;
122            tmp2 = result.element(SearchResultFields.FILE_NAME);
123            if (tmp2 == null)
124            {
125                return;
126            }
127            Filename = tmp2.getText();
128
129            tmp2 = result.element(SearchResultFields.FILE_HASH);
130            if (tmp2 == null)
131            {
132                return;
133            }
134            FileHash = tmp2.getText();
135
136            tmp2 = result.element(SearchResultFields.FILE_SIZE);
137            if (tmp2 == null)
138            {
139                return;
140            }
141            FileSize = tmp2.getText();
142
143            tmp2 = result.element(SearchResultFields.EXTRAFIELDS);
144            if (tmp2 == null)
145            {
146                return;
147            }
148            List<Element> fields = tmp2.elements();
149            HashMap<String, Object> Extrafields = new HashMap();
150            for (Element field : fields)
151            {
152                Extrafields.put(field.getName(), field.getText());
153            }
154            //res.add(new SearchResult(FileHash, Filename, sender, FileSize, Extrafields, this.NPA.getName()));
155            throw new UnsupportedOperationException("FIX THIS!!!: qwe123");
156        }
157        synchronized (this.results) // monitor to queryNumber
158        {
159            if (queryNumber != QueryNumber.getInstance().getQueryNumber())
160            {
161                //System.out.println("different QueryNumber");
162                return;
163            }
164            this.results.resetArray();
165            this.results.addAll(res);
166            //System.out.println(this.results.getArray().size() + "results added to the observable");
167        }
168
169    }
170}