private void parseAndAddEntry(String type) { /** * Morten Alver 13 Aug 2006: Trying to make the parser more robust. If an exception is thrown * when parsing an entry, drop the entry and try to resume parsing. Add a warning for the user. */ try { BibEntry entry = parseEntry(type); boolean duplicateKey = database.insertEntry(entry); entry.setParsedSerialization(dumpTextReadSoFarToString()); if (duplicateKey) { parserResult.addDuplicateKey(entry.getCiteKey()); } else if ((entry.getCiteKey() == null) || entry.getCiteKey().isEmpty()) { parserResult.addWarning( Localization.lang("Empty BibTeX key") + ": " + entry.getAuthorTitleYear(40) + " (" + Localization.lang("Grouping may not work for this entry.") + ")"); } } catch (IOException ex) { LOGGER.warn("Could not parse entry", ex); parserResult.addWarning( Localization.lang("Error occurred when parsing entry") + ": '" + ex.getMessage() + "'. " + Localization.lang("Skipped entry.")); } }
@Override public void actionPerformed(ActionEvent e) { panel = frame.getCurrentBasePanel(); // Check if a BasePanel exists: if (panel == null) { return; } // Check if any entries are selected: entries = panel.getSelectedEntries(); if (entries.length == 0) { JOptionPane.showMessageDialog( frame, Localization.lang("This operation requires one or more entries to be selected."), (String) getValue(Action.NAME), JOptionPane.ERROR_MESSAGE); return; } // If required, check that all entries have BibTeX keys defined: if (operation.requiresBibtexKeys()) { for (BibEntry entry : entries) { if ((entry.getCiteKey() == null) || entry.getCiteKey().trim().isEmpty()) { JOptionPane.showMessageDialog( frame, Localization.lang( "This operation requires all selected entries to have BibTex keys defined."), (String) getValue(Action.NAME), JOptionPane.ERROR_MESSAGE); return; } } } // All set, call the operation in a new thread: JabRefExecutorService.INSTANCE.execute(this); }
private static String getKeyString(BibEntry[] bibentries) { StringBuilder result = new StringBuilder(); String citeKey; boolean first = true; for (BibEntry bes : bibentries) { citeKey = bes.getCiteKey(); // if the key is empty we give a warning and ignore this entry if ((citeKey == null) || citeKey.isEmpty()) { continue; } if (first) { result.append(citeKey); first = false; } else { result.append(',').append(citeKey); } } return result.toString(); }
@Override public void run() { if (!goOn) { panel.output( Localization.lang("This operation requires one or more entries to be selected.")); return; } entriesChangedCount = 0; panel.frame().setProgressBarValue(0); panel.frame().setProgressBarVisible(true); int weightAutoSet = 10; // autoSet takes 10 (?) times longer than checkExisting int progressBarMax = (autoSet ? weightAutoSet * sel.size() : 0) + (checkExisting ? sel.size() : 0); panel.frame().setProgressBarMaximum(progressBarMax); int progress = 0; final NamedCompound ce = new NamedCompound(Localization.lang("Automatically set file links")); Set<BibEntry> changedEntries = new HashSet<>(); // First we try to autoset fields if (autoSet) { Collection<BibEntry> entries = new ArrayList<>(sel); // Start the automatically setting process: Runnable r = AutoSetLinks.autoSetLinks( entries, ce, changedEntries, null, panel.getBibDatabaseContext(), null, null); JabRefExecutorService.INSTANCE.executeAndWait(r); } progress += sel.size() * weightAutoSet; panel.frame().setProgressBarValue(progress); // The following loop checks all external links that are already set. if (checkExisting) { boolean removeAllBroken = false; mainLoop: for (BibEntry aSel : sel) { panel.frame().setProgressBarValue(progress++); final String old = aSel.getField(Globals.FILE_FIELD); // Check if a extension is set: if ((old != null) && !(old.isEmpty())) { FileListTableModel tableModel = new FileListTableModel(); tableModel.setContentDontGuessTypes(old); // We need to specify which directories to search in for Util.expandFilename: List<String> dirsS = panel.getBibDatabaseContext().getFileDirectory(); List<File> dirs = new ArrayList<>(); for (String dirs1 : dirsS) { dirs.add(new File(dirs1)); } for (int j = 0; j < tableModel.getRowCount(); j++) { FileListEntry flEntry = tableModel.getEntry(j); // See if the link looks like an URL: boolean httpLink = flEntry.link.toLowerCase(Locale.ENGLISH).startsWith("http"); if (httpLink) { continue; // Don't check the remote file. // TODO: should there be an option to check remote links? } // A variable to keep track of whether this link gets deleted: boolean deleted = false; // Get an absolute path representation: Optional<File> file = FileUtil.expandFilename(flEntry.link, dirsS); if ((!file.isPresent()) || !file.get().exists()) { int answer; if (removeAllBroken) { answer = 2; // We should delete this link. } else { answer = JOptionPane.showOptionDialog( panel.frame(), Localization.lang( "<HTML>Could not find file '%0'<BR>linked from entry '%1'</HTML>", flEntry.link, aSel.getCiteKey()), Localization.lang("Broken link"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, brokenLinkOptions, brokenLinkOptions[0]); } switch (answer) { case 1: // Assign new file. FileListEntryEditor flEditor = new FileListEntryEditor( panel.frame(), flEntry, false, true, panel.getBibDatabaseContext()); flEditor.setVisible(true, true); break; case 2: // Clear field: tableModel.removeEntry(j); deleted = true; // Make sure we don't investigate this link further. j--; // Step back in the iteration, because we removed an entry. break; case 3: // Clear field: tableModel.removeEntry(j); deleted = true; // Make sure we don't investigate this link further. j--; // Step back in the iteration, because we removed an entry. removeAllBroken = true; // Notify for further cases. break; default: // Cancel break mainLoop; } } // Unless we deleted this link, see if its file type is recognized: if (!deleted && flEntry.type.isPresent() && (flEntry.type.get() instanceof UnknownExternalFileType)) { String[] options = new String[] { Localization.lang("Define '%0'", flEntry.type.get().getName()), Localization.lang("Change file type"), Localization.lang("Cancel") }; String defOption = options[0]; int answer = JOptionPane.showOptionDialog( panel.frame(), Localization.lang( "One or more file links are of the type '%0', which is undefined. What do you want to do?", flEntry.type.get().getName()), Localization.lang("Undefined file type"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, defOption); if (answer == JOptionPane.CANCEL_OPTION) { // User doesn't want to handle this unknown link type. } else if (answer == JOptionPane.YES_OPTION) { // User wants to define the new file type. Show the dialog: ExternalFileType newType = new ExternalFileType( flEntry.type.get().getName(), "", "", "", "new", IconTheme.JabRefIcon.FILE.getSmallIcon()); ExternalFileTypeEntryEditor editor = new ExternalFileTypeEntryEditor(panel.frame(), newType); editor.setVisible(true); if (editor.okPressed()) { // Get the old list of types, add this one, and update the list in prefs: List<ExternalFileType> fileTypes = new ArrayList<>( ExternalFileTypes.getInstance().getExternalFileTypeSelection()); fileTypes.add(newType); Collections.sort(fileTypes); ExternalFileTypes.getInstance().setExternalFileTypes(fileTypes); panel.getMainTable().repaint(); } } else { // User wants to change the type of this link. // First get a model of all file links for this entry: FileListEntryEditor editor = new FileListEntryEditor( panel.frame(), flEntry, false, true, panel.getBibDatabaseContext()); editor.setVisible(true, false); } } } if (!tableModel.getStringRepresentation().equals(old)) { // The table has been modified. Store the change: String toSet = tableModel.getStringRepresentation(); if (toSet.isEmpty()) { ce.addEdit(new UndoableFieldChange(aSel, Globals.FILE_FIELD, old, null)); aSel.clearField(Globals.FILE_FIELD); } else { ce.addEdit(new UndoableFieldChange(aSel, Globals.FILE_FIELD, old, toSet)); aSel.setField(Globals.FILE_FIELD, toSet); } changedEntries.add(aSel); } } } } if (!changedEntries.isEmpty()) { // Add the undo edit: ce.end(); panel.getUndoManager().addEdit(ce); panel.markBaseChanged(); entriesChangedCount = changedEntries.size(); } }