Search in sources :

Example 81 with BibDatabase

use of org.jabref.model.database.BibDatabase in project jabref by JabRef.

the class ImportInspectionDialog method generateKeyForEntry.

/**
     * Generate key for an entry.
     */
private void generateKeyForEntry(BibEntry entry) {
    entries.getReadWriteLock().writeLock().lock();
    try {
        BibDatabase database;
        MetaData localMetaData;
        // Relate to existing database, if any:
        if (panel == null) {
            database = new BibDatabase();
            localMetaData = new MetaData();
        } else {
            database = panel.getDatabase();
            localMetaData = panel.getBibDatabaseContext().getMetaData();
        }
        entry.setId(IdGenerator.next());
        // Add the entry to the database we are working with:
        database.insertEntry(entry);
        // Generate a unique key:
        BibtexKeyPatternUtil.makeAndSetLabel(localMetaData.getCiteKeyPattern(Globals.prefs.getBibtexKeyPatternPreferences().getKeyPattern()), database, entry, Globals.prefs.getBibtexKeyPatternPreferences());
        // Remove the entry from the database again, since we only added it in
        // order to
        // make sure the key was unique:
        database.removeEntry(entry);
    } finally {
        entries.getReadWriteLock().writeLock().unlock();
    }
    glTable.repaint();
}
Also used : MetaData(org.jabref.model.metadata.MetaData) BibDatabase(org.jabref.model.database.BibDatabase)

Example 82 with BibDatabase

use of org.jabref.model.database.BibDatabase in project jabref by JabRef.

the class ImportInspectionDialog method generateKeys.

/**
     * Generate keys for all entries. All keys will be unique with respect to
     * one another, and, if they are destined for an existing database, with
     * respect to existing keys in the database.
     */
private void generateKeys() {
    entries.getReadWriteLock().writeLock().lock();
    try {
        BibDatabase database;
        MetaData localMetaData;
        // Relate to existing database, if any:
        if (panel == null) {
            database = new BibDatabase();
            localMetaData = new MetaData();
        } else {
            database = panel.getDatabase();
            localMetaData = panel.getBibDatabaseContext().getMetaData();
        }
        List<Optional<String>> keys = new ArrayList<>(entries.size());
        // and generate unique keys:
        for (BibEntry entry : entries) {
            entry.setId(IdGenerator.next());
            database.insertEntry(entry);
            BibtexKeyPatternUtil.makeAndSetLabel(localMetaData.getCiteKeyPattern(Globals.prefs.getBibtexKeyPatternPreferences().getKeyPattern()), database, entry, Globals.prefs.getBibtexKeyPatternPreferences());
            // Add the generated key to our list:   -- TODO: Why??
            keys.add(entry.getCiteKeyOptional());
        }
        preview.update();
        preview.repaint();
        // control over key uniqueness.
        for (BibEntry entry : entries) {
            database.removeEntry(entry);
        }
    } finally {
        entries.getReadWriteLock().writeLock().unlock();
    }
    glTable.repaint();
}
Also used : BibEntry(org.jabref.model.entry.BibEntry) Optional(java.util.Optional) MetaData(org.jabref.model.metadata.MetaData) ArrayList(java.util.ArrayList) BibDatabase(org.jabref.model.database.BibDatabase)

Example 83 with BibDatabase

use of org.jabref.model.database.BibDatabase in project jabref by JabRef.

the class ImportMenuItem method mergeImportResults.

