Logo Search packages:      
Sourcecode: jabref version File versions  Download package

CiteSeerFetcher.java

/*
 * Created on Jun 13, 2004
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package net.sf.jabref.imports;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeSet;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import net.sf.jabref.BibtexDatabase;
import net.sf.jabref.BibtexEntry;
import net.sf.jabref.GUIGlobals;
import net.sf.jabref.Globals;
import net.sf.jabref.KeyCollisionException;
import net.sf.jabref.SidePaneComponent;
import net.sf.jabref.SidePaneManager;
import net.sf.jabref.Util;
import net.sf.jabref.undo.NamedCompound;

import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * @author mspiegel
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
00055 public class CiteSeerFetcher extends SidePaneComponent {

    final static String CITESEER_HOST = "citeseer.ist.psu.edu";
      final static String PREFIX_URL = "http://" + CITESEER_HOST + "/";
      final static String PREFIX_IDENTIFIER = "oai:CiteSeerPSU:";
      final static String OAI_HOST = "http://cs1.ist.psu.edu/";
      final static String OAI_URL = OAI_HOST + "cgi-bin/oai.cgi?";
      final static String OAI_ACTION = "verb=GetRecord";
      final static String OAI_METADATAPREFIX ="metadataPrefix=oai_citeseer";
      protected SAXParserFactory parserFactory;
      protected SAXParser saxParser;
      
      boolean citationFetcherActive;
      boolean importFetcherActive;

      JProgressBar progressBar, progressBar2;
      JLabel citeSeerProgress;
      GridBagLayout gbl = new GridBagLayout();
      GridBagConstraints con = new GridBagConstraints();
      SidePaneManager sidePaneManager;


      public CiteSeerFetcher(SidePaneManager p0)  {
            super(p0, GUIGlobals.getIconUrl("citeseer"), Globals.lang("CiteSeer Transfer"));

            sidePaneManager = p0;
            progressBar = new JProgressBar();
            progressBar2 = new JProgressBar();
            citeSeerProgress = new JLabel();
            progressBar.setValue(0);
            progressBar.setMinimum(0);
            progressBar.setMaximum(100);
            progressBar.setStringPainted(true);
            progressBar2.setValue(0);
            progressBar2.setMinimum(0);
            progressBar2.setMaximum(100);
            progressBar2.setStringPainted(true);
                JPanel main = new JPanel();
            main.setLayout(gbl);
            //SidePaneHeader header = new SidePaneHeader
            //    ("CiteSeer Transfer", GUIGlobals.wwwCiteSeerIcon, this);
            con.gridwidth = GridBagConstraints.REMAINDER;               
            con.fill = GridBagConstraints.BOTH;
            con.weightx = 1;
            con.insets = new Insets(0, 0, 2,  0);
            //gbl.setConstraints(header, con);
            //add(header);
            con.insets = new Insets(0, 0, 0,  0);
            con.fill = GridBagConstraints.HORIZONTAL;       
            gbl.setConstraints(progressBar, con);
            main.add(progressBar);        
            gbl.setConstraints(progressBar2, con);
            main.add(progressBar2);
            gbl.setConstraints(citeSeerProgress, con);
            main.add(citeSeerProgress);         
                main.setBorder(BorderFactory.createEmptyBorder(1,1,1,1));
                add(main, BorderLayout.CENTER);
            try {
                  citationFetcherActive = false;
                  importFetcherActive = false;
                  parserFactory = SAXParserFactory.newInstance();
                  saxParser = parserFactory.newSAXParser();

            } catch (ParserConfigurationException e) {
                  e.printStackTrace();
            } catch (SAXException e) {
                  e.printStackTrace();
            }
      }

      /***********************************/
      /* Begin Inner Class Declarations */
      /* The inner classes are used to modify components, when not in the
       * event-dispatching thread.  These are used to follow the "single-threaded
       * rule", as defined here: http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html
       *
       *
       * I'm pretty sure the Dialog box invokers should remain as inner classes,
       * but I can't decide whether or not to break the one-thread rule for the
       * progress bar classes.  Because the search contains a locking-mechanism,
       * activateFetcher() and deactivateFetcher(), there should only be at-most-one
       * thread accessing the progress bar at any time.
       */

      class ShowEmptyFetchSetDialog implements Runnable {
      
            public void run() {
                  JOptionPane.showMessageDialog(panel.frame(),
                        Globals.lang("The CiteSeer fetch operation returned zero results" 
                                    + "."),
                        "CiteSeer",
                        JOptionPane.INFORMATION_MESSAGE);
                  deactivateCitationFetcher();
            }           
      }

      public ShowEmptyFetchSetDialog getEmptyFetchSetDialog() {
            return(new ShowEmptyFetchSetDialog());
      }
      
      class ShowNoConnectionDialog implements Runnable {
            protected String targetURL = "";
            ShowNoConnectionDialog(String URL) {
                        targetURL = URL;
            }
            public void run() {
                        JOptionPane.showMessageDialog(panel.frame(),
                        Globals.lang("Could not connect to host") + " " + targetURL + ".  " +
                        Globals.lang("Please check your network connection to this machine" + "."),
                        Globals.lang("CiteSeer Error"),
                        JOptionPane.ERROR_MESSAGE);
            }
      }

      class ShowBadIdentifiersDialog implements Runnable {

          Hashtable<Integer, BibtexEntry> rejectedEntries;
          
          ShowBadIdentifiersDialog(Hashtable<Integer, BibtexEntry> entries) {
              rejectedEntries = entries;
          }
          
        /* (non-Javadoc)
         * @see java.lang.Runnable#run()
         */
        public void run() {
            if (rejectedEntries.size() == 1) {
                
            } else if (rejectedEntries.size() > 1) {
                  int i;
                String rowNumbers = "";
                String oneRowOfNumbers = "";
                TreeSet<Integer> rowSet = new TreeSet<Integer>(rejectedEntries.keySet());
                int rowSize = rowSet.size();
                for(i=0; (i < rowSize - 1) && (i < 100); i++) {
                    Integer next = rowSet.first();
                    if (oneRowOfNumbers.equals(""))
                        oneRowOfNumbers = next.toString();
                    else {
                        oneRowOfNumbers = oneRowOfNumbers + ", ";
                        if (oneRowOfNumbers.length() > 50) {
                              oneRowOfNumbers = oneRowOfNumbers + "\n";
                              rowNumbers = rowNumbers + oneRowOfNumbers;
                              oneRowOfNumbers = "";
                        }
                        oneRowOfNumbers = oneRowOfNumbers + next.toString();
                    }
                    rowSet.remove(next);
                }
                  rowNumbers = rowNumbers + oneRowOfNumbers;
                  if (i == 100) {
                        rowNumbers = rowNumbers + "..";
                  } else {
                        rowNumbers = rowNumbers + " "+Globals.lang("and")+" " + rowSet.first().toString();
                  }
                JOptionPane.showMessageDialog(panel.frame(),
                        Globals.lang("Couldn't parse the 'citeseerurl' field of the following entries") + ':' + '\n' + 
                        rowNumbers + ".\n" + 
                        Globals.lang("Please refer to the JabRef help manual on using the CiteSeer tools" + '.'),
                        Globals.lang("Warning"),
                        JOptionPane.WARNING_MESSAGE);
            }
        }
      }     
      
      class ShowBadIdentifierDialog implements Runnable {
            protected String badURL = "";
            protected int rowNumber;

            ShowBadIdentifierDialog(String URL, int row) {
                  badURL = URL;
                  rowNumber = row;
            }
            public void run() {
                  JOptionPane.showMessageDialog(panel.frame(),
                  Globals.lang("Couldn't find an entry associated with this URL") + ": \"" + badURL + '\"' +
                  Globals.lang(" on entry number ") + (rowNumber + 1) + ".  " +
                  Globals.lang("Please refer to the JabRef help manual on using the CiteSeer tools."),
                  Globals.lang("CiteSeer Error"),
                  JOptionPane.ERROR_MESSAGE);
            }
      }
      
      class ShowBadURLDialog implements Runnable {
            protected String badURL = "";
            protected int rowNumber;

            ShowBadURLDialog(String URL, int row) {
                  badURL = URL;
                  rowNumber = row;
            }
            public void run() {
                  JOptionPane.showMessageDialog(panel.frame(),
                  Globals.lang("Unable to parse the following URL") + ": \"" + badURL + '\"' +
                  Globals.lang(" on entry number ") + (rowNumber + 1) + ".  " +
                  Globals.lang("Please refer to the JabRef help manual on using the CiteSeer tools."),
                  Globals.lang("CiteSeer Error"),
                  JOptionPane.ERROR_MESSAGE);
            }
      }

      class ShowMissingURLDialog implements Runnable {
            protected int rowNumber;

            ShowMissingURLDialog(int row) {
                  rowNumber = row;
            }
            public void run() {
                  JOptionPane.showMessageDialog(panel.frame(),
                  Globals.lang("The URL field appears to be empty on entry number ") + (rowNumber + 1) + ".  " +
                  Globals.lang("Please refer to the JabRef help manual on using the CiteSeer tools."),
                  Globals.lang("CiteSeer Error"),
                  JOptionPane.ERROR_MESSAGE);
            }
      }
      
      class UpdateProgressBarMaximum implements Runnable {
            protected int maximum;
            UpdateProgressBarMaximum(int newValue) {
                  maximum = newValue;
            }
            public void run() {
                  progressBar.setMaximum(maximum);
            }
      }

      class UpdateProgressBarTwoMaximum implements Runnable {
            protected int maximum;
            UpdateProgressBarTwoMaximum(int newValue) {
                  maximum = newValue;
            }
            public void run() {
                  progressBar2.setMaximum(maximum);
            }
      }

      class InitializeProgressBar implements Runnable {
          public void run() {
                  progressBar.setValue(0);
              progressBar.setMinimum(0);
                  progressBar.setMaximum(100);
                progressBar.setString(null);
          }
      }

      class InitializeProgressBarTwo implements Runnable {

            public void run() {
                  progressBar2.setValue(0);
              progressBar2.setMinimum(0);
                  progressBar2.setMaximum(100);
                progressBar2.setString(null);
          }
      }
            
      class UpdateProgressBarValue implements Runnable {
            protected int counter;
            UpdateProgressBarValue(int newValue) {
                  counter = newValue;
            }
            public void run() {
                  progressBar.setValue(counter);
            }
      }

      class UpdateProgressBarTwoValue implements Runnable {
            protected int counter;
            UpdateProgressBarTwoValue(int newValue) {
                  counter = newValue;
            }
            public void run() {
                  progressBar2.setValue(counter);
            }           
      }

      class UpdateProgressStatus implements Runnable {
            protected String status;
            UpdateProgressStatus(String newStatus) {
                  status = newStatus;
            }
            public void run() {
                  citeSeerProgress.setText(status);
            }
      }
      
      /* End Inner Class Declarations */


      /***********************************/

      synchronized public boolean activateCitationFetcher() {
            if (citationFetcherActive == true) {
                  return(false);
            }     else {
                  citationFetcherActive = true;
                  return(true);
            }
      }
      synchronized public void deactivateCitationFetcher() {
            citationFetcherActive = false;
      }

      synchronized public boolean activateImportFetcher() {
            if (importFetcherActive == true) {
                  return(false);
            }     else {
                  importFetcherActive = true;
                  return(true);
            }
      }
      synchronized public void deactivateImportFetcher() {
            importFetcherActive = false;
      }

      public void beginImportCiteSeerProgress() {
          progressBar.setIndeterminate(true);
          progressBar.setString("");
          progressBar2.setVisible(false);
          citeSeerProgress.setText("");
          sidePaneManager.show("CiteSeerProgress");
      }
      public void endImportCiteSeerProgress() {
          progressBar.setIndeterminate(false);
            progressBar.setMinimum(0);
            progressBar.setMaximum(100);
            progressBar.setValue(100);
      }


      /**
       * @param newDatabase
       * @param targetDatabase
       */
