diff --git a/pom.xml b/pom.xml index a0936e1..8790205 100644 --- a/pom.xml +++ b/pom.xml @@ -80,6 +80,7 @@ nl.knaw.dans dans-dataverse-client-lib + 0.33.0 org.apache.commons diff --git a/src/main/java/nl/knaw/dans/dvcli/DdDataverseCli.java b/src/main/java/nl/knaw/dans/dvcli/DdDataverseCli.java index e59046a..cdfedc2 100644 --- a/src/main/java/nl/knaw/dans/dvcli/DdDataverseCli.java +++ b/src/main/java/nl/knaw/dans/dvcli/DdDataverseCli.java @@ -18,7 +18,6 @@ import lombok.extern.slf4j.Slf4j; import nl.knaw.dans.dvcli.action.Database; -import nl.knaw.dans.dvcli.command.CollectionAssignRole; import nl.knaw.dans.dvcli.command.CollectionCmd; import nl.knaw.dans.dvcli.command.CollectionCreateDataset; import nl.knaw.dans.dvcli.command.CollectionDelete; @@ -27,14 +26,19 @@ import nl.knaw.dans.dvcli.command.CollectionImportDataset; import nl.knaw.dans.dvcli.command.CollectionIsMetadataBlocksRoot; import nl.knaw.dans.dvcli.command.CollectionListMetadataBlocks; -import nl.knaw.dans.dvcli.command.CollectionListRoleAssignments; import nl.knaw.dans.dvcli.command.CollectionListRoles; import nl.knaw.dans.dvcli.command.CollectionPublish; +import nl.knaw.dans.dvcli.command.CollectionRoleAssignment; import nl.knaw.dans.dvcli.command.CollectionSetMetadataBlocksRoot; import nl.knaw.dans.dvcli.command.CollectionView; import nl.knaw.dans.dvcli.command.DatasetCmd; +import nl.knaw.dans.dvcli.command.DatasetDeleteDraft; +import nl.knaw.dans.dvcli.command.DatasetGetFiles; +import nl.knaw.dans.dvcli.command.DatasetGetLatestVersion; +import nl.knaw.dans.dvcli.command.DatasetGetVersion; +import nl.knaw.dans.dvcli.command.DatasetPublish; +import nl.knaw.dans.dvcli.command.DatasetRoleAssignment; import nl.knaw.dans.dvcli.command.DatasetValidateFiles; -import nl.knaw.dans.dvcli.command.DeleteDraft; import nl.knaw.dans.dvcli.command.NotificationTruncate; import nl.knaw.dans.dvcli.config.DdDataverseCliConfig; import nl.knaw.dans.lib.dataverse.DataverseClient; @@ -63,9 +67,8 @@ public void configureCommandLine(CommandLine commandLine, DdDataverseCliConfig c var dataverseClient = config.getApi().build(); var databaseConfig = config.getDb(); var database = new Database(databaseConfig); - + commandLine.addSubcommand(new CommandLine(new CollectionCmd(dataverseClient)) - .addSubcommand(new CollectionAssignRole()) .addSubcommand(new CollectionCreateDataset()) .addSubcommand(new CollectionDelete()) .addSubcommand(new CollectionGetContents()) @@ -73,14 +76,19 @@ public void configureCommandLine(CommandLine commandLine, DdDataverseCliConfig c .addSubcommand(new CollectionImportDataset()) .addSubcommand(new CollectionIsMetadataBlocksRoot()) .addSubcommand(new CollectionListMetadataBlocks()) - .addSubcommand(new CollectionListRoleAssignments()) .addSubcommand(new CollectionListRoles()) .addSubcommand(new CollectionPublish()) + .addSubcommand(new CollectionRoleAssignment()) .addSubcommand(new CollectionSetMetadataBlocksRoot()) .addSubcommand(new CollectionView())) .addSubcommand(new CommandLine(new DatasetCmd(dataverseClient)) + .addSubcommand(new DatasetDeleteDraft()) + .addSubcommand(new DatasetGetFiles()) + .addSubcommand(new DatasetGetLatestVersion()) + .addSubcommand(new DatasetGetVersion()) + .addSubcommand(new DatasetPublish()) + .addSubcommand(new DatasetRoleAssignment()) .addSubcommand(new DatasetValidateFiles()) - .addSubcommand(new DeleteDraft()) ) .addSubcommand(new CommandLine(new NotificationTruncate(database))); log.debug("Configuring command line"); diff --git a/src/main/java/nl/knaw/dans/dvcli/command/AbstractAssignmentRole.java b/src/main/java/nl/knaw/dans/dvcli/command/AbstractAssignmentRole.java new file mode 100644 index 0000000..ad2fa96 --- /dev/null +++ b/src/main/java/nl/knaw/dans/dvcli/command/AbstractAssignmentRole.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2024 DANS - Data Archiving and Networked Services (info@dans.knaw.nl) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.knaw.dans.dvcli.command; + +import nl.knaw.dans.dvcli.action.Pair; +import nl.knaw.dans.lib.dataverse.model.RoleAssignment; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.apache.commons.csv.CSVRecord; +import picocli.CommandLine.ArgGroup; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; + +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Command +public abstract class AbstractAssignmentRole, API> extends AbstractCmd { + + static class CommandParameter { + @Parameters(description = "Alias and role assignee (example: @dataverseAdmin=contributor)") + String assignment = ""; + + @Option(names = { "-f", + "--parameter-file" }, description = "CSV file to read parameters from. The file should have a header row with columns 'PID', 'ASSIGNEE' and 'ROLE'.") + Path parameterFile; + } + + @ArgGroup(multiplicity = "1") + CommandParameter commandParameter; + + private Optional readFromCommandLine() { + if (!this.commandParameter.assignment.isEmpty() && this.commandParameter.assignment.contains("=")) { + String[] assigneeRole = this.commandParameter.assignment.split("="); + + RoleAssignment roleAssignment = new RoleAssignment(); + roleAssignment.setAssignee(assigneeRole[0]); + roleAssignment.setRole(assigneeRole[1]); + return Optional.of(roleAssignment); + } + return Optional.empty(); + } + + private List>> readFromFile(CMD cmd) throws IOException { + try (BufferedReader reader = Files.newBufferedReader(commandParameter.parameterFile); + CSVParser csvParser = new CSVParser(reader, CSVFormat.Builder.create(CSVFormat.DEFAULT) + .setHeader("PID", "ASSIGNEE", "ROLE") + .setSkipHeaderRecord(true) + .build())) { + + List>> result = new ArrayList<>(); + + for (CSVRecord csvRecord : csvParser) { + var pid = csvRecord.get("PID"); + API api = getItem(pid); + RoleAssignment roleAssignment = new RoleAssignment(); + roleAssignment.setAssignee(csvRecord.get("ASSIGNEE")); + roleAssignment.setRole(csvRecord.get("ROLE")); + + RoleAssignmentParams params = new RoleAssignmentParams<>(api, Optional.of(roleAssignment)); + result.add(new Pair<>(pid, params)); + } + + return result; + } + } + + protected abstract API getItem(String pid); + + protected List>> getRoleAssignmentParams(CMD cmd) throws IOException { + if (commandParameter.parameterFile != null) { + return readFromFile(cmd); + } + else if (commandParameter.assignment != null) { + var items = cmd.getItems(); + return items.stream() + .map(p -> { + var second = new RoleAssignmentParams((API) p.getSecond(), readFromCommandLine()); + return new Pair<>(p.getFirst(), second); + }) + .toList(); + } + return List.of(); + } + + protected record RoleAssignmentParams(A pid, Optional roleAssignment) { + } +} diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionAssignRole.java b/src/main/java/nl/knaw/dans/dvcli/command/CollectionAssignRole.java deleted file mode 100644 index ee28996..0000000 --- a/src/main/java/nl/knaw/dans/dvcli/command/CollectionAssignRole.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2024 DANS - Data Archiving and Networked Services (info@dans.knaw.nl) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package nl.knaw.dans.dvcli.command; - -import nl.knaw.dans.dvcli.action.ConsoleReport; -import nl.knaw.dans.dvcli.action.Pair; -import nl.knaw.dans.dvcli.action.ThrowingFunction; -import nl.knaw.dans.lib.dataverse.DataverseApi; -import nl.knaw.dans.lib.dataverse.DataverseException; -import nl.knaw.dans.lib.dataverse.model.RoleAssignment; -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVParser; -import org.apache.commons.csv.CSVRecord; -import picocli.CommandLine.ArgGroup; -import picocli.CommandLine.Command; -import picocli.CommandLine.Option; -import picocli.CommandLine.Parameters; -import picocli.CommandLine.ParentCommand; - -import java.io.IOException; -import java.io.Reader; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -@Command(name = "assign-role", - mixinStandardHelpOptions = true, - description = "Assign a role to a user in a Dataverse collection.") -public class CollectionAssignRole extends AbstractCmd { - @ParentCommand - private CollectionCmd collectionCmd; - - static class SingleAssignment { - @Parameters(index = "0", paramLabel = "role", description = "The role to assign") - String role; - - @Parameters(index = "1", paramLabel = "assignee", description = "The identifier of the user to assign the role to") - String assignee; - } - - static class AllArgs { - @ArgGroup(exclusive = false) - SingleAssignment singleAssignment; - - @Option(names = { "-f", "--parameters-file" }, description = "CSV file to read parameters from. The file should have a header row with columns 'PID', 'ROLE', and 'ASSIGNEE'.") - Path paramsFile; - } - - @ArgGroup(exclusive = true, multiplicity = "1") - private AllArgs allArgs; - - private record RoleAssignmentParams(DataverseApi collection, String role, String assignee) { - } - - private static class RoleAssignmentAction implements ThrowingFunction { - @Override - public String apply(RoleAssignmentParams roleAssignmentParams) throws IOException, DataverseException { - var assignment = new RoleAssignment(); - assignment.setAssignee(roleAssignmentParams.assignee()); - assignment.setRole(roleAssignmentParams.role()); - var r = roleAssignmentParams.collection.assignRole(assignment); - return r.getEnvelopeAsString(); - } - } - - private List> readFromFile(Path file) throws IOException { - try (Reader reader = Files.newBufferedReader(file); - CSVParser csvParser = new CSVParser(reader, CSVFormat.Builder.create(CSVFormat.DEFAULT) - .setHeader("PID", "ROLE", "ASSIGNEE") - .setSkipHeaderRecord(true) - .build())) { - - List> result = new ArrayList<>(); - - for (CSVRecord csvRecord : csvParser) { - var pid = csvRecord.get("PID"); - DataverseApi collection = collectionCmd.dataverseClient.dataverse(pid); - String role = csvRecord.get("ROLE"); - String assignee = csvRecord.get("ASSIGNEE"); - - RoleAssignmentParams params = new RoleAssignmentParams(collection, role, assignee); - result.add(new Pair<>(pid, params)); - } - - return result; - } - } - - private List> getRoleAssignmentParams() throws IOException { - if (allArgs.paramsFile != null) { - return readFromFile(allArgs.paramsFile); - } - else { - return collectionCmd.getItems().stream() - .map(p -> new Pair<>(p.getFirst(), new RoleAssignmentParams(p.getSecond(), allArgs.singleAssignment.role, allArgs.singleAssignment.assignee))) - .toList(); - } - } - - @Override - public void doCall() throws IOException, DataverseException { - collectionCmd. paramsBatchProcessorBuilder() - .labeledItems(getRoleAssignmentParams()) - .action(new RoleAssignmentAction()) - .report(new ConsoleReport<>()) - .build() - .process(); - } -} diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionCmd.java b/src/main/java/nl/knaw/dans/dvcli/command/CollectionCmd.java index 1e90cd6..8bf08c4 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/CollectionCmd.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/CollectionCmd.java @@ -29,12 +29,13 @@ mixinStandardHelpOptions = true, description = "Manage Dataverse collections (i.e. 'dataverses')") public class CollectionCmd extends AbstractSubcommandContainer { + public CollectionCmd(@NonNull DataverseClient dataverseClient) { + super(dataverseClient); + } + @Override protected List> getItems() throws IOException { return new SingleCollectionOrCollectionsFile(targets, dataverseClient).getCollections().toList(); } - public CollectionCmd(@NonNull DataverseClient dataverseClient) { - super(dataverseClient); - } } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionCreateDataset.java b/src/main/java/nl/knaw/dans/dvcli/command/CollectionCreateDataset.java index 0890cb5..83ee78b 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/CollectionCreateDataset.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/CollectionCreateDataset.java @@ -15,7 +15,6 @@ */ package nl.knaw.dans.dvcli.command; -import nl.knaw.dans.dvcli.action.ConsoleReport; import nl.knaw.dans.lib.dataverse.DataverseException; import picocli.CommandLine.Command; import picocli.CommandLine.Option; @@ -43,14 +42,7 @@ public class CollectionCreateDataset extends AbstractCmd { @Override public void doCall() throws IOException, DataverseException { - collectionCmd.batchProcessorBuilder() - .action(d -> { - var json = Files.readString(Path.of(dataset)); - var r = d.createDataset(json, metadataKeys); - return r.getEnvelopeAsString(); - }) - .report(new ConsoleReport<>()) - .build() - .process(); + collectionCmd.batchProcessor(c -> + c.createDataset(Files.readString(Path.of(dataset)), metadataKeys).getEnvelopeAsString()).process(); } } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionDelete.java b/src/main/java/nl/knaw/dans/dvcli/command/CollectionDelete.java index f7eba89..15d70ed 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/CollectionDelete.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/CollectionDelete.java @@ -15,7 +15,6 @@ */ package nl.knaw.dans.dvcli.command; -import nl.knaw.dans.dvcli.action.ConsoleReport; import nl.knaw.dans.lib.dataverse.DataverseException; import picocli.CommandLine.Command; import picocli.CommandLine.ParentCommand; @@ -31,13 +30,6 @@ public class CollectionDelete extends AbstractCmd { @Override public void doCall() throws IOException, DataverseException { - collectionCmd.batchProcessorBuilder() - .action(d -> { - var r = d.delete(); - return r.getEnvelopeAsString(); - }) - .report(new ConsoleReport<>()) - .build() - .process(); + collectionCmd.batchProcessor(c -> c.delete().getEnvelopeAsString()).process(); } } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionGetContents.java b/src/main/java/nl/knaw/dans/dvcli/command/CollectionGetContents.java index e8743ff..4ac1a07 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/CollectionGetContents.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/CollectionGetContents.java @@ -15,7 +15,6 @@ */ package nl.knaw.dans.dvcli.command; -import nl.knaw.dans.dvcli.action.ConsoleReport; import nl.knaw.dans.lib.dataverse.DataverseException; import picocli.CommandLine.Command; import picocli.CommandLine.ParentCommand; @@ -31,13 +30,6 @@ public class CollectionGetContents extends AbstractCmd { @Override public void doCall() throws IOException, DataverseException { - collectionCmd.batchProcessorBuilder() - .action(d -> { - var r = d.getContents(); - return r.getEnvelopeAsString(); - }) - .report(new ConsoleReport<>()) - .build() - .process(); + collectionCmd.batchProcessor(c -> c.getContents().getEnvelopeAsString()).process(); } } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionGetStorageSize.java b/src/main/java/nl/knaw/dans/dvcli/command/CollectionGetStorageSize.java index a616f69..828d0a5 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/CollectionGetStorageSize.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/CollectionGetStorageSize.java @@ -15,7 +15,6 @@ */ package nl.knaw.dans.dvcli.command; -import nl.knaw.dans.dvcli.action.ConsoleReport; import nl.knaw.dans.lib.dataverse.DataverseException; import picocli.CommandLine.Command; import picocli.CommandLine.ParentCommand; @@ -31,13 +30,6 @@ public class CollectionGetStorageSize extends AbstractCmd { @Override public void doCall() throws IOException, DataverseException { - collectionCmd.batchProcessorBuilder() - .action(d -> { - var r = d.getStorageSize(); - return r.getEnvelopeAsString(); - }) - .report(new ConsoleReport<>()) - .build() - .process(); + collectionCmd.batchProcessor(c -> c.getStorageSize().getEnvelopeAsString()).process(); } } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionImportDataset.java b/src/main/java/nl/knaw/dans/dvcli/command/CollectionImportDataset.java index 3faefe8..34c5d02 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/CollectionImportDataset.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/CollectionImportDataset.java @@ -15,7 +15,6 @@ */ package nl.knaw.dans.dvcli.command; -import nl.knaw.dans.dvcli.action.ConsoleReport; import nl.knaw.dans.lib.dataverse.DataverseException; import picocli.CommandLine.Command; import picocli.CommandLine.Option; @@ -49,14 +48,7 @@ public class CollectionImportDataset extends AbstractCmd { @Override public void doCall() throws IOException, DataverseException { - collectionCmd.batchProcessorBuilder() - .action(d -> { - var json = Files.readString(Path.of(dataset)); - var r = d.importDataset(json, persistentId, autoPublish, metadataKeys); - return r.getEnvelopeAsString(); - }) - .report(new ConsoleReport<>()) - .build() - .process(); + collectionCmd.batchProcessor(c -> + c.importDataset(Files.readString(Path.of(dataset)), persistentId, autoPublish, metadataKeys).getEnvelopeAsString()).process(); } } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionIsMetadataBlocksRoot.java b/src/main/java/nl/knaw/dans/dvcli/command/CollectionIsMetadataBlocksRoot.java index d010237..3337b56 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/CollectionIsMetadataBlocksRoot.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/CollectionIsMetadataBlocksRoot.java @@ -15,7 +15,6 @@ */ package nl.knaw.dans.dvcli.command; -import nl.knaw.dans.dvcli.action.ConsoleReport; import nl.knaw.dans.lib.dataverse.DataverseException; import picocli.CommandLine.Command; import picocli.CommandLine.ParentCommand; @@ -31,13 +30,6 @@ public class CollectionIsMetadataBlocksRoot extends AbstractCmd { @Override public void doCall() throws IOException, DataverseException { - collectionCmd.batchProcessorBuilder() - .action(d -> { - var r = d.isMetadataBlocksRoot(); - return r.getEnvelopeAsString(); - }) - .report(new ConsoleReport<>()) - .build() - .process(); + collectionCmd.batchProcessor(c -> c.isMetadataBlocksRoot().getEnvelopeAsString()).process(); } } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionListMetadataBlocks.java b/src/main/java/nl/knaw/dans/dvcli/command/CollectionListMetadataBlocks.java index b2a3462..1534681 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/CollectionListMetadataBlocks.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/CollectionListMetadataBlocks.java @@ -15,7 +15,6 @@ */ package nl.knaw.dans.dvcli.command; -import nl.knaw.dans.dvcli.action.ConsoleReport; import nl.knaw.dans.lib.dataverse.DataverseException; import picocli.CommandLine.Command; import picocli.CommandLine.ParentCommand; @@ -31,13 +30,6 @@ public class CollectionListMetadataBlocks extends AbstractCmd { @Override public void doCall() throws IOException, DataverseException { - collectionCmd.batchProcessorBuilder() - .action(d -> { - var r = d.listMetadataBlocks(); - return r.getEnvelopeAsString(); - }) - .report(new ConsoleReport<>()) - .build() - .process(); + collectionCmd.batchProcessor(c -> c.listMetadataBlocks().getEnvelopeAsString()).process(); } } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionListRoles.java b/src/main/java/nl/knaw/dans/dvcli/command/CollectionListRoles.java index 160c7c6..d0391f2 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/CollectionListRoles.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/CollectionListRoles.java @@ -15,7 +15,6 @@ */ package nl.knaw.dans.dvcli.command; -import nl.knaw.dans.dvcli.action.ConsoleReport; import nl.knaw.dans.lib.dataverse.DataverseException; import picocli.CommandLine.Command; import picocli.CommandLine.ParentCommand; @@ -31,13 +30,6 @@ public class CollectionListRoles extends AbstractCmd { @Override public void doCall() throws IOException, DataverseException { - collectionCmd.batchProcessorBuilder() - .action(d -> { - var r = d.listRoles(); - return r.getEnvelopeAsString(); - }) - .report(new ConsoleReport<>()) - .build() - .process(); + collectionCmd.batchProcessor(c -> c.listRoles().getEnvelopeAsString()).process(); } } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionPublish.java b/src/main/java/nl/knaw/dans/dvcli/command/CollectionPublish.java index 9ff7048..b444595 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/CollectionPublish.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/CollectionPublish.java @@ -15,7 +15,6 @@ */ package nl.knaw.dans.dvcli.command; -import nl.knaw.dans.dvcli.action.ConsoleReport; import nl.knaw.dans.lib.dataverse.DataverseException; import picocli.CommandLine.Command; import picocli.CommandLine.ParentCommand; @@ -31,13 +30,6 @@ public class CollectionPublish extends AbstractCmd { @Override public void doCall() throws IOException, DataverseException { - collectionCmd.batchProcessorBuilder() - .action(d -> { - var r = d.publish(); - return r.getEnvelopeAsString(); - }) - .report(new ConsoleReport<>()) - .build() - .process(); + collectionCmd.batchProcessor(c -> c.publish().getEnvelopeAsString()).process(); } } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionRoleAssignment.java b/src/main/java/nl/knaw/dans/dvcli/command/CollectionRoleAssignment.java new file mode 100644 index 0000000..908d2d5 --- /dev/null +++ b/src/main/java/nl/knaw/dans/dvcli/command/CollectionRoleAssignment.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2024 DANS - Data Archiving and Networked Services (info@dans.knaw.nl) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package nl.knaw.dans.dvcli.command; + +import nl.knaw.dans.dvcli.action.ConsoleReport; +import nl.knaw.dans.dvcli.action.ThrowingFunction; +import nl.knaw.dans.lib.dataverse.DataverseApi; +import nl.knaw.dans.lib.dataverse.DataverseException; +import nl.knaw.dans.lib.dataverse.model.RoleAssignment; +import nl.knaw.dans.lib.dataverse.model.RoleAssignmentReadOnly; +import picocli.CommandLine.Command; +import picocli.CommandLine.ParentCommand; + +import java.io.IOException; +import java.util.Optional; + +@Command(name = "role-assignment", + mixinStandardHelpOptions = true, + description = "Manage role assignments.", + subcommands = { CollectionRoleAssignment.CollectionListRoleAssignments.class, CollectionRoleAssignment.CollectionAssignRole.class, CollectionRoleAssignment.CollectionDeleteRole.class }) +public class CollectionRoleAssignment extends AbstractCmd { + @ParentCommand + static private CollectionCmd collectionCmd; + + @Command(name = "list", + mixinStandardHelpOptions = true, + description = "List the role assignments of a Dataverse collection.") + static class CollectionListRoleAssignments extends AbstractCmd { + + @Override + public void doCall() throws IOException, DataverseException { + collectionCmd.batchProcessor(d -> d.listRoleAssignments().getEnvelopeAsString()).process(); + } + } + + @Command(name = "add", + mixinStandardHelpOptions = true, + description = "Assign a role to a user in a Dataverse collection.") + static class CollectionAssignRole extends AbstractAssignmentRole { + @Override + protected DataverseApi getItem(String pid) { + return collectionCmd.dataverseClient.dataverse(pid); + } + + private static class RoleAssignmentAction implements ThrowingFunction, String, Exception> { + @Override + public String apply(RoleAssignmentParams roleAssignmentParams) throws IOException, DataverseException { + if (roleAssignmentParams.roleAssignment().isPresent()) { + var r = roleAssignmentParams.pid().assignRole(roleAssignmentParams.roleAssignment().get()); + return r.getEnvelopeAsString(); + } + return "There was no assignment-role to assign."; + } + } + + @Override + public void doCall() throws IOException, DataverseException { + collectionCmd.> paramsBatchProcessorBuilder() + .labeledItems(getRoleAssignmentParams(collectionCmd)) + .action(new RoleAssignmentAction()) + .report(new ConsoleReport<>()) + .build() + .process(); + } + } + + @Command(name = "remove", + mixinStandardHelpOptions = true, + description = "remove a role assignment from the specified dataverse collection") + static class CollectionDeleteRole extends AbstractAssignmentRole { + + @Override + protected DataverseApi getItem(String pid) { + return collectionCmd.dataverseClient.dataverse(pid); + } + + private static class RoleAssignmentAction implements ThrowingFunction, String, Exception> { + @Override + public String apply(RoleAssignmentParams roleAssignmentParams) throws IOException, DataverseException { + if (roleAssignmentParams.roleAssignment().isPresent()) { + RoleAssignment roleAssignment = roleAssignmentParams.roleAssignment().get(); + Optional role = roleAssignmentParams.pid().listRoleAssignments().getData().stream() + .filter(r -> r.get_roleAlias().equals(roleAssignment.getRole()) && r.getAssignee().equals(roleAssignment.getAssignee())).findFirst(); + if (role.isPresent()) { + var r = roleAssignmentParams.pid().deleteRoleAssignment(role.get().getId()); + return r.getEnvelopeAsString(); + } + } + return "There was no assignment-role to assign."; + } + } + + @Override + public void doCall() throws IOException, DataverseException { + collectionCmd.> paramsBatchProcessorBuilder() + .labeledItems(getRoleAssignmentParams(collectionCmd)) + .action(new CollectionRoleAssignment.CollectionDeleteRole.RoleAssignmentAction()) + .report(new ConsoleReport<>()) + .build() + .process(); + } + } + + @Override + public void doCall() throws IOException, DataverseException { + + } +} diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionSetMetadataBlocksRoot.java b/src/main/java/nl/knaw/dans/dvcli/command/CollectionSetMetadataBlocksRoot.java index 61fade6..b36f975 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/CollectionSetMetadataBlocksRoot.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/CollectionSetMetadataBlocksRoot.java @@ -15,10 +15,9 @@ */ package nl.knaw.dans.dvcli.command; -import nl.knaw.dans.dvcli.action.ConsoleReport; import nl.knaw.dans.lib.dataverse.DataverseException; -import picocli.CommandLine; import picocli.CommandLine.Command; +import picocli.CommandLine.Parameters; import picocli.CommandLine.ParentCommand; import java.io.IOException; @@ -30,18 +29,11 @@ public class CollectionSetMetadataBlocksRoot extends AbstractCmd { @ParentCommand private CollectionCmd collectionCmd; - @CommandLine.Parameters(index = "0", paramLabel = "isRoot", type = Boolean.class, description = "Whether to make it a metadata blocks root.") + @Parameters(index = "0", paramLabel = "isRoot", type = Boolean.class, description = "Whether to make it a metadata blocks root.") private Boolean isRoot; @Override public void doCall() throws IOException, DataverseException { - collectionCmd.batchProcessorBuilder() - .action(d -> { - var r = d.setMetadataBlocksRoot(isRoot); - return r.getEnvelopeAsString(); - }) - .report(new ConsoleReport<>()) - .build() - .process(); + collectionCmd.batchProcessor(c -> c.setMetadataBlocksRoot(isRoot).getEnvelopeAsString()).process(); } } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionView.java b/src/main/java/nl/knaw/dans/dvcli/command/CollectionView.java index 4c78208..63622e4 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/CollectionView.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/CollectionView.java @@ -15,7 +15,6 @@ */ package nl.knaw.dans.dvcli.command; -import nl.knaw.dans.dvcli.action.ConsoleReport; import nl.knaw.dans.lib.dataverse.DataverseException; import picocli.CommandLine.Command; import picocli.CommandLine.ParentCommand; @@ -31,13 +30,6 @@ public class CollectionView extends AbstractCmd { @Override public void doCall() throws IOException, DataverseException { - collectionCmd.batchProcessorBuilder() - .action(d -> { - var r = d.view(); - return r.getEnvelopeAsString(); - }) - .report(new ConsoleReport<>()) - .build() - .process(); + collectionCmd.batchProcessor(c -> c.view().getEnvelopeAsString()).process(); } } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/DatasetCmd.java b/src/main/java/nl/knaw/dans/dvcli/command/DatasetCmd.java index e4c536c..fbf770e 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/DatasetCmd.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/DatasetCmd.java @@ -15,6 +15,7 @@ */ package nl.knaw.dans.dvcli.command; +import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import nl.knaw.dans.dvcli.action.Pair; import nl.knaw.dans.dvcli.action.SingleDatasetOrDatasetsFile; @@ -31,7 +32,7 @@ description = "Manage Dataverse datasets") @Slf4j public class DatasetCmd extends AbstractSubcommandContainer { - public DatasetCmd(DataverseClient dataverseClient) { + public DatasetCmd(@NonNull DataverseClient dataverseClient) { super(dataverseClient); } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/DeleteDraft.java b/src/main/java/nl/knaw/dans/dvcli/command/DatasetDeleteDraft.java similarity index 67% rename from src/main/java/nl/knaw/dans/dvcli/command/DeleteDraft.java rename to src/main/java/nl/knaw/dans/dvcli/command/DatasetDeleteDraft.java index 63dfec2..bfed14b 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/DeleteDraft.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/DatasetDeleteDraft.java @@ -15,9 +15,6 @@ */ package nl.knaw.dans.dvcli.command; -import nl.knaw.dans.dvcli.action.BatchProcessor; -import nl.knaw.dans.dvcli.action.ConsoleReport; -import nl.knaw.dans.lib.dataverse.DatasetApi; import nl.knaw.dans.lib.dataverse.DataverseException; import picocli.CommandLine.Command; import picocli.CommandLine.ParentCommand; @@ -27,21 +24,12 @@ @Command(name = "delete-draft", mixinStandardHelpOptions = true, description = "Delete the draft version of a dataset.") -public class DeleteDraft extends AbstractCmd { +public class DatasetDeleteDraft extends AbstractCmd { @ParentCommand private DatasetCmd datasetCmd; @Override public void doCall() throws IOException, DataverseException { - BatchProcessor. builder() - .labeledItems(datasetCmd.getItems()) - .action(d -> { - var r = d.deleteDraft(); - return r.getEnvelopeAsString(); - }) - .report(new ConsoleReport<>()) - .delay(1000L) - .build() - .process(); + datasetCmd.batchProcessor(d -> d.deleteDraft().getEnvelopeAsString()).process(); } } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/CollectionListRoleAssignments.java b/src/main/java/nl/knaw/dans/dvcli/command/DatasetGetFiles.java similarity index 64% rename from src/main/java/nl/knaw/dans/dvcli/command/CollectionListRoleAssignments.java rename to src/main/java/nl/knaw/dans/dvcli/command/DatasetGetFiles.java index a7e9971..7487824 100644 --- a/src/main/java/nl/knaw/dans/dvcli/command/CollectionListRoleAssignments.java +++ b/src/main/java/nl/knaw/dans/dvcli/command/DatasetGetFiles.java @@ -15,29 +15,25 @@ */ package nl.knaw.dans.dvcli.command; -import nl.knaw.dans.dvcli.action.ConsoleReport; import nl.knaw.dans.lib.dataverse.DataverseException; import picocli.CommandLine.Command; +import picocli.CommandLine.Parameters; import picocli.CommandLine.ParentCommand; import java.io.IOException; -@Command(name = "list-role-assignments", +@Command(name = "get-files", mixinStandardHelpOptions = true, - description = "List the role assignments of a Dataverse collection.") -public class CollectionListRoleAssignments extends AbstractCmd { + description = "Get a list of file metadata.") +public class DatasetGetFiles extends AbstractCmd { @ParentCommand - private CollectionCmd collectionCmd; + private DatasetCmd datasetCmd; + + @Parameters(index = "0", paramLabel = "version", description = "version to get file metadata from.") + private String version; @Override public void doCall() throws IOException, DataverseException { - collectionCmd.batchProcessorBuilder() - .action(d -> { - var r = d.listRoleAssignments(); - return r.getEnvelopeAsString(); - }) - .report(new ConsoleReport<>()) - .build() - .process(); + datasetCmd.batchProcessor(d -> d.getFiles(version).getEnvelopeAsString()).process(); } } diff --git a/src/main/java/nl/knaw/dans/dvcli/command/DatasetGetLatestVersion.java b/src/main/java/nl/knaw/dans/dvcli/command/DatasetGetLatestVersion.java new file mode 100644 index 0000000..5b5f051 --- /dev/null +++ b/src/main/java/nl/knaw/dans/dvcli/command/DatasetGetLatestVersion.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 DANS - Data Archiving and Networked Services (info@dans.knaw.nl) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.knaw.dans.dvcli.command; + +import nl.knaw.dans.lib.dataverse.DataverseException; +import picocli.CommandLine.Command; +import picocli.CommandLine.ParentCommand; + +import java.io.IOException; + +@Command(name = "get-latest-version", + mixinStandardHelpOptions = true, + description = "A JSON object that starts at the dataset level, most fields are replicated at the dataset version level.") +public class DatasetGetLatestVersion extends AbstractCmd { + @ParentCommand + private DatasetCmd datasetCmd; + + @Override + public void doCall() throws IOException, DataverseException { + datasetCmd.batchProcessor(d -> d.getLatestVersion().getEnvelopeAsString()).process(); + } + +} diff --git a/src/main/java/nl/knaw/dans/dvcli/command/DatasetGetVersion.java b/src/main/java/nl/knaw/dans/dvcli/command/DatasetGetVersion.java new file mode 100644 index 0000000..b957758 --- /dev/null +++ b/src/main/java/nl/knaw/dans/dvcli/command/DatasetGetVersion.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2024 DANS - Data Archiving and Networked Services (info@dans.knaw.nl) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.knaw.dans.dvcli.command; + +import nl.knaw.dans.lib.dataverse.DataverseException; +import picocli.CommandLine.ArgGroup; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; +import picocli.CommandLine.ParentCommand; + +import java.io.IOException; + +@Command(name = "get-version", + mixinStandardHelpOptions = true, + description = "Returns an object containing the dataset version metadata.") +public class DatasetGetVersion extends AbstractCmd { + @ParentCommand + private DatasetCmd datasetCmd; + + @ArgGroup(exclusive = true, multiplicity = "1") + VersionInfo versionInfo; + + static class VersionInfo { + @Parameters(description = "Specified a version to retrieve.") + String version = ""; + @Option(names = "--all", description = "Get all versions") + boolean allVersions; + } + + @Override + public void doCall() throws IOException, DataverseException { + datasetCmd.batchProcessor(d -> + versionInfo.allVersions ? d.getAllVersions().getEnvelopeAsString() : d.getVersion(versionInfo.version).getEnvelopeAsString() + ) + .process(); + } +} diff --git a/src/main/java/nl/knaw/dans/dvcli/command/DatasetPublish.java b/src/main/java/nl/knaw/dans/dvcli/command/DatasetPublish.java new file mode 100644 index 0000000..61d8421 --- /dev/null +++ b/src/main/java/nl/knaw/dans/dvcli/command/DatasetPublish.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2024 DANS - Data Archiving and Networked Services (info@dans.knaw.nl) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.knaw.dans.dvcli.command; + +import nl.knaw.dans.lib.dataverse.DataverseException; +import nl.knaw.dans.lib.dataverse.model.dataset.UpdateType; +import picocli.CommandLine.ArgGroup; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; +import picocli.CommandLine.ParentCommand; + +import java.io.IOException; + +@Command(name = "publish", + mixinStandardHelpOptions = true, + description = "Dataset publication result.") +public class DatasetPublish extends AbstractCmd { + @ParentCommand + private DatasetCmd datasetCmd; + + static class PublishParams { + @ArgGroup(exclusive = true) + VersionUpdateType versionUpdateType; + + static class VersionUpdateType { + @Option(names = "--major", description = "Version update type: major (default)") + boolean major; + @Option(names = "--minor", description = "Version update type: minor") + boolean minor; + } + + @Option(names = { "-a", "--assure-indexed" }, paramLabel = "assure-indexed", description = "Set to true to ensure that indexing has already happened before publish.") + private boolean assureIsIndexed = true; + } + + @ArgGroup(exclusive = false) + PublishParams publishParams; + + private UpdateType getUpdateType() { + if (publishParams != null && publishParams.versionUpdateType != null) { + if (publishParams.versionUpdateType.minor) { + return UpdateType.minor; + } + } + return UpdateType.major; + } + + private boolean isAssureIndexed() { + if (publishParams != null) + return publishParams.assureIsIndexed; + + return true; + } + + @Override + public void doCall() throws IOException, DataverseException { + datasetCmd.batchProcessor(dataset -> dataset + .publish(this.getUpdateType(), this.isAssureIndexed()) + .getEnvelopeAsString() + ).process(); + } + +} diff --git a/src/main/java/nl/knaw/dans/dvcli/command/DatasetRoleAssignment.java b/src/main/java/nl/knaw/dans/dvcli/command/DatasetRoleAssignment.java new file mode 100644 index 0000000..3b52156 --- /dev/null +++ b/src/main/java/nl/knaw/dans/dvcli/command/DatasetRoleAssignment.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2024 DANS - Data Archiving and Networked Services (info@dans.knaw.nl) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package nl.knaw.dans.dvcli.command; + +import nl.knaw.dans.dvcli.action.ConsoleReport; +import nl.knaw.dans.dvcli.action.ThrowingFunction; +import nl.knaw.dans.lib.dataverse.DatasetApi; +import nl.knaw.dans.lib.dataverse.DataverseException; +import nl.knaw.dans.lib.dataverse.model.RoleAssignment; +import nl.knaw.dans.lib.dataverse.model.RoleAssignmentReadOnly; +import picocli.CommandLine.Command; +import picocli.CommandLine.ParentCommand; + +import java.io.IOException; +import java.util.Optional; + +@Command(name = "role-assignment", + mixinStandardHelpOptions = true, + description = "Manage role assignments.", + subcommands = { DatasetRoleAssignment.DatasetListRoleAssignments.class, DatasetRoleAssignment.DatasetAssignRole.class, DatasetRoleAssignment.DatasetDeleteRole.class }) +public class DatasetRoleAssignment extends AbstractCmd { + @ParentCommand + static private DatasetCmd datasetCmd; + + @Command(name = "list", + mixinStandardHelpOptions = true, + description = "List role assignments for the specified dataset.") + static class DatasetListRoleAssignments extends AbstractCmd { + + @Override + public void doCall() throws IOException, DataverseException { + datasetCmd.batchProcessor(d -> d.listRoleAssignments().getEnvelopeAsString()).process(); + } + } + + @Command(name = "add", + mixinStandardHelpOptions = true, + description = "Assign a role to a user in a dataset.") + static class DatasetAssignRole extends AbstractAssignmentRole { + @Override + protected DatasetApi getItem(String pid) { + return datasetCmd.dataverseClient.dataset(pid); + } + + private static class RoleAssignmentAction implements ThrowingFunction, String, Exception> { + @Override + public String apply(RoleAssignmentParams roleAssignmentParams) throws IOException, DataverseException { + if (roleAssignmentParams.roleAssignment().isPresent()) { + var r = roleAssignmentParams.pid().assignRole(roleAssignmentParams.roleAssignment().get()); + return r.getEnvelopeAsString(); + } + return "There was no assignment-role to assign."; + } + } + + @Override + public void doCall() throws IOException, DataverseException { + datasetCmd.> paramsBatchProcessorBuilder() + .labeledItems(getRoleAssignmentParams(datasetCmd)) + .action(new RoleAssignmentAction()) + .report(new ConsoleReport<>()) + .build() + .process(); + } + + } + + @Command(name = "remove", + mixinStandardHelpOptions = true, + description = "remove role assignment from specified dataset(s)") + static class DatasetDeleteRole extends AbstractAssignmentRole { + + @Override + protected DatasetApi getItem(String pid) { + return datasetCmd.dataverseClient.dataset(pid); + } + + private static class RoleAssignmentAction implements ThrowingFunction, String, Exception> { + @Override + public String apply(RoleAssignmentParams roleAssignmentParams) throws IOException, DataverseException { + if (roleAssignmentParams.roleAssignment().isPresent()) { + RoleAssignment roleAssignment = roleAssignmentParams.roleAssignment().get(); + Optional role = roleAssignmentParams.pid().listRoleAssignments().getData().stream() + .filter(r -> r.get_roleAlias().equals(roleAssignment.getRole()) && r.getAssignee().equals(roleAssignment.getAssignee())).findFirst(); + if (role.isPresent()) { + var r = roleAssignmentParams.pid().deleteRoleAssignment(role.get().getId()); + return r.getEnvelopeAsString(); + } + } + return "There was no assignment-role to assign."; + } + } + + @Override + public void doCall() throws IOException, DataverseException { + datasetCmd.> paramsBatchProcessorBuilder() + .labeledItems(getRoleAssignmentParams(datasetCmd)) + .action(new RoleAssignmentAction()) + .report(new ConsoleReport<>()) + .build() + .process(); + } + } + + @Override + public void doCall() throws IOException, DataverseException { + + } +}