Skip to content

MCR-3578 Changes modsperson attribute handling#2773

Open
erodde wants to merge 18 commits intomainfrom
issues/MCR-3578-changes-modsperson-attribute-handling
Open

MCR-3578 Changes modsperson attribute handling#2773
erodde wants to merge 18 commits intomainfrom
issues/MCR-3578-changes-modsperson-attribute-handling

Conversation

@erodde
Copy link
Copy Markdown
Contributor

@erodde erodde commented Dec 12, 2025

Link to jira.
This PR: #2733, but renamed branch and Jira Ticket

Comment on lines +36 to +44
Set<MCRIdentifier> getAllIdentifiers(MCRIdentifier identifier);

/**
* Gets a legal entity's identifiers of a given type. The legal entity is determined by a specific identifier.
* @param primaryIdentifier unique identifier of legal entity, not null
* @param identifierType the type of looked up identifiers as a string, not null
* @return a set of identifiers a legal entity owns
*/
Set<MCRIdentifier> getTypedIdentifiers(MCRIdentifier primaryIdentifier, String identifierType);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: I would not call the methods "get" but rather findAllIdentifiers / findAllIdentifiersByType or lookupAllIdentifiers / lookupAllIdentifiersByType...

import java.util.Set;
import java.util.stream.Collectors;

public class MCRUser2MODSPersonIdentifierService implements MCRLegalEntityService {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the name confusing. Maybe just MCRMODSPersonIdentifierService?

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<mycoreobject xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="datamodel-modsperson.xsd" ID="junit_modsperson_00000001">
<metadata>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use two spaces for indentation.

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<mycoreobject xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="datamodel-modsperson.xsd" ID="junit_modsperson_00000002">
<metadata>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use two spaces for indentation.

Comment on lines +85 to +86
legalEntityService = MCRConfiguration2.getInstanceOfOrThrow(
MCRLegalEntityService.class, MCRORCIDConstants.CONFIG_PREFIX + "LegalEntityService.Class");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it perhaps make more sense to have a centralized service? Something like a DefaultLegalEntityService where you can configure the default service? There are certainly other places where this service is needed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the current implementation, each class makes its own decision which LegalEntityService to use through a configuration string. The MCROrcidUser uses the class configured in MCR.ORCID2.LegalEntityService.Class. Would you propose to have one centralized configuration for all classes that want to use a LegalEntityService? Or should all configurations be managed in that DefaultLegalEntityService? Or would that DefaultService be a fallback to a specific, configurable Service?

Copy link
Copy Markdown
Member

@golsch golsch Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, this would prevent the "wrong" service from being called. In addition, the service is independent of the MCRORCIDUser and does not need to be loaded in the constructor every time. I would expect something like a DefaultLegalEntityService that manages the corresponding implementation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After discussing this with @golsch and @toKrause, the globally configured LegalEntityService implementation ist now instantiated via the LegalEntityService interface and can be accessed from there through a static method.

import org.mycore.orcid2.client.MCRORCIDCredential;
import org.mycore.orcid2.exception.MCRORCIDException;
import org.mycore.orcid2.util.MCRIdentifier;
import org.mycore.datamodel.legalentity.MCRIdentifier;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix package ordner.

import org.mycore.orcid2.exception.MCRORCIDException;
import org.mycore.orcid2.oauth.MCRORCIDOAuthClient;
import org.mycore.orcid2.util.MCRIdentifier;
import org.mycore.datamodel.legalentity.MCRIdentifier;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix package order

@BeforeEach
public void prepare() throws NoSuchFieldException, IllegalAccessException {
userMock = new MCRUser("junit");
MCRLegalEntityServiceMock legalEntityServiceMock = new MCRLegalEntityServiceMock();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use mockito?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure I tried that and failed, but will look into it again..

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I mocked the service using mockito.

import org.mycore.orcid2.user.MCRORCIDUser;
import org.mycore.orcid2.user.MCRORCIDUserUtils;
import org.mycore.orcid2.util.MCRIdentifier;
import org.mycore.datamodel.legalentity.MCRIdentifier;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Package order

@erodde erodde requested a review from golsch January 19, 2026 12:19
@toKrause toKrause requested review from toKrause and removed request for toKrause January 19, 2026 14:56
@erodde
Copy link
Copy Markdown
Contributor Author

erodde commented Feb 18, 2026

@golsch should be ready for review again. Should I add the PR checklist to this PR?

}
MCRMODSWrapper wrapper = new MCRMODSWrapper(modspersonOptional.get());
Element modsName = wrapper.getMODS().getChild(MODS_NAME, MCRConstants.MODS_NAMESPACE);
if (modsName == null) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How could that happen?

return user.getAttributes().stream()
.filter(a -> Objects.equals(a.getName(), ATTR_ORCID_ID))
.map(MCRUserAttribute::getValue).collect(Collectors.toSet());
final MCRIdentifier userid = new MCRIdentifier("userid", user.getUserID());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could userid somehow be moved to a global constant? It seems like it is the magic reference, right?

import org.mycore.orcid2.client.MCRORCIDCredential;
import org.mycore.orcid2.metadata.MCRORCIDPutCodeInfo;
import org.mycore.orcid2.util.MCRIdentifier;
import org.mycore.datamodel.legalentity.MCRIdentifier;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix order

import org.mycore.orcid2.metadata.MCRORCIDPutCodeInfo;
import org.mycore.orcid2.metadata.MCRORCIDUserInfo;
import org.mycore.orcid2.util.MCRIdentifier;
import org.mycore.datamodel.legalentity.MCRIdentifier;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix order

import org.mycore.orcid2.exception.MCRORCIDTransformationException;
import org.mycore.orcid2.metadata.MCRORCIDPutCodeInfo;
import org.mycore.orcid2.util.MCRIdentifier;
import org.mycore.datamodel.legalentity.MCRIdentifier;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix order

Comment on lines +98 to +101
if (LOGGER.isWarnEnabled()) {
LOGGER.warn("Could not update modsperson object for user id {}",
userId.getValue(), e);
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be an inconsistent state or a general error. In that case, I would rather expect an exception.

* @return all known identifiers or an empty set
*/
@Override
public Set<MCRIdentifier> findAllIdentifiers(MCRIdentifier userId) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comment for MCRLegalEntityService#findAllIdentifiers

* @param attributeToAdd the nameIdentifier to add to the modsperson
*/
@Override
public void addIdentifier(MCRIdentifier userId, MCRIdentifier attributeToAdd) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comment for MCRLegalEntityService#addIdentifier

* @param userId the user id
* @return a nullable Optional that might contain a user
*/
private Optional<MCRUser> findUserByUserID(MCRIdentifier userId) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comments for MCRLegalEntityService.

# LegalEntityService
##############################################################################
# No-op Implementation of MCRLegalEntityService for querying UserIdentifier
MCR.LegalEntityService.Class=org.mycore.datamodel.legalentity.MCRNoOpLegalEntityService
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn’t it be better to just leave it empty? It doesn’t seem to serve any purpose…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants