private static void exportFieldToKeywords(
      SpecialField e, String newValue, BibtexEntry be, NamedCompound ce) {
    if (!SpecialFieldsUtils.keywordSyncEnabled()) {
      return;
    }
    ArrayList<String> keywordList = Util.getSeparatedKeywords(be);
    List<String> values = e.getKeyWords();

    int foundPos = -1;

    // cleanup keywords
    for (Object value : values) {
      int pos = keywordList.indexOf(value);
      if (pos >= 0) {
        foundPos = pos;
        keywordList.remove(pos);
      }
    }

    if (newValue != null) {
      if (foundPos == -1) {
        keywordList.add(newValue);
      } else {
        keywordList.add(foundPos, newValue);
      }
    }
    Util.putKeywords(be, keywordList, ce);
  }
  /**
   * @param owner the parent Window (Dialog or Frame)
   * @param frame the JabRef Frame
   * @param panel the currently selected BasePanel
   * @param modal should this dialog be modal?
   * @param metaData The metadata of the current database
   * @param fieldName the field this selector is initialized for. May be null.
   */
  public ContentSelectorDialog2(
      Window owner,
      JabRefFrame frame,
      BasePanel panel,
      boolean modal,
      MetaData metaData,
      String fieldName) {
    super(owner, Localization.lang("Setup selectors"));
    this.setModal(modal);
    this.metaData = metaData;
    this.frame = frame;
    this.panel = panel;
    this.currentField = fieldName;

    initLayout();

    setupFieldSelector();
    setupWordSelector();
    setupActions();
    Util.bindCloseDialogKeyToCancelAction(this.rootPane, cancel.getAction());
    int fieldInd = fieldListModel.indexOf(currentField);
    if (fieldInd >= 0) {
      fieldList.setSelectedIndex(fieldInd);
    }

    pack();
  }
Beispiel #3
0
 @Override
 public void actionPerformed(ActionEvent e) {
   try {
     Util.runAbstractWorker(DbImportAction.this);
   } catch (Throwable throwable) {
     LOGGER.warn("Problem importing from database", throwable);
   }
 }
