Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
1980c75
QDR-898 - support shoulders in generated DOIs
qqmyers Jan 27, 2018
94309e9
updates to test/warn about shoulders that contain the separator
qqmyers Jan 29, 2018
03b6317
comment update
qqmyers Apr 26, 2018
7d8b503
QDR-898 - to run with a database where all DOI shoulders have moved to
qqmyers May 4, 2018
d831b42
cleaner diff
qqmyers May 4, 2018
0b25d57
Removing DoiSeparator key since the authority:shoulder separator is
qqmyers May 15, 2018
356d37a
shoulder can contain a '/' - the findByGlobalId logic looks for the
qqmyers May 15, 2018
c77c8a9
comment update
qqmyers May 15, 2018
ddba6c5
Merge remote-tracking branch 'IQSS/develop' into 3583-DV-cannot-parse…
qqmyers May 16, 2018
4142d58
Merge remote-tracking branch 'IQSS/develop' into
qqmyers May 16, 2018
65c0c8d
remove doiSeparator key after merge with DOI for files code
qqmyers May 17, 2018
d986c4c
mixed case flag no longer needed
qqmyers May 17, 2018
f5b4e57
when parsing IDs should now look for first '/' separator, not the last.
qqmyers May 17, 2018
470af86
merge miss - this was deleted in develop after I branched.
qqmyers May 17, 2018
dc2893d
Separating the choice of identifier generation style for datasets and
qqmyers May 17, 2018
dded772
one more instance of doiSeparator
qqmyers May 17, 2018
a9cb711
Update test to expect shoulder as part of identifier
qqmyers May 17, 2018
7fc3b0f
shoulder support for datafiles and fix for uniqueid checks with shoulder
qqmyers May 17, 2018
54d43a4
Simplifying - no need for new cases
qqmyers May 17, 2018
e3a7eab
Single IdentifierGenerationStyle key and simplify prepend logic
qqmyers May 18, 2018
9347a47
hardcode id separator in AbstractIdServiceBean
qqmyers May 18, 2018
4917697
hardcode id separator as '/'
qqmyers May 18, 2018
30914c9
Merge remote-tracking branch 'IQSS/develop' into
qqmyers May 18, 2018
88f4a02
fixes per discussion
qqmyers May 19, 2018
c2c26bc
removing authority and protocol from dataset
qqmyers May 19, 2018
a3bcb9b
add statements to SQL upgrade script #3583 #898
pdurbin May 22, 2018
599a224
more table changes and new findByGlobalId query
qqmyers May 22, 2018
0c57f8a
don't create doiseparator column in dvobject
qqmyers May 22, 2018
31236d3
Add migration for non-shoulder authority
sekmiller May 22, 2018
59bbbae
change query to explicitly check for dtype
qqmyers May 22, 2018
508f13e
Merge branch '3583-DV-cannot-parse-DOIs-that-don't-have-a-separator-i…
qqmyers May 22, 2018
04b9dda
Remove identifier from Dataset
sekmiller May 23, 2018
9b7fe11
integrating/removing duplicate code...
qqmyers May 23, 2018
402ed59
if should use local variables, class vars not yet set
qqmyers May 24, 2018
b2b9e55
authority not set before authority check
qqmyers May 24, 2018
ed253f7
update comment
qqmyers May 24, 2018
2159050
#3583 Add updates to settings for DOI Shoulder and Authority
sekmiller May 25, 2018
83a76a0
remove :DoiSeparator, add :DoiShoulder (misnomer, affects handles) #3…
pdurbin May 25, 2018
cf7a720
Update documentation
qqmyers May 25, 2018
baa9052
changing name of DoiShoulder to Shoulder
qqmyers May 25, 2018
d497dee
don't set :Authority and :Shoulder in Harvard script #3583 #898
pdurbin May 31, 2018
5478470
'develop' into 3583-DV-cannot-parse-DOIs-that-don't-have-a-separator-…
pdurbin May 31, 2018
57896b7
Redo migration script to migrate doi to dvobject
sekmiller May 31, 2018
3198d52
doiseparator isn't used in dvobject
qqmyers May 31, 2018
1872f72
#3583 fix for generic separator
sekmiller May 31, 2018
bb4d64d
#3583 Add and remove doi separator from dvobject - for migration only
sekmiller May 31, 2018
db5ea2d
Update upgrade_v4.8.6_to_v4.9.0.sql
sekmiller May 31, 2018
715d4d8
check separator for null
sekmiller May 31, 2018
f646a82
Update upgrade_v4.8.6_to_v4.9.0.sql
sekmiller May 31, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 11 additions & 13 deletions doc/sphinx-guides/source/installation/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ Out of the box, Dataverse is configured for DOIs. Here are the configuration opt
- :ref:`:DoiProvider <:DoiProvider>`
- :ref:`:Protocol <:Protocol>`
- :ref:`:Authority <:Authority>`
- :ref:`:DoiSeparator <:DoiSeparator>`
- :ref:`:Shoulder <:Shoulder>`
- :ref:`:IdentifierGenerationStyle <:IdentifierGenerationStyle>` (optional)
- :ref:`:DataFilePIDFormat <:DataFilePIDFormat>` (optional)

