Package org.alastairmailer

Source Code of org.alastairmailer.LuceneBibtexDatabase

package org.alastairmailer;

import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JDialog;

import net.sf.jabref.BasePanel;
import net.sf.jabref.BibtexDatabase;
import net.sf.jabref.BibtexEntry;
import net.sf.jabref.GUIGlobals;
import net.sf.jabref.Globals;
import net.sf.jabref.MetaData;
import net.sf.jabref.Util;
import net.sf.jabref.gui.FileListEntry;
import net.sf.jabref.gui.FileListTableModel;

import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.store.FSDirectory;

public class LuceneBibtexDatabase implements ActionListener {

  public static Logger log = Logger.getLogger(LuceneBibtexDatabase.class
      .getCanonicalName());

  public final synchronized int getUpdateTime() {
                Vector<String> auto = getMd().getData("lucene-AutoIndexInterval");
                if (auto == null) {
                    return 60;
                } else {
                    return Integer.parseInt(auto.firstElement());
                }
  }

  public synchronized void setUpdateTime(int update_time) {
                Vector<String> auto = new Vector<String>();
                auto.add("" + update_time);
                getMd().putData("lucene-AutoIndexInterval", auto);
                bp.markBaseChanged();
                log.info("Automatic update interval for " + getDb().toString() + " changed to " + update_time + "s");
                if (getAutoIndexEnabled()) {
                  stopUpdateMonitor();
                  startUpdateMonitor();
                }
  }

  private Map<String, Set<BibtexEntry>> fileBibMap;
  private IndexReader index;
  private BasePanel bp;
  private Timer updateMonitorTimer;
  private Thread updateMonitorThread;
  private IndexBuilder builder;
  private long lastIndexed = -1l;
  private Thread indexThread;

        public final synchronized boolean getAutoIndexEnabled() {
            Vector<String> auto = getMd().getData("lucene-AutoIndexEnabled");
            if (auto == null) {
                return true;
            } else {
                return Boolean.parseBoolean(auto.firstElement());
            }
        }

        public void setAutoIndexEnabled(boolean auto_index) {
            if (auto_index) {
                startUpdateMonitor();
            } else {
                stopUpdateMonitor();
            }
            Vector<String> auto = new Vector<String>();
            auto.add("" + auto_index);
            getMd().putData("lucene-AutoIndexEnabled", auto);
            bp.markBaseChanged();
        }

  public LuceneBibtexDatabase(BasePanel bp) {
    this.bp = bp;
    initFileBibMap();
    File indexDir = getIndexDir();
    File fileDir = getFileDir();
        boolean autoIndex = getAutoIndexEnabled();
        this.updateMonitorTimer = new Timer("Update monitor thread");
        if (autoIndex) {
            startUpdateMonitor();
        }

  }
 
  public void stopUpdateMonitor() {
    updateMonitorTimer.cancel();
    log.info("Automatic updates stopped for " + getDb().toString());
  }

        public final void startUpdateMonitor() {
                    updateMonitorTimer = new Timer("Update monitor thread");
                    updateMonitorTimer.schedule(new TimerTask() {

      @Override
      public void run() {
        if (getIndexDir() == null || getFileDir() == null
            || isIndexed() != true) {
          log
              .info("Automatic background update skipped as index or file directory does not exist");
          return;
        } else if (isUpdating()) {
          log
              .info("Automatic background update skipped as update already in progress");
          return;
        } else if (System.currentTimeMillis() - lastIndexed < getUpdateTime()) {
          log
              .info("Automatic background update skipped as update performed recently");
          return;
        } else {
          try {
            log.info("Automatic background update started");
            updateIndex(null, false);
            log.info("Automatic background update finished");
          } catch (FileNotFoundException e) {
            log.info("Automatic background update failed");
          }
        }
      }

    }, Math.round(getUpdateTime()*1000), getUpdateTime()*1000);
                    log.info("Automatic updates activated for " + getDb().toString() + " with update interval " + getUpdateTime() + "s");
        }

  public synchronized boolean isUpdating() {
    if (indexThread == null) {
      return false;
    } else {
      return indexThread.isAlive();
    }
  }

  public boolean indexingError() {
    if (builder == null) {
      return true;
    } else {
      return builder.getStatus() == IndexBuilder.ERROR;
    }
  }

  public boolean isIndexed() {
    if (getFileDir() == null || getIndexDir() == null) {
      return false;
    }
    boolean indexed = false;
    try {
      indexed = IndexReader.indexExists(FSDirectory.open(getIndexDir()));
    } catch (IOException e) {
    }
    return indexed;
  }

  public final File getFileDir() {
    String[] fileDirs = getMd().getFileDirectory(GUIGlobals.FILE_FIELD);
    // This function now returns an array, as it seems multiple file directories can be defined
    // TODO: Handle this functionality - for now, just use top of list
    File fileDir = Util.expandFilename(fileDirs[0], "");
    /* This no longer needed, as getFileDirectory looks in all the places for us
     * if (fileDir == null) {
      String fDir = Globals.prefs.get("fileDirectory");
      if (fDir != null) {
        fileDir = new File(fDir);
      }
    }*/
    return fileDir;

  }

