/*
* Copyright 2010-2015 Institut Pasteur.
*
* This file is part of Icy.
*
* Icy is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Icy is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Icy. If not, see <http://www.gnu.org/licenses/>.
*/
package icy.search;
import icy.network.URLUtil;
import icy.system.thread.ThreadUtil;
import icy.util.XMLUtil;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.w3c.dom.Document;
/**
* The OnlineSearchResultProducer is the basic class for {@link SearchResult} producer from online
* results.<br>
* It does use a single static instance to do the online search then dispatch XML result the
* overriding class.
*
* @author Stephane Dallongeville
* @see SearchResultProducer
*/
public abstract class OnlineSearchResultProducer extends SearchResultProducer
{
protected static final String SEARCH_URL = "http://bioimageanalysis.org/icy/search/search.php?search=";
protected static final long REQUEST_INTERVAL = 400;
protected static final long MAXIMUM_SEARCH_TIME = 10000;
// we want to have only one online search shared between all online providers
protected static volatile boolean searchingOnline = false;
protected static Document document = null;
@Override
public void doSearch(String[] words, SearchResultConsumer consumer)
{
if (searchingOnline)
{
// just wait while searching end
while (searchingOnline)
{
// abort
if (hasWaitingSearch())
return;
ThreadUtil.sleep(10);
}
}
else
{
// do the online search
searchingOnline = true;
try
{
document = null;
String request = SEARCH_URL;
try
{
if (words.length > 0)
request += URLEncoder.encode(words[0], "UTF-8");
for (int i = 1; i < words.length; i++)
request += "%20" + URLEncoder.encode(words[i], "UTF-8");
}
catch (UnsupportedEncodingException e)
{
// can't encode
return;
}
final long startTime = System.currentTimeMillis();
// wait interval elapsed before sending request (avoid website request spam)
while ((System.currentTimeMillis() - startTime) < REQUEST_INTERVAL)
{
ThreadUtil.sleep(10);
// abort
if (hasWaitingSearch())
return;
}
int retry = 0;
// let's 5 tries to get the result
while (((System.currentTimeMillis() - startTime) < MAXIMUM_SEARCH_TIME) && (document == null)
&& (retry < 5))
{
// we use an online request as website can search in plugin documentation
document = XMLUtil.loadDocument(URLUtil.getURL(request), false);
// abort
if (hasWaitingSearch())
return;
// error ? --> wait a bit before retry
if (document == null)
ThreadUtil.sleep(100);
retry++;
}
// can't get result from website --> exit
if (document == null)
return;
// already have other pending search --> exit
if (hasWaitingSearch())
return;
}
finally
{
searchingOnline = false;
}
}
final Document doc = document;
// another search waiting or error --> exit
if (hasWaitingSearch() || (doc == null))
return;
doSearch(doc, words, consumer);
}
public abstract void doSearch(Document doc, String[] words, SearchResultConsumer consumer);
}