Beispiel #4
0
  private static BibEntry downloadEntryBibTeX(String id, boolean downloadAbstract) {
    try {
      URL url =
          new URL(
              ACMPortalFetcher.START_URL
                  + ACMPortalFetcher.BIBTEX_URL
                  + id
                  + ACMPortalFetcher.BIBTEX_URL_END);
      URLConnection connection = url.openConnection();

      // set user-agent to avoid being blocked as a crawler
      connection.addRequestProperty(
          "User-Agent", "Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0");
      Collection<BibEntry> items = null;
      try (BufferedReader in =
          new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
        items = BibtexParser.parse(in).getDatabase().getEntries();
      } catch (IOException e) {
        LOGGER.info("Download of BibTeX information from ACM Portal failed.", e);
      }
      if ((items == null) || items.isEmpty()) {
        return null;
      }
      BibEntry entry = items.iterator().next();
      Thread.sleep(
          ACMPortalFetcher.WAIT_TIME); // wait between requests or you will be blocked by ACM

      // get abstract
      if (downloadAbstract) {
        url = new URL(ACMPortalFetcher.START_URL + ACMPortalFetcher.ABSTRACT_URL + id);
        String page = Util.getResults(url);
        Matcher absM = ACMPortalFetcher.ABSTRACT_PATTERN.matcher(page);
        if (absM.find()) {
          entry.setField("abstract", absM.group(1).trim());
        }
        Thread.sleep(
            ACMPortalFetcher.WAIT_TIME); // wait between requests or you will be blocked by ACM
      }

      return entry;
    } catch (NoSuchElementException e) {
      LOGGER.info(
          "Bad Bibtex record read at: "
              + ACMPortalFetcher.BIBTEX_URL
              + id
              + ACMPortalFetcher.BIBTEX_URL_END,
          e);
      return null;
    } catch (MalformedURLException e) {
      LOGGER.info("Malformed URL.", e);
      return null;
    } catch (IOException e) {
      LOGGER.info("Cannot connect.", e);
      return null;
    } catch (InterruptedException ignored) {
      return null;
    }
  }
 /**
  * @param e - Field to be handled
  * @param value - may be null to state that field should be emptied
  * @param be - BibTeXEntry to be handled
  * @param ce - Filled with undo info (if necessary)
  * @param nullFieldIfValueIsTheSame - true: field is nulled if value is the same than the current
  *     value in be
  */
 public static void updateField(
     SpecialField e,
     String value,
     BibtexEntry be,
     NamedCompound ce,
     boolean nullFieldIfValueIsTheSame) {
   Util.updateField(be, e.getFieldName(), value, ce, nullFieldIfValueIsTheSame);
   // we cannot use "value" here as updateField has side effects: "nullFieldIfValueIsTheSame" nulls
   // the field if value is the same
   SpecialFieldsUtils.exportFieldToKeywords(e, be.getField(e.getFieldName()), be, ce);
 }
 /**
  * updates field values according to keywords
  *
  * @param ce indicates the undo named compound. May be null
  */
 public static void syncSpecialFieldsFromKeywords(BibtexEntry be, NamedCompound ce) {
   if (be.getField("keywords") == null) {
     return;
   }
   ArrayList<String> keywordList = Util.getSeparatedKeywords(be.getField("keywords"));
   SpecialFieldsUtils.importKeywordsForField(keywordList, Priority.getInstance(), be, ce);
   SpecialFieldsUtils.importKeywordsForField(keywordList, Rank.getInstance(), be, ce);
   SpecialFieldsUtils.importKeywordsForField(keywordList, Quality.getInstance(), be, ce);
   SpecialFieldsUtils.importKeywordsForField(keywordList, Relevance.getInstance(), be, ce);
   SpecialFieldsUtils.importKeywordsForField(keywordList, ReadStatus.getInstance(), be, ce);
   SpecialFieldsUtils.importKeywordsForField(keywordList, Printed.getInstance(), be, ce);
 }
 private static void importKeywordsForField(
     ArrayList<String> keywordList, SpecialField c, BibtexEntry be, NamedCompound nc) {
   List<String> values = c.getKeyWords();
   String newValue = null;
   for (String val : values) {
     if (keywordList.contains(val)) {
       newValue = val;
       break;
     }
   }
   Util.updateField(be, c.getFieldName(), newValue, nc);
 }
 @Override
 public void actionPerformed(ActionEvent e) {
   try {
     Util.openBrowser("https://github.com/JabRef/jabref");
   } catch (IOException ex) {
     ex.printStackTrace();
     JabRef.jrf
         .basePanel()
         .output(
             Globals.lang("Could not open browser.")
                 + " "
                 + Globals.lang("Please open http://github.com/JabRef/jabref manually."));
   }
 }
  private void init() {
    getContentPane().setLayout(new BorderLayout());
    getContentPane().add(labelPatternPanel, BorderLayout.CENTER);

    JButton ok = new JButton(Localization.lang("Ok"));
    JButton cancel =
        new JButton(); // label of "cancel" is set later as the label is overwritten by assigning an
                       // action to the button

    JPanel lower = new JPanel();
    lower.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
    ButtonBarBuilder bb = new ButtonBarBuilder(lower);
    bb.addGlue();
    bb.addButton(ok);
    bb.addButton(cancel);
    bb.addGlue();

    getContentPane().add(lower, BorderLayout.SOUTH);

    this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    getContentPane().setPreferredSize(new Dimension(500, 600));
    pack();

    ok.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent e) {
            metaData.setLabelPattern(labelPatternPanel.getLabelPatternAsDatabaseLabelPattern());
            panel.markNonUndoableBaseChanged();
            dispose();
          }
        });

    final JDialog dialog = this;

    Action cancelAction =
        new AbstractAction() {

          @Override
          public void actionPerformed(ActionEvent e) {
            dialog.dispatchEvent(new WindowEvent(dialog, WindowEvent.WINDOW_CLOSING));
          }
        };
    cancel.setAction(cancelAction);
    cancel.setText(Localization.lang("Cancel"));

    Util.bindCloseDialogKeyToCancelAction(this.getRootPane(), cancelAction);
  }
    @Override
    public void actionPerformed(ActionEvent e) {
      if (lastSelected == null) {
        return;
      }
      defaulted.add(lastSelected);

      BibtexEntryType type = BibtexEntryType.getStandardType(lastSelected);
      if (type != null) {
        String[] rf = type.getRequiredFieldsForCustomization(), of = type.getOptionalFields();
        List<String> req, opt1, opt2;
        if (rf != null) {
          req = java.util.Arrays.asList(rf);
        } else {
          req = new ArrayList<String>();
        }

        opt1 = new ArrayList<String>();
        opt2 = new ArrayList<String>();
        if (biblatexMode) {
          if (of != null) {
            String[] priOptArray = type.getPrimaryOptionalFields();
            String[] secOptArray = Util.getRemainder(of, priOptArray);
            if (priOptArray != null) {
              opt1 = java.util.Arrays.asList(priOptArray);
            }
            if (secOptArray != null) {
              opt2 = java.util.Arrays.asList(secOptArray);
            }
          }
        } else {
          if (of != null) {
            opt1 = java.util.Arrays.asList(of);
          }
        }

        reqComp.setFields(req);
        reqComp.setEnabled(true);
        optComp.setFields(opt1);
        if (biblatexMode) {
          optComp2.setFields(opt2);
        }
      }
    }
  /**
   * This method performs the actual changes.
   *
   * @param panel
   * @param pr
   * @param fileDir The path to the file directory to set, or null if it should not be set.
   */
  private void makeChanges(
      BasePanel panel,
      ParserResult pr,
      boolean upgradePrefs,
      boolean upgradeDatabase,
      String fileDir) {

    if (upgradeDatabase) {
      // Update file links links in the database:
      NamedCompound ce =
          Util.upgradePdfPsToFile(pr.getDatabase(), FileLinksUpgradeWarning.FIELDS_TO_LOOK_FOR);
      panel.undoManager.addEdit(ce);
      panel.markBaseChanged();
    }

    if (fileDir != null) {
      Globals.prefs.put(GUIGlobals.FILE_FIELD + "Directory", fileDir);
    }

    if (upgradePrefs) {
      // Exchange table columns:
      Globals.prefs.putBoolean(JabRefPreferences.PDF_COLUMN, Boolean.FALSE);
      Globals.prefs.putBoolean(JabRefPreferences.FILE_COLUMN, Boolean.TRUE);

      // Modify General fields if necessary:
      // If we don't find the file field, insert it at the bottom of the first tab:
      if (!showsFileInGenFields()) {
        String gfs = Globals.prefs.get(JabRefPreferences.CUSTOM_TAB_FIELDS + "0");
        // System.out.println(gfs);
        StringBuilder sb = new StringBuilder(gfs);
        if (gfs.length() > 0) {
          sb.append(";");
        }
        sb.append(GUIGlobals.FILE_FIELD);
        Globals.prefs.put(JabRefPreferences.CUSTOM_TAB_FIELDS + "0", sb.toString());
        Globals.prefs.updateEntryEditorTabList();
        panel.frame().removeCachedEntryEditors();
      }
      panel.frame().setupAllTables();
    }
  }