Expand Down Expand Up @@ -552,7 +552,7 @@ See also these related database settings below:
- :ref:`:DoiProvider`
- :ref:`:Protocol`
- :ref:`:Authority`
- :ref:`:DoiSeparator`
- :ref:`:Shoulder`

.. _doi.username:

Expand Down Expand Up @@ -717,7 +717,7 @@ As of this writing "EZID" and "DataCite" are the only valid options. DoiProvider

``curl -X PUT -d EZID http://localhost:8080/api/admin/settings/:DoiProvider``

This setting relates to the ``:Protocol``, ``:Authority``, ``:DoiSeparator``, and ``:IdentifierGenerationStyle`` database settings below as well as the following JVM options:
This setting relates to the ``:Protocol``, ``:Authority``, ``:Shoulder``, and ``:IdentifierGenerationStyle`` database settings below as well as the following JVM options:

- :ref:`doi.baseurlstring`
- :ref:`doi.username`
Expand All @@ -741,25 +741,23 @@ Use the authority assigned to you by your DoiProvider or HandleProvider.

``curl -X PUT -d 10.xxxx http://localhost:8080/api/admin/settings/:Authority``

.. _:DoiSeparator:
.. _:Shoulder:

:DoiSeparator
+++++++++++++

It is recommended that you keep this as a slash ("/").
:Shoulder
++++++++++++

``curl -X PUT -d "/" http://localhost:8080/api/admin/settings/:DoiSeparator``
Out of the box, the DOI shoulder is set to "FK2/" but this is for testing only! When you apply for your DOI namespace, you may have requested a shoulder. The following is only an example and a trailing slash is optional.

**Note:** The name DoiSeparator is a misnomer. This setting is used by some **handles**-specific code too. It *must* be set to '/' when using handles.
``curl -X PUT -d "MyShoulder/" http://localhost:8080/api/admin/settings/:Shoulder``

.. _:IdentifierGenerationStyle:

:IdentifierGenerationStyle
++++++++++++++++++++++++++

By default, Dataverse generates a random 6 character string to use as the identifier
By default, Dataverse generates a random 6 character string, pre-pended by the Shoulder if set, to use as the identifier
for a Dataset. Set this to ``sequentialNumber`` to use sequential numeric values
instead. (the assumed default setting is ``randomString``).
instead (again pre-pended by the Shoulder if set). (the assumed default setting is ``randomString``).
In addition to this setting, a database sequence must be created in the database.
We provide the script below (downloadable :download:`here </_static/util/createsequence.sql>`).
You may need to make some changes to suit your system setup, see the comments for more information:
Expand All @@ -785,7 +783,7 @@ This setting controls the way that the "identifier" component of a file's persis

By default the identifier for a file is dependent on its parent dataset. For example, if the identifier of a dataset is "TJCLKP", the identifier for a file within that dataset will consist of the parent dataset's identifier followed by a slash ("/"), followed by a random 6 character string, yielding "TJCLKP/MLGWJO". Identifiers in this format are what you should expect if you leave ``:DataFilePIDFormat`` undefined or set it to ``DEPENDENT`` and have not changed the ``:IdentifierGenerationStyle`` setting from its default.

Alternatively, the indentifier for File PIDs can be configured to be independent of Dataset PIDs using the setting "``INDEPENDENT``". In this case, file PIDs will not contain the PIDs of their parent datasets, and their PIDs will be generated the exact same way that datasets' PIDs are, based on the ``:IdentifierGenerationStyle`` setting described above (random 6 character strings or sequential numbers).
Alternatively, the identifier for File PIDs can be configured to be independent of Dataset PIDs using the setting "``INDEPENDENT``". In this case, file PIDs will not contain the PIDs of their parent datasets, and their PIDs will be generated the exact same way that datasets' PIDs are, based on the ``:IdentifierGenerationStyle`` setting described above (random 6 character strings or sequential numbers, pre-pended by any shoulder).

