From e812e48f5861d0116143cab8573c8524b392efb1 Mon Sep 17 00:00:00 2001 From: dyrpsf Date: Mon, 12 Jan 2026 17:22:19 +0530 Subject: [PATCH 1/2] Parse creators from dcterms:creator vCard4 annotations --- .../xml/parsers/SBMLRDFAnnotationParser.java | 116 +++++++++++++++--- 1 file changed, 101 insertions(+), 15 deletions(-) diff --git a/core/src/org/sbml/jsbml/xml/parsers/SBMLRDFAnnotationParser.java b/core/src/org/sbml/jsbml/xml/parsers/SBMLRDFAnnotationParser.java index a0f12482a..af86b5420 100644 --- a/core/src/org/sbml/jsbml/xml/parsers/SBMLRDFAnnotationParser.java +++ b/core/src/org/sbml/jsbml/xml/parsers/SBMLRDFAnnotationParser.java @@ -37,6 +37,7 @@ import org.sbml.jsbml.xml.XMLAttributes; import org.sbml.jsbml.xml.XMLNode; import org.sbml.jsbml.xml.XMLTriple; +import org.sbml.jsbml.xml.parsers.SBMLRDFAnnotationParser.NODE_COLOR; import org.w3c.util.DateParser; import org.w3c.util.InvalidDateException; @@ -65,6 +66,10 @@ public class SBMLRDFAnnotationParser implements AnnotationReader, AnnotationWrit * */ public static final String CUSTOM_RDF = "jsbml.custom.rdf"; + /** + * Namespace for vCard4 RDF (used by some tools such as libSBML). + */ + private static final String VCARD4_NS = "http://www.w3.org/2006/vcard/ns#"; /** * @@ -527,9 +532,8 @@ private void readRDFHistory(SBase contextSBase, XMLNode descriptionNode) { logger.debug("readRDFHistory - called"); - // get the dc:creator children + // dc:creator children (old vCard format) List creatorNodes = descriptionNode.getChildElements("creator", JSBML.URI_PURL_ELEMENTS); - if (creatorNodes != null && creatorNodes.size() > 0) { for (XMLNode creator : creatorNodes) @@ -538,6 +542,16 @@ private void readRDFHistory(SBase contextSBase, XMLNode descriptionNode) } } + // dcterms:creator children (vCard4 format as written by libSBML) + List dctermsCreatorNodes = descriptionNode.getChildElements("creator", JSBML.URI_PURL_TERMS); + if (dctermsCreatorNodes != null && dctermsCreatorNodes.size() > 0) + { + for (XMLNode creator : dctermsCreatorNodes) + { + readCreator(contextSBase, creator); + } + } + // getting the dates children List createdNodes = descriptionNode.getChildElements("created", JSBML.URI_PURL_TERMS); List modifiedNodes = descriptionNode.getChildElements("modified", JSBML.URI_PURL_TERMS); @@ -721,21 +735,21 @@ private void readCreatedDate(SBase contextSBase, XMLNode createdNode) } /** - * Reads the 'dc:creator' part of the SBML RDF annotation into {@link Creator}s. + * Reads the 'dc:creator' / 'dcterms:creator' part of the SBML RDF annotation into {@link Creator}s. * * @param contextSBase the {@link SBase} in which we will add the {@link Creator}s. - * @param creatorNode the 'dc:creator' {@link XMLNode} that contain the definition of the creator vCards. + * @param creatorNode the 'dc:creator' or 'dcterms:creator' {@link XMLNode} that contain the definition of the creator vCards. */ private void readCreator(SBase contextSBase, XMLNode creatorNode) { logger.debug("readCreator called"); XMLNode bagNode = creatorNode.getChildElement("Bag", Annotation.URI_RDF_SYNTAX_NS); - + if (bagNode == null) { return; } - + List liNodes = bagNode.getChildElements("li", Annotation.URI_RDF_SYNTAX_NS); for (XMLNode liNode : liNodes) @@ -749,16 +763,16 @@ private void readCreator(SBase contextSBase, XMLNode creatorNode) contextSBase.getHistory().addCreator(creator); creator.putUserObject(JSBML.READING_IN_PROGRESS, Boolean.TRUE); - // get name information + // ---- vCard3 name (N/Family/Given) ---- + boolean nameFound = false; List nameNodes = liNode.getChildElements("N", Creator.URI_RDF_VCARD_NS); if (nameNodes != null && nameNodes.size() == 1) { XMLNode nameNode = nameNodes.get(0); - // get family name information + // family name List famillyNameNodes = nameNode.getChildElements("Family", Creator.URI_RDF_VCARD_NS); - if (famillyNameNodes != null & famillyNameNodes.size() == 1) { XMLNode famillyNode = famillyNameNodes.get(0); @@ -781,9 +795,8 @@ private void readCreator(SBase contextSBase, XMLNode creatorNode) logger.debug("readCreator - did not found one and only one 'Family' node: " + famillyNameNodes); } - // get first name information + // given name List firstNameNodes = nameNode.getChildElements("Given", Creator.URI_RDF_VCARD_NS); - if (firstNameNodes != null & firstNameNodes.size() == 1) { XMLNode firstNameNode = firstNameNodes.get(0); @@ -808,13 +821,50 @@ private void readCreator(SBase contextSBase, XMLNode creatorNode) nameNode.removeAttr("parseType"); removeXmlNodeIfEmpty(nameNode); + nameFound = true; } else { logger.debug("readCreator - did not found one and only one 'N' node: " + nameNodes); } - // get email information + // ---- vCard4 name (hasName/family-name/given-name) ---- + if (!nameFound) + { + List v4NameNodes = liNode.getChildElements("hasName", VCARD4_NS); + if (v4NameNodes != null && v4NameNodes.size() == 1) + { + XMLNode hasNameNode = v4NameNodes.get(0); + + List familyNodes = hasNameNode.getChildElements("family-name", VCARD4_NS); + if (familyNodes != null && familyNodes.size() == 1) + { + XMLNode familyNode = familyNodes.get(0); + int textNodeIndex = findFirstNonEmptyTextElementIndex(familyNode); + if (textNodeIndex != -1) + { + String familyName = familyNode.getChildAt(textNodeIndex).getCharacters().trim(); + logger.debug("readCreator (vCard4) - family name = " + familyName); + creator.setFamilyName(familyName); + } + } + + List givenNodes = hasNameNode.getChildElements("given-name", VCARD4_NS); + if (givenNodes != null && givenNodes.size() == 1) + { + XMLNode givenNode = givenNodes.get(0); + int textNodeIndex = findFirstNonEmptyTextElementIndex(givenNode); + if (textNodeIndex != -1) + { + String givenName = givenNode.getChildAt(textNodeIndex).getCharacters().trim(); + logger.debug("readCreator (vCard4) - given name = " + givenName); + creator.setGivenName(givenName); + } + } + } + } + + // ---- email (vCard3: EMAIL) ---- List emailNodes = liNode.getChildElements("EMAIL", Creator.URI_RDF_VCARD_NS); if (emailNodes != null && emailNodes.size() == 1) @@ -839,14 +889,32 @@ private void readCreator(SBase contextSBase, XMLNode creatorNode) logger.debug("readCreator - did not found one and only one 'EMAIL' node : " + emailNodes); } - // get organization information + // ---- email (vCard4: hasEmail) ---- + if (!creator.isSetEmail()) + { + List v4EmailNodes = liNode.getChildElements("hasEmail", VCARD4_NS); + + if (v4EmailNodes != null && v4EmailNodes.size() == 1) + { + XMLNode emailNode = v4EmailNodes.get(0); + int textNodeIndex = findFirstNonEmptyTextElementIndex(emailNode); + + if (textNodeIndex != -1) + { + String email = emailNode.getChildAt(textNodeIndex).getCharacters().trim(); + logger.debug("readCreator (vCard4) - email = " + email); + creator.setEmail(email); + } + } + } + + // ---- organisation (vCard3: ORG/Orgname) ---- List orgNodes = liNode.getChildElements("ORG", Creator.URI_RDF_VCARD_NS); if (orgNodes != null && orgNodes.size() == 1) { XMLNode firstNode = orgNodes.get(0); - // get Organization name information List orgNameNodes = firstNode.getChildElements("Orgname", Creator.URI_RDF_VCARD_NS); if (orgNameNodes != null & orgNameNodes.size() == 1) @@ -879,12 +947,30 @@ private void readCreator(SBase contextSBase, XMLNode creatorNode) logger.debug("readCreator - did not found one and only one 'ORG' node : " + orgNodes); } + // ---- organisation (vCard4: organization-name) ---- + if (!creator.isSetOrganisation()) + { + List v4OrgNodes = liNode.getChildElements("organization-name", VCARD4_NS); + + if (v4OrgNodes != null && v4OrgNodes.size() == 1) + { + XMLNode orgNode = v4OrgNodes.get(0); + int textNodeIndex = findFirstNonEmptyTextElementIndex(orgNode); + + if (textNodeIndex != -1) + { + String orgName = orgNode.getChildAt(textNodeIndex).getCharacters().trim(); + logger.debug("readCreator (vCard4) - organization-name = " + orgName); + creator.setOrganisation(orgName); + } + } + } + liNode.removeAttr("parseType"); boolean nodeRemoved = removeXmlNodeIfEmpty(liNode); if (!nodeRemoved) { - // remove and store the 'li' XMLNode to be able to keep any additional information part of the SBML specifications or not. liNode.removeFromParent(); creator.putUserObject(CUSTOM_RDF, liNode); } From c117f999a391ba7960cee0e57771648b1c1e174c Mon Sep 17 00:00:00 2001 From: dyrpsf Date: Sun, 25 Jan 2026 08:00:45 +0530 Subject: [PATCH 2/2] Factor vCard element names into constants in SBMLRDFAnnotationParser --- .../xml/parsers/SBMLRDFAnnotationParser.java | 57 ++++++++++++------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/core/src/org/sbml/jsbml/xml/parsers/SBMLRDFAnnotationParser.java b/core/src/org/sbml/jsbml/xml/parsers/SBMLRDFAnnotationParser.java index af86b5420..4e532792b 100644 --- a/core/src/org/sbml/jsbml/xml/parsers/SBMLRDFAnnotationParser.java +++ b/core/src/org/sbml/jsbml/xml/parsers/SBMLRDFAnnotationParser.java @@ -70,6 +70,20 @@ public class SBMLRDFAnnotationParser implements AnnotationReader, AnnotationWrit * Namespace for vCard4 RDF (used by some tools such as libSBML). */ private static final String VCARD4_NS = "http://www.w3.org/2006/vcard/ns#"; + // vCard 3 element names + private static final String VCARD3_ELEMENT_N = "N"; + private static final String VCARD3_ELEMENT_EMAIL = "EMAIL"; + private static final String VCARD3_ELEMENT_ORG = "ORG"; + private static final String VCARD3_ELEMENT_FAMILY = "Family"; + private static final String VCARD3_ELEMENT_GIVEN = "Given"; + private static final String VCARD3_ELEMENT_ORGNAME = "Orgname"; + + // vCard 4 element names + private static final String VCARD4_ELEMENT_HAS_NAME = "hasName"; + private static final String VCARD4_ELEMENT_FAMILY_NAME = "family-name"; + private static final String VCARD4_ELEMENT_GIVEN_NAME = "given-name"; + private static final String VCARD4_ELEMENT_HAS_EMAIL = "hasEmail"; + private static final String VCARD4_ELEMENT_ORGANIZATION_NAME = "organization-name"; /** * @@ -299,9 +313,9 @@ private NODE_COLOR isValidVCard(XMLNode xmlNode) { // nothing really mandatory there !! // vCard:N->vCard:Family|vCard:given vCard:EMAIL vCard:ORG->vCard:Orgname - XMLNode nameNode = xmlNode.getChildElement("N", Creator.URI_RDF_VCARD_NS); - XMLNode emailNode = xmlNode.getChildElement("EMAIL", Creator.URI_RDF_VCARD_NS); - XMLNode orgNode = xmlNode.getChildElement("ORG", Creator.URI_RDF_VCARD_NS); + XMLNode nameNode = xmlNode.getChildElement(VCARD3_ELEMENT_N, Creator.URI_RDF_VCARD_NS); + XMLNode emailNode = xmlNode.getChildElement(VCARD3_ELEMENT_EMAIL, Creator.URI_RDF_VCARD_NS); + XMLNode orgNode = xmlNode.getChildElement(VCARD3_ELEMENT_ORG, Creator.URI_RDF_VCARD_NS); // at least one of these three nodes is present if (nameNode != null || emailNode != null || orgNode != null) { @@ -765,14 +779,14 @@ private void readCreator(SBase contextSBase, XMLNode creatorNode) // ---- vCard3 name (N/Family/Given) ---- boolean nameFound = false; - List nameNodes = liNode.getChildElements("N", Creator.URI_RDF_VCARD_NS); + List nameNodes = liNode.getChildElements(VCARD3_ELEMENT_N, Creator.URI_RDF_VCARD_NS); if (nameNodes != null && nameNodes.size() == 1) { XMLNode nameNode = nameNodes.get(0); // family name - List famillyNameNodes = nameNode.getChildElements("Family", Creator.URI_RDF_VCARD_NS); + List famillyNameNodes = nameNode.getChildElements(VCARD3_ELEMENT_FAMILY, Creator.URI_RDF_VCARD_NS); if (famillyNameNodes != null & famillyNameNodes.size() == 1) { XMLNode famillyNode = famillyNameNodes.get(0); @@ -796,7 +810,7 @@ private void readCreator(SBase contextSBase, XMLNode creatorNode) } // given name - List firstNameNodes = nameNode.getChildElements("Given", Creator.URI_RDF_VCARD_NS); + List firstNameNodes = nameNode.getChildElements(VCARD3_ELEMENT_GIVEN, Creator.URI_RDF_VCARD_NS); if (firstNameNodes != null & firstNameNodes.size() == 1) { XMLNode firstNameNode = firstNameNodes.get(0); @@ -831,12 +845,12 @@ private void readCreator(SBase contextSBase, XMLNode creatorNode) // ---- vCard4 name (hasName/family-name/given-name) ---- if (!nameFound) { - List v4NameNodes = liNode.getChildElements("hasName", VCARD4_NS); + List v4NameNodes = liNode.getChildElements(VCARD4_ELEMENT_HAS_NAME, VCARD4_NS); if (v4NameNodes != null && v4NameNodes.size() == 1) { XMLNode hasNameNode = v4NameNodes.get(0); - List familyNodes = hasNameNode.getChildElements("family-name", VCARD4_NS); + List familyNodes = hasNameNode.getChildElements(VCARD4_ELEMENT_FAMILY_NAME, VCARD4_NS); if (familyNodes != null && familyNodes.size() == 1) { XMLNode familyNode = familyNodes.get(0); @@ -849,7 +863,7 @@ private void readCreator(SBase contextSBase, XMLNode creatorNode) } } - List givenNodes = hasNameNode.getChildElements("given-name", VCARD4_NS); + List givenNodes = hasNameNode.getChildElements(VCARD4_ELEMENT_GIVEN_NAME, VCARD4_NS); if (givenNodes != null && givenNodes.size() == 1) { XMLNode givenNode = givenNodes.get(0); @@ -865,7 +879,7 @@ private void readCreator(SBase contextSBase, XMLNode creatorNode) } // ---- email (vCard3: EMAIL) ---- - List emailNodes = liNode.getChildElements("EMAIL", Creator.URI_RDF_VCARD_NS); + List emailNodes = liNode.getChildElements(VCARD3_ELEMENT_EMAIL, Creator.URI_RDF_VCARD_NS); if (emailNodes != null && emailNodes.size() == 1) { @@ -892,7 +906,7 @@ private void readCreator(SBase contextSBase, XMLNode creatorNode) // ---- email (vCard4: hasEmail) ---- if (!creator.isSetEmail()) { - List v4EmailNodes = liNode.getChildElements("hasEmail", VCARD4_NS); + List v4EmailNodes = liNode.getChildElements(VCARD4_ELEMENT_HAS_EMAIL, VCARD4_NS); if (v4EmailNodes != null && v4EmailNodes.size() == 1) { @@ -909,13 +923,14 @@ private void readCreator(SBase contextSBase, XMLNode creatorNode) } // ---- organisation (vCard3: ORG/Orgname) ---- - List orgNodes = liNode.getChildElements("ORG", Creator.URI_RDF_VCARD_NS); + List orgNodes = liNode.getChildElements(VCARD3_ELEMENT_ORG, Creator.URI_RDF_VCARD_NS); if (orgNodes != null && orgNodes.size() == 1) { XMLNode firstNode = orgNodes.get(0); - List orgNameNodes = firstNode.getChildElements("Orgname", Creator.URI_RDF_VCARD_NS); + List orgNameNodes = firstNode.getChildElements(VCARD3_ELEMENT_ORGNAME, Creator.URI_RDF_VCARD_NS); + if (orgNameNodes != null & orgNameNodes.size() == 1) { @@ -950,7 +965,7 @@ private void readCreator(SBase contextSBase, XMLNode creatorNode) // ---- organisation (vCard4: organization-name) ---- if (!creator.isSetOrganisation()) { - List v4OrgNodes = liNode.getChildElements("organization-name", VCARD4_NS); + List v4OrgNodes = liNode.getChildElements(VCARD4_ELEMENT_ORGANIZATION_NAME, VCARD4_NS); if (v4OrgNodes != null && v4OrgNodes.size() == 1) { @@ -1739,34 +1754,34 @@ private void writeCreators(History history, XMLNode descriptionNode) if (creator.isSetFamilyName() || creator.isSetGivenName()) { - XMLNode vCardNNode = getOrCreate(liNode, "N", Creator.URI_RDF_VCARD_NS, "vCard"); + XMLNode vCardNNode = getOrCreate(liNode, VCARD3_ELEMENT_N, Creator.URI_RDF_VCARD_NS, "vCard"); vCardNNode.addAttr("parseType", "Resource", Annotation.URI_RDF_SYNTAX_NS, "rdf"); if (creator.isSetFamilyName()) { - XMLNode vCardFamilyNode = getOrCreate(vCardNNode, "Family", Creator.URI_RDF_VCARD_NS, "vCard"); - vCardFamilyNode.insertChild(0, new XMLNode(creator.getFamilyName())); + XMLNode vCardFamilyNode = getOrCreate(vCardNNode, VCARD3_ELEMENT_FAMILY, Creator.URI_RDF_VCARD_NS, "vCard"); + vCardFamilyNode.insertChild(0, new XMLNode(creator.getFamilyName())); } if (creator.isSetGivenName()) { - XMLNode vCardGivenNode = getOrCreate(vCardNNode, "Given", Creator.URI_RDF_VCARD_NS, "vCard"); + XMLNode vCardGivenNode = getOrCreate(vCardNNode, VCARD3_ELEMENT_GIVEN, Creator.URI_RDF_VCARD_NS, "vCard"); vCardGivenNode.insertChild(0, new XMLNode(creator.getGivenName())); } } if (creator.isSetEmail()) { - XMLNode vCardEmailNode = getOrCreate(liNode, "EMAIL", Creator.URI_RDF_VCARD_NS, "vCard"); + XMLNode vCardEmailNode = getOrCreate(liNode, VCARD3_ELEMENT_EMAIL, Creator.URI_RDF_VCARD_NS, "vCard"); vCardEmailNode.insertChild(0, new XMLNode(creator.getEmail())); } if (creator.isSetOrganisation()) { - XMLNode vCardOrgNode = getOrCreate(liNode, "ORG", Creator.URI_RDF_VCARD_NS, "vCard"); + XMLNode vCardOrgNode = getOrCreate(liNode, VCARD3_ELEMENT_ORG, Creator.URI_RDF_VCARD_NS, "vCard"); vCardOrgNode.addAttr("parseType", "Resource", Annotation.URI_RDF_SYNTAX_NS, "rdf"); - XMLNode vCardOrgNameNode = getOrCreate(vCardOrgNode, "Orgname", Creator.URI_RDF_VCARD_NS, "vCard"); + XMLNode vCardOrgNameNode = getOrCreate(vCardOrgNode, VCARD3_ELEMENT_ORGNAME, Creator.URI_RDF_VCARD_NS, "vCard"); vCardOrgNameNode.insertChild(0, new XMLNode(creator.getOrganisation())); }