org.siberia.image.searcher.impl.GoogleImageSearcher.java Source code

Java tutorial

Introduction

Here is the source code for org.siberia.image.searcher.impl.GoogleImageSearcher.java

Source

/* 
 * Siberia image searcher : siberia plugin defining image searchers
 *
 * Copyright (C) 2008 Alexis PARIS
 * Project Lead:  Alexis Paris
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library;
 * if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 */
package org.siberia.image.searcher.impl;

import org.siberia.image.searcher.AbstractImageSearcher;
import org.siberia.image.searcher.ImageSize;
import org.siberia.image.searcher.event.ImageFoundEvent;
import org.siberia.image.searcher.event.ImageSearcherEvent;
import org.siberia.image.searcher.event.ImageSearcherListener;
import java.awt.Image;
import java.awt.Toolkit;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.EventListenerList;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.log4j.Logger;

/**
 *
 * Object that is able to do search about images on google search engine
 *
 * @author Alexis
 */
public class GoogleImageSearcher extends AbstractImageSearcher {
    /** logger */
    private transient Logger logger = Logger.getLogger(GoogleImageSearcher.class);

    /** url du site de recherche d'images de google */
    private static final String GOOGLE_URL = "http://images.google.com/images";

    /** nom du paramtre html pour la taille de l'image */
    private static final String PARAMETER_IMAGE_SIZE = "imgsz";

    /** nom du paramtre html pour la la locale */
    private static final String PARAMETER_LOCALE = "hl";

    /** nom du paramtre html pour les paramtres de recherche */
    private static final String PARAMETER_TOKENS = "q";

    /** list de liens trouvs */
    private List<URL> linkFound = null;

    /** executor service */
    private ExecutorService service = Executors.newFixedThreadPool(5);

    /** list of futures */

    /** Creates a new instance of ImageResearch
     *  @param criterions une liste de critres de recherches
     */
    public GoogleImageSearcher() {
    }

    /** convert an ImageSize into a String that google understand
     *   @param size an Imagesize
     *   @return a String
     */
    private String convertImageSizeCriterion(ImageSize size) {
        String converted = null;

        if (size != null) {
            if (size.equals(ImageSize.ICON)) {
                converted = "icon";
            }
            if (size.equals(ImageSize.MEDIUM)) {
                converted = "small|medium|large|xlarge";
            }
            if (size.equals(ImageSize.LARGE)) {
                converted = "xxlarge";
            }
            if (size.equals(ImageSize.HUGE)) {
                converted = "huge";
            }
        }

        if (converted == null) {
            converted = "";
        }

        return converted;
    }

    /** cancel search */
    public void cancel() {
        if (this.service != null) {
            this.service.shutdownNow();

            // bof ... a revoir
            this.service = Executors.newFixedThreadPool(5);
        }
    }