The chart below shows examples from each possible combination of parameters from the two settings. ``:IdentifierGenerationStyle`` can be either ``randomString`` (the default) or ``sequentialNumber`` and ``:DataFilePIDFormat`` can be either ``DEPENDENT`` (the default) or ``INDEPENDENT``. In the examples below the "identifier" for the dataset is "TJCLKP" for "randomString" and "100001" for "sequentialNumber".

Expand Down
4 changes: 2 additions & 2 deletions scripts/api/setup-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ curl -X PUT -d yes "$SERVER/admin/settings/:AllowSignUp"
curl -X PUT -d /dataverseuser.xhtml?editMode=CREATE "$SERVER/admin/settings/:SignUpUrl"

curl -X PUT -d doi "$SERVER/admin/settings/:Protocol"
curl -X PUT -d 10.5072/FK2 "$SERVER/admin/settings/:Authority"
curl -X PUT -d 10.5072 "$SERVER/admin/settings/:Authority"
curl -X PUT -d "FK2/" "$SERVER/admin/settings/:Shoulder"
curl -X PUT -d EZID "$SERVER/admin/settings/:DoiProvider"
curl -X PUT -d / "$SERVER/admin/settings/:DoiSeparator"
curl -X PUT -d burrito $SERVER/admin/settings/BuiltinUsers.KEY
curl -X PUT -d localhost-only $SERVER/admin/settings/:BlockedApiPolicy
echo
Expand Down
3 changes: 3 additions & 0 deletions scripts/api/setup-optional-harvard.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
SERVER=http://localhost:8080/api

echo "Setting up Harvard-specific settings"
# :Authority and :Shoulder are commented out so this script can be used on test servers
#curl -X PUT -d 10.7910 "$SERVER/admin/settings/:Authority"
#curl -X PUT -d "DVN/" "$SERVER/admin/settings/:Shoulder"
echo "- Application Status header"
curl -s -X PUT -d 'Upgrade in progress...' $SERVER/admin/settings/:StatusMessageHeader
echo "- Application Status message"
Expand Down
127 changes: 71 additions & 56 deletions scripts/database/upgrades/upgrade_v4.8.6_to_v4.9.0.sql
Original file line number Diff line number Diff line change
@@ -1,56 +1,71 @@
ALTER TABLE externaltool ADD COLUMN type character varying(255);
ALTER TABLE externaltool ALTER COLUMN type SET NOT NULL;
-- Previously, the only explore tool was TwoRavens. We now persist the name of the tool.
UPDATE guestbookresponse SET downloadtype = 'TwoRavens' WHERE downloadtype = 'Explore';
ALTER TABLE filemetadata ADD COLUMN prov_freeform text;
-- ALTER TABLE datafile ADD COLUMN prov_cplid int;
ALTER TABLE datafile ADD COLUMN prov_entityname text;

-- Moves DOI fields from Dataset to DVObject
-- so that Identifiers may be added to DataFiles

ALTER TABLE dvobject ADD COLUMN
authority character varying(255),
ADD COLUMN doiseparator character varying(255),
ADD COLUMN globalidcreatetime timestamp without time zone,
ADD COLUMN identifierRegistered boolean,
ADD COLUMN identifier character varying(255),
ADD COLUMN protocol character varying(255);


UPDATE dvobject
SET authority=(SELECT dataset.authority
FROM dataset
WHERE dataset.id=dvobject.id AND dvobject.dtype='Dataset') where dvobject.dtype='Dataset';

UPDATE dvobject
SET doiseparator=(SELECT dataset.doiseparator
FROM dataset
WHERE dataset.id=dvobject.id AND dvobject.dtype='Dataset') where dvobject.dtype='Dataset';

UPDATE dvobject
SET globalidcreatetime=(SELECT dataset.globalidcreatetime
FROM dataset
WHERE dataset.id=dvobject.id AND dvobject.dtype='Dataset') where dvobject.dtype='Dataset';

UPDATE dvobject
SET identifierRegistered= true where globalidcreatetime is not null;

UPDATE dvobject
SET identifier=(SELECT dataset.identifier
FROM dataset
WHERE dataset.id=dvobject.id AND dvobject.dtype='Dataset') where dvobject.dtype='Dataset';

