diff --git a/pom.xml b/pom.xml
index 98bf0b1da..f53d4843d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -55,7 +55,7 @@
3.5.12022.06.3-SNAPSHOTv16.0.0
- 2.8-SNAPSHOT
+ 2.9-SNAPSHOTscope,groupId,artifactIdhttps://gist.githubusercontent.com/yagee-de/dfd3698c1b49173dbf251f74eb6a9297/raw/406460c088ff3cb6354e4ae6b40535e6f841607d/mycore_sort.xmltrue
diff --git a/ubo-common/pom.xml b/ubo-common/pom.xml
index ddf16e59c..ac3e2a229 100644
--- a/ubo-common/pom.xml
+++ b/ubo-common/pom.xml
@@ -133,6 +133,19 @@
+
+ maven-dependency-plugin
+
+
+ analyze
+
+
+ jaxen:jaxen
+
+
+
+
+
@@ -162,6 +175,24 @@
jakarta.xml.bindjakarta.xml.bind-api
+
+ jaxen
+ jaxen
+
+
+ jdom
+ jdom2
+
+
+ xom
+ xom
+
+
+ xml-apis
+ xml-apis
+
+
+ net.sf.saxonSaxon-HE
@@ -262,25 +293,6 @@
2.3.2runtime
-
- jaxen
- jaxen
- runtime
-
-
- jdom
- jdom2
-
-
- xom
- xom
-
-
- xml-apis
- xml-apis
-
-
- org.apache.logging.log4jlog4j-core
diff --git a/ubo-common/src/main/java/org/mycore/ubo/DozBibCommands.java b/ubo-common/src/main/java/org/mycore/ubo/DozBibCommands.java
index d9657720e..76a668503 100644
--- a/ubo-common/src/main/java/org/mycore/ubo/DozBibCommands.java
+++ b/ubo-common/src/main/java/org/mycore/ubo/DozBibCommands.java
@@ -29,8 +29,10 @@
import org.jdom2.Content;
import org.jdom2.Document;
import org.jdom2.Element;
+import org.jdom2.filter.Filters;
import org.jdom2.input.SAXBuilder;
import org.jdom2.input.sax.XMLReaders;
+import org.mycore.access.MCRAccessException;
import org.mycore.common.MCRConstants;
import org.mycore.common.MCRException;
import org.mycore.common.config.MCRConfiguration2;
@@ -51,6 +53,9 @@
import org.mycore.mods.MCRMODSWrapper;
import org.mycore.ubo.importer.scopus.ScopusInitialImporter;
+import static org.mycore.common.MCRConstants.MODS_NAMESPACE;
+import static org.mycore.common.MCRConstants.XPATH_FACTORY;
+
public class DozBibCommands extends MCRAbstractCommands {
private static final Logger LOGGER = LogManager.getLogger(DozBibCommands.class);
@@ -85,8 +90,14 @@ public DozBibCommands() {
"org.mycore.ubo.importer.scopus.ScopusInitialImporter.initialImport String int",
"Queries all affiliation IDs and imports all documents {0} = afid {1} = start point should be 0"));
addCommand(new MCRCommand(ScopusInitialImporter.IMPORT_SINGLE_COMMAND,
- "org.mycore.ubo.importer.scopus.ScopusInitialImporter.doImport String",
- "{0] = ID of object"));
+ "org.mycore.ubo.importer.scopus.ScopusInitialImporter.doImport String",
+ "{0] = ID of object"));
+ addCommand(
+ new MCRCommand("migrate http uris matching {0} to https in {1}",
+ "org.mycore.ubo.DozBibCommands.migrateURItoHttps String String",
+ "Migrates http protocol of uris to https if they match the pattern given in {0} "
+ + "(xpath will be '//mods:identifier[@type = 'uri'][contains(text(), {0})]'). "
+ + "The mycore object id must be provided in {1}"));
}
/** Exports all entries as MODS dump to a zipped xml file in the given directory */
@@ -221,4 +232,32 @@ public static void importMODSCollection(String fileName) throws Exception {
MCRMetadataManager.create(obj);
}
}
+
+ public static void migrateURItoHttps(String uriContains, String id) {
+ MCRObjectID mcrObjectID = MCRObjectID.getInstance(id);
+ if (!MCRMetadataManager.exists(mcrObjectID)) {
+ LOGGER.error("{} does not exist", id);
+ return;
+ }
+
+ Document xml = MCRMetadataManager.retrieveMCRObject(mcrObjectID).createXML();
+ List elements = XPATH_FACTORY.compile(
+ "//mods:identifier[@type = 'uri'][contains(text(), '" + uriContains + "')]",
+ Filters.element(), null, MODS_NAMESPACE).evaluate(xml);
+
+ if (elements.isEmpty()) {
+ return;
+ }
+
+ elements.forEach(element -> {
+ String uri = element.getText();
+ element.setText(uri.replace("http:", "https:"));
+ });
+
+ try {
+ MCRMetadataManager.update(new MCRObject(xml));
+ } catch (MCRAccessException e) {
+ LOGGER.error("Could not replace URI protocol in ", id);
+ }
+ }
}
diff --git a/ubo-common/src/main/java/org/mycore/ubo/matcher/MCRUserMatcherLDAP.java b/ubo-common/src/main/java/org/mycore/ubo/matcher/MCRUserMatcherLDAP.java
index dff84c480..7da028559 100644
--- a/ubo-common/src/main/java/org/mycore/ubo/matcher/MCRUserMatcherLDAP.java
+++ b/ubo-common/src/main/java/org/mycore/ubo/matcher/MCRUserMatcherLDAP.java
@@ -100,6 +100,15 @@ public class MCRUserMatcherLDAP implements MCRUserMatcher {
private String realm;
+ /**
+ * The default filter applied to LDAP searches
+ *
+ * TODO: take into consideration the member-status of the (email?) of the LDAP-users
+ * */
+ protected final String SEARCH_FILTER_TEMPLATE = MCRConfiguration2
+ .getString("MCR.user2.LDAP.searchFilter.base")
+ .orElse("(&(objectClass=eduPerson)(|%s))");
+
public MCRUserMatcherLDAP() {
loadLDAPMappingConfiguration();
orcid_resolver = MCRConfiguration2.getString(CONFIG_ORCID_NORMALIZATION_RESOLVER).orElse("");
@@ -492,9 +501,6 @@ public List getLDAPUsersByGivenLDAPAttributes(Multimap ldapAttribute
* @return A LDAP-searchfilter of the form (&(objectClass=eduPerson)(|(%a1=%v1)(%a2=%v2)...(%aN=%vN)))
*/
private String createLDAPSearchFilter(Multimap ldapAttributes, String innerTemplate) {
- // TODO: take into consideration the member-status of the (email?) of the LDAP-users
- String searchFilterBaseTemplate = "(&(objectClass=eduPerson)(|%s))";
-
StringBuilder searchFilterInner = new StringBuilder();
for (Map.Entry> ldapAttribute : ldapAttributes.asMap().entrySet()) {
String attributeName = ldapAttribute.getKey();
@@ -521,7 +527,7 @@ private String createLDAPSearchFilter(Multimap ldapAttributes, S
searchFilterInner.append(")");
}
}
- return String.format(Locale.ROOT, searchFilterBaseTemplate, searchFilterInner);
+ return String.format(Locale.ROOT, SEARCH_FILTER_TEMPLATE, searchFilterInner);
}
/**
diff --git a/ubo-common/src/main/java/org/mycore/ubo/matcher/MCRUserMatcherLocal.java b/ubo-common/src/main/java/org/mycore/ubo/matcher/MCRUserMatcherLocal.java
index 4d34a1178..718125550 100644
--- a/ubo-common/src/main/java/org/mycore/ubo/matcher/MCRUserMatcherLocal.java
+++ b/ubo-common/src/main/java/org/mycore/ubo/matcher/MCRUserMatcherLocal.java
@@ -10,6 +10,11 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.jdom2.Element;
+import org.mycore.common.MCRException;
+import org.mycore.common.xml.MCRNodeBuilder;
+import org.mycore.mods.merger.MCRMerger;
+import org.mycore.mods.merger.MCRMergerFactory;
import org.mycore.user2.MCRUser;
import org.mycore.user2.MCRUserAttribute;
import org.mycore.user2.MCRUserManager;
@@ -17,6 +22,7 @@
/**
* Given a MCRUser, match against the local MCRUsers, returning the given User or an existing local one if matched.
* If matched, the returned local MCRUsers attributes are enriched by attributes from the given MCRUser.
+ * The attribute id_connection is considered unique and can not be enriched/added a second time.
*
* @author Pascal Rost
*/
@@ -24,28 +30,39 @@ public class MCRUserMatcherLocal implements MCRUserMatcher {
private final static Logger LOGGER = LogManager.getLogger(MCRUserMatcherLocal.class);
+ private final static String CONNECTION_TYPE_NAME = "id_connection";
+
+ private static final String XPATH_TO_BUILD_MODSNAME = "mods:name[@type='personal']/mods:namePart";
+
@Override
public MCRUserMatcherDTO matchUser(MCRUserMatcherDTO matcherDTO) {
-
MCRUser mcrUser = matcherDTO.getMCRUser();
List matchingUsers = new ArrayList<>(getUsersForGivenAttributes(mcrUser.getAttributes()));
- if(matchingUsers.size() == 1) {
+
+ MCRMerger nameThatShouldMatch = buildNameMergerFrom(mcrUser);
+ matchingUsers.removeIf(userToTest -> !buildNameMergerFrom(userToTest).isProbablySameAs(nameThatShouldMatch));
+
+ if (!matchingUsers.isEmpty()) {
MCRUser matchingUser = matchingUsers.get(0);
- LOGGER.info("Found local matching user! Matched user: {} and attributes: {} with local user: {} and attributes: {}",
- mcrUser.getUserName(),
- mcrUser.getAttributes().stream().map(a -> a.getName() + "=" + a.getValue()).collect(Collectors.joining(" | ")),
- matchingUser.getUserName(),
- matchingUser.getAttributes().stream().map(a -> a.getName() + "=" + a.getValue()).collect(Collectors.joining(" | ")));
+ LOGGER.info(
+ "Found local matching user! Matched user: {} and attributes: {} with local user: {} and attributes: {}",
+ mcrUser.getUserName(),
+ mcrUser.getAttributes().stream().map(a -> a.getName() + "=" + a.getValue())
+ .collect(Collectors.joining(" | ")),
+ matchingUser.getUserName(),
+ matchingUser.getAttributes().stream().map(a -> a.getName() + "=" + a.getValue())
+ .collect(Collectors.joining(" | ")));
- // only add not attributes which are not present
- matchingUser.getAttributes()
- .addAll(mcrUser.getAttributes().stream()
- .filter(Predicate.not(matchingUser.getAttributes()::contains))
- .collect(Collectors.toUnmodifiableList()));
+ final boolean hasMatchingUserConnectionKey = matchingUser.getUserAttribute(CONNECTION_TYPE_NAME) != null;
- mcrUser = matchingUser;
- matcherDTO.setMCRUser(mcrUser);
+ // only add attributes which are not present, don't add duplicate connection attributes
+ matchingUser.getAttributes().addAll(mcrUser.getAttributes().stream()
+ .filter(attribute -> !attribute.getName().equals(CONNECTION_TYPE_NAME) || !hasMatchingUserConnectionKey)
+ .filter(Predicate.not(matchingUser.getAttributes()::contains))
+ .toList());
+
+ matcherDTO.setMCRUser(matchingUser);
matcherDTO.setMatchedOrEnriched(true);
}
return matcherDTO;
@@ -53,12 +70,22 @@ public MCRUserMatcherDTO matchUser(MCRUserMatcherDTO matcherDTO) {
private Set getUsersForGivenAttributes(SortedSet mcrAttributes) {
Set users = new HashSet<>();
- for(MCRUserAttribute mcrAttribute : mcrAttributes) {
+ for (MCRUserAttribute mcrAttribute : mcrAttributes) {
String attributeName = mcrAttribute.getName();
String attributeValue = mcrAttribute.getValue();
- users.addAll(MCRUserManager.getUsers(attributeName, attributeValue).collect(Collectors.toList()));
+ users.addAll(MCRUserManager.getUsers(attributeName, attributeValue).toList());
}
return users;
}
+ private MCRMerger buildNameMergerFrom(MCRUser user) {
+ try {
+ Element modsName = new MCRNodeBuilder().buildElement(XPATH_TO_BUILD_MODSNAME,
+ user.getRealName(), null).getParentElement();
+ return MCRMergerFactory.buildFrom(modsName);
+ } catch (Exception shouldNeverOccur) {
+ throw new MCRException(shouldNeverOccur);
+ }
+ }
+
}
diff --git a/ubo-common/src/main/java/org/mycore/ubo/matcher/MCRUserMatcherUtils.java b/ubo-common/src/main/java/org/mycore/ubo/matcher/MCRUserMatcherUtils.java
index 5fcf8ba96..0c76be552 100644
--- a/ubo-common/src/main/java/org/mycore/ubo/matcher/MCRUserMatcherUtils.java
+++ b/ubo-common/src/main/java/org/mycore/ubo/matcher/MCRUserMatcherUtils.java
@@ -28,22 +28,23 @@
import org.mycore.user2.MCRUser2Constants;
import org.mycore.user2.MCRUserAttribute;
+import static org.mycore.common.MCRConstants.XPATH_FACTORY;
/**
* Utility class for everything related to matching users of publications in MODS-format with MCRUsers and other
* applications/servers/APIs.
- *
+ *
* The following properties in the mycore.properties are used:
- *
+ *
* # Used to check the affiliation of publication authors
* MCR.user2.IdentityManagement.UserCreation.Affiliation=Uni Jena
- *
+ *
* # Mapping from LDAP attribute to real name of user
* MCR.user2.LDAP.Mapping.Name=cn
- *
+ *
* # Mapping from LDAP attribute to E-Mail address of user
* MCR.user2.LDAP.Mapping.E-Mail=mail
- *
+ *
* # Mapping of any attribute.value combination to group membership of user
* # eduPersonScopedAffiliation may be faculty|staff|employee|student|alum|member|affiliate
* MCR.user2.LDAP.Mapping.Group.eduPersonScopedAffiliation.staff@uni-duisburg-essen.de=submitter *
@@ -66,9 +67,9 @@ public static List getNameElements(MCRObject obj) {
public static Map getNameIdentifiers(Element modsNameElement) {
Map nameIdentifiers = new HashMap<>(); // TODO: possible use of MultiMap for multiple attributes of the same type
List identifiers = modsNameElement.getChildren("nameIdentifier", MODS_NAMESPACE);
- for(Element identifierElement : identifiers) {
+ for (Element identifierElement : identifiers) {
String type = identifierElement.getAttributeValue("type");
- if(type!=null){
+ if (type != null) {
String identifier = identifierElement.getText();
nameIdentifiers.put(type, identifier);
}
@@ -77,21 +78,43 @@ public static Map getNameIdentifiers(Element modsNameElement) {
return nameIdentifiers;
}
+ /**
+ * Extracts the real name from the given MODS-Element
+ * @param modsNameElement the given MODS "name"-Element
+ * @return the real name in the format "family-name, given-name", or only the family name,
+ * or null if real name could not be determined
+ */
+ public static String getRealName(Element modsNameElement) {
+ Element givenName = XPATH_FACTORY.compile("mods:namePart[@type='given']",
+ Filters.element(), null, MODS_NAMESPACE).evaluateFirst(modsNameElement);
+
+ Element familyName = XPATH_FACTORY.compile("mods:namePart[@type='family']",
+ Filters.element(), null, MODS_NAMESPACE).evaluateFirst(modsNameElement);
+
+ if ((givenName != null) && (familyName != null)) {
+ return familyName.getText() + ", " + givenName.getText();
+ } else if ((familyName != null)) {
+ return familyName.getText();
+ }
+ return null;
+ }
+
public static boolean containsNameIdentifierWithType(Element modsNameElement, String identifierType) {
return MCRUserMatcherUtils.getNameIdentifiers(modsNameElement).containsKey(identifierType);
}
/**
* Extend the MCRUsers attributes by the given mods:nameIdentifiers if the user does not already have these IDs
- * @param user the MCRUser whose attributes will be enriched
+ *
+ * @param user the MCRUser whose attributes will be enriched
* @param nameIdentifiers the mods:nameIdentifiers that should be added, if they are not already present
*/
public static void enrichUserWithGivenNameIdentifiers(MCRUser user, Map nameIdentifiers) {
SortedSet userAttributes = user.getAttributes();
- for(Map.Entry nameIdentifier : nameIdentifiers.entrySet()) {
+ for (Map.Entry nameIdentifier : nameIdentifiers.entrySet()) {
String name = mapModsNameIdentifierTypeToMycore(nameIdentifier.getKey());
String value = nameIdentifier.getValue();
- if(user.getUserAttribute(name) == null) {
+ if (user.getUserAttribute(name) == null) {
LOGGER.debug("Enriching user: {} with attribute: {}, value: {}", user.getUserName(), name, value);
userAttributes.add(new MCRUserAttribute(name, value));
}
@@ -107,6 +130,7 @@ private static String mapModsNameIdentifierTypeToMycore(String nameIdentifierTyp
* Given a mods:name Element, create a new transient (not persisted) MCRUser where the mods:namePart and
* mods:nameIdentifier child-elements are used for the user name and attributes of the new MCRUser. Does not set a
* realm for the new MCRUser (the default one is the configured "local"-realm).
+ *
* @param modsNameElement the mods:name-Element (xml) from which a new transient MCRUser shall be created
* @return MCRUser, a transient MCRUser in the realm "local" (as configured)
*/
@@ -119,41 +143,42 @@ public static MCRUser createNewMCRUserFromModsNameElement(Element modsNameElemen
Map nameIdentifiers = MCRUserMatcherUtils.getNameIdentifiers(modsNameElement);
MCRUser mcrUser = new MCRUser(userName, realmID);
enrichUserWithGivenNameIdentifiers(mcrUser, nameIdentifiers);
+ mcrUser.setRealName(getRealName(modsNameElement));
return mcrUser;
}
public static String getAttributesAsURLString(List modsNameElements) {
String parameters = "";
- for(Element modsNameElement : modsNameElements) {
+ for (Element modsNameElement : modsNameElements) {
Map parametersMap = getNameIdentifiers(modsNameElement);
XPathFactory xFactory = XPathFactory.instance();
XPathExpression givenNameExpr = xFactory.compile("mods:namePart[@type='given']",
- Filters.element(), null, MODS_NAMESPACE);
+ Filters.element(), null, MODS_NAMESPACE);
Element givenNameElem = givenNameExpr.evaluateFirst(modsNameElement);
XPathExpression familyNameExpr = xFactory.compile("mods:namePart[@type='family']",
- Filters.element(), null, MODS_NAMESPACE);
+ Filters.element(), null, MODS_NAMESPACE);
Element familyNameElem = familyNameExpr.evaluateFirst(modsNameElement);
- if(familyNameElem != null) {
+ if (familyNameElem != null) {
parametersMap.put("lastName", familyNameElem.getText());
}
- if(givenNameElem != null) {
+ if (givenNameElem != null) {
// the following is a compatibility preserving hack, the LSF-Search works with "firstname" WITHOUT CAMELCASE
parametersMap.put("firstname", givenNameElem.getText());
// the LDAP-Search works WITH CAMELCASE so at this point we just provide both parameters
parametersMap.put("firstName", givenNameElem.getText());
}
List singleParameters = new ArrayList<>();
- for(Map.Entry parameter : parametersMap.entrySet()) {
+ for (Map.Entry parameter : parametersMap.entrySet()) {
String encodedValue = null;
try {
encodedValue = URLEncoder.encode(parameter.getValue(), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
- if(!parameter.getKey().isEmpty()){
+ if (!parameter.getKey().isEmpty()) {
singleParameters.add(parameter.getKey() + '=' + encodedValue);
}
}
@@ -166,8 +191,9 @@ public static String getAttributesAsURLString(List modsNameElements) {
}
public static boolean checkAffiliation(Element modsNameElement) {
- String affiliation = MCRConfiguration2.getString("MCR.user2.IdentityManagement.UserCreation.Affiliation").orElse(null);
- if(affiliation == null) {
+ String affiliation
+ = MCRConfiguration2.getString("MCR.user2.IdentityManagement.UserCreation.Affiliation").orElse(null);
+ if (affiliation == null) {
return false;
}
@@ -178,11 +204,11 @@ public static boolean checkAffiliation(Element modsNameElement) {
XPathFactory xFactory = XPathFactory.instance();
XPathExpression affiliationExpr = xFactory.compile("mods:affiliation",
- Filters.element(), null, MODS_NAMESPACE);
+ Filters.element(), null, MODS_NAMESPACE);
Element affiliationElem = affiliationExpr.evaluateFirst(modsNameElement);
- if(affiliationElem != null) {
+ if (affiliationElem != null) {
String modsNameAffiliation = affiliationElem.getText();
- if(modsNameAffiliation.contains(affiliation)) {
+ if (modsNameAffiliation.contains(affiliation)) {
affiliated = true;
}
}
@@ -192,11 +218,12 @@ public static boolean checkAffiliation(Element modsNameElement) {
/**
* Method to set the static MCRUser-Attributes (RealName and Email)
- * @param mcrUser the MCRUser whose static Attributes should be set
+ *
+ * @param mcrUser the MCRUser whose static Attributes should be set
* @param ldapUser the ldapUser whose Attributes are used to fill the static attributes of the MCRUser
*/
public static void setStaticMCRUserAttributes(MCRUser mcrUser, LDAPObject ldapUser) {
- for(Map.Entry attributeEntry : ldapUser.getAttributes().entries()) {
+ for (Map.Entry attributeEntry : ldapUser.getAttributes().entries()) {
String attributeID = attributeEntry.getKey();
String attributeValue = attributeEntry.getValue();
setUserRealName(mcrUser, attributeID, attributeValue);
@@ -221,7 +248,9 @@ private static void setUserRealName(MCRUser user, String attributeID, String att
}
}
- /** Formats a user name into "lastname, firstname" syntax. */
+ /**
+ * Formats a user name into "lastname, firstname" syntax.
+ */
private static String formatName(String name) {
name = name.replaceAll("\\s+", " ").trim();
if (name.contains(",")) {
@@ -240,13 +269,14 @@ private static String formatName(String name) {
* # Mapping of any attribute.value combination to group membership of user
* # eduPersonScopedAffiliation may be faculty|staff|employee|student|alum|member|affiliate
* MCR.user2.LDAP.Mapping.Group.eduPersonScopedAffiliation.staff@uni-duisburg-essen.de=submitter *
- * @param mcrUser the MCRUser that shall be added to the configured groups/roles if the corresponding
- * LDAP-Attributes exist
+ *
+ * @param mcrUser the MCRUser that shall be added to the configured groups/roles if the corresponding
+ * LDAP-Attributes exist
* @param ldapUser the LDAPObject/User from which the LDAP-Attributes should be used to map against the configured
* groups/roles for the MCRUser
*/
public static void addMCRUserToDynamicGroups(MCRUser mcrUser, LDAPObject ldapUser) {
- for(Map.Entry attributeEntry : ldapUser.getAttributes().entries()) {
+ for (Map.Entry attributeEntry : ldapUser.getAttributes().entries()) {
String attributeID = attributeEntry.getKey();
String attributeValue = attributeEntry.getValue();
addToGroup(mcrUser, attributeID, attributeValue);
diff --git a/ubo-common/src/main/java/org/mycore/ubo/publication/PublicationEventHandler.java b/ubo-common/src/main/java/org/mycore/ubo/publication/PublicationEventHandler.java
index 160a31390..0b0089c99 100644
--- a/ubo-common/src/main/java/org/mycore/ubo/publication/PublicationEventHandler.java
+++ b/ubo-common/src/main/java/org/mycore/ubo/publication/PublicationEventHandler.java
@@ -1,6 +1,5 @@
package org.mycore.ubo.publication;
-import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jdom2.Element;
@@ -51,21 +50,11 @@
*
* 4. Persist all new MCRUsers ONLY if they where matched/enriched in 2.1. or in 3.
*
- * 5. Extend the mods:name -> mods:nameIdentifier element of the publication with the configured "lead-ID" if it is
- * not present but available in the matched MCRUsers attributes.
- *
- * 6. If no MCRUser was created because there was neither Match found nor attributes enriched (2.1. or 3.), check each
- * person in the publication for affiliation. If an affiliation is found, create a new MCRUser in a special realm and
- * persist it.
- *
* The following properties in the mycore.properties are used:
*
* # Default Role that is assigned to newly created users
* MCR.user2.IdentityManagement.UserCreation.DefaultRole=submitter
*
- * # Realm of unvalidated MCRUsers
- * MCR.user2.IdentityManagement.UserCreation.Unvalidated.Realm=unvalidated
- *
* MCR.user2.matching.chain (Multiple implementations separated by ",")
* Example:
* MCR.user2.matching.chain=org.mycore.ubo.matcher.MCRUserMatcherLDAP,org.mycore.ubo.matcher.MCRUserMatcherDummy
@@ -87,17 +76,11 @@ public class PublicationEventHandler extends MCREventHandlerBase {
private final static String CONFIG_LEAD_ID = "MCR.user2.matching.lead_id";
private final static String CONFIG_CONNECTION_STRATEGY = "MCR.user2.matching.publication.connection.strategy";
private final static String CONFIG_DEFAULT_ROLE = "MCR.user2.IdentityManagement.UserCreation.DefaultRole";
- private final static String CONFIG_UNVALIDATED_REALM = "MCR.user2.IdentityManagement.UserCreation.Unvalidated.Realm";
-
private final static String CONFIG_SKIP_LEAD_ID = "MCR.user2.matching.lead_id.skip";
-
private final static String CONNECTION_TYPE_NAME = "id_connection";
/** The default Role that is assigned to newly created users **/
private String defaultRoleForNewlyCreatedUsers;
-
- /** The ID of the realm for newly created unvalidated MCRUsers **/
- private String unvalidatedRealmID;
/** If the matched MCRUser has this ID set in its attributes, enrich the publication with it */
private String leadIDName;
@@ -107,15 +90,14 @@ public class PublicationEventHandler extends MCREventHandlerBase {
/** A chain of implemented user matchers */
private List chainOfUserMatchers;
-
+
/** The configured connection strategy to "connect" publications to MCRUsers */
private String connectionStrategy;
public PublicationEventHandler() {
super();
-
+
this.defaultRoleForNewlyCreatedUsers = MCRConfiguration2.getString(CONFIG_DEFAULT_ROLE).orElse("submitter");
- this.unvalidatedRealmID = MCRConfiguration2.getString(CONFIG_UNVALIDATED_REALM).get();
this.leadIDName = MCRConfiguration2.getString(CONFIG_LEAD_ID).orElse("");
this.localMatcher = new MCRUserMatcherLocal();
this.chainOfUserMatchers = loadMatcherImplementationChain();
@@ -126,13 +108,14 @@ private List loadMatcherImplementationChain() {
List matchers = new ArrayList<>();
Optional matcherConfig = MCRConfiguration2.getString(CONFIG_MATCHERS);
- if(matcherConfig.isPresent()) {
+ if (matcherConfig.isPresent()) {
String[] matcherClasses = matcherConfig.get().split(",");
for (int i = 0; i < matcherClasses.length; i++) {
String matcherClass = matcherClasses[i];
try {
-
- matchers.add((MCRUserMatcher) MCRClassTools.forName(matcherClass).getDeclaredConstructor().newInstance());
+
+ matchers.add(
+ (MCRUserMatcher) MCRClassTools.forName(matcherClass).getDeclaredConstructor().newInstance());
} catch (Exception e) {
throw new MCRConfigurationException("Property key " + CONFIG_MATCHERS + " not valid.", e);
}
@@ -165,7 +148,7 @@ protected void handlePublication(MCRObject obj) {
}
private void handleName(Element modsNameElement) {
- MCRUser userFromModsName = MCRUserMatcherUtils.createNewMCRUserFromModsNameElement(modsNameElement);
+ MCRUser userFromModsName = MCRUserMatcherUtils.createNewMCRUserFromModsNameElement(modsNameElement);
MCRUserMatcherDTO matcherDTO = new MCRUserMatcherDTO(userFromModsName);
// call our configured Implementation(s) of MCRUserMatcher
@@ -179,11 +162,6 @@ private void handleName(Element modsNameElement) {
MCRUserMatcherDTO localMatcherDTO = localMatcher.matchUser(matcherDTO);
if (localMatcherDTO.wasMatchedOrEnriched()) {
handleUser(modsNameElement, localMatcherDTO.getMCRUser());
- } else if (MCRUserMatcherUtils.checkAffiliation(modsNameElement) &&
- (!MCRUserMatcherUtils.getNameIdentifiers(modsNameElement).isEmpty())) {
- MCRUser affiliatedUser
- = MCRUserMatcherUtils.createNewMCRUserFromModsNameElement(modsNameElement, unvalidatedRealmID);
- handleUser(modsNameElement, affiliatedUser);
} else if (containsLeadID(modsNameElement)) {
MCRUser newLocalUser = MCRUserMatcherUtils.createNewMCRUserFromModsNameElement(
modsNameElement, MCRRealmFactory.getLocalRealm().getID());
@@ -195,7 +173,8 @@ private void handleName(Element modsNameElement) {
MCRConfiguration2.getBoolean(CONFIG_SKIP_LEAD_ID)
.filter(Boolean::booleanValue)
.ifPresent(trueValue -> {
- List elementsToRemove = modsNameElement.getChildren("nameIdentifier", MCRConstants.MODS_NAMESPACE)
+ List elementsToRemove
+ = modsNameElement.getChildren("nameIdentifier", MCRConstants.MODS_NAMESPACE)
.stream()
.filter(element -> element.getAttributeValue("type").equals(leadIDName))
.collect(Collectors.toList());
@@ -209,7 +188,6 @@ private boolean containsLeadID(Element modsNameElement) {
}
private void handleUser(Element modsName, MCRUser user) {
- enrichModsNameElementByLeadID(modsName, user);
connectModsNameElementWithMCRUser(modsName, user);
user.assignRole(defaultRoleForNewlyCreatedUsers);
MCRUserManager.updateUser(user);
@@ -225,42 +203,14 @@ private void logUserMatch(Element modsNameElement, MCRUserMatcherDTO matcherDTO,
matcher.getClass());
}
- /**
- * Enriches the mods:name-element that corresponds to the given MCRUser with a mods:nameIdentifier-element if the
- * given MCRUser has an attribute with the name of the so called "lead_id" that is configured in the
- * mycore.properties and given as parameter "leadID".
- * A new mods:nameIdentifier-element with type "lead_id" and its value will only be created if no other
- * mods:nameIdentifier-element with the same ID/type exists as a sub-element of the given modsNameElement.
-
- * @param modsNameElement the mods:name-element which will be enriched
- * @param mcrUser the MCRUser corresponding to the modsNameElement
- */
- private void enrichModsNameElementByLeadID(Element modsNameElement, MCRUser mcrUser) {
- if (!MCRUserMatcherUtils.containsNameIdentifierWithType(modsNameElement, leadIDName)) {
- getLeadIDAttributeFromUser(mcrUser).ifPresent(leadIDAttribute -> {
- String leadIDValue = leadIDAttribute.getValue();
- LOGGER.info("Enriched publication for MCRUser: {}, with nameIdentifier of type: {} (lead_id) " +
- "and value: {}", mcrUser.getUserName(), leadIDName, leadIDValue);
- addNameIdentifierTo(modsNameElement, leadIDName, leadIDValue);
- });
- }
- }
-
- private Optional getLeadIDAttributeFromUser(MCRUser mcrUser) {
- String attributeName = "id_" + leadIDName;
- return mcrUser.getAttributes().stream()
- .filter(a -> a.getName().equals(attributeName))
- .filter(a -> StringUtils.isNotEmpty(a.getValue())).findFirst();
- }
-
private void connectModsNameElementWithMCRUser(Element modsNameElement, MCRUser mcrUser) {
- if("uuid".equals(connectionStrategy)) {
+ if ("uuid".equals(connectionStrategy)) {
String connectionID = getOrAddConnectionID(mcrUser);
// if not already present, persist connection in mods:name - nameIdentifier-Element
String connectionIDType = CONNECTION_TYPE_NAME.replace("id_", "");
- if(!MCRUserMatcherUtils.containsNameIdentifierWithType(modsNameElement, connectionIDType)) {
+ if (!MCRUserMatcherUtils.containsNameIdentifierWithType(modsNameElement, connectionIDType)) {
LOGGER.info("Connecting publication with MCRUser: {}, via nameIdentifier of type: {} " +
- "and value: {}", mcrUser.getUserName(), connectionIDType, connectionID);
+ "and value: {}", mcrUser.getUserName(), connectionIDType, connectionID);
addNameIdentifierTo(modsNameElement, connectionIDType, connectionID);
}
}
@@ -269,7 +219,7 @@ private void connectModsNameElementWithMCRUser(Element modsNameElement, MCRUser
private String getOrAddConnectionID(MCRUser mcrUser) {
// check if MCRUser already has a "connection" UUID
String uuid = mcrUser.getUserAttribute(CONNECTION_TYPE_NAME);
- if(uuid == null) {
+ if (uuid == null) {
// create new UUID and persist it for mcrUser
uuid = UUID.randomUUID().toString();
mcrUser.getAttributes().add(new MCRUserAttribute(CONNECTION_TYPE_NAME, uuid));
@@ -290,8 +240,10 @@ protected Optional buildPersonNameFromMODS(Element nameElement) {
Element givenName = XPATH_TO_GET_GIVEN_NAME.evaluateFirst(nameElement);
Element familyName = XPATH_TO_GET_FAMILY_NAME.evaluateFirst(nameElement);
- if ( (givenName != null) && (familyName != null)) {
- return Optional.of( familyName.getText() + ", " + givenName.getText() );
+ if ((givenName != null) && (familyName != null)) {
+ return Optional.of(familyName.getText() + ", " + givenName.getText());
+ } else if (familyName != null) {
+ return Optional.of(familyName.getText());
} else {
return Optional.empty();
}
diff --git a/ubo-common/src/main/resources/META-INF/resources/import-search.xed b/ubo-common/src/main/resources/META-INF/resources/import-search.xed
index e69f303f0..ebd30981a 100644
--- a/ubo-common/src/main/resources/META-INF/resources/import-search.xed
+++ b/ubo-common/src/main/resources/META-INF/resources/import-search.xed
@@ -111,5 +111,11 @@
-
+
+
+
+
+
+
diff --git a/ubo-common/src/main/resources/META-INF/resources/search.xed b/ubo-common/src/main/resources/META-INF/resources/search.xed
index a5c18baa5..ac959bf89 100644
--- a/ubo-common/src/main/resources/META-INF/resources/search.xed
+++ b/ubo-common/src/main/resources/META-INF/resources/search.xed
@@ -7,6 +7,8 @@