00388       public int populate(BibtexDatabase newDatabase, BibtexDatabase targetDatabase) {
            int errorCode = 0;
            Iterator<String> targetIterator = targetDatabase.getKeySet().iterator();
            boolean abortOperation = false;
            String currentKey;
            BibtexEntry currentEntry;
            Map<String, Boolean> citationHashTable = new HashMap<String, Boolean>();
            Hashtable<Integer, BibtexEntry> rejectedEntries = new Hashtable<Integer, BibtexEntry>();
            InitializeProgressBar initializeProgressBar = new InitializeProgressBar();
            InitializeProgressBarTwo initializeProgressBarTwo = new InitializeProgressBarTwo();
            UpdateProgressBarMaximum updateMaximum = new UpdateProgressBarMaximum(targetDatabase.getEntryCount());            
          progressBar2.setVisible(true);        
            SwingUtilities.invokeLater(initializeProgressBar);
            SwingUtilities.invokeLater(initializeProgressBarTwo);
            SwingUtilities.invokeLater(updateMaximum);            
            int identifierCounter = 0;
            UpdateProgressStatus progressStatus = new UpdateProgressStatus(Globals.lang("Fetching Identifiers"));
            SwingUtilities.invokeLater(progressStatus);
            while (targetIterator.hasNext() && !abortOperation) {
                  currentKey = targetIterator.next();
                  currentEntry = targetDatabase.getEntryById(currentKey);
                  abortOperation = generateIdentifierList(currentEntry, citationHashTable, rejectedEntries);
                  UpdateProgressBarValue updateValue = new UpdateProgressBarValue(++identifierCounter);                 
                  SwingUtilities.invokeLater(updateValue);
            }
            if (rejectedEntries.size() > 0) {
                  errorCode = -1;
                ShowBadIdentifiersDialog badIdentifiersDialog = new ShowBadIdentifiersDialog(rejectedEntries);
                SwingUtilities.invokeLater(badIdentifiersDialog);
            }
            if (citationHashTable.size() > 0) {
                  UpdateProgressBarTwoMaximum update2Maximum = new UpdateProgressBarTwoMaximum(citationHashTable.size());
                  SwingUtilities.invokeLater(update2Maximum);
            }
            progressStatus = new UpdateProgressStatus(Globals.lang("Fetching Citations"));
            SwingUtilities.invokeLater(progressStatus);           
            generateCitationList(citationHashTable, newDatabase);
            progressStatus = new UpdateProgressStatus(Globals.lang("Done"));
            SwingUtilities.invokeLater(progressStatus);
            if (abortOperation)
                  errorCode = -2;
            return(errorCode);
      }


      private Map<String, Boolean> generateCitationList(Map<String, Boolean> citationHashTable, BibtexDatabase database)
       {
            try {
                  NamedCompound dummyNamedCompound = new NamedCompound(Globals.lang("Import Data from CiteSeer Database"));
                  BooleanAssign dummyBoolean = new BooleanAssign(false);
                  if ((citationHashTable != null) && (citationHashTable.size() > 0)) {
                      int citationCounter=0;
                      for (String key : citationHashTable.keySet()){
                        String id = Util.createNeutralId();
                              BibtexEntry newEntry = new BibtexEntry(id);
                              StringBuffer citeseerURLString = new StringBuffer();
                              citeseerURLString.append(OAI_URL);
                              citeseerURLString.append(OAI_ACTION);
                              citeseerURLString.append("&" + OAI_METADATAPREFIX);
                    citeseerURLString.append("&" + "identifier=").append(key);
                              URL citeseerUrl = new URL( citeseerURLString.toString());
                              HttpURLConnection citeseerConnection = (HttpURLConnection)citeseerUrl.openConnection();                     
                              saxParser.parse(citeseerConnection.getInputStream(), new CiteSeerUndoHandler(dummyNamedCompound, newEntry, panel, dummyBoolean));
                              database.insertEntry(newEntry);
                              citationCounter++;
                              UpdateProgressBarTwoValue updateValue = new UpdateProgressBarTwoValue(citationCounter);
                              SwingUtilities.invokeLater(updateValue);
                      }
                  }
            } catch (SAXException e) {
                        System.out.println("SAXException: " + e.getLocalizedMessage());
                        e.printStackTrace();
            } catch (IOException e) {
                        ShowNoConnectionDialog dialog = new ShowNoConnectionDialog(OAI_HOST);
                        SwingUtilities.invokeLater(dialog);
            } catch (KeyCollisionException e) {
                  System.out.println("KeyCollisionException: " + e.getLocalizedMessage());
                e.printStackTrace();
        }
            return citationHashTable;
      }

      public static String generateCanonicalNumber(BibtexEntry be) {
          return(generateCanonicalNumber(be.getField("citeseerurl")));
      }
      
    public static String generateCanonicalNumber(String link) {
        String IDnumber = null;
          if (link != null) {
              Pattern pattern = Pattern.compile("[0-9]+");
              Matcher matcher = pattern.matcher(link);
              if (matcher.find()) {
                  IDnumber = matcher.group();
              }
          }
        return IDnumber;
    }
      
      public String generateCanonicalIdentifier(BibtexEntry be) {
          String canonID = null;
          String IDnumber = generateCanonicalNumber(be);
          if (IDnumber != null) {
              canonID = PREFIX_IDENTIFIER + IDnumber;
          }
          return(canonID);
      }
      
      public static String generateCanonicalURL(String link) {
          String canonURL = null;
          String IDnumber = generateCanonicalNumber(link);
          if (IDnumber != null) {
              canonURL = PREFIX_URL + IDnumber + ".html";
          }
          return(canonURL);
      }     

    public static String generateCanonicalURL(BibtexEntry be) {
        return(generateCanonicalURL(be.getField("citeseerurl")));
      }
      
      private boolean generateIdentifierList(BibtexEntry currentEntry, Map<String, Boolean> citationHashTable, Hashtable<Integer, BibtexEntry> rejectedEntries)
            {
                  boolean abortOperation = false;
                  String identifier = generateCanonicalIdentifier(currentEntry);                  
                  try {
                    if (identifier != null) {
                      StringBuffer citeseerURLString = new StringBuffer();
                      citeseerURLString.append(OAI_URL);
                      citeseerURLString.append(OAI_ACTION);
                      citeseerURLString.append("&" + OAI_METADATAPREFIX);
                        citeseerURLString.append("&" + "identifier=").append(identifier);
                      URL citeseerUrl = new URL( citeseerURLString.toString());
                      HttpURLConnection citeseerConnection = (HttpURLConnection)citeseerUrl.openConnection();                       
                      saxParser.parse(citeseerConnection.getInputStream(), new CiteSeerCitationHandler(citationHashTable));
                    } else {
                      int row = panel.mainTable.findEntry(currentEntry);
                      rejectedEntries.put(new Integer(row+1),currentEntry);                     
                    }
            } catch (SAXException e) {
                  System.out.println("SAXException: " + e.getLocalizedMessage());
                  e.printStackTrace();
            } catch (IOException e) {
                  System.out.println("IOException: " + e.getLocalizedMessage());
                ShowNoConnectionDialog dialog = new ShowNoConnectionDialog(OAI_HOST);
                  abortOperation = true;
                  SwingUtilities.invokeLater(dialog);
            }
            return(abortOperation);
      }

      public boolean importCiteSeerEntries(int[] clickedOn, NamedCompound citeseerNamedCompound) {
            boolean newValues = false;
            boolean abortOperation = false;
            Vector<Integer> clickedVector = new Vector<Integer>();
            Hashtable<Integer, BibtexEntry> rejectedEntries = new Hashtable<Integer, BibtexEntry>();        
            for(int i=0; i < clickedOn.length; i++)
                  clickedVector.add(new Integer(clickedOn[i]));
            Iterator<Integer> clickedIterator = clickedVector.iterator();
            BooleanAssign overwriteAll = new BooleanAssign(false);
            BooleanAssign overwriteNone = new BooleanAssign(false);

            while (clickedIterator.hasNext() && !abortOperation) {
                  int currentIndex = clickedIterator.next().intValue();
                  BooleanAssign newValue = new BooleanAssign(false);
                  BibtexEntry be = panel.mainTable.getEntryAt(currentIndex);
                  abortOperation = importCiteSeerEntry(be, citeseerNamedCompound, overwriteAll, overwriteNone, newValue, rejectedEntries);
                  if (newValue.getValue())
                        newValues = true;
            }
            if (rejectedEntries.size() > 0) {
                ShowBadIdentifiersDialog badIdentifiersDialog = new ShowBadIdentifiersDialog(rejectedEntries);
                SwingUtilities.invokeLater(badIdentifiersDialog);
            }
            return newValues;
      }
      
      
      
      /**
       * @param be
       * @param overwriteNone
       * @param overwriteAll
       * @param rejectedEntries
       *
       */