UPDATE dvobject
SET protocol=(SELECT dataset.protocol
FROM dataset
WHERE dataset.id=dvobject.id AND dvobject.dtype='Dataset') where dvobject.dtype='Dataset';

ALTER TABLE dataset ALTER identifier DROP NOT NULL;

ALTER TABLE dataset DROP COLUMN authority;
ALTER TABLE dataset DROP COLUMN doiseparator;
ALTER TABLE dataset DROP COLUMN globalidcreatetime;
ALTER TABLE dataset DROP COLUMN identifier;
ALTER TABLE dataset DROP COLUMN protocol;

ALTER TABLE externaltool ADD COLUMN type character varying(255);
ALTER TABLE externaltool ALTER COLUMN type SET NOT NULL;
-- Previously, the only explore tool was TwoRavens. We now persist the name of the tool.
UPDATE guestbookresponse SET downloadtype = 'TwoRavens' WHERE downloadtype = 'Explore';
ALTER TABLE filemetadata ADD COLUMN prov_freeform text;
-- ALTER TABLE datafile ADD COLUMN prov_cplid int;
ALTER TABLE datafile ADD COLUMN prov_entityname text;

-- Moves DOI fields from Dataset to DVObject
-- so that Identifiers may be added to DataFiles

ALTER TABLE dvobject ADD COLUMN
authority character varying(255),
ADD COLUMN globalidcreatetime timestamp without time zone,
ADD COLUMN doiseparator character varying(255),
ADD COLUMN identifierRegistered boolean,
ADD COLUMN identifier character varying(255),
ADD COLUMN protocol character varying(255);

--Migrate data from Dataset to DvObject
UPDATE dvobject
SET authority=(SELECT dataset.authority
FROM dataset
WHERE dataset.id=dvobject.id AND dvobject.dtype='Dataset') where dvobject.dtype='Dataset';

UPDATE dvobject
SET globalidcreatetime=(SELECT dataset.globalidcreatetime
FROM dataset
WHERE dataset.id=dvobject.id AND dvobject.dtype='Dataset') where dvobject.dtype='Dataset';

UPDATE dvobject
SET doiseparator=(SELECT dataset.doiseparator
FROM dataset
WHERE dataset.id=dvobject.id AND dvobject.dtype='Dataset') where dvobject.dtype='Dataset';

UPDATE dvobject
SET identifierRegistered= true where globalidcreatetime is not null;

UPDATE dvobject
SET identifier=(SELECT dataset.identifier
FROM dataset
WHERE dataset.id=dvobject.id AND dvobject.dtype='Dataset') where dvobject.dtype='Dataset';

UPDATE dvobject
SET protocol=(SELECT dataset.protocol
FROM dataset
WHERE dataset.id=dvobject.id AND dvobject.dtype='Dataset' ) where dvobject.dtype='Dataset';

--Once in DvObject re-parse identifier and authority
UPDATE dvobject SET identifier=substring(authority, strpos(authority,'/')+1) || doiseparator || identifier WHERE strpos(authority,'/')>0 ;
UPDATE dvobject SET authority=substring(authority from 0 for strpos(authority,'/')) WHERE strpos(authority,'/')>0;

ALTER TABLE dataset ALTER identifier DROP NOT NULL;

ALTER TABLE dataset DROP COLUMN authority;
ALTER TABLE dataset DROP COLUMN doiseparator;
ALTER TABLE dataset DROP COLUMN globalidcreatetime;
ALTER TABLE dataset DROP COLUMN identifier;
ALTER TABLE dataset DROP COLUMN protocol;

ALTER TABLE dvobject DROP COLUMN doiseparator;

--Add new setting into content for shoulder
INSERT INTO setting(name, content)
VALUES (':Shoulder', (SELECT substring(content, strpos(content,'/')+1) || '/' from setting where name = ':Authority'));

