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(); }
@Override public void actionPerformed(ActionEvent e) { try { Util.runAbstractWorker(DbImportAction.this); } catch (Throwable throwable) { LOGGER.warn("Problem importing from database", throwable); } }
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(); } }
@Override public String[] getSecondaryOptionalFields() { return Util.getRemainder(opt, priOpt); }
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(); }
public CustomEntryType(String name_, String[] req_, String[] priOpt_, String[] secOpt_) { name = StringUtil.capitalizeFirst(name_); parseRequiredFields(req_); priOpt = priOpt_; opt = Util.arrayConcat(priOpt_, secOpt_); }
@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); } } }
@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; }