Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,18 @@
import java.nio.channels.ReadableByteChannel;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.CopyOption;
import java.nio.file.FileStore;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.AclEntry;
import java.nio.file.attribute.AclFileAttributeView;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Base64;
import java.util.List;
import java.util.Set;

import javax.xml.transform.Source;

Expand Down Expand Up @@ -245,7 +252,33 @@ public void sendSafelyTo(Path target) throws IOException {
if (!Files.isWritable(dir)) {
throw new IOException("Target directory is not writable: " + dir);
}

// store current permissions of target file
// usually: ACLs for Windows and POSIX permissions for UNIX
List<AclEntry> aclEntries = null;
Set<PosixFilePermission> posixPermissions = null;
FileStore fileStore = Files.getFileStore(target);
if (fileStore.supportsFileAttributeView(AclFileAttributeView.class)) {
aclEntries = Files.getFileAttributeView(target, AclFileAttributeView.class).getAcl();
}
if (fileStore.supportsFileAttributeView(PosixFileAttributeView.class)) {
posixPermissions = Files.getPosixFilePermissions(target);
}
if (LOGGER.isWarnEnabled() && (aclEntries == null && posixPermissions == null)) {
LOGGER.warn("No supported file permissions (ACLs, POSIX) were found when recrating {} with new content;"
+ " new version of file will have default file permissions", target::toAbsolutePath);
}

Path tmp = Files.createTempFile(dir, target.getFileName().toString(), ".tmp");

// apply stored permissions to tmp file; will be preserved during the move operation below
if (aclEntries != null) {
Files.getFileAttributeView(tmp, AclFileAttributeView.class).setAcl(aclEntries);
}
if (posixPermissions != null) {
Files.setPosixFilePermissions(tmp, posixPermissions);
}

try {
final int chunkSize = 128 * 1024;
try (InputStream in = getInputStream();
Expand All @@ -272,6 +305,7 @@ public void sendSafelyTo(Path target) throws IOException {
LOGGER.error("Failed to delete temporary file at {}", tmp, e);
}
}

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package org.mycore.orcid2.v3.work;

import java.util.List;
import java.util.Set;

import org.mycore.common.content.MCRJDOMContent;
Expand Down Expand Up @@ -73,4 +74,12 @@ protected Set<String> findMatchingORCIDs(Set<MCRIdentifier> identifiers) {
protected Work transformObject(MCRJDOMContent object) {
return MCRORCIDWorkTransformerHelper.transformContent(object);
}

@Override
protected List<String> listRelatedOrcidIdentifiers(Work work) {
return work.getWorkContributors().getContributor().stream().filter(c -> c.getContributorOrcid() != null)
.filter(c -> c.getContributorAttributes() != null)
.filter(c -> c.getContributorAttributes().getContributorRole() != null)
.map(c -> c.getContributorOrcid().getPath()).toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,14 @@ private void handlePublication(MCRObject object) {
final Map<String, MCRORCIDUser> toPublish = new HashMap<>(userOrcidPairFromFlag);
toPublish.putAll(userOrcidPairFromObject);
toPublish.keySet().removeAll(toDelete.keySet());
final T work = transformObject(new MCRJDOMContent(filteredObject.createXML()));
toPublish.keySet().removeAll(listRelatedOrcidIdentifiers(work));
if (toDelete.isEmpty() && toPublish.isEmpty()) {
LOGGER.info("Nothing to delete or publish. Skipping {}...", objectID);
tryCollectAndSaveExternalPutCodes(filteredObject);
return;
}
try {
final T work = transformObject(new MCRJDOMContent(filteredObject.createXML()));
final Set<MCRIdentifier> identifiers = listTrustedIdentifiers(work);
if (!toDelete.isEmpty()) {
deleteWorks(toDelete, identifiers, flagContent);
Expand Down Expand Up @@ -376,15 +377,15 @@ private List<MCRIdentifier> listTrustedNameIdentifiers(Element nameElement) {

/**
* Lists trusted identifiers as Set of MCRIdentifier.
*
*
* @param work the Work
* @return Set of MCRIdentifier
*/
abstract protected Set<MCRIdentifier> listTrustedIdentifiers(T work);

/**
* Lists matching ORCID iDs based on search via MCRIdentifier
*
*
* @param identifiers the MCRIdentifiers
* @return Set of ORCID iDs as String
* @throws MCRORCIDException if request fails
Expand All @@ -393,7 +394,7 @@ private List<MCRIdentifier> listTrustedNameIdentifiers(Element nameElement) {

/**
* Removes Work in ORCID profile and updates MCRORCIDPutCodeInfo.
*
*
* @param workInfo the MCRORCIDPutCodeInfo
* @param orcid the ORCID iD
* @param credential the MCRORCIDCredential
Expand All @@ -405,7 +406,7 @@ private List<MCRIdentifier> listTrustedNameIdentifiers(Element nameElement) {

/**
* Updates Work in ORCID profile.
*
*
* @param putCode the put code
* @param work the Work
* @param orcid the ORCID iD
Expand All @@ -418,7 +419,7 @@ private List<MCRIdentifier> listTrustedNameIdentifiers(Element nameElement) {

/**
* Creates Work in ORCID profile and updates MCRORCIDPutCodeInfo.
*
*
* @param work the Work
* @param workInfo the MCRORCIDPutCodeInfo
* @param orcid the ORCID iD
Expand All @@ -431,7 +432,7 @@ abstract protected void createWork(T work, MCRORCIDPutCodeInfo workInfo, String

/**
* Updates work info based on MCRIdentifier.
*
*
* @param identifiers the MCRIdentifier
* @param workInfo the MCRORCIDPutCodeInfo
* @param orcid the ORCID iD
Expand All @@ -443,7 +444,7 @@ abstract protected void updateWorkInfo(Set<MCRIdentifier> identifiers, MCRORCIDP

/**
* Updates work info based on MCRIdentifier.
*
*
* @param identifiers the MCRIdentifier
* @param workInfo the MCRORCIDPutCodeInfo
* @param orcid the ORCID iD
Expand All @@ -453,10 +454,18 @@ abstract protected void updateWorkInfo(Set<MCRIdentifier> identifiers, MCRORCIDP

/**
* Transforms MCRObject as MCRJDOMContent to Work.
*
*
* @param object the MCRObject
* @return the Work
*/
@SuppressWarnings("TypeParameterUnusedInFormals")
abstract protected <T> T transformObject(MCRJDOMContent object);

/**
* Returns all ORCID iDs of related persons for work.
*
* @param work the work
* @return list over ORCID iD elements
*/
abstract protected List<String> listRelatedOrcidIdentifiers(T work);
}
10 changes: 6 additions & 4 deletions mycore-pi/src/main/java/org/mycore/pi/urn/MCRURNUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@
package org.mycore.pi.urn;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Date;
import java.util.Locale;
import java.util.Optional;

import org.apache.logging.log4j.LogManager;
Expand Down Expand Up @@ -53,11 +52,14 @@ public static Date getDNBRegisterDate(String identifier) throws ParseException {
.map(JsonElement::getAsString)
.orElse(null);

return parseDNBRegisterDate(date);
}

static Date parseDNBRegisterDate(String date) {
if (date == null) {
return null;
}

return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.GERMAN).parse(date);
return Date.from(Instant.parse(date));
}

}
59 changes: 59 additions & 0 deletions mycore-pi/src/test/java/org/mycore/pi/urn/MCRURNUtilsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* This file is part of *** M y C o R e ***
* See http://www.mycore.de/ for details.
*
* MyCoRe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MyCoRe is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MyCoRe. If not, see <http://www.gnu.org/licenses/>.
*/

package org.mycore.pi.urn;

import java.time.Instant;
import java.time.format.DateTimeParseException;
import java.util.Date;

import org.junit.Assert;
import org.junit.Test;

public class MCRURNUtilsTest {

private static final String[] VALID_DATES = {
"2025-11-07T15:00:21.000Z",
"2025-11-07T15:00:21Z",
"2025-11-07T15:00:21.1Z",
"2025-11-07T15:00:21-12:00",
"2025-11-07T15:00:21+01:00",
"2025-11-07T15:00:21.123456Z",
};

@Test
public void parseValidDates() {
for (String date : VALID_DATES) {
Date result = MCRURNUtils.parseDNBRegisterDate(date);
Assert.assertNotNull("should parse: " + date, result);
Assert.assertEquals("parsed date should match Instant.parse for: " + date,
Date.from(Instant.parse(date)), result);
}
}

@Test
public void parseNullReturnsNull() {
Assert.assertNull(MCRURNUtils.parseDNBRegisterDate(null));
}

@Test(expected = DateTimeParseException.class)
public void parseInvalidThrows() {
MCRURNUtils.parseDNBRegisterDate("invalidDate");
}

}
1 change: 1 addition & 0 deletions mycore-user2/src/main/resources/xsl/users-subselect.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
</xsl:variable>

<xsl:template match="/users" mode="searchFormAdditional" priority="10">
<input type="hidden" name="XSL.Style" value="subselect" />
<input type="hidden" name="_xed_subselect_session" value="{$xedSession}" />
</xsl:template>

Expand Down
1 change: 1 addition & 0 deletions mycore-user2/src/main/resources/xslt/users-subselect.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<xsl:variable name="xedSession" select="mcrurl:get-param($RequestURL, '_xed_subselect_session')" />

<xsl:template match="/users" mode="searchFormAdditional" priority="10">
<input type="hidden" name="XSL.Style" value="subselect" />
<input type="hidden" name="_xed_subselect_session" value="{$xedSession}" />
</xsl:template>

Expand Down
Loading