Beispiel #12
0
 @Override
 public String[] getSecondaryOptionalFields() {
   return Util.getRemainder(opt, priOpt);
 }
Beispiel #13
0
  private void doRenamePDFs(BibtexEntry entry, NamedCompound ce) {
    // Extract the path
    String oldValue = entry.getField(Globals.FILE_FIELD);
    if (oldValue == null) {
      return;
    }
    FileListTableModel flModel = new FileListTableModel();
    flModel.setContent(oldValue);
    if (flModel.getRowCount() == 0) {
      return;
    }
    boolean changed = false;

    for (int i = 0; i < flModel.getRowCount(); i++) {
      String realOldFilename = flModel.getEntry(i).getLink();

      if (cleanUpRenamePDFonlyRelativePaths.isSelected()
          && (new File(realOldFilename).isAbsolute())) {
        continue;
      }

      String newFilename = Util.getLinkedFileName(panel.database(), entry);
      // String oldFilename = bes.getField(GUIGlobals.FILE_FIELD); // would have to be stored for
      // undoing purposes

      // Add extension to newFilename
      newFilename = newFilename + "." + flModel.getEntry(i).getType().getExtension();

      // get new Filename with path
      // Create new Path based on old Path and new filename
      File expandedOldFile =
          FileUtil.expandFilename(
              realOldFilename, panel.metaData().getFileDirectory(Globals.FILE_FIELD));
      if (expandedOldFile.getParent() == null) {
        // something went wrong. Just skip this entry
        continue;
      }
      String newPath =
          expandedOldFile
              .getParent()
              .concat(System.getProperty("file.separator"))
              .concat(newFilename);

      if (new File(newPath).exists()) {
        // we do not overwrite files
        // TODO: we could check here if the newPath file is linked with the current entry. And if
        // not, we could add a link
        continue;
      }

      // do rename
      boolean renameSuccessful = FileUtil.renameFile(expandedOldFile.toString(), newPath);

      if (renameSuccessful) {
        changed = true;

        // Change the path for this entry
        String description = flModel.getEntry(i).getDescription();
        ExternalFileType type = flModel.getEntry(i).getType();
        flModel.removeEntry(i);

        // we cannot use "newPath" to generate a FileListEntry as newPath is absolute, but we want
        // to keep relative paths whenever possible
        File parent = (new File(realOldFilename)).getParentFile();
        String newFileEntryFileName;
        if (parent == null) {
          newFileEntryFileName = newFilename;
        } else {
          newFileEntryFileName =
              parent.toString().concat(System.getProperty("file.separator")).concat(newFilename);
        }
        flModel.addEntry(i, new FileListEntry(description, newFileEntryFileName, type));
      } else {
        unsuccessfulRenames++;
      }
    }

    if (changed) {
      String newValue = flModel.getStringRepresentation();
      assert (!oldValue.equals(newValue));
      entry.setField(Globals.FILE_FIELD, newValue);
      // we put an undo of the field content here
      // the file is not being renamed back, which leads to inconsistencies
      // if we put a null undo object here, the change by "doMakePathsRelative" would overwrite the
      // field value nevertheless.
      ce.addEdit(new UndoableFieldChange(entry, Globals.FILE_FIELD, oldValue, newValue));
    }
  }
  private void applyChanges() {
    valueChanged(new ListSelectionEvent(new JList(), 0, 0, false));
    // Iterate over our map of required fields, and list those types if necessary:

    List<String> types = typeComp.getFields();
    for (Map.Entry<String, List<String>> stringListEntry : reqLists.entrySet()) {
      if (!types.contains(stringListEntry.getKey())) {
        continue;
      }

      List<String> reqFields = stringListEntry.getValue();
      List<String> optFields = optLists.get(stringListEntry.getKey());
      List<String> opt2Fields = opt2Lists.get(stringListEntry.getKey());
      String[] reqStr = new String[reqFields.size()];
      reqStr = reqFields.toArray(reqStr);
      String[] optStr = new String[optFields.size()];
      optStr = optFields.toArray(optStr);
      String[] opt2Str;
      if (opt2Fields != null) {
        opt2Str = opt2Fields.toArray(new String[opt2Fields.size()]);
      } else {
        opt2Str = new String[0];
      }

      // If this type is already existing, check if any changes have
      // been made
      boolean changesMade = true;

      if (defaulted.contains(stringListEntry.getKey())) {
        // This type should be reverted to its default setup.
        // System.out.println("Defaulting: "+typeName);
        String nm = StringUtil.nCase(stringListEntry.getKey());
        BibtexEntryType.removeType(nm);

        updateTypesForEntries(nm);
        continue;
      }

      BibtexEntryType oldType = BibtexEntryType.getType(stringListEntry.getKey());
      if (oldType != null) {
        String[] oldReq = oldType.getRequiredFields(), oldOpt = oldType.getOptionalFields();
        if (biblatexMode) {
          String[] priOpt = oldType.getPrimaryOptionalFields();
          String[] secOpt = Util.getRemainder(oldOpt, priOpt);
          if (equalArrays(oldReq, reqStr)
              && equalArrays(oldOpt, optStr)
              && equalArrays(secOpt, opt2Str)) {
            changesMade = false;
          }
        } else if (equalArrays(oldReq, reqStr) && equalArrays(oldOpt, optStr)) {
          changesMade = false;
        }
      }

      if (changesMade) {
        // System.out.println("Updating: "+typeName);
        CustomEntryType typ =
            biblatexMode
                ? new CustomEntryType(
                    StringUtil.nCase(stringListEntry.getKey()), reqStr, optStr, opt2Str)
                : new CustomEntryType(StringUtil.nCase(stringListEntry.getKey()), reqStr, optStr);

        BibtexEntryType.ALL_TYPES.put(stringListEntry.getKey().toLowerCase(), typ);
        updateTypesForEntries(typ.getName());
      }
    }

    Set<Object> toRemove = new HashSet<Object>();
    for (String o : BibtexEntryType.ALL_TYPES.keySet()) {
      if (!types.contains(o)) {
        toRemove.add(o);
      }
    }

    // Remove those that should be removed:
    if (!toRemove.isEmpty()) {
      for (Object aToRemove : toRemove) {
        typeDeletion((String) aToRemove);
      }
    }

    updateTables();
  }