00573       public boolean importCiteSeerEntry(BibtexEntry be, NamedCompound citeseerNC, BooleanAssign overwriteAll, 
                  BooleanAssign overwriteNone, BooleanAssign newValue, Hashtable<Integer, BibtexEntry> rejectedEntries) {
          boolean abortOperation = false;
            
      String identifier = generateCanonicalIdentifier(be);               
            try {
                  if (identifier != null) {
                              StringBuffer citeseerURLString = new StringBuffer();
                              citeseerURLString.append(OAI_URL);
                              citeseerURLString.append(OAI_ACTION);
                              citeseerURLString.append("&" + OAI_METADATAPREFIX);
                citeseerURLString.append("&" + "identifier=").append(identifier);
                    URL citeseerUrl = new URL( citeseerURLString.toString());
                    HttpURLConnection citeseerConnection = (HttpURLConnection)citeseerUrl.openConnection();                                                 
                              InputStream inputStream  = citeseerConnection.getInputStream();
                              DefaultHandler handlerBase = new CiteSeerUndoHandler(citeseerNC, be, panel, newValue, overwriteAll, overwriteNone);

                              saxParser.parse(inputStream, handlerBase);
                        } else {
                    int row = panel.mainTable.findEntry(be);
                    rejectedEntries.put(new Integer(row+1), be);                
                        }
                  } catch (IOException e) {
                              ShowNoConnectionDialog dialog = new ShowNoConnectionDialog(OAI_HOST);
                              SwingUtilities.invokeLater(dialog);
                              abortOperation = true;
                  } catch (SAXException e) {
                        System.out.println("SAXException: " + e.getLocalizedMessage());
                        e.printStackTrace();
                        abortOperation = true;                    
                  }
                  return abortOperation;
            }



}

Generated by  Doxygen 1.6.0   Back to index