    /** search */
    public void search() {

        //        http://images.google.fr/images?imgsz=xxlarge&gbv=2&hl=fr&q=b+e&btnG=Recherche+d%27images
        //        http://images.google.fr/images?imgsz=xxlarge&hl=fr&q=b+e

        Runnable run = new Runnable() {
            public void run() {
                fireSearchHasBegan(new ImageSearcherEvent(GoogleImageSearcher.this));

                StringBuffer buffer = new StringBuffer(50);

                if (getCriterions() != null) {
                    boolean oneTokenAlreadyApplied = false;

                    for (int i = 0; i < getCriterions().length; i++) {
                        String current = getCriterions()[i];

                        if (current != null) {
                            if (oneTokenAlreadyApplied) {
                                buffer.append("+");
                            }

                            buffer.append(current);

                            oneTokenAlreadyApplied = true;
                        }
                    }
                }

                Locale locale = getLocale();
                if (locale == null) {
                    locale = Locale.getDefault();
                }

                if (logger.isDebugEnabled()) {
                    logger.debug("uri : " + buffer.toString());
                }

                HttpClient client = new HttpClient();

                HttpMethod method = new GetMethod(GOOGLE_URL);

                NameValuePair[] pairs = new NameValuePair[3];
                pairs[0] = new NameValuePair("imgsz", convertImageSizeCriterion(getImageSize()));
                pairs[1] = new NameValuePair("hl", locale.getCountry().toLowerCase());
                pairs[2] = new NameValuePair("q", buffer.toString());
                method.setQueryString(pairs);

                method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                        new DefaultHttpMethodRetryHandler(3, false));

                InputStream stream = null;

                try {
                    // Execute the method.
                    int statusCode = client.executeMethod(method);

                    if (statusCode == HttpStatus.SC_OK) {
                        /** on recherche  partir des motifs suivants
                         *  la premire occurrence de http://  partir de l, on prend jusqu'au prochaine espace ou '>' :
                         *
                         *  exemple :
                         *      <img src=http://tbn0.google.com/images?q=tbn:GIJo-j_dSy4FiM:http://www.discogs.com/image/R-378796-1136999170.jpeg width=135 height=135>
                         *
                         *  on trouve le motif, puis, on prend  partir de http://www.discogs jusqu'au prochain espace...
                         *
                         *  --> http://www.discogs.com/image/R-378796-1136999170.jpeg
                         */
                        String searchMotif = "<img src=http://tbn0.google.com/images?q";
                        String urlMotif = "http://";

                        int indexInSearchMotif = -1;
                        int indexInUrlMotif = -1;
                        boolean motifFound = false;
                        boolean foundUrl = false;

                        StringBuffer urlBuffer = new StringBuffer(50);

                        // Read the response body.
                        byte[] bytes = new byte[1024 * 8];
                        stream = method.getResponseBodyAsStream();

                        if (stream != null) {
                            int read = -1;

                            int linksRetrieved = 0;

                            while ((read = stream.read(bytes)) != -1) {
                                for (int i = 0; i < read; i++) {
                                    byte currentByte = bytes[i];

                                    if (motifFound) {
                                        if (foundUrl) {
                                            if (currentByte == ' ' || currentByte == '>') {
                                                /* add current url to list of result */
                                                try {
                                                    URL url = new URL(urlBuffer.toString());

                                                    fireImageFound(new ImageFoundEvent(GoogleImageSearcher.this,
                                                            url, linksRetrieved));
                                                    linksRetrieved++;

                                                    if (linksRetrieved >= getMaximumLinksRetrieved()) {
                                                        break;
                                                    }
                                                } catch (Exception e) {
                                                    e.printStackTrace();
                                                } finally {
                                                    urlBuffer.delete(0, urlBuffer.length());

                                                    foundUrl = false;
                                                    motifFound = false;
                                                }
                                            } else {
                                                /* add current byte to url buffer */
                                                urlBuffer.append((char) currentByte);
                                            }
                                        } else {
                                            if (indexInUrlMotif == urlMotif.length() - 1) {
                                                urlBuffer.append(urlMotif);
                                                urlBuffer.append((char) currentByte);
                                                foundUrl = true;
                                                indexInUrlMotif = -1;
                                            }

                                            /* if the current byte is the same as that attempted on the url motif let's continue */
                                            if (((char) currentByte) == urlMotif.charAt(indexInUrlMotif + 1)) {
                                                indexInUrlMotif++;
                                            } else {
                                                indexInUrlMotif = -1;
                                            }
                                        }
                                    } else {
                                        if (indexInSearchMotif == searchMotif.length() - 1) {
                                            motifFound = true;
                                            indexInSearchMotif = -1;
                                        }

                                        if (((char) currentByte) == searchMotif.charAt(indexInSearchMotif + 1)) {
                                            indexInSearchMotif++;
                                        } else {
                                            indexInSearchMotif = -1;
                                        }
                                    }
                                }
                                if (linksRetrieved >= getMaximumLinksRetrieved()) {
                                    break;
                                }
                            }
                        }
                    } else {
                        System.err.println("Method failed: " + method.getStatusLine());
                    }
                } catch (HttpException e) {
                    System.err.println("Fatal protocol violation: " + e.getMessage());
                    e.printStackTrace();
                } catch (IOException e) {
                    if (stream != null) {
                        try {
                            stream.close();
                        } catch (IOException ex) {
                            System.err.println("Fatal transport error: " + ex.getMessage());
                        }
                    }
                    System.err.println("Fatal transport error: " + e.getMessage());
                    e.printStackTrace();
                } finally { // Release the connection.
                    method.releaseConnection();

                    fireSearchFinished(new ImageSearcherEvent(GoogleImageSearcher.this));
                }
            }
        };

        this.service.submit(run);
    }
}