Beispiel #15
0
 public CustomEntryType(String name_, String[] req_, String[] priOpt_, String[] secOpt_) {
   name = StringUtil.capitalizeFirst(name_);
   parseRequiredFields(req_);
   priOpt = priOpt_;
   opt = Util.arrayConcat(priOpt_, secOpt_);
 }
Beispiel #16
0
  @Override
  public void run() {
    if (cancelled) {
      return;
    }
    int choice = showCleanUpDialog();
    if (choice != JOptionPane.OK_OPTION) {
      cancelled = true;
      return;
    }
    storeSettings();
    boolean choiceCleanUpSuperscripts = cleanUpSuperscripts.isSelected();
    boolean choiceCleanUpDOI = cleanUpDOI.isSelected();
    boolean choiceCleanUpMonth = cleanUpMonth.isSelected();
    boolean choiceCleanUpPageNumbers = cleanUpPageNumbers.isSelected();
    boolean choiceCleanUpDate = cleanUpDate.isSelected();
    boolean choiceCleanUpUpgradeExternalLinks = cleanUpUpgradeExternalLinks.isSelected();
    boolean choiceMakePathsRelative = cleanUpMakePathsRelative.isSelected();
    boolean choiceRenamePDF = cleanUpRenamePDF.isSelected();
    boolean choiceConvertHTML = cleanUpHTML.isSelected();
    boolean choiceConvertCase = cleanUpCase.isSelected();
    boolean choiceConvertLaTeX = cleanUpLaTeX.isSelected();
    boolean choiceConvertUnits = cleanUpUnits.isSelected();
    boolean choiceConvertUnicode = cleanUpUnicode.isSelected();
    boolean choiceConvertToBiblatex = cleanUpBibLatex.isSelected();

    if (choiceRenamePDF && Globals.prefs.getBoolean(CleanUpAction.AKS_AUTO_NAMING_PDFS_AGAIN)) {
      CheckBoxMessage cbm =
          new CheckBoxMessage(
              Localization.lang("Auto-generating PDF-Names does not support undo. Continue?"),
              Localization.lang("Disable this confirmation dialog"),
              false);
      int answer =
          JOptionPane.showConfirmDialog(
              frame, cbm, Localization.lang("Autogenerate PDF Names"), JOptionPane.YES_NO_OPTION);
      if (cbm.isSelected()) {
        Globals.prefs.putBoolean(CleanUpAction.AKS_AUTO_NAMING_PDFS_AGAIN, false);
      }
      if (answer == JOptionPane.NO_OPTION) {
        cancelled = true;
        return;
      }
    }

    // first upgrade the external links
    // we have to use it separately as the Utils function generates a separate Named Compound
    if (choiceCleanUpUpgradeExternalLinks) {
      NamedCompound ce =
          Util.upgradePdfPsToFile(
              Arrays.asList(panel.getSelectedEntries()), new String[] {"pdf", "ps"});
      if (ce.hasEdits()) {
        panel.undoManager.addEdit(ce);
        panel.markBaseChanged();
        panel.updateEntryEditorIfShowing();
        panel.output(Localization.lang("Upgraded links."));
      }
    }

    for (BibtexEntry entry : panel.getSelectedEntries()) {
      // undo granularity is on entry level
      NamedCompound ce = new NamedCompound(Localization.lang("Cleanup entry"));

      if (choiceCleanUpSuperscripts) {
        doCleanUpSuperscripts(entry, ce);
      }
      if (choiceCleanUpDOI) {
        doCleanUpDOI(entry, ce);
      }
      if (choiceCleanUpMonth) {
        doCleanUpMonth(entry, ce);
      }
      if (choiceCleanUpPageNumbers) {
        doCleanUpPageNumbers(entry, ce);
      }
      if (choiceCleanUpDate) {
        doCleanUpDate(entry, ce);
      }

      fixWrongFileEntries(entry, ce);
      if (choiceMakePathsRelative) {
        doMakePathsRelative(entry, ce);
      }
      if (choiceRenamePDF) {
        doRenamePDFs(entry, ce);
      }
      if (choiceConvertHTML) {
        doConvertHTML(entry, ce);
      }
      if (choiceConvertUnits) {
        doConvertUnits(entry, ce);
      }
      if (choiceConvertCase) {
        doConvertCase(entry, ce);
      }
      if (choiceConvertLaTeX) {
        doConvertLaTeX(entry, ce);
      }
      if (choiceConvertUnicode) {
        doConvertUnicode(entry, ce);
      }
      if (choiceConvertToBiblatex) {
        convertToBiblatex(entry, ce);
      }

      ce.end();
      if (ce.hasEdits()) {
        modifiedEntriesCount++;
        panel.undoManager.addEdit(ce);
      }
    }
  }