private ParserResult mergeImportResults(List<ImportFormatReader.UnknownFormatImport> imports) {
    BibDatabase database = new BibDatabase();
    ParserResult directParserResult = null;
    boolean anythingUseful = false;
    for (ImportFormatReader.UnknownFormatImport importResult : imports) {
        if (importResult == null) {
            continue;
        }
        if (ImportFormatReader.BIBTEX_FORMAT.equals(importResult.format)) {
            // Bibtex result. We must merge it into our main base.
            ParserResult pr = importResult.parserResult;
            anythingUseful = anythingUseful || pr.getDatabase().hasEntries() || (!pr.getDatabase().hasNoStrings());
            // Record the parserResult, as long as this is the first bibtex result:
            if (directParserResult == null) {
                directParserResult = pr;
            }
            // Merge entries:
            for (BibEntry entry : pr.getDatabase().getEntries()) {
                database.insertEntry(entry);
            }
            // Merge strings:
            for (BibtexString bs : pr.getDatabase().getStringValues()) {
                try {
                    database.addString((BibtexString) bs.clone());
                } catch (KeyCollisionException e) {
                // TODO: This means a duplicate string name exists, so it's not
                // a very exceptional situation. We should maybe give a warning...?
                }
            }
        } else {
            ParserResult pr = importResult.parserResult;
            Collection<BibEntry> entries = pr.getDatabase().getEntries();
            anythingUseful = anythingUseful | !entries.isEmpty();
            // set timestamp and owner
            // set timestamp and owner
            UpdateField.setAutomaticFields(entries, Globals.prefs.getUpdateFieldPreferences());
            boolean markEntries = !openInNew && EntryMarker.shouldMarkEntries();
            for (BibEntry entry : entries) {
                if (markEntries) {
                    EntryMarker.markEntry(entry, EntryMarker.IMPORT_MARK_LEVEL, false, new NamedCompound(""));
                }
                database.insertEntry(entry);
            }
        }
    }
    if (!anythingUseful) {
        return null;
    }
    if ((imports.size() == 1) && (directParserResult != null)) {
        return directParserResult;
    } else {
        return new ParserResult(database);
    }
}
Also used : KeyCollisionException(org.jabref.model.database.KeyCollisionException) ParserResult(org.jabref.logic.importer.ParserResult) BibEntry(org.jabref.model.entry.BibEntry) NamedCompound(org.jabref.gui.undo.NamedCompound) ImportFormatReader(org.jabref.logic.importer.ImportFormatReader) BibtexString(org.jabref.model.entry.BibtexString) BibDatabase(org.jabref.model.database.BibDatabase)

Example 84 with BibDatabase

use of org.jabref.model.database.BibDatabase in project jabref by JabRef.

the class OpenDatabaseAction method addNewDatabase.

private BasePanel addNewDatabase(ParserResult result, final Path file, boolean raisePanel) {
    BibDatabase database = result.getDatabase();
    if (result.hasWarnings()) {
        JabRefExecutorService.INSTANCE.execute(() -> ParserResultWarningDialog.showParserResultWarningDialog(result, frame));
    }
    BasePanel basePanel = new BasePanel(frame, result.getDatabaseContext());
    // file is set to null inside the EventDispatcherThread
    SwingUtilities.invokeLater(() -> frame.addTab(basePanel, raisePanel));
    if (Objects.nonNull(file)) {
        frame.output(Localization.lang("Opened library") + " '" + file.toString() + "' " + Localization.lang("with") + " " + database.getEntryCount() + " " + Localization.lang("entries") + ".");
    }
    return basePanel;
}
Also used : BasePanel(org.jabref.gui.BasePanel) BibDatabase(org.jabref.model.database.BibDatabase)

Example 85 with BibDatabase

use of org.jabref.model.database.BibDatabase in project jabref by JabRef.

the class OOBibBase method refreshCiteMarkersInternal.