--strip shoulder from authority setting
UPDATE setting
SET content=(SELECT substring(content from 0 for strpos(content,'/'))
FROM setting
WHERE name=':Authority' and strpos(content,'/')>0) where name=':Authority';
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ public abstract class AbstractIdServiceBean implements IdServiceBean {
SystemConfig systemConfig;

@Override
public String getIdentifierForLookup(String protocol, String authority, String separator, String identifier) {
public String getIdentifierForLookup(String protocol, String authority, String identifier) {
logger.log(Level.FINE,"getIdentifierForLookup");
return protocol + ":" + authority + separator + identifier;
return protocol + ":" + authority + "/" + identifier;
}


Expand Down Expand Up @@ -96,7 +96,6 @@ public DvObject generateIdentifier(DvObject dvObject) {

String protocol = dvObject.getProtocol() == null ? settingsService.getValueForKey(SettingsServiceBean.Key.Protocol) : dvObject.getProtocol();
String authority = dvObject.getAuthority() == null ? settingsService.getValueForKey(SettingsServiceBean.Key.Authority) : dvObject.getAuthority();
String doiSeparator = dvObject.getDoiSeparator() == null ? settingsService.getValueForKey(SettingsServiceBean.Key.DoiSeparator) : dvObject.getDoiSeparator();
IdServiceBean idServiceBean = IdServiceBean.getBean(protocol, commandEngine.getContext());
if (dvObject.isInstanceofDataset()) {
dvObject.setIdentifier(datasetService.generateDatasetIdentifier((Dataset) dvObject, idServiceBean));
Expand All @@ -109,9 +108,6 @@ public DvObject generateIdentifier(DvObject dvObject) {
if (dvObject.getAuthority() == null) {
dvObject.setAuthority(authority);
}
if (dvObject.getDoiSeparator() == null) {
dvObject.setDoiSeparator(doiSeparator);
}
return dvObject;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,14 @@ public HashMap getIdentifierMetadata(DvObject dvObject) {
* Looks up the metadata for a Global Identifier
* @param protocol the identifier system, e.g. "doi"
* @param authority the namespace that the authority manages in the identifier system
* @param separator the string that separates authority from local identifier part
* @param identifier the local identifier part
* @return a Map of metadata. It is empty when the lookup failed, e.g. when
* the identifier does not exist.
*/
@Override
public HashMap<String, String> lookupMetadataFromIdentifier(String protocol, String authority, String separator, String identifier) {
public HashMap<String, String> lookupMetadataFromIdentifier(String protocol, String authority, String identifier) {
logger.log(Level.FINE,"lookupMetadataFromIdentifier");
String identifierOut = getIdentifierForLookup(protocol, authority, separator, identifier);
String identifierOut = getIdentifierForLookup(protocol, authority, identifier);
HashMap<String, String> metadata = new HashMap<>();
try {
metadata = doiDataCiteRegisterService.getMetadata(identifierOut);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,15 @@ public HashMap<String, String> getIdentifierMetadata(DvObject dvObject) {
* @param protocol the identifier system, e.g. "doi"
* @param authority the namespace that the authority manages in the
* identifier system
* @param separator the string that separates authority from local
* identifier part
* @param identifier the local identifier part
* @return a Map of metadata. It is empty when the lookup failed, e.g. when
* the identifier does not exist.
*/
@Override
public HashMap<String, String> lookupMetadataFromIdentifier(String protocol, String authority, String separator, String identifier) {
public HashMap<String, String> lookupMetadataFromIdentifier(String protocol, String authority, String identifier) {
logger.log(Level.FINE,"lookupMetadataFromIdentifier");
String identifierOut = getIdentifierForLookup(protocol, authority, separator, identifier);
String identifierOut = getIdentifierForLookup(protocol, authority, identifier);
HashMap<String, String> metadata = new HashMap<>();
try {
metadata = ezidService.getMetadata(identifierOut);
Expand Down Expand Up @@ -181,15 +180,15 @@ public void deleteIdentifier(DvObject dvObject) throws Exception {
updateIdentifierStatus(dvObject, "unavailable | withdrawn by author");
HashMap<String, String> metadata = new HashMap<>();
metadata.put("_target", "http://ezid.cdlib.org/id/" + dvObject.getProtocol() + ":" + dvObject.getAuthority()
+ dvObject.getDoiSeparator() + dvObject.getIdentifier());
+ "/" + dvObject.getIdentifier());
try {
modifyIdentifierTargetURL(dvObject);
if (dvObject instanceof Dataset ) {
Dataset dataset = (Dataset) dvObject;
for (DataFile df : dataset.getFiles()) {
metadata = new HashMap<>();
metadata.put("_target", "http://ezid.cdlib.org/id/" + df.getProtocol() + ":" + df.getAuthority()
+ df.getDoiSeparator() + df.getIdentifier());
+ "/" + df.getIdentifier());
modifyIdentifierTargetURL(df);
}
}
Expand Down
Loading