Beispiel #17
0
  @Override
  public boolean processQueryGetPreview(
      String query, FetcherPreviewDialog preview, OutputPrinter status) {
    this.terms = query;
    piv = 0;
    shouldContinue = true;
    acmOrGuide = acmButton.isSelected();
    fetchAbstract = absCheckBox.isSelected();
    String address = makeUrl();
    LinkedHashMap<String, JLabel> previews = new LinkedHashMap<>();

    try {
      URL url = new URL(address);

      String page = Util.getResults(url);

      String resultsFound = "<div id=\"resfound\">";
      int hits = getNumberOfHits(page, resultsFound, ACMPortalFetcher.HITS_PATTERN);

      int index = page.indexOf(resultsFound);
      if (index >= 0) {
        page = page.substring(index + resultsFound.length());
      }

      if (hits == 0) {
        status.showMessage(
            Localization.lang("No entries found for the search string '%0'", terms),
            Localization.lang("Search ACM Portal"),
            JOptionPane.INFORMATION_MESSAGE);
        return false;
      } else if (hits > 20) {
        status.showMessage(
            Localization.lang(
                "%0 entries found. To reduce server load, only %1 will be downloaded.",
                String.valueOf(hits), String.valueOf(PER_PAGE)),
            Localization.lang("Search ACM Portal"),
            JOptionPane.INFORMATION_MESSAGE);
      }

      hits = getNumberOfHits(page, "<div class=\"pagerange\">", ACMPortalFetcher.MAX_HITS_PATTERN);
      parse(page, Math.min(hits, PER_PAGE), previews);
      for (Map.Entry<String, JLabel> entry : previews.entrySet()) {
        preview.addEntry(entry.getKey(), entry.getValue());
      }

      return true;

    } catch (MalformedURLException e) {
      LOGGER.warn("Problem with ACM fetcher URL", e);
    } catch (ConnectException e) {
      status.showMessage(
          Localization.lang("Connection to ACM Portal failed"),
          Localization.lang("Search ACM Portal"),
          JOptionPane.ERROR_MESSAGE);
    } catch (IOException e) {
      status.showMessage(
          e.getMessage(), Localization.lang("Search ACM Portal"), JOptionPane.ERROR_MESSAGE);
      LOGGER.warn("Problem with ACM Portal", e);
    }
    return false;
  }