1919import java .util .Objects ;
2020import java .util .Optional ;
2121import java .util .Set ;
22+ import java .util .function .Predicate ;
2223import java .util .regex .Pattern ;
2324
2425import javax .xml .parsers .DocumentBuilderFactory ;
6566import org .w3c .dom .NodeList ;
6667import org .xml .sax .SAXException ;
6768
69+ import static org .jabref .logic .util .MetadataSerializationConfiguration .GROUP_QUOTE_CHAR ;
70+ import static org .jabref .logic .util .MetadataSerializationConfiguration .GROUP_TYPE_SUFFIX ;
71+
6872/**
6973 * Class for importing BibTeX-files.
7074 * <p>
@@ -259,7 +263,23 @@ private ParserResult parseFileContent() throws IOException {
259263 meta ,
260264 importFormatPreferences .bibEntryPreferences ().getKeywordSeparator ());
261265 if (bibDeskGroupTreeNode != null ) {
262- metaData .setGroups (bibDeskGroupTreeNode );
266+ metaData .getGroups ().ifPresentOrElse (existingGroupTree -> {
267+ var existingGroups = meta .get (MetaData .GROUPSTREE );
268+ // We only have one Group BibDeskGroup with n children
269+ // instead of iterating through the whole group structure every time we just search in the metadata for the group name
270+ var groupsToAdd = bibDeskGroupTreeNode .getChildren ()
271+ .stream ().
272+ filter (Predicate .not (groupTreeNode -> existingGroups .contains (GROUP_TYPE_SUFFIX + groupTreeNode .getName () + GROUP_QUOTE_CHAR )));
273+ groupsToAdd .forEach (existingGroupTree ::addChild );
274+
275+ },
276+ // metadata does not contain any groups, so we need to create an AllEntriesGroup and add the other groups as children
277+ () -> {
278+ GroupTreeNode rootNode = new GroupTreeNode (DefaultGroupsFactory .getAllEntriesGroup ());
279+ bibDeskGroupTreeNode .moveTo (rootNode );
280+ metaData .setGroups (rootNode );
281+ }
282+ );
263283 }
264284 parserResult .setMetaData (metaData );
265285 } catch (ParseException exception ) {
@@ -313,7 +333,6 @@ private void parseAndAddEntry(String type) {
313333 } catch (IOException ex ) {
314334 // This makes the parser more robust:
315335 // If an exception is thrown when parsing an entry, drop the entry and try to resume parsing.
316-
317336 LOGGER .warn ("Could not parse entry" , ex );
318337 parserResult .addWarning (Localization .lang ("Error occurred when parsing entry" ) + ": '" + ex .getMessage ()
319338 + "'. " + "\n \n " + Localization .lang ("JabRef skipped the entry." ));
@@ -381,7 +400,8 @@ private void addBibDeskGroupEntriesToJabRefGroups() {
381400 Optional <String > groupValue = bibEntry .flatMap (entry -> entry .getField (StandardField .GROUPS ));
382401 if (groupValue .isEmpty ()) { // if the citation does not belong to a group already
383402 bibEntry .flatMap (entry -> entry .setField (StandardField .GROUPS , groupName ));
384- } else { // if the citation does belong to a group already, we concatenate
403+ } else if (!groupValue .get ().contains (groupName )) {
404+ // if the citation does belong to a group already and is not yet assigned to the same group, we concatenate
385405 String concatGroup = groupValue .get () + "," + groupName ;
386406 bibEntry .flatMap (entryByCitationKey -> entryByCitationKey .setField (StandardField .GROUPS , concatGroup ));
387407 }
@@ -401,7 +421,7 @@ private void parseBibDeskComment(String comment, Map<String, String> meta) throw
401421
402422 NodeList dictList = doc .getElementsByTagName ("dict" );
403423 meta .putIfAbsent (MetaData .DATABASE_TYPE , "bibtex;" );
404- bibDeskGroupTreeNode = new GroupTreeNode ( DefaultGroupsFactory . getAllEntriesGroup ( ));
424+ bibDeskGroupTreeNode = GroupTreeNode . fromGroup ( new ExplicitGroup ( "BibDeskGroups" , GroupHierarchyType . INDEPENDENT , importFormatPreferences . bibEntryPreferences (). getKeywordSeparator () ));
405425
406426 // Since each static group has their own dict element, we iterate through them
407427 for (int i = 0 ; i < dictList .getLength (); i ++) {
0 commit comments