private List<String> refreshCiteMarkersInternal(List<BibDatabase> databases, OOBibStyle style) throws WrappedTargetException, IllegalArgumentException, NoSuchElementException, UndefinedCharacterFormatException, UnknownPropertyException, PropertyVetoException, CreationException, BibEntryNotFoundException {
    List<String> cited = findCitedKeys();
    Map<String, BibDatabase> linkSourceBase = new HashMap<>();
    Map<BibEntry, BibDatabase> entries = findCitedEntries(databases, cited, linkSourceBase);
    XNameAccess xReferenceMarks = getReferenceMarks();
    List<String> names;
    if (style.isSortByPosition()) {
        // We need to sort the reference marks according to their order of appearance:
        names = sortedReferenceMarks;
    } else if (style.isNumberEntries()) {
        // We need to sort the reference marks according to the sorting of the bibliographic
        // entries:
        SortedMap<BibEntry, BibDatabase> newMap = new TreeMap<>(entryComparator);
        for (Map.Entry<BibEntry, BibDatabase> bibtexEntryBibtexDatabaseEntry : entries.entrySet()) {
            newMap.put(bibtexEntryBibtexDatabaseEntry.getKey(), bibtexEntryBibtexDatabaseEntry.getValue());
        }
        entries = newMap;
        // Rebuild the list of cited keys according to the sort order:
        cited.clear();
        for (BibEntry entry : entries.keySet()) {
            cited.add(entry.getCiteKeyOptional().orElse(null));
        }
        names = Arrays.asList(xReferenceMarks.getElementNames());
    } else {
        names = sortedReferenceMarks;
    }
    // Remove all reference marks that don't look like JabRef citations:
    List<String> tmp = new ArrayList<>();
    for (String name : names) {
        if (CITE_PATTERN.matcher(name).find()) {
            tmp.add(name);
        }
    }
    names = tmp;
    Map<String, Integer> numbers = new HashMap<>();
    int lastNum = 0;
    // First compute citation markers for all citations:
    String[] citMarkers = new String[names.size()];
    String[][] normCitMarkers = new String[names.size()][];
    String[][] bibtexKeys = new String[names.size()][];
    int minGroupingCount = style.getIntCitProperty(OOBibStyle.MINIMUM_GROUPING_COUNT);
    int[] types = new int[names.size()];
    for (int i = 0; i < names.size(); i++) {
        Matcher citeMatcher = CITE_PATTERN.matcher(names.get(i));
        if (citeMatcher.find()) {
            String typeStr = citeMatcher.group(1);
            int type = Integer.parseInt(typeStr);
            // Remember the type in case we need to uniquefy.
            types[i] = type;
            String[] keys = citeMatcher.group(2).split(",");
            bibtexKeys[i] = keys;
            BibEntry[] cEntries = new BibEntry[keys.length];
            for (int j = 0; j < cEntries.length; j++) {
                BibDatabase database = linkSourceBase.get(keys[j]);
                Optional<BibEntry> tmpEntry = Optional.empty();
                if (database != null) {
                    tmpEntry = database.getEntryByKey(keys[j]);
                }
                if (tmpEntry.isPresent()) {
                    cEntries[j] = tmpEntry.get();
                } else {
                    LOGGER.info("BibTeX key not found: '" + keys[j] + '\'');
                    LOGGER.info("Problem with reference mark: '" + names.get(i) + '\'');
                    cEntries[j] = new UndefinedBibtexEntry(keys[j]);
                }
            }
            String[] normCitMarker = new String[keys.length];
            String citationMarker;
            if (style.isBibtexKeyCiteMarkers()) {
                StringBuilder sb = new StringBuilder();
                normCitMarkers[i] = new String[keys.length];
                for (int j = 0; j < keys.length; j++) {
                    normCitMarkers[i][j] = cEntries[j].getCiteKeyOptional().orElse(null);
                    sb.append(cEntries[j].getCiteKeyOptional().orElse(""));
                    if (j < (keys.length - 1)) {
                        sb.append(',');
                    }
                }
                citationMarker = sb.toString();
            } else if (style.isNumberEntries()) {
                if (style.isSortByPosition()) {
                    // We have sorted the citation markers according to their order of appearance,
                    // so we simply count up for each marker referring to a new entry:
                    List<Integer> num = new ArrayList<>(keys.length);
                    for (int j = 0; j < keys.length; j++) {
                        if (cEntries[j] instanceof UndefinedBibtexEntry) {
                            num.add(j, -1);
                        } else {
                            num.add(j, lastNum + 1);
                            if (numbers.containsKey(keys[j])) {
                                num.set(j, numbers.get(keys[j]));
                            } else {
                                numbers.put(keys[j], num.get(j));
                                lastNum = num.get(j);
                            }
                        }
                    }
                    citationMarker = style.getNumCitationMarker(num, minGroupingCount, false);
                    for (int j = 0; j < keys.length; j++) {
                        normCitMarker[j] = style.getNumCitationMarker(Collections.singletonList(num.get(j)), minGroupingCount, false);
                    }
                } else {
                    // We need to find the number of the cited entry in the bibliography,
                    // and use that number for the cite marker:
                    List<Integer> num = findCitedEntryIndex(names.get(i), cited);
                    if (num.isEmpty()) {
                        throw new BibEntryNotFoundException(names.get(i), Localization.lang("Could not resolve BibTeX entry for citation marker '%0'.", names.get(i)));
                    } else {
                        citationMarker = style.getNumCitationMarker(num, minGroupingCount, false);
                    }
                    for (int j = 0; j < keys.length; j++) {
                        List<Integer> list = new ArrayList<>(1);
                        list.add(num.get(j));
                        normCitMarker[j] = style.getNumCitationMarker(list, minGroupingCount, false);
                    }
                }
            } else {
                if (cEntries.length > 1) {
                    if (style.getBooleanCitProperty(OOBibStyle.MULTI_CITE_CHRONOLOGICAL)) {
                        Arrays.sort(cEntries, yearAuthorTitleComparator);
                    } else {
                        Arrays.sort(cEntries, entryComparator);
                    }
                    // Update key list to match the new sorting:
                    for (int j = 0; j < cEntries.length; j++) {
                        bibtexKeys[i][j] = cEntries[j].getCiteKeyOptional().orElse(null);
                    }
                }
                citationMarker = style.getCitationMarker(Arrays.asList(cEntries), entries, type == OOBibBase.AUTHORYEAR_PAR, null, null);
                // We need "normalized" (in parenthesis) markers for uniqueness checking purposes:
                for (int j = 0; j < cEntries.length; j++) {
                    normCitMarker[j] = style.getCitationMarker(Collections.singletonList(cEntries[j]), entries, true, null, new int[] { -1 });
                }
            }
            citMarkers[i] = citationMarker;
            normCitMarkers[i] = normCitMarker;
        }
    }
    uniquefiers.clear();
    if (!style.isBibtexKeyCiteMarkers() && !style.isNumberEntries()) {
        // See if there are duplicate citations marks referring to different entries. If so, we need to
        // use uniquefiers:
        Map<String, List<String>> refKeys = new HashMap<>();
        Map<String, List<Integer>> refNums = new HashMap<>();
        for (int i = 0; i < citMarkers.length; i++) {
            // compare normalized markers, since the actual markers can be different
            String[] markers = normCitMarkers[i];
            for (int j = 0; j < markers.length; j++) {
                String marker = markers[j];
                String currentKey = bibtexKeys[i][j];
                if (refKeys.containsKey(marker)) {
                    // Ok, we have seen this exact marker before.
                    if (!refKeys.get(marker).contains(currentKey)) {
                        // ... but not for this entry.
                        refKeys.get(marker).add(currentKey);
                        refNums.get(marker).add(i);
                    }
                } else {
                    List<String> l = new ArrayList<>(1);
                    l.add(currentKey);
                    refKeys.put(marker, l);
                    List<Integer> l2 = new ArrayList<>(1);
                    l2.add(i);
                    refNums.put(marker, l2);
                }
            }
        }
        // Go through the collected lists and see where we need to uniquefy:
        for (Map.Entry<String, List<String>> stringListEntry : refKeys.entrySet()) {
            List<String> keys = stringListEntry.getValue();
            if (keys.size() > 1) {
                // This marker appears for more than one unique entry:
                int uniq = 'a';
                for (String key : keys) {
                    // Update the map of uniquefiers for the benefit of both the following generation of new
                    // citation markers, and for the method that builds the bibliography:
                    uniquefiers.put(key, String.valueOf((char) uniq));
                    uniq++;
                }
            }
        }
        // Finally, go through all citation markers, and update those referring to entries in our current list:
        int maxAuthorsFirst = style.getIntCitProperty(OOBibStyle.MAX_AUTHORS_FIRST);
        Set<String> seenBefore = new HashSet<>();
        for (int j = 0; j < bibtexKeys.length; j++) {
            boolean needsChange = false;
            int[] firstLimAuthors = new int[bibtexKeys[j].length];
            String[] uniquif = new String[bibtexKeys[j].length];
            BibEntry[] cEntries = new BibEntry[bibtexKeys[j].length];
            for (int k = 0; k < bibtexKeys[j].length; k++) {
                String currentKey = bibtexKeys[j][k];
                firstLimAuthors[k] = -1;
                if (maxAuthorsFirst > 0) {
                    if (!seenBefore.contains(currentKey)) {
                        firstLimAuthors[k] = maxAuthorsFirst;
                    }
                    seenBefore.add(currentKey);
                }
                String uniq = uniquefiers.get(currentKey);
                Optional<BibEntry> tmpEntry = Optional.empty();
                if (uniq == null) {
                    if (firstLimAuthors[k] > 0) {
                        needsChange = true;
                        BibDatabase database = linkSourceBase.get(currentKey);
                        if (database != null) {
                            tmpEntry = database.getEntryByKey(currentKey);
                        }
                    } else {
                        BibDatabase database = linkSourceBase.get(currentKey);
                        if (database != null) {
                            tmpEntry = database.getEntryByKey(currentKey);
                        }
                    }
                    uniquif[k] = "";
                } else {
                    needsChange = true;
                    BibDatabase database = linkSourceBase.get(currentKey);
                    if (database != null) {
                        tmpEntry = database.getEntryByKey(currentKey);
                    }
                    uniquif[k] = uniq;
                }
                if (tmpEntry.isPresent()) {
                    cEntries[k] = tmpEntry.get();
                }
            }
            if (needsChange) {
                citMarkers[j] = style.getCitationMarker(Arrays.asList(cEntries), entries, types[j] == OOBibBase.AUTHORYEAR_PAR, uniquif, firstLimAuthors);
            }
        }
    }
    // Refresh all reference marks with the citation markers we computed:
    boolean hadBibSection = getBookmarkRange(OOBibBase.BIB_SECTION_NAME) != null;
    // Check if we are supposed to set a character format for citations:
    boolean mustTestCharFormat = style.isFormatCitations();
    for (int i = 0; i < names.size(); i++) {
        Object referenceMark = xReferenceMarks.getByName(names.get(i));
        XTextContent bookmark = UnoRuntime.queryInterface(XTextContent.class, referenceMark);
        XTextCursor cursor = bookmark.getAnchor().getText().createTextCursorByRange(bookmark.getAnchor());
        if (mustTestCharFormat) {
            // If we are supposed to set character format for citations, must run a test before we
            // delete old citation markers. Otherwise, if the specified character format doesn't
            // exist, we end up deleting the markers before the process crashes due to a the missing
            // format, with catastrophic consequences for the user.
            // need to do this only once
            mustTestCharFormat = false;
            XPropertySet xCursorProps = UnoRuntime.queryInterface(XPropertySet.class, cursor);
            String charStyle = style.getCitationCharacterFormat();
            try {
                xCursorProps.setPropertyValue(CHAR_STYLE_NAME, charStyle);
            } catch (UnknownPropertyException | PropertyVetoException | IllegalArgumentException | WrappedTargetException ex) {
                throw new UndefinedCharacterFormatException(charStyle);
            }
        }
        text.removeTextContent(bookmark);
        insertReferenceMark(names.get(i), citMarkers[i], cursor, types[i] != OOBibBase.INVISIBLE_CIT, style);
        if (hadBibSection && (getBookmarkRange(OOBibBase.BIB_SECTION_NAME) == null)) {
            // We have overwritten the marker for the start of the reference list.
            // We need to add it again.
            cursor.collapseToEnd();
            OOUtil.insertParagraphBreak(text, cursor);
            insertBookMark(OOBibBase.BIB_SECTION_NAME, cursor);
        }
    }
    List<String> unresolvedKeys = new ArrayList<>();
    for (BibEntry entry : entries.keySet()) {
        if (entry instanceof UndefinedBibtexEntry) {
            String key = ((UndefinedBibtexEntry) entry).getKey();
            if (!unresolvedKeys.contains(key)) {
                unresolvedKeys.add(key);
            }
        }
    }
    return unresolvedKeys;
}
Also used : WrappedTargetException(com.sun.star.lang.WrappedTargetException) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Matcher(java.util.regex.Matcher) ArrayList(java.util.ArrayList) XTextCursor(com.sun.star.text.XTextCursor) BibEntry(org.jabref.model.entry.BibEntry) UndefinedBibtexEntry(org.jabref.logic.openoffice.UndefinedBibtexEntry) List(java.util.List) ArrayList(java.util.ArrayList) JList(javax.swing.JList) IllegalArgumentException(com.sun.star.lang.IllegalArgumentException) HashSet(java.util.HashSet) BibEntry(org.jabref.model.entry.BibEntry) UndefinedBibtexEntry(org.jabref.logic.openoffice.UndefinedBibtexEntry) XNameAccess(com.sun.star.container.XNameAccess) UnknownPropertyException(com.sun.star.beans.UnknownPropertyException) Point(com.sun.star.awt.Point) XPropertySet(com.sun.star.beans.XPropertySet) PropertyVetoException(com.sun.star.beans.PropertyVetoException) XTextContent(com.sun.star.text.XTextContent) SortedMap(java.util.SortedMap) BibDatabase(org.jabref.model.database.BibDatabase) Map(java.util.Map) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TreeMap(java.util.TreeMap)

Aggregations

BibDatabase (org.jabref.model.database.BibDatabase)88 BibEntry (org.jabref.model.entry.BibEntry)60 Test (org.junit.Test)44 ParserResult (org.jabref.logic.importer.ParserResult)20 ArrayList (java.util.ArrayList)19 HashMap (java.util.HashMap)15 BibDatabaseContext (org.jabref.model.database.BibDatabaseContext)15 BibtexParser (org.jabref.logic.importer.fileformat.BibtexParser)13 MetaData (org.jabref.model.metadata.MetaData)12 IOException (java.io.IOException)10 Defaults (org.jabref.model.Defaults)9 Before (org.junit.Before)9 File (java.io.File)8 InputStreamReader (java.io.InputStreamReader)8 InputStream (java.io.InputStream)7 PropertyVetoException (com.sun.star.beans.PropertyVetoException)6 UnknownPropertyException (com.sun.star.beans.UnknownPropertyException)6 WrappedTargetException (com.sun.star.lang.WrappedTargetException)6 LinkedHashMap (java.util.LinkedHashMap)5 BasePanel (org.jabref.gui.BasePanel)5