Package net.sf.jabref.imports

Source Code of net.sf.jabref.imports.JSTORFetcher

package net.sf.jabref.imports;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.StringTokenizer;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

import net.sf.jabref.BibtexEntry;
import net.sf.jabref.GUIGlobals;
import net.sf.jabref.Globals;
import net.sf.jabref.OutputPrinter;

/**
* This class fetches up to 200 citations from JStor by a given search query. It
* communicates with jstor via HTTP and Cookies. The fetcher automates the
* following steps:
* <ol>
* <li>Do a basic search on www.jstor.org</li>
* <li>Save the first 200 hits</li>
* <li>Download the saved citations as bibtex</li>
* <li>Parse it with the BibtexParser</li>
* <li>Import the BibtexEntrys via the ImportInspectionDialog</li>
* </ol>
*
* @author Juliane Doege, Tobias Langner
*/
public class JSTORFetcher implements EntryFetcher {

    /**
     * cookies can't save more than 200 citations
     */
    protected static int MAX_CITATIONS = 200;

    /**
     * Cookie key for Jstor ticket (authentication)
     */
    protected static final String COOKIE_TICKET = "Jstor_Ticket";

    /**
     * location where the ticket is obtained
     *
     */
    protected static final String URL_TICKET = "http://www.jstor.org/search";

    /**
     * Cookie key for citations to be fetched
     *
     */
    protected static final String COOKIE_CITATIONS = "Jstor_citations0";

    /**
     * location where to obtain the citations cookie
     *
     */
    protected static final String URL_BIBTEX = "http://www.jstor.org/browse/citations.txt?exportFormat=bibtex&exportAction=Display&frame=noframe&dpi=3&config=jstor&viewCitations=1&View=View";

    public String getHelpPage() {
        return "JSTOR.html";
    }

    public URL getIcon() {
        return GUIGlobals.getIconUrl("www");
    }

    public String getKeyName() {
        return "Search JSTOR";
    }

    public JPanel getOptionsPanel() {
        // No Options panel
        return null;
    }

    public String getTitle() {
        return Globals.menuTitle("Search JSTOR");
    }
   
    public void stopFetching() {
        // cannot be interrupted
    }

    public boolean processQuery(String query, ImportInspector dialog, OutputPrinter status) {

        try {
            // First open a ticket with JStor
            String ticket = openTicket();

            // Then execute the query
            String citations = getCitations(ticket, query);

            // Last retrieve the Bibtex-entries of the citations found
            Collection<BibtexEntry> entries = getBibtexEntries(ticket, citations);
           
            if (entries.size() == 0){
                status.showMessage(Globals.lang("No entries found for the search string '%0'",
                        query),
                        Globals.lang("Search JSTOR"), JOptionPane.INFORMATION_MESSAGE);
                return false;
            }
           
            for (BibtexEntry entry : entries){
                dialog.addEntry(entry);
            }
            return true;
        } catch (IOException e) {
            status.showMessage(Globals.lang("Error while fetching from JSTOR") + ": " + e.getMessage());
        }
        return false;
    }

    /**
     * Given a ticket an a list of citations, retrieve BibtexEntries from JStor
     *
     * @param ticket
     *            A valid ticket as returned by openTicket()
     * @param citations
     *            A list of citations as returned by getCitations()
     * @return A collection of BibtexEntries parsed from the bibtex returned by
     *         JStor.
     * @throws IOException
     *             Most probably related to a problem connecting to JStor.
     */
    protected Collection<BibtexEntry> getBibtexEntries(String ticket, String citations)
        throws IOException {
        try {
            URL url = new URL(URL_BIBTEX);
            URLConnection conn = url.openConnection();
            conn.setRequestProperty("Cookie", ticket + "; " + citations);
            conn.connect();

            BibtexParser parser = new BibtexParser(new BufferedReader(new InputStreamReader(conn
                .getInputStream())));
            return parser.parse().getDatabase().getEntries();
        } catch (MalformedURLException e) {
            // Propagate...
            throw new RuntimeException(e);
        }
    }

    /**
     *
     * @return a Jstor ticket ID
     * @throws IOException
     */
    protected String openTicket() throws IOException {
        URL url = new URL(URL_TICKET);
        URLConnection conn = url.openConnection();
        return getCookie(COOKIE_TICKET, conn);
    }

    /**
     * requires a valid JStor Ticket ID
     *
     * @param query
     *            The search term to query JStor for.
     * @param ticket
     *            JStor ticket
     * @return cookie value of the key JSTORFetcher.COOKIE_CITATIONS. null if
     *         search is empty or ticket is invalid
     * @throws IOException
     */
    protected String getCitations(String ticket, String query) throws IOException {
        String urlQuery;
        try {
            urlQuery = "http://www.jstor.org/search/BasicResults?hp=" + MAX_CITATIONS +
                "&si=1&gw=jtx&jtxsi=1&jcpsi=1&artsi=1&Query=" + URLEncoder.encode(query, "UTF-8") +
                "&wc=on&citationAction=saveAll";
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }

        URL url = new URL(urlQuery);
        URLConnection conn = url.openConnection();
        conn.setRequestProperty("Cookie", ticket);
        return getCookie(COOKIE_CITATIONS, conn);
    }

    /**
     * evaluates the 'Set-Cookie'-Header of a HTTP response
     *
     * @param name
     *            key of a cookie value
     * @param conn
     *            URLConnection
     * @return cookie value referenced by the key. null if key not found
     * @throws IOException
     */
    public static String getCookie(String name, URLConnection conn) throws IOException {

        for (int i = 0;; i++) {
            String headerName = conn.getHeaderFieldKey(i);
            String headerValue = conn.getHeaderField(i);

            if (headerName == null && headerValue == null) {
                // No more headers
                break;
            }
            if (headerName != null && headerName.equals("Set-Cookie")) {
                if (headerValue.startsWith(name)) {
                    // several key-value-pairs are separated by ';'
                    StringTokenizer st = new StringTokenizer(headerValue, "; ");
                    while (st.hasMoreElements()) {
                        String token = st.nextToken();
                        if (token.startsWith(name)) {
                            return token;
                        }
                    }
                }
            }

        }
        return null;
    }

}
TOP

Related Classes of net.sf.jabref.imports.JSTORFetcher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.