  public void setIndexDir(File indexDir) {
                if (indexDir == null) {
                    getMd().remove("lucene-IndexDirectory");
                } else {
                    Vector<String> temp = new Vector<String>(1);
                    temp.add(indexDir.getAbsolutePath());
                    getMd().putData("lucene-IndexDirectory", temp);
                }
    bp.markBaseChanged();
  }

  public final File getIndexDir() {
    Vector<String> indexDirStr = getMd().getData("lucene-IndexDirectory");
    if (indexDirStr != null) {
      return new File(indexDirStr.firstElement());
    } else {
      return null;
    }
  }

  public IndexReader getIndexReader() throws IOException,
      CorruptIndexException {
    if (index == null) {
      index = IndexReader.open(FSDirectory.open(getIndexDir()));
    } else if (!index.isCurrent()) {
                    index.close();
                    index = IndexReader.open(FSDirectory.open(getIndexDir()));
                }
    return index;
  }

  public void updateIndex(Window logDialogParent, boolean rebuild)
      throws FileNotFoundException {
    File indexDir = getIndexDir();
    File fileDir = getFileDir();
    if (indexDir == null) {
      throw new FileNotFoundException("The index for " + toString()
          + " cannot be found - please ensure it is set correctly.");
    }
    if (fileDir == null) {
      throw new FileNotFoundException("The file directory for "
          + toString()
          + " cannot be found - please ensure it is set correctly.");
    }
    IndexBuilder myBuilder = new IndexBuilder(this, rebuild);
    indexThread = new Thread(myBuilder);
    indexThread.start();
    lastIndexed = System.currentTimeMillis();
    if (logDialogParent != null) {
      IndexLogMsgHandler handler = new IndexLogMsgHandler(myBuilder);
      JDialog dialog = handler.getDialog(logDialogParent, true);
      handler.startTimer();
      dialog.setVisible(true);
    }
  }

  @Override
  public String toString() {
    File bibFile = getMd().getFile();
    if (bibFile == null) { return "<unsaved database>"; }
    else { return bibFile.getName(); }
  }

  public Set<BibtexEntry> getBibtexEntries(String f) {
    return fileBibMap.get(f);
  }

  public final void initFileBibMap() {

    long start = 0, stop = 0;
    if (log.isLoggable(Level.INFO)) {
      start = System.currentTimeMillis();
    }

                fileBibMap = new HashMap<String, Set<BibtexEntry>>();

    for (BibtexEntry entry : getDb().getEntries()) {
      String fField = entry.getField(GUIGlobals.FILE_FIELD);
      FileListTableModel fLTM = new FileListTableModel();
      fLTM.setContent(fField);
      for (int i = 0; i < fLTM.getRowCount(); i++) {
        FileListEntry flEntry = fLTM.getEntry(i);
        String link = flEntry.getLink();
//        String fileDir = getMd().getFileDirectory(GUIGlobals.FILE_FIELD);
//        File f = net.sf.jabref.Util.expandFilename(link, fileDir);
        if (fileBibMap.containsKey(link)) {
          Set<BibtexEntry> s = fileBibMap.get(link);
          s.add(entry);
        } else {
          Set<BibtexEntry> s = new HashSet<BibtexEntry>();
          s.add(entry);
          fileBibMap.put(link, s);
        }
      }
    }

    if (log.isLoggable(Level.INFO)) {
      stop = System.currentTimeMillis();
      log.info("Total file mapping time: " + (stop - start) / 1000.0
          + " ms");
      log.info("Mapped " + fileBibMap.keySet().size()
          + " file entries to " + getDb().getEntries().size()
          + " bibtex entries.");
    }

  }

    public Map<String, Set<BibtexEntry>> getFileBibMap() {
        return fileBibMap;
    }

  public void actionPerformed(ActionEvent e) {
    log.info("Background update of " + getMd().getFile().toString());
//    if (isUpdating()) {
//      log.info("Background update skipped as update already in progress");
//    } else if (indexingError()) {
//      log.info("Backgorund update skipped due to indexing error");
//    } else if (getIndexDir() == null || getFileDir() == null) {
//      log
//          .info("Background update skipped as index or file directories are not set.");
                try {
                     if (indexCurrent()) {
                     log.info("Background update unnecessary.");
                     } else {
      builder = new IndexBuilder(this, false);
      updateMonitorThread = new Thread(builder);
      updateMonitorThread.start();
                    }
    } catch (IOException ex) {
                    log.info("Background update skipped due to IOException: " + ex.toString());
                }

  }

  public synchronized BasePanel getBp() {
    return bp;
  }

  public BibtexDatabase getDb() {
    return getBp().database();
  }

  public synchronized MetaData getMd() {
    return getBp().metaData();
  }

        public synchronized boolean indexCurrent() throws IOException {
      try {
              long indexMod = getIndexDir().lastModified();
              long fileMod = getFileDir().lastModified();
              //log.info(getFileDir().toString() + " indexCurrent = " + (indexMod >= fileMod) + " indexMod: " + (new Date(indexMod)) + "fileMod: " + (new Date(fileMod)));
              return indexMod >= fileMod;
      } catch (NullPointerException e) {
    throw new IOException("Index or file directory not set: " + e);
      }
        }
}
TOP

Related Classes of org.alastairmailer.LuceneBibtexDatabase

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.