From cd139dc41c63b9750508f3d23deab50d65bdbc16 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Wed, 21 May 2014 10:02:47 -0400 Subject: [PATCH 01/74] SWORD: rather than creator, check for Permission.DestructiveEdit #3385 - seems similar to "admin" in DVN 3.x - random users will never have this permission in the root, though --- scripts/api/data-deposit/list-datasets | 7 ++++- scripts/api/data-deposit/service-document | 8 ++++- .../dataverse/api/datadeposit/SwordAuth.java | 30 ++++++++++++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/scripts/api/data-deposit/list-datasets b/scripts/api/data-deposit/list-datasets index 91fb9dc4f8d..238da4f5857 100755 --- a/scripts/api/data-deposit/list-datasets +++ b/scripts/api/data-deposit/list-datasets @@ -2,6 +2,11 @@ USERNAME=pete PASSWORD=pete DVN_SERVER=localhost:8181 -DATAVERSE_ALIAS=peteTop +if [ -z "$1" ]; then + DATAVERSE_ALIAS=peteTop + #DATAVERSE_ALIAS=root +else + DATAVERSE_ALIAS=$1 +fi curl --insecure https://$USERNAME:$PASSWORD@$DVN_SERVER/dvn/api/data-deposit/v1/swordv2/collection/dataverse/$DATAVERSE_ALIAS \ | xmllint -format - diff --git a/scripts/api/data-deposit/service-document b/scripts/api/data-deposit/service-document index 87ccdf8c18d..405f14f0a1f 100755 --- a/scripts/api/data-deposit/service-document +++ b/scripts/api/data-deposit/service-document @@ -1,2 +1,8 @@ #!/bin/bash -curl --insecure https://pete:pete@localhost:8181/dvn/api/data-deposit/v1/swordv2/service-document | xmllint -format - +if [ -z "$1" ]; then + USERNAME=pete +else + USERNAME=$1 +fi +PASSWORD=$USERNAME +curl --insecure -s https://$USERNAME:$PASSWORD@localhost:8181/dvn/api/data-deposit/v1/swordv2/service-document | xmllint -format - diff --git a/src/main/java/edu/harvard/iq/dataverse/api/datadeposit/SwordAuth.java b/src/main/java/edu/harvard/iq/dataverse/api/datadeposit/SwordAuth.java index 849ea4b4e05..fb22725b8a7 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/datadeposit/SwordAuth.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/datadeposit/SwordAuth.java @@ -1,9 +1,13 @@ package edu.harvard.iq.dataverse.api.datadeposit; import edu.harvard.iq.dataverse.Dataverse; +import edu.harvard.iq.dataverse.DataverseRoleServiceBean; import edu.harvard.iq.dataverse.DataverseUser; import edu.harvard.iq.dataverse.DataverseUserServiceBean; import edu.harvard.iq.dataverse.PasswordEncryption; +import edu.harvard.iq.dataverse.PermissionServiceBean; +import edu.harvard.iq.dataverse.RoleAssignment; +import edu.harvard.iq.dataverse.engine.Permission; import java.util.logging.Logger; import javax.ejb.EJB; import org.swordapp.server.AuthCredentials; @@ -14,8 +18,13 @@ public class SwordAuth { private static final Logger logger = Logger.getLogger(SwordAuth.class.getCanonicalName()); + @EJB DataverseUserServiceBean dataverseUserService; + @EJB + PermissionServiceBean permissionService; + @EJB + DataverseRoleServiceBean roleService; public DataverseUser auth(AuthCredentials authCredentials) throws SwordAuthException, SwordServerException { @@ -64,7 +73,26 @@ boolean hasAccessToModifyDataverse(DataverseUser dataverseUser, Dataverse datave // } // } // - if (dataverse.getCreator().equals(dataverseUser)) { + for (RoleAssignment roleAssignment : roleService.assignmentsFor(dataverseUser, dataverse).getAssignments()) { + /** + * @todo do we want to hard code a check for the string "manager" + * here? Probably not... for now let's just check for + * Permission.DestructiveEdit which feels equivalent to the "admin" + * role in DVN 3.x. We could also do a check for an admin-type + * command like this: permissionService.userOn(dataverseUser, + * dataverse).canIssue(DestroyDataverseCommand.class) + * + * @todo What about the root dataverse? With the GUI, any user can + * create datasets in the root dataverse but users won't be "admin" + * of the root dataverse. The "all or nothing" admin concept for all + * SWORD operations will probably need to go away. Rather than a + * single hasAccessToModifyDataverse method, we should have methods + * per SWORD commands that map onto permissions like + * canIssue(CreateDatasetCommand.class) + */ + logger.fine(dataverse.getAlias() + ": " + dataverseUser.getUserName() + " has role " + roleAssignment.getRole().getAlias()); + } + if (permissionService.userOn(dataverseUser, dataverse).has(Permission.DestructiveEdit)) { authorized = true; return authorized; } else { From 521d6ad034f5f1bc3d9fc35308f82c65fb6d1380 Mon Sep 17 00:00:00 2001 From: Michael Bar-Sinai Date: Wed, 21 May 2014 10:37:46 -0400 Subject: [PATCH 02/74] Adding datasets and datasets via API - DONE. --- .../dataset-bad-missingInitialVersion.json | 7 +- ...t-sample1.json => dataset-create-new.json} | 125 +++++---- scripts/api/data/dataset-updated-version.json | 261 ++++++++++++++++++ scripts/api/readme.md | 14 +- .../iq/dataverse/DatasetServiceBean.java | 2 +- .../harvard/iq/dataverse/DatasetVersion.java | 6 +- .../harvard/iq/dataverse/api/Datasets.java | 45 ++- .../harvard/iq/dataverse/api/Dataverses.java | 22 +- .../iq/dataverse/engine/Permission.java | 1 + .../engine/command/RequiredPermissions.java | 2 +- .../command/impl/CreateDatasetCommand.java | 10 +- .../impl/CreateDatasetVersionCommand.java | 57 ++++ .../command/impl/UpdateDatasetCommand.java | 9 +- .../iq/dataverse/util/json/JsonParser.java | 34 --- .../iq/dataverse/util/json/JsonPrinter.java | 67 +---- 15 files changed, 490 insertions(+), 172 deletions(-) rename scripts/api/data/{dataset-sample1.json => dataset-create-new.json} (61%) create mode 100644 scripts/api/data/dataset-updated-version.json create mode 100644 src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDatasetVersionCommand.java diff --git a/scripts/api/data/dataset-bad-missingInitialVersion.json b/scripts/api/data/dataset-bad-missingInitialVersion.json index caa698d3713..855702046b8 100644 --- a/scripts/api/data/dataset-bad-missingInitialVersion.json +++ b/scripts/api/data/dataset-bad-missingInitialVersion.json @@ -1,5 +1,6 @@ { - "authority":"anAuthority", - "identifier":"dataset-one", - "protocol":"chadham-house-rule" + "authority": "anAuthority", + "identifier": "dataset-one", + "persistentUrl": "http://dx.doi.org/10.5072/FK2/9", + "protocol": "chadham-house-rule" } \ No newline at end of file diff --git a/scripts/api/data/dataset-sample1.json b/scripts/api/data/dataset-create-new.json similarity index 61% rename from scripts/api/data/dataset-sample1.json rename to scripts/api/data/dataset-create-new.json index dd43fe4c394..c4c6f1aa5f5 100644 --- a/scripts/api/data/dataset-sample1.json +++ b/scripts/api/data/dataset-create-new.json @@ -1,10 +1,14 @@ { - "data": { + "authority": "anAuthority", + "identifier": "dataset-one", + "persistentUrl": "http://dx.doi.org/10.5072/FK2/9", + "protocol": "chadham-house-rule", + "initialVersion": { "metadataBlocks": { "citation": { "fields": [ { - "value": "sample dataset", + "value": "SampleTitle", "typeClass": "primitive", "multiple": false, "typeName": "title" @@ -27,7 +31,7 @@ }, { "authorAffiliation": { - "value": "Coca-cola co", + "value": "UMASS, Amherst", "typeClass": "primitive", "multiple": false, "typeName": "authorAffiliation" @@ -46,23 +50,24 @@ }, { "value": [ - "pete@malinator.com" + "pete@malinator.com", + "beat@pailinator.gov" ], "typeClass": "primitive", "multiple": true, "typeName": "distributorContact" }, { - "value": "description description description description description description description description description ", + "value": "lorem ipsum dolor sit amet. That must've been pretty interesting, I bet.", "typeClass": "primitive", "multiple": false, "typeName": "dsDescription" }, { "value": [ - "Keyword1", - "KeywordTwo", - "TheThirdKeyWord" + "kw1", + "kw2", + "kw3" ], "typeClass": "primitive", "multiple": true, @@ -70,14 +75,15 @@ }, { "value": [ - "Social Sciences" + "Arts and Humanities", + "Astronomy and Astrophysics" ], "typeClass": "controlledVocabulary", "multiple": true, "typeName": "subject" }, { - "value": "notes notes notes notes notes notes notes notes notes notes notes ", + "value": "Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note.\r\nNOTANOTANOTANOTANnot.e\r\n", "typeClass": "primitive", "multiple": false, "typeName": "notesText" @@ -86,13 +92,13 @@ "value": [ { "otherIdAgency": { - "value": "otheridAgency", + "value": "NSF", "typeClass": "primitive", "multiple": false, "typeName": "otherIdAgency" }, "otherIdValue": { - "value": "otherid", + "value": "NSF1234", "typeClass": "primitive", "multiple": false, "typeName": "otherIdValue" @@ -104,13 +110,46 @@ "typeName": "otherId" }, { - "value": "2014-04-01", + "value": [ + { + "contributorAbbreviation": { + "value": "DDD", + "typeClass": "primitive", + "multiple": false, + "typeName": "contributorAbbreviation" + }, + "contributorAffiliation": { + "value": "Denmark", + "typeClass": "primitive", + "multiple": false, + "typeName": "contributorAffiliation" + }, + "contributorName": { + "value": "Dennis", + "typeClass": "primitive", + "multiple": false, + "typeName": "contributorName" + }, + "contributorType": { + "value": "Distributor", + "typeClass": "controlledVocabulary", + "multiple": false, + "typeName": "contributorType" + } + } + ], + "typeClass": "compound", + "multiple": true, + "typeName": "contributor" + }, + { + "value": "2014-02-03", "typeClass": "primitive", "multiple": false, "typeName": "productionDate" }, { - "value": "2014-04-01", + "value": "Cambridge, MA", "typeClass": "primitive", "multiple": false, "typeName": "productionPlace" @@ -119,13 +158,13 @@ "value": [ { "grantNumberAgency": { - "value": "NSF", + "value": "NIH", "typeClass": "primitive", "multiple": false, "typeName": "grantNumberAgency" }, "grantNumberValue": { - "value": "NSF12345", + "value": "NIH1231245154", "typeClass": "primitive", "multiple": false, "typeName": "grantNumberValue" @@ -139,7 +178,7 @@ "typeName": "grantNumberAgency" }, "grantNumberValue": { - "value": "NIH99999", + "value": "NIH99999999", "typeClass": "primitive", "multiple": false, "typeName": "grantNumberValue" @@ -157,15 +196,30 @@ "typeName": "depositor" }, { - "value": "2014-05-06", + "value": "2014-05-20", "typeClass": "primitive", "multiple": false, "typeName": "dateOfDeposit" }, { "value": [ - "Other reference number one", - "Other reference number two" + "Bananas" + ], + "typeClass": "primitive", + "multiple": true, + "typeName": "relatedMaterial" + }, + { + "value": [ + "Data about bananas" + ], + "typeClass": "primitive", + "multiple": true, + "typeName": "relatedDatasets" + }, + { + "value": [ + "other ref other ref other ref ef ef" ], "typeClass": "primitive", "multiple": true, @@ -175,36 +229,13 @@ "displayName": "Citation Metadata" } }, - "authors": [ - { - "displayOrder": 0, - "affiliation": { - "value": null - }, - "name": { - "value": null - } - }, - { - "displayOrder": 0, - "affiliation": { - "value": null - }, - "name": { - "value": null - } - } - ], - "createTime": "2014-05-06 01:38:01 -04", + "createTime": "2014-05-20 11:52:55 -04", "UNF": "UNF", - "id": 4, - "version": 1, + "id": 1, "versionNumber": 1, "versionMinorNumber": 0, "versionState": "DRAFT", - "title": "sample dataset", "distributionDate": "Distribution Date", "productionDate": "Production Date" - }, - "status": "OK" -} + } +} \ No newline at end of file diff --git a/scripts/api/data/dataset-updated-version.json b/scripts/api/data/dataset-updated-version.json new file mode 100644 index 00000000000..bef27390db1 --- /dev/null +++ b/scripts/api/data/dataset-updated-version.json @@ -0,0 +1,261 @@ +{ + "createTime": "2014-05-20 11:52:55 -04", + "UNF": "UNF", + "versionNumber": 1, + "versionMinorNumber": 0, + "versionState": "DRAFT", + "distributionDate": "Distribution Date", + "productionDate": "Production Date", + "metadataBlocks": { + "citation": { + "fields": [ + { + "value": "UpdatedTitle", + "typeClass": "primitive", + "multiple": false, + "typeName": "title" + }, + { + "value": [ + { + "authorAffiliation": { + "value": "Tippie Top", + "typeClass": "primitive", + "multiple": false, + "typeName": "authorAffiliation" + }, + "authorName": { + "value": "McPrivileged, Pete", + "typeClass": "primitive", + "multiple": false, + "typeName": "authorName" + } + }, + { + "authorAffiliation": { + "value": "UNC", + "typeClass": "primitive", + "multiple": false, + "typeName": "authorAffiliation" + }, + "authorName": { + "value": "Borrator, Colla", + "typeClass": "primitive", + "multiple": false, + "typeName": "authorName" + } + }, + { + "authorAffiliation": { + "value": "NASA", + "typeClass": "primitive", + "multiple": false, + "typeName": "authorAffiliation" + }, + "authorName": { + "value": "Naut, Astro", + "typeClass": "primitive", + "multiple": false, + "typeName": "authorName" + } + } + ], + "typeClass": "compound", + "multiple": true, + "typeName": "author" + }, + { + "value": [ + "pete@malinator.com" + ], + "typeClass": "primitive", + "multiple": true, + "typeName": "distributorContact" + }, + { + "value": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos, eos, natus soluta porro harum beatae voluptatem unde rerum eius quaerat officiis maxime autem asperiores facere.", + "typeClass": "primitive", + "multiple": false, + "typeName": "dsDescription" + }, + { + "value": [ + "kw10", + "kw20", + "kw30" + ], + "typeClass": "primitive", + "multiple": true, + "typeName": "keyword" + }, + { + "value": [ + "Arts and Humanities", + "Astronomy and Astrophysics" + ], + "typeClass": "controlledVocabulary", + "multiple": true, + "typeName": "subject" + }, + { + "value": "Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note Note note note note.\r\nNOTANOTANOTANOTANnot.e\r\n", + "typeClass": "primitive", + "multiple": false, + "typeName": "notesText" + }, + { + "value": [ + { + "otherIdAgency": { + "value": "NSF", + "typeClass": "primitive", + "multiple": false, + "typeName": "otherIdAgency" + }, + "otherIdValue": { + "value": "NSF1234", + "typeClass": "primitive", + "multiple": false, + "typeName": "otherIdValue" + } + }, + { + "otherIdAgency": { + "value": "NIH", + "typeClass": "primitive", + "multiple": false, + "typeName": "otherIdAgency" + }, + "otherIdValue": { + "value": "NIH98765", + "typeClass": "primitive", + "multiple": false, + "typeName": "otherIdValue" + } + } + ], + "typeClass": "compound", + "multiple": true, + "typeName": "otherId" + }, + { + "value": [ + { + "contributorAbbreviation": { + "value": "DDD", + "typeClass": "primitive", + "multiple": false, + "typeName": "contributorAbbreviation" + }, + "contributorAffiliation": { + "value": "Denmark", + "typeClass": "primitive", + "multiple": false, + "typeName": "contributorAffiliation" + }, + "contributorName": { + "value": "Dennis", + "typeClass": "primitive", + "multiple": false, + "typeName": "contributorName" + }, + "contributorType": { + "value": "Distributor", + "typeClass": "controlledVocabulary", + "multiple": false, + "typeName": "contributorType" + } + } + ], + "typeClass": "compound", + "multiple": true, + "typeName": "contributor" + }, + { + "value": "2014-02-03", + "typeClass": "primitive", + "multiple": false, + "typeName": "productionDate" + }, + { + "value": "Cambridge, UK", + "typeClass": "primitive", + "multiple": false, + "typeName": "productionPlace" + }, + { + "value": [ + { + "grantNumberAgency": { + "value": "NIH", + "typeClass": "primitive", + "multiple": false, + "typeName": "grantNumberAgency" + }, + "grantNumberValue": { + "value": "NIH1231245154", + "typeClass": "primitive", + "multiple": false, + "typeName": "grantNumberValue" + } + }, + { + "grantNumberAgency": { + "value": "NIH", + "typeClass": "primitive", + "multiple": false, + "typeName": "grantNumberAgency" + }, + "grantNumberValue": { + "value": "NIH99999999", + "typeClass": "primitive", + "multiple": false, + "typeName": "grantNumberValue" + } + } + ], + "typeClass": "compound", + "multiple": true, + "typeName": "grantNumber" + }, + { + "value": "Privileged, Pete", + "typeClass": "primitive", + "multiple": false, + "typeName": "depositor" + }, + { + "value": "2014-05-20", + "typeClass": "primitive", + "multiple": false, + "typeName": "dateOfDeposit" + }, + { + "value": [ + "Bananas" + ], + "typeClass": "primitive", + "multiple": true, + "typeName": "relatedMaterial" + }, + { + "value": [ + "Data about bananas" + ], + "typeClass": "primitive", + "multiple": true, + "typeName": "relatedDatasets" + }, + { + "value": [ + "other ref other ref other ref ef ef" + ], + "typeClass": "primitive", + "multiple": true, + "typeName": "otherReferences" + } + ], + "displayName": "Citation Metadata" + } + } +} \ No newline at end of file diff --git a/scripts/api/readme.md b/scripts/api/readme.md index 5d0945e3a37..8a3d2cf141e 100644 --- a/scripts/api/readme.md +++ b/scripts/api/readme.md @@ -5,7 +5,7 @@ The API uses `json`, and sometimes query parameters as well. Also, sometimes the To have a fresh start in the database, you can execute the script `drop-create.sh` in the `../database` folder. -## Pre-made scripts +## Pre-made Scripts setup-users.sh @@ -79,6 +79,10 @@ Get whether the dataverse is a metadata block root, or does it uses its parent b Set whether the dataverse is a metadata block root, or does it uses its parent blocks. Possible values are `true` and `false` (both are valid JSON expressions). + POST http://{{SERVER}}/api/dvs/{{id}}/datasets/?key={{username}} + +Create a new dataset in dataverse `id`. The post data is a Json object, containing the dataset fields and an initial dataset version, under the field of `"initialVersion"`. The initial versions version number will be set to `1.0`, and its state will be set to `DRAFT` regardless of the content of the json object. Example json can be found at `data/dataset-create-new.json`. + ### Datasets GET http://{{SERVER}}/api/datasets/?key={{apikey}} @@ -102,14 +106,18 @@ List versions of the dataset. Show a version of the dataset. The `versionId` can be a number, or the values `:edit` for the edit version, and `:latest` for the latest one. The Dataset also include any metadata blocks the data might have. - GET http://{{SERVER}}//api/datasets/{{id}}/versions/{{versionId}}/metadata?key={{apikey}} + GET http://{{SERVER}}/api/datasets/{{id}}/versions/{{versionId}}/metadata?key={{apikey}} Lists all the metadata blocks and their content, for the given dataset and version. - GET http://{{SERVER}}//api/datasets/{{id}}/versions/{{versionId}}/metadata/{{blockname}}?key={{apikey}} + GET http://{{SERVER}}/api/datasets/{{id}}/versions/{{versionId}}/metadata/{{blockname}}?key={{apikey}} Lists the metadata block block named `blockname`, for the given dataset and version. + POST http://{{SERVER}}/api/datasets/{{id}}/versions/?bump={{minor|major}}&key={{apiKey}} + +Adds a new version to a dataset. The `POST` parameter contains json version data. The new version number is determined by the server, based on the `bump` parameter. When `minor`, the dot-number is advances (2.4 → 2.5). When `major`, the major version number is advanced (2.4 → 3.0). + ### permissions GET http://{{SERVER}}/api/permissions?user={{uid}}&on={{dvoId}} diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/DatasetServiceBean.java index 5ffff921859..54a96cdcd13 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetServiceBean.java @@ -30,7 +30,7 @@ public class DatasetServiceBean { private EntityManager em; public Dataset find(Object pk) { - return (Dataset) em.find(Dataset.class, pk); + return em.find(Dataset.class, pk); } public List findByOwnerId(Long ownerId) { diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index a5c91f8195d..75cc3d1f4d3 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -61,7 +61,11 @@ public void setId(Long id) { @Version private Long version; - + + /** + * This is JPA's optimistic locking mechanism, and has no semantic meaning in the DV object model. + * @return the object db version + */ public Long getVersion() { return this.version; } diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Datasets.java b/src/main/java/edu/harvard/iq/dataverse/api/Datasets.java index 5a5621827c5..bae2547ed07 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Datasets.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Datasets.java @@ -8,13 +8,17 @@ import edu.harvard.iq.dataverse.DataverseServiceBean; import edu.harvard.iq.dataverse.DataverseUser; import edu.harvard.iq.dataverse.MetadataBlock; -import static edu.harvard.iq.dataverse.util.json.JsonPrinter.json; import edu.harvard.iq.dataverse.api.dto.DatasetDTO; import edu.harvard.iq.dataverse.engine.command.exception.CommandException; import edu.harvard.iq.dataverse.engine.command.exception.CommandExecutionException; import edu.harvard.iq.dataverse.engine.command.impl.CreateDatasetCommand; +import edu.harvard.iq.dataverse.engine.command.impl.CreateDatasetVersionCommand; +import edu.harvard.iq.dataverse.engine.command.impl.CreateDatasetVersionCommand.BumpWhat; import edu.harvard.iq.dataverse.engine.command.impl.DeleteDatasetCommand; +import edu.harvard.iq.dataverse.util.json.JsonParseException; import edu.harvard.iq.dataverse.util.json.JsonPrinter; +import static edu.harvard.iq.dataverse.util.json.JsonPrinter.json; +import java.io.StringReader; import java.util.List; import java.util.Map; import java.util.logging.Level; @@ -23,6 +27,7 @@ import javax.ejb.EJBException; import javax.json.Json; import javax.json.JsonArrayBuilder; +import javax.json.JsonObject; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.ws.rs.DELETE; @@ -70,7 +75,6 @@ public String getDataset( @PathParam("id") Long id, @QueryParam("key") String ap Dataset ds = datasetService.find(id); return (ds != null) ? ok(json(ds)) : error("dataset not found"); - } @@ -249,12 +253,41 @@ public String listFiles() { return error("Not implemented yet"); } - @POST @Path("{id}/versions") - public String addVersion( @PathParam("id") Long id, @QueryParam("key") String apikey, DatasetDTO dsDto ){ - // CONTPOINT accept the dsDto and push it to the DB. - return null; + public Response addVersion( String jsonBody, @PathParam("id") Long id, @QueryParam("bump")String bumpParam, @QueryParam("key") String apiKey ){ + + DataverseUser u = userSvc.findByUserName(apiKey); + if ( u == null ) return errorResponse( Response.Status.UNAUTHORIZED, "Invalid apikey '" + apiKey + "'"); + + if ( bumpParam == null ) return errorResponse(Response.Status.BAD_REQUEST, "Must specify 'bump' parameter, either 'minor' or 'major'"); + + CreateDatasetVersionCommand.BumpWhat bump; + switch (bumpParam.toLowerCase()) { + case "major": bump = BumpWhat.BumpMajor; break; + case "minor": bump = BumpWhat.BumpMinor; break; + default: return errorResponse(Response.Status.BAD_REQUEST, "bump parameter must be either 'minor' or 'major'"); + } + + Dataset ds = datasetService.find(id); + if ( ds == null ) return errorResponse( Response.Status.NOT_FOUND, "Can't find dataset with id '" + id + "'"); + + + try ( StringReader rdr = new StringReader(jsonBody) ) { + JsonObject json = Json.createReader(rdr).readObject(); + DatasetVersion version = jsonParser().parseDatasetVersion(json); + DatasetVersion managedVersion = engineSvc.submit( new CreateDatasetVersionCommand(u, ds, version, bump) ); + return okResponse( json(managedVersion) ); + + } catch (CommandException ex) { + logger.log(Level.SEVERE, "Error executing CreateDatasetVersionCommand: " + ex.getMessage(), ex); + return errorResponse(Response.Status.INTERNAL_SERVER_ERROR, "Error: " + ex.getMessage() ); + + } catch (JsonParseException ex) { + logger.log(Level.SEVERE, "Semantic error parsing dataset version Json: " + ex.getMessage(), ex); + return errorResponse( Response.Status.BAD_REQUEST, "Error parsing dataset version: " + ex.getMessage() ); + } + } // used to primarily to feed data into elasticsearch diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java b/src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java index 86837993673..3fee3e4d036 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java @@ -24,7 +24,6 @@ import edu.harvard.iq.dataverse.engine.command.impl.UpdateDataverseMetadataBlocksCommand; import edu.harvard.iq.dataverse.util.json.JsonParseException; import java.io.StringReader; -import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.UUID; @@ -41,7 +40,6 @@ import javax.json.stream.JsonParsingException; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; -import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.POST; import javax.ws.rs.PathParam; @@ -145,15 +143,17 @@ public Response createDataset( String jsonBody, @PathParam("identifier") String } try { try { - DatasetVersion version = jsonParser().parseDatasetVersion(jsonVersion); - - // force "initial version" properties - version.setMinorVersionNumber(0l); - version.setVersion(1l); - version.setVersionNumber(1l); - version.setVersionState(DatasetVersion.VersionState.DRAFT); - - ds.setVersions( Collections.singletonList(version) ); + DatasetVersion version = jsonParser().parseDatasetVersion(jsonVersion); + + // force "initial version" properties + version.setMinorVersionNumber(0l); + version.setVersionNumber(1l); + version.setVersionState(DatasetVersion.VersionState.DRAFT); + LinkedList versions = new LinkedList<>(); + versions.add(version); + version.setDataset(ds); + + ds.setVersions( versions ); } catch ( javax.ejb.TransactionRolledbackLocalException rbe ) { throw rbe.getCausedByException(); } diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/Permission.java b/src/main/java/edu/harvard/iq/dataverse/engine/Permission.java index e5e2791b942..58c51f9b18d 100644 --- a/src/main/java/edu/harvard/iq/dataverse/engine/Permission.java +++ b/src/main/java/edu/harvard/iq/dataverse/engine/Permission.java @@ -13,6 +13,7 @@ public enum Permission implements java.io.Serializable { EditMetadata("Edit the metadata of objects"), AddDataverse("Add a dataverse within another dataverse"), AddDataset("Add a dataset to a dataverse"), + AddDatasetVersion("Add a version to a dataset"), ChooseTemplate("Choose metadata template for dataverses and datasets"), Release("Release a dataverse or a dataset"), Style("Customize the appearance of objects"), diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/RequiredPermissions.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/RequiredPermissions.java index 7855bd99163..5ba67043284 100644 --- a/src/main/java/edu/harvard/iq/dataverse/engine/command/RequiredPermissions.java +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/RequiredPermissions.java @@ -16,5 +16,5 @@ @Target(ElementType.TYPE) public @interface RequiredPermissions { Permission[] value(); - String dataverseName() default ""; + String dataverseName() default ""; // TODO change to "dvObjectName" } diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDatasetCommand.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDatasetCommand.java index 15dfbb71f2e..d5130d625d5 100644 --- a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDatasetCommand.java +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDatasetCommand.java @@ -57,8 +57,6 @@ public Dataset execute(CommandContext ctxt) throws CommandException { dataFile.setCreateDate(theDataset.getCreateDate()); } Dataset savedDataset = ctxt.em().merge(theDataset); - String indexingResult = ctxt.index().indexDataset(savedDataset); - logger.log(Level.INFO, "during dataset save, indexing result was: {0}", indexingResult); DataverseRole manager = new DataverseRole(); manager.addPermissions(EnumSet.allOf(Permission.class)); @@ -68,6 +66,14 @@ public Dataset execute(CommandContext ctxt) throws CommandException { manager.setOwner(savedDataset); ctxt.roles().save(manager); ctxt.roles().save(new RoleAssignment(manager, getUser(), savedDataset)); + + try { + // TODO make async + String indexingResult = ctxt.index().indexDataset(savedDataset); + logger.log(Level.INFO, "during dataset save, indexing result was: {0}", indexingResult); + } catch ( RuntimeException e ) { + logger.log(Level.WARNING, "Exception while indexing:" + e.getMessage(), e); + } return savedDataset; } diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDatasetVersionCommand.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDatasetVersionCommand.java new file mode 100644 index 00000000000..95d29859d5b --- /dev/null +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDatasetVersionCommand.java @@ -0,0 +1,57 @@ +package edu.harvard.iq.dataverse.engine.command.impl; + +import edu.harvard.iq.dataverse.Dataset; +import edu.harvard.iq.dataverse.DatasetVersion; +import edu.harvard.iq.dataverse.DataverseUser; +import edu.harvard.iq.dataverse.engine.Permission; +import edu.harvard.iq.dataverse.engine.command.AbstractCommand; +import edu.harvard.iq.dataverse.engine.command.CommandContext; +import edu.harvard.iq.dataverse.engine.command.RequiredPermissions; +import edu.harvard.iq.dataverse.engine.command.exception.CommandException; + +/** + * + * @author michael + */ +@RequiredPermissions( Permission.AddDatasetVersion ) +public class CreateDatasetVersionCommand extends AbstractCommand { + + public enum BumpWhat { + BumpMinor, + BumpMajor + } + final BumpWhat whatToBump; + final DatasetVersion newVersion; + final Dataset dataset; + + public CreateDatasetVersionCommand(DataverseUser aUser, Dataset theDataset, DatasetVersion aVersion, BumpWhat bump) { + super(aUser, theDataset); + dataset = theDataset; + newVersion = aVersion; + whatToBump = bump; + } + + @Override + public DatasetVersion execute(CommandContext ctxt) throws CommandException { + DatasetVersion latest = dataset.getLatestVersion(); + switch ( whatToBump ) { + case BumpMajor: + newVersion.setMinorVersionNumber(0l); + newVersion.setVersionNumber( latest.getVersionNumber() + 1l ); + break; + case BumpMinor: + newVersion.setMinorVersionNumber( latest.getMinorVersionNumber() + 1l); + newVersion.setVersionNumber( latest.getVersionNumber()); + break; + } + + newVersion.setDataset(dataset); + ctxt.em().persist(newVersion); + + // TODO make async + ctxt.index().indexDataset(dataset); + + return newVersion; + } + +} diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/UpdateDatasetCommand.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/UpdateDatasetCommand.java index e5c2cd1c250..516e25d131d 100644 --- a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/UpdateDatasetCommand.java +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/UpdateDatasetCommand.java @@ -13,7 +13,6 @@ import edu.harvard.iq.dataverse.engine.command.AbstractCommand; import edu.harvard.iq.dataverse.engine.command.CommandContext; import edu.harvard.iq.dataverse.engine.command.RequiredPermissions; -import edu.harvard.iq.dataverse.engine.command.RequiredPermissionsMap; import edu.harvard.iq.dataverse.engine.command.exception.CommandException; import java.sql.Timestamp; import java.util.Date; @@ -24,10 +23,7 @@ * * @author skraffmiller */ -@RequiredPermissionsMap({ - @RequiredPermissions(dataverseName = "", value = Permission.UndoableEdit), - @RequiredPermissions(dataverseName = "", value = Permission.EditMetadata) -}) +@RequiredPermissions({Permission.UndoableEdit,Permission.EditMetadata} ) public class UpdateDatasetCommand extends AbstractCommand { private static final Logger logger = Logger.getLogger(UpdateDatasetCommand.class.getCanonicalName()); private final Dataset theDataset; @@ -46,7 +42,6 @@ public void saveDatasetAPI(CommandContext ctxt) { save(ctxt); } - public Dataset save(CommandContext ctxt) { Iterator dsfIt = theDataset.getEditVersion().getDatasetFields().iterator(); while (dsfIt.hasNext()) { @@ -58,7 +53,7 @@ public Dataset save(CommandContext ctxt) { while (dsfItSort.hasNext()) { dsfItSort.next().setValueDisplayOrder(); } - Timestamp updateTime = new Timestamp(new Date().getTime()); + Timestamp updateTime = new Timestamp(new Date().getTime()); for (DataFile dataFile: theDataset.getFiles() ){ if(dataFile.getCreateDate() == null){ diff --git a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonParser.java b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonParser.java index 453c22c0471..abcd09a724b 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonParser.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonParser.java @@ -48,7 +48,6 @@ public DatasetVersion parseDatasetVersion( JsonObject obj ) throws JsonParseExce if ( archiveNote != null ) dsv.setArchiveNote( archiveNote ); dsv.setDeaccessionLink( obj.getString("deaccessionLink", null) ); - dsv.setVersion( parseLong(obj.getString("version", null)) ); dsv.setVersionNumber( parseLong(obj.getString("versionNumber", null)) ); dsv.setMinorVersionNumber( parseLong(obj.getString("minorVersionNumber", null)) ); dsv.setId( parseLong(obj.getString("id", null)) ); @@ -65,39 +64,6 @@ public DatasetVersion parseDatasetVersion( JsonObject obj ) throws JsonParseExce dsv.setDatasetFields( parseMetadataBlocks(obj.getJsonObject("metadataBlocks")) ); - // parse authors - JsonArray authorsJson = obj.getJsonArray("authors"); - List authors = new ArrayList<>( authorsJson.size() ); - for ( JsonObject authorJson : authorsJson.getValuesAs(JsonObject.class) ) { - DatasetAuthor author = new DatasetAuthor(); - author.setAffiliation( parseField( authorJson.getJsonObject("affiliation")) ); - author.setIdType( authorJson.getString("idType", null) ); - author.setIdValue( authorJson.getString("idValue", null)); - author.setDisplayOrder( parsePrimitiveInt(authorJson.getString("displayOrder", null), 0) ); - author.setName( parseField( authorJson.getJsonObject("name")) ); - - authors.add( author ); - author.setDatasetVersion(dsv); - } - dsv.setDatasetAuthors(authors); - - // parse distributors - JsonArray distrosJson = obj.getJsonArray("distributors"); - if ( distrosJson != null ) { - List distros = new ArrayList<>(distrosJson.size()); - for ( JsonObject distJson : distrosJson.getValuesAs(JsonObject.class) ) { - DatasetDistributor distr = new DatasetDistributor(); - distr.setDisplayOrder( distJson.getInt("displayOrder", 0)); - distr.setVersion( Long.valueOf(distJson.getInt("version", 0)) ); - distr.setAbbreviation( parseField(distJson.getJsonObject("abbreviation"))); - distr.setAffiliation( parseField(distJson.getJsonObject("affiliation"))); - distr.setLogo( parseField(distJson.getJsonObject("logo"))); - distr.setName( parseField(distJson.getJsonObject("name"))); - distr.setUrl( parseField(distJson.getJsonObject("url"))); - } - dsv.setDatasetDistributors(distros); - } - return dsv; } catch (ParseException ex) { diff --git a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java index 27d370740e4..22cdca5fd3d 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java @@ -30,13 +30,11 @@ import java.util.TreeSet; import static edu.harvard.iq.dataverse.util.json.NullSafeJsonBuilder.jsonObjectBuilder; -import java.math.BigDecimal; import java.util.Deque; import java.util.LinkedList; import java.util.Map; import javax.json.JsonArray; import javax.json.JsonObject; -import javax.json.JsonValue; /** * Convert objects to Json. @@ -50,12 +48,12 @@ public class JsonPrinter { public static final BriefJsonPrinter brief = new BriefJsonPrinter(); public static JsonObjectBuilder json( RoleAssignment ra ) { - return Json.createObjectBuilder() + return jsonObjectBuilder() .add("id", ra.getId()) .add("userId", ra.getUser().getId() ) - .add("_username", nullFill(ra.getUser().getUserName())) + .add("_username", ra.getUser().getUserName()) .add("roleId", ra.getRole().getId() ) - .add("_roleAlias", nullFill(ra.getRole().getAlias())) + .add("_roleAlias", ra.getRole().getAlias()) .add("definitionPointId", ra.getDefinitionPoint().getId() ); } @@ -68,11 +66,11 @@ public static JsonArrayBuilder json( Set permissions ) { } public static JsonObjectBuilder json( DataverseRole role ) { - JsonObjectBuilder bld = Json.createObjectBuilder() - .add("alias", nullFill(role.getAlias()) ) - .add("name", nullFill(role.getName())) + JsonObjectBuilder bld = jsonObjectBuilder() + .add("alias", role.getAlias()) + .add("name", role.getName()) .add("permissions", json(role.permissions())) - .add("description", nullFill(role.getDescription())); + .add("description", role.getDescription()); if ( role.getId() != null ) bld.add("id", role.getId() ); if ( role.getOwner()!=null && role.getOwner().getId()!=null ) bld.add("ownerId", role.getOwner().getId()); @@ -82,9 +80,9 @@ public static JsonObjectBuilder json( DataverseRole role ) { public static JsonObjectBuilder json( Dataverse dv ) { JsonObjectBuilder bld = jsonObjectBuilder() .add("id", dv.getId() ) - .add("alias", nullFill(dv.getAlias()) ) - .add("name", nullFill(dv.getName())) - .add("affiliation", dv.getAffiliation()) + .add("alias", dv.getAlias()) + .add("name", dv.getName()) + .add("affiliation", dv.getAffiliation()) .add("contactEmail", dv.getContactEmail()) .add("permissionRoot", dv.isPermissionRoot()) .add("creator",json(dv.getCreator())) @@ -130,12 +128,10 @@ public static JsonObjectBuilder json( Dataset ds ) { public static JsonObjectBuilder json( DatasetVersion dsv ) { JsonObjectBuilder bld = jsonObjectBuilder() .add("id", dsv.getId()) - .add("version", dsv.getVersion() ) .add("versionNumber", dsv.getVersionNumber()) .add("versionMinorNumber", dsv.getMinorVersionNumber()) .add("versionState", dsv.getVersionState().name() ) .add("versionNote", dsv.getVersionNote()) - .add("title", dsv.getTitle()) .add("archiveNote", dsv.getArchiveNote()) .add("deaccessionLink", dsv.getDeaccessionLink()) .add("distributionDate", dsv.getDistributionDate()) @@ -146,33 +142,7 @@ public static JsonObjectBuilder json( DatasetVersion dsv ) { .add("releaseTime", format(dsv.getReleaseTime()) ) .add("createTime", format(dsv.getCreateTime()) ) ; - - // Add distributors - List dists = dsv.getDatasetDistributors(); - if ( ! dists.isEmpty() ) { - if ( dists.size() > 1 ) { - Collections.sort(dists, DatasetDistributor.DisplayOrder ); - } - JsonArrayBuilder ab = Json.createArrayBuilder(); - for ( DatasetDistributor dist : dists ) { - ab.add( json(dist) ); - } - bld.add( "distributors", ab ); - } - - // Add authors - List auth = dsv.getDatasetAuthors(); - if ( ! auth.isEmpty() ) { - if ( auth.size() > 1 ) { - Collections.sort(auth, DatasetAuthor.DisplayOrder ); - } - JsonArrayBuilder ab = Json.createArrayBuilder(); - for ( DatasetAuthor da : auth ) { - ab.add( json(da) ); - } - bld.add("authors", ab); - } - + bld.add("metadataBlocks", jsonByBlocks(dsv.getDatasetFields())); return bld; @@ -302,21 +272,6 @@ public static JsonObjectBuilder json( DataFile df ) { ; } - public static JsonObjectBuilder json( DatasetAuthor da ) { - return jsonObjectBuilder() - .add( "idType", da.getIdType() ) - .add( "idValue", da.getIdValue() ) - .add( "name", json(da.getName()) ) - .add( "affiliation", json(da.getAffiliation()) ) - .add( "displayOrder", da.getDisplayOrder() ) - ; - } - - - public static String nullFill( String s ) { - return s==null ? "" : s; - } - public static String format( Date d ) { return (d==null) ? null : dateFormat.format(d); } From 9a50a4ae27643a08addda55dd5685de01fc08f77 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Wed, 21 May 2014 11:40:41 -0400 Subject: [PATCH 03/74] no more manual dataset creation! use JSON thanks to Michael! --- scripts/database/homebrew/rebuild-and-test | 3 + scripts/search/create | 6 +- scripts/search/data/dataset01-create-new.json | 130 ++++++++++++++++++ scripts/search/tests/highlighting | 30 +--- scripts/search/tests/highlighting-setup01 | 7 + scripts/search/tests/highlighting-setup02 | 22 +++ 6 files changed, 166 insertions(+), 32 deletions(-) create mode 100644 scripts/search/data/dataset01-create-new.json create mode 100755 scripts/search/tests/highlighting-setup01 create mode 100755 scripts/search/tests/highlighting-setup02 diff --git a/scripts/database/homebrew/rebuild-and-test b/scripts/database/homebrew/rebuild-and-test index 57d97b07469..2bd8ef0cf1f 100755 --- a/scripts/database/homebrew/rebuild-and-test +++ b/scripts/database/homebrew/rebuild-and-test @@ -13,3 +13,6 @@ scripts/database/homebrew/run-post-create-post-deploy scripts/search/tests/permissions scripts/search/tests/delete-dataverse scripts/search/tests/query-unparseable +scripts/search/tests/highlighting-setup01 > /dev/null +scripts/search/tests/highlighting-setup02 +#scripts/search/tests/highlighting diff --git a/scripts/search/create b/scripts/search/create index d6d18d03df6..754be01068f 100755 --- a/scripts/search/create +++ b/scripts/search/create @@ -7,15 +7,15 @@ FILESDIR='data/in/files' #rm data/in/dataverses/1 for i in `ls $DVDIR_ROOT`; do - curl -H "Content-type:application/json" -X POST -d @$DVDIR_ROOT/$i "http://localhost:8080/api/dvs/root?key=pete" + curl -s -H "Content-type:application/json" -X POST -d @$DVDIR_ROOT/$i "http://localhost:8080/api/dvs/root?key=pete" done for i in `ls $DVDIR_BIRDS`; do - curl -H "Content-type:application/json" -X POST -d @$DVDIR_BIRDS/$i "http://localhost:8080/api/dvs/birds?key=pete" + curl -s -H "Content-type:application/json" -X POST -d @$DVDIR_BIRDS/$i "http://localhost:8080/api/dvs/birds?key=pete" done for i in `ls $DVDIR_TREES`; do - curl -H "Content-type:application/json" -X POST -d @$DVDIR_TREES/$i "http://localhost:8080/api/dvs/trees?key=pete" + curl -s -H "Content-type:application/json" -X POST -d @$DVDIR_TREES/$i "http://localhost:8080/api/dvs/trees?key=pete" done # 9 is "sparrows" diff --git a/scripts/search/data/dataset01-create-new.json b/scripts/search/data/dataset01-create-new.json new file mode 100644 index 00000000000..a9a9b6fe8fe --- /dev/null +++ b/scripts/search/data/dataset01-create-new.json @@ -0,0 +1,130 @@ +{ + "authority": "anAuthority", + "identifier": "dataset-one", + "persistentUrl": "http://dx.doi.org/10.5072/FK2/9", + "protocol": "chadham-house-rule", + "initialVersion": { + "metadataBlocks": { + "citation": { + "fields": [ + { + "value": "Rings of Trees and Other Observations", + "typeClass": "primitive", + "multiple": false, + "typeName": "title" + }, + { + "value": [ + { + "authorName": { + "value": "Tree, Tony", + "typeClass": "primitive", + "multiple": false, + "typeName": "authorName" + }, + "authorAffiliation": { + "value": "Trees Inc.", + "typeClass": "primitive", + "multiple": false, + "typeName": "authorAffiliation" + } + } + ], + "typeClass": "compound", + "multiple": true, + "typeName": "author" + }, + { + "value": [ + "tony@trees.com" + ], + "typeClass": "primitive", + "multiple": true, + "typeName": "distributorContact" + }, + { + "value": "Trees have rings. Trees can be tall.", + "typeClass": "primitive", + "multiple": false, + "typeName": "dsDescription" + }, + { + "value": [ + "trees", + "rings", + "tall" + ], + "typeClass": "primitive", + "multiple": true, + "typeName": "keyword" + }, + { + "value": [ + "Medicine, Health & Life Sciences" + ], + "typeClass": "controlledVocabulary", + "multiple": true, + "typeName": "subject" + }, + { + "value": "Many notes have been taken about trees over the years.", + "typeClass": "primitive", + "multiple": false, + "typeName": "notesText" + }, + { + "value": [ + { + "otherIdAgency": { + "value": "NSF", + "typeClass": "primitive", + "multiple": false, + "typeName": "otherIdAgency" + }, + "otherIdValue": { + "value": "NSF1234", + "typeClass": "primitive", + "multiple": false, + "typeName": "otherIdValue" + } + } + ], + "typeClass": "compound", + "multiple": true, + "typeName": "otherId" + }, + { + "value": [ + { + "contributorType": { + "value": "Data Collector", + "typeClass": "controlledVocabulary", + "multiple": false, + "typeName": "contributorType" + }, + "contributorName": { + "value": "Edward Trees Jr.", + "typeClass": "primitive", + "multiple": false, + "typeName": "contributorName" + } + } + ], + "typeClass": "compound", + "multiple": true, + "typeName": "contributor" + } + ], + "displayName": "Citation Metadata" + } + }, + "createTime": "2014-05-20 11:52:55 -04", + "UNF": "UNF", + "id": 1, + "versionNumber": 1, + "versionMinorNumber": 0, + "versionState": "DRAFT", + "distributionDate": "Distribution Date", + "productionDate": "Production Date" + } +} diff --git a/scripts/search/tests/highlighting b/scripts/search/tests/highlighting index 1d76815f4b7..8297a187f9e 100755 --- a/scripts/search/tests/highlighting +++ b/scripts/search/tests/highlighting @@ -1,34 +1,6 @@ #!/bin/bash -# We assume that scripts/search/tests/permissions came back clean. -# We assume you've added the bird and tree dataverses with this: -# -#cd scripts/search -#./populate -#./create -#exit -# -# We assume you've created a dataset as pete in the "Trees" dataverse at -# http://localhost:8080/dataverse.xhtml?id=11 -# with the following: -# Title: Rings of Trees and Other Observations -# Author: Tree, Tony -# Affiliation: Trees Inc. -# Contact E-mail: tony@trees.com -# Description: Trees have rings. Trees can be tall. -# Keyword: trees -# Keyword: rings -# Keyword: tall -# Subject: Medicine, Health & Life Sciences -# Notes: Many notes have been taken about trees over the years. -# -# We assume you edit the metadata of this dataset at +# We assume you add a file called "trees.png" to the dataset at # http://localhost:8080/dataset.xhtml?id=17 -# and add the following -# Contributor: -# Type: Data Collector -# Name: Edward Trees Jr. -# -# We assume you add a file called "trees.png" to this dataset # with a description of "Trees are lovely." # diff <(curl -s 'http://localhost:8080/api/search?q=trees&showrelevance=true&key=nick') scripts/search/tests/expected/highlighting-nick-trees diff --git a/scripts/search/tests/highlighting-setup01 b/scripts/search/tests/highlighting-setup01 new file mode 100755 index 00000000000..82218643f7e --- /dev/null +++ b/scripts/search/tests/highlighting-setup01 @@ -0,0 +1,7 @@ +#!/bin/bash +# We assume that scripts/search/tests/permissions came back clean. +# We assume you've added the bird and tree dataverses with this: +# +cd scripts/search +./populate +./create diff --git a/scripts/search/tests/highlighting-setup02 b/scripts/search/tests/highlighting-setup02 new file mode 100755 index 00000000000..85ba9c6ae7a --- /dev/null +++ b/scripts/search/tests/highlighting-setup02 @@ -0,0 +1,22 @@ +#!/bin/bash +# We assume you've added the bird and tree dataverses with highlighting-setup01 +# We run the command below to create http://localhost:8080/dataset.xhtml?id=17 +# in the "Trees" dataverse at http://localhost:8080/dataverse.xhtml?id=11 +# with the following: +# +# Title: Rings of Trees and Other Observations +# Author: Tree, Tony +# Affiliation: Trees Inc. +# Contact E-mail: tony@trees.com +# Description: Trees have rings. Trees can be tall. +# Keyword: trees +# Keyword: rings +# Keyword: tall +# Subject: Medicine, Health & Life Sciences +# Notes: Many notes have been taken about trees over the years. +# +# Contributor: +# Type: Data Collector +# Name: Edward Trees Jr. +# +curl -X POST -H "Content-type:application/json" -d @scripts/search/data/dataset01-create-new.json http://localhost:8080/api/dvs/11/datasets/?key=pete From e604e465747509948c6a2c2ff558586b44d8c417 Mon Sep 17 00:00:00 2001 From: Michael Bar-Sinai Date: Wed, 21 May 2014 13:02:31 -0400 Subject: [PATCH 04/74] Dataset version API endpoint now specifies x.y versioning, NOT the version numeric field --- scripts/api/readme.md | 4 ++-- .../edu/harvard/iq/dataverse/api/Datasets.java | 17 ++++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/scripts/api/readme.md b/scripts/api/readme.md index 8a3d2cf141e..9321b11f0aa 100644 --- a/scripts/api/readme.md +++ b/scripts/api/readme.md @@ -101,9 +101,9 @@ Delete the dataset whose id is passed. List versions of the dataset. - GET http://{{SERVER}}/api/datasets/{{id}}/versions/{{versionId}}?key={{apikey}} + GET http://{{SERVER}}/api/datasets/{{id}}/versions/{{versionNumber}}?key={{apikey}} -Show a version of the dataset. The `versionId` can be a number, or the values `:edit` for the edit version, and `:latest` for the latest one. +Show a version of the dataset. The `versionNumber` can be a specific version number (in the form of `major.minor`, e.g. `1.2` or `3.0`), or the values `:edit` for the edit version, and `:latest` for the latest one. The Dataset also include any metadata blocks the data might have. GET http://{{SERVER}}/api/datasets/{{id}}/versions/{{versionId}}/metadata?key={{apikey}} diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Datasets.java b/src/main/java/edu/harvard/iq/dataverse/api/Datasets.java index bae2547ed07..b85b7f0db27 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Datasets.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Datasets.java @@ -200,9 +200,9 @@ public Response getVersionMetadata( @PathParam("id") Long datasetId, @PathParam( } @GET - @Path("{id}/versions/{versionId}/metadata/{block}") + @Path("{id}/versions/{versionNumber}/metadata/{block}") public Response getVersionMetadataBlock( @PathParam("id") Long datasetId, - @PathParam("versionId") String versionId, + @PathParam("versionNumber") String versionNumber, @PathParam("block") String blockName, @QueryParam("key") String apiKey ) { DataverseUser u = userSvc.findByUserName(apiKey); @@ -214,7 +214,7 @@ public Response getVersionMetadataBlock( @PathParam("id") Long datasetId, if (ds == null) return errorResponse(Response.Status.NOT_FOUND, "dataset " + datasetId + " not found"); DatasetVersion dsv = null; - switch (versionId) { + switch (versionNumber) { case ":latest": dsv = ds.getLatestVersion(); break; @@ -223,15 +223,18 @@ public Response getVersionMetadataBlock( @PathParam("id") Long datasetId, break; default: try { - long versionNumericId = Long.parseLong(versionId); + String[] comps = versionNumber.split("\\."); + long majorVersion = Long.parseLong(comps[0]); + long minorVersion = comps.length > 1 ? Long.parseLong(comps[1]) : 0; for ( DatasetVersion aDsv : ds.getVersions() ) { - if ( aDsv.getId().equals(versionNumericId) ) { + if ( aDsv.getVersionNumber().equals(majorVersion) && + aDsv.getMinorVersionNumber().equals(minorVersion)) { dsv = aDsv; - break; // for, not while + break; // for, not switch } } } catch ( NumberFormatException nfe ) { - return errorResponse( Response.Status.BAD_REQUEST, "Illegal id number '" + versionId + "'"); + return errorResponse( Response.Status.BAD_REQUEST, "Illegal version number '" + versionNumber + "'. Values are :latest, :edit and x.y"); } break; } From 2dbe8834beacca88f05f299283c9f51356e03ffe Mon Sep 17 00:00:00 2001 From: Michael Bar-Sinai Date: Wed, 21 May 2014 13:17:27 -0400 Subject: [PATCH 05/74] Can now delete a permission from a role (closes #4012) --- src/main/java/edu/harvard/iq/dataverse/ManageRolesPage.java | 4 ++-- src/main/webapp/manage-roles.xhtml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/ManageRolesPage.java b/src/main/java/edu/harvard/iq/dataverse/ManageRolesPage.java index 75d4b654fd4..883948b8cac 100644 --- a/src/main/java/edu/harvard/iq/dataverse/ManageRolesPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/ManageRolesPage.java @@ -155,11 +155,11 @@ public void saveDataverse( ActionEvent e ) { public void saveRole( ActionEvent e ) { role.setOwner(getDataverse()); - role.permissions().clear(); + role.clearPermissions(); for ( String pmsnStr : getSelectedPermissions() ) { role.addPermission(Permission.valueOf(pmsnStr) ); } - setRole( rolesService.save(role) );; + setRole( rolesService.save(role) ); JH.addMessage(FacesMessage.SEVERITY_INFO, "Role '" + role.getName() + "' saved", ""); intent = Intent.LIST; } diff --git a/src/main/webapp/manage-roles.xhtml b/src/main/webapp/manage-roles.xhtml index 74347212286..93bac6ac5fc 100644 --- a/src/main/webapp/manage-roles.xhtml +++ b/src/main/webapp/manage-roles.xhtml @@ -138,7 +138,7 @@ layout="pageDirection"> From 725fe65f026b2ee5b8a7a50a3dbe57c416da483e Mon Sep 17 00:00:00 2001 From: sekmiller Date: Wed, 21 May 2014 17:08:43 -0400 Subject: [PATCH 06/74] Add Version difference functionality notes to display general differences. pop-up for details of adjacent versions. Allow for selection when 3 or more versions --- .../harvard/iq/dataverse/DatasetField.java | 12 + .../dataverse/DatasetFieldCompoundValue.java | 2 + .../dataverse/DatasetFieldValueValidator.java | 2 +- .../edu/harvard/iq/dataverse/DatasetPage.java | 76 +++- .../harvard/iq/dataverse/DatasetVersion.java | 25 +- .../dataverse/DatasetVersionDifference.java | 411 ++++++++++++++++++ .../dataverse/DatasetVersionServiceBean.java | 3 + src/main/webapp/dataset.xhtml | 217 +++++++-- 8 files changed, 709 insertions(+), 39 deletions(-) create mode 100644 src/main/java/edu/harvard/iq/dataverse/DatasetVersionDifference.java diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetField.java b/src/main/java/edu/harvard/iq/dataverse/DatasetField.java index 131705aa86d..28f88be3b16 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetField.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetField.java @@ -218,6 +218,18 @@ public String getDisplayValue() { return returnString; } + public String getCompoundDisplayValue() { + String returnString = ""; + for (DatasetFieldCompoundValue dscv : datasetFieldCompoundValues) { + for (DatasetField dsf : dscv.getChildDatasetFields()){ + for (String value : dsf.getValues()) { + returnString += (returnString.equals("") ? "" : "; ") + value; + } + } + } + return returnString; + } + public List getValues() { List returnList = new ArrayList(); if (!datasetFieldValues.isEmpty()) { diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldCompoundValue.java b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldCompoundValue.java index fc0a8bc85d8..7dc5ff00464 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldCompoundValue.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldCompoundValue.java @@ -17,6 +17,7 @@ import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; +import javax.persistence.OrderBy; /** * @@ -54,6 +55,7 @@ public static DatasetFieldCompoundValue createNewEmptyDatasetFieldCompoundValue( private DatasetField parentDatasetField; @OneToMany(mappedBy = "parentDatasetFieldCompoundValue", orphanRemoval=true, cascade = {CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST}) + @OrderBy("datasetFieldType ASC") private List childDatasetFields = new ArrayList(); public Long getId() { diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldValueValidator.java b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldValueValidator.java index 0ca72bff60e..59c0d113757 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldValueValidator.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldValueValidator.java @@ -110,7 +110,7 @@ public boolean isValid(DatasetFieldValue value, ConstraintValidatorContext conte } if (fieldType.equals("email")) { - Pattern p = Pattern.compile(".+@.+\\.[a-z]+"); + Pattern p = Pattern.compile("^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"); Matcher m = p.matcher(value.getValue()); boolean matchFound = m.matches(); if (!matchFound) { diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 9fb7fbbafcf..bd43aca8643 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -26,7 +26,9 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -50,6 +52,7 @@ import javax.validation.ValidatorFactory; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.GetMethod; +import org.primefaces.context.RequestContext; /** * @@ -108,6 +111,10 @@ public enum DisplayMode { private String datasetNextMajorVersion = "1.0"; private String datasetNextMinorVersion = ""; private String dropBoxSelection = ""; + private DatasetVersionDifference datasetVersionDifference; + private Map checked = new HashMap<>(); + + private String displayCitation; @@ -503,7 +510,7 @@ public String save() { } } - return "/dataset.xhtml?id=" + dataset.getId() + "&versionId=" + dataset.getLatestVersion().getId() + "&faces-redirect=true"; + return "/dataset.xhtml?id=" + dataset.getId() + "&versionId=" + dataset.getLatestVersion().getId() + "&faces-redirect=true"; } private String getFilesTempDirectory() { @@ -707,6 +714,71 @@ public List getVersionTabList() { public void setVersionTabList(List versionTabList) { this.versionTabList = versionTabList; } + + + private List selectedVersions; + public List getSelectedVersions() { + return selectedVersions; + } + + public void setSelectedVersions(List selectedVersions) { + this.selectedVersions = selectedVersions; + } + + + public DatasetVersionDifference getDatasetVersionDifference() { + return datasetVersionDifference; + } + + public void setDatasetVersionDifference(DatasetVersionDifference datasetVersionDifference) { + this.datasetVersionDifference = datasetVersionDifference; + } + + public void compareVersionDifferences() { + twoSelected = false; + RequestContext requestContext = RequestContext.getCurrentInstance(); + if (this.selectedVersions.size() != 2) { + twoSelected = false; + requestContext.execute("openCompareTwo();"); + } else { + twoSelected = true; + //order depends on order of selection - needs to be chronological order + if (this.selectedVersions.get(0).getId().intValue() > this.selectedVersions.get(1).getId().intValue() ){ + updateVersionDifferences(this.selectedVersions.get(0), this.selectedVersions.get(1)); + } else { + updateVersionDifferences(this.selectedVersions.get(1), this.selectedVersions.get(0)); + } + } + } + + public void updateVersionDifferences(DatasetVersion newVersion, DatasetVersion originalVersion) { + int count = 0; + int size = this.getDataset().getVersions().size(); + + if (originalVersion == null) { + for (DatasetVersion dsv : newVersion.getDataset().getVersions()) { + if (newVersion.equals(dsv)) { + if ((count + 1) < size) { + setDatasetVersionDifference(new DatasetVersionDifference(newVersion, newVersion.getDataset().getVersions().get(count + 1))); + break; + } + } + count++; + } + } else { + setDatasetVersionDifference(new DatasetVersionDifference(newVersion, originalVersion)); + } + } + + private boolean twoSelected; + + public boolean isTwoSelected() { + return twoSelected; + } + + public void setTwoSelected(boolean twoSelected) { + this.twoSelected = twoSelected; + } private boolean canIssueUpdateCommand() { try { @@ -733,8 +805,6 @@ private List resetVersionTabList() { } } return retList; - } } - } diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index 75cc3d1f4d3..34ba1ba9b8a 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -200,6 +200,29 @@ public void setReleaseTime(Date releaseTime) { public String getVersionNote() { return versionNote; } + + public List getDifferencesNotes(){ + List retList = new ArrayList(); + int count = 0; + int size = this.getDataset().getVersions().size(); + for (DatasetVersion dsv: this.getDataset().getVersions()){ + if (this.equals(dsv)){ + if ((count + 1) < size){ + DatasetVersionDifference dvd = new DatasetVersionDifference(this, this.getDataset().getVersions().get(count+1)); + return dvd.getNotes(); + } + } + count++; + } + String defaultNote; + if (this.isReleased()){ + defaultNote = "This is the first published version."; + } else { + defaultNote = "This is an unpublished draft."; + } + retList.add(defaultNote); + return retList; + } public void setVersionNote(String note) { if (note != null && note.length() > VERSION_NOTE_MAX_LENGTH) { @@ -346,7 +369,7 @@ public String getTitle() { } return retVal; } - + public String getProductionDate() { //todo get "Production Date" from datasetfieldvalue table return "Production Date"; diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersionDifference.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersionDifference.java new file mode 100644 index 00000000000..7242a5ff06b --- /dev/null +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersionDifference.java @@ -0,0 +1,411 @@ + +package edu.harvard.iq.dataverse; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * + * @author skraffmiller + */ +public class DatasetVersionDifference { + private DatasetVersion newVersion; + private DatasetVersion originalVersion; + private ListaddedDataAll = new ArrayList(); + private List addedFiles = new ArrayList(); + private List removedFiles = new ArrayList(); + private List changedFileMetadata = new ArrayList(); + private List addedData = new ArrayList(); + private List removedData = new ArrayList(); + private List changedData = new ArrayList(); + private List addedSummaryData = new ArrayList(); + private List removedSummaryData = new ArrayList(); + private List changedSummaryData = new ArrayList(); + + public DatasetVersionDifference(DatasetVersion newVersion, DatasetVersion originalVersion) { + + setOriginalVersion(originalVersion); + setNewVersion(newVersion); + //Compare Data + for (DatasetField dsfo : originalVersion.getDatasetFields()) { + boolean deleted = true; + for (DatasetField dsfn : newVersion.getDatasetFields()) { + if (dsfo.getDatasetFieldType().equals(dsfn.getDatasetFieldType())) { + deleted = false; + if (dsfo.getDatasetFieldType().isPrimitive()) { + if (!dsfo.getDatasetFieldType().getFieldType().equals("email") && !compareValuesPrimitive(dsfo, dsfn)) { + if (!dsfo.getDatasetFieldType().isDisplayOnCreate()) { + changedData.add(dsfo); + changedData.add(dsfn); + } else { + changedSummaryData.add(dsfo); + changedSummaryData.add(dsfn); + } + } + } else { + if (!compareValuesCompound(dsfo, dsfn)) { + if (!dsfo.getDatasetFieldType().isDisplayOnCreate()) { + changedData.add(dsfo); + changedData.add(dsfn); + } else { + changedSummaryData.add(dsfo); + changedSummaryData.add(dsfn); + } + } + } + break; + } + } + if (deleted) { + if (dsfo.getDatasetFieldType().isDisplayOnCreate()) { + removedSummaryData.add(dsfo); + } else { + removedData.add(dsfo); + } + } + } + for (DatasetField dsfn : newVersion.getDatasetFields()) { + boolean added = true; + for (DatasetField dsfo : originalVersion.getDatasetFields()) { + if (dsfo.getDatasetFieldType().equals(dsfn.getDatasetFieldType())) { + added = false; + break; + } + } + if (added) { + if (dsfn.getDatasetFieldType().isDisplayOnCreate()) { + addedSummaryData.add(dsfn); + } else { + addedData.add(dsfn); + } + } + } + + for (FileMetadata fmdo : originalVersion.getFileMetadatas()) { + boolean deleted = true; + for (FileMetadata fmdn : newVersion.getFileMetadatas()) { + if (fmdo.getDataFile().equals(fmdn.getDataFile())) { + deleted = false; + if (!compareFileMetadatas(fmdo, fmdn)) { + changedFileMetadata.add(fmdo); + changedFileMetadata.add(fmdn); + } + break; + } + } + if (deleted) { + removedFiles.add(fmdo); + } + } + + for (FileMetadata fmdn : newVersion.getFileMetadatas()) { + boolean added = true; + for (FileMetadata fmdo : originalVersion.getFileMetadatas()) { + if (fmdo.getDataFile().equals(fmdn.getDataFile())) { + added = false; + break; + } + } + if (added) { + addedFiles.add(fmdn); + } + } + + } + + + + private boolean compareFileMetadatas(FileMetadata fmdo, FileMetadata fmdn) { + + if (!(fmdo.getDescription().equals(fmdn.getDescription()))) { + return false; + } + if (!(fmdo.getCategory().equals(fmdn.getCategory()))) { + return false; + } + if (!(fmdo.getLabel().equals(fmdn.getLabel()))) { + return false; + } + + return true; + } + + private boolean compareValuesPrimitive(DatasetField originalField, DatasetField newField) { + + String originalValue = originalField.getDisplayValue(); + String newValue = newField.getDisplayValue(); + if (originalValue == null || newValue == null) { + return true; + } + return originalValue.equals(newValue); + + } + + private boolean compareValuesCompound(DatasetField originalField, DatasetField newField) { + String originalValue = ""; + String newValue = ""; + for (DatasetFieldCompoundValue datasetFieldCompoundValueNew : newField.getDatasetFieldCompoundValues()) { + for (DatasetField dsfn : datasetFieldCompoundValueNew.getChildDatasetFields()) { + newValue += dsfn.getDisplayValue() + ", "; + } + newValue += ";"; + } + for (DatasetFieldCompoundValue datasetFieldCompoundValueOriginal : originalField.getDatasetFieldCompoundValues()) { + for (DatasetField dsfn : datasetFieldCompoundValueOriginal.getChildDatasetFields()) { + originalValue += dsfn.getDisplayValue() + ", "; + } + originalValue += ";"; + } + + if (originalValue == null || newValue == null) { + return true; + } + return originalValue.equals(newValue); + + } + + public List getNotes(){ + String retString = ""; + List retList = new ArrayList(); + if (addedSummaryData.size() > 0) { + retString = " Summary data added "; + int count = 0; + for (DatasetField dsf : addedSummaryData) { + if (count == 0) { + retString += ":"; + } else { + retString += ";"; + } + retString += " " + dsf.getDatasetFieldType().getDisplayName(); + count++; + } + retList.add(retString); + } + if (removedSummaryData.size() > 0) { + retString = " Summary data deleted "; + int count = 0; + for (DatasetField dsf : removedSummaryData) { + if (count == 0) { + retString += ":"; + } else { + retString += ";"; + } + retString += " " + dsf.getDatasetFieldType().getDisplayName(); + count++; + } + retList.add(retString); + } + if (changedSummaryData.size() > 0) { + retString = " Summary data changed: "; + for (Iterator iter = changedSummaryData.iterator(); iter.hasNext();) { + DatasetField dsf = iter.next(); + retString += " " + dsf.getDatasetFieldType().getDisplayName() + "; "; + DatasetField dsfn = iter.next(); + } + retList.add(retString); + } + /* + for (Iterator iter = changedSummaryData.iterator(); iter.hasNext();) { + DatasetField dsf = iter.next(); + if (dsf.getDatasetFieldType().isPrimitive()) { + retString += " " + dsf.getDatasetFieldType().getDisplayName() + " from " + dsf.getDisplayValue(); + DatasetField dsfn = iter.next(); + retString += " to " + dsfn.getDisplayValue() + "; "; + } else { + retString += " " + dsf.getDatasetFieldType().getDisplayName() + " from " + dsf.getCompoundDisplayValue(); + DatasetField dsfn = iter.next(); + retString += " to " + dsfn.getCompoundDisplayValue() + "; "; + } + + }*/ + + if (addedData.size() > 0) { + retString = " Number of Additional Data added: " + addedData.size(); + retList.add(retString); + } + if (removedData.size() > 0) { + retString = " Number of Additional Data deleted: " + removedData.size() ; + retList.add(retString); + } + if (changedData.size() > 0) { + retString = " Number of Additional Data changed: " + changedData.size()/2 ; + retList.add(retString); + } + if (addedFiles.size() > 0) { + retString = " Number of Files added: " + addedFiles.size() ; + retList.add(retString); + } + if (removedFiles.size() > 0) { + retString = " Number of Files deleted: " + removedFiles.size() ; + retList.add(retString); + } + if (changedFileMetadata.size() > 0) { + retString = " Number of File Metadata changed: " + changedFileMetadata.size()/2 ; + retList.add(retString); + } + + return retList; + } + + public String getNote() { + String retString = ""; + if (addedSummaryData.size() > 0) { + retString += " Summary data added "; + int count = 0; + for (DatasetField dsf : addedSummaryData) { + if (count == 0) { + retString += ":"; + } else { + retString += ";"; + } + retString += " " + dsf.getDatasetFieldType().getDisplayName(); + count++; + } + } + if (removedSummaryData.size() > 0) { + retString += " Summary data deleted "; + int count = 0; + for (DatasetField dsf : removedSummaryData) { + if (count == 0) { + retString += ":"; + } else { + retString += ";"; + } + retString += " " + dsf.getDatasetFieldType().getDisplayName(); + count++; + } + } + if (changedSummaryData.size() > 0) { + retString += " Summary data changed: "; + for (Iterator iter = changedSummaryData.iterator(); iter.hasNext();) { + DatasetField dsf = iter.next(); + retString += " " + dsf.getDatasetFieldType().getDisplayName() + "; "; + DatasetField dsfn = iter.next(); + } + } + /* + for (Iterator iter = changedSummaryData.iterator(); iter.hasNext();) { + DatasetField dsf = iter.next(); + if (dsf.getDatasetFieldType().isPrimitive()) { + retString += " " + dsf.getDatasetFieldType().getDisplayName() + " from " + dsf.getDisplayValue(); + DatasetField dsfn = iter.next(); + retString += " to " + dsfn.getDisplayValue() + "; "; + } else { + retString += " " + dsf.getDatasetFieldType().getDisplayName() + " from " + dsf.getCompoundDisplayValue(); + DatasetField dsfn = iter.next(); + retString += " to " + dsfn.getCompoundDisplayValue() + "; "; + } + + }*/ + + if (addedData.size() > 0) { + retString += " Number of Additional Data added " + addedData.size()+ ";"; + } + if (removedData.size() > 0) { + retString += " Number of Additional Data deleted " + removedData.size() + ";"; + } + if (changedData.size() > 0) { + retString += " Number of Additional Data changed " + changedData.size()/2 + ";"; + } + if (addedFiles.size() > 0) { + retString += " Number of Files added " + addedFiles.size() + ";"; + } + if (removedFiles.size() > 0) { + retString += " Number of Files deleted " + removedFiles.size() + ";"; + } + if (changedFileMetadata.size() > 0) { + retString += " Number of File Metadata changed " + changedFileMetadata.size()/2 + ";"; + } + + return retString; + } + public List getAddedFiles() { + return addedFiles; + } + + public void setAddedFiles(List addedFiles) { + this.addedFiles = addedFiles; + } + + public List getRemovedFiles() { + return removedFiles; + } + + public void setRemovedFiles(List removedFiles) { + this.removedFiles = removedFiles; + } + + public List getAddedData() { + return addedData; + } + + public void setAddedData(List addedData) { + this.addedData = addedData; + } + + public List getRemovedData() { + return removedData; + } + + public void setRemovedData(List removedData) { + this.removedData = removedData; + } + + public List getChangedData() { + return changedData; + } + + public void setChangedData(List changedData) { + this.changedData = changedData; + } + + public List getAddedSummaryData() { + return addedSummaryData; + } + + public void setAddedSummaryData(List addedSummaryData) { + this.addedSummaryData = addedSummaryData; + } + + public List getRemovedSummaryData() { + return removedSummaryData; + } + + public void setRemovedSummaryData(List removedSummaryData) { + this.removedSummaryData = removedSummaryData; + } + + public List getChangedSummaryData() { + return changedSummaryData; + } + + public void setChangedSummaryData(List changedSummaryData) { + this.changedSummaryData = changedSummaryData; + } + + public DatasetVersion getNewVersion() { + return newVersion; + } + + public void setNewVersion(DatasetVersion newVersion) { + this.newVersion = newVersion; + } + + public DatasetVersion getOriginalVersion() { + return originalVersion; + } + + public void setOriginalVersion(DatasetVersion originalVersion) { + this.originalVersion = originalVersion; + } + + public List getChangedFileMetadata() { + return changedFileMetadata; + } + + public void setChangedFileMetadata(List changedFileMetadata) { + this.changedFileMetadata = changedFileMetadata; + } + +} diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersionServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersionServiceBean.java index 671a87efc1e..e2286ec9259 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersionServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersionServiceBean.java @@ -26,4 +26,7 @@ public DatasetVersion find(Object pk) { return (DatasetVersion) em.find(DatasetVersion.class, pk); } + + + } diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index b1080045ad7..4d9b3324069 100644 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -19,7 +19,23 @@ - + - + - -
- +
- + fileUploadListener="#{DatasetPage.handleFileUpload}" process="filesTable" update="filesTable" label="Select Files to Add" oncomplete="javascript:bind_bsui_components();"/> +