1
1
package edu .harvard .iq .dataverse .util ;
2
2
3
- /**
4
- * Eko Indarto, DANS
5
- * Vic Ding, DANS
6
- *
7
- * This file prepares the resources used in Signposting
8
- *
9
- * It requires correspondence configuration to function well.
10
- * The configuration key used is SignpostingConf.
11
- * It is a json structure shown below
12
- *
13
- * useDefaultFileType is an on/off switch during linkset creating time, it controls whether the default type is
14
- * used, which is always Dataset
15
- * {
16
- * "indetifier-schema": {"ORCID":"https://orcid.org/", "ISNI":"https://isni.org/isni/", "ScopusID":"https://www.scopus.com/authid/detail.uri?authorId="},
17
- * "license": {"CC0":"https://creativecommons.org/licenses/by/4.0/", "MIT": "https://url", "APACHE":"https://url"},
18
- * "cite-as": {"doi":"https://citation.crosscite.org/format?style=bibtex&doi=", "type":"application/vnd.datacite.datacite+json"},
19
- * "useDefaultFileType": true,
20
- * "defaultFileTypeValue": "https://schema.org/Dataset"
21
- * }
22
- *
23
- * The configuration can be modified during run time by the administrator.
24
- *
3
+ /*
4
+ Eko Indarto, DANS
5
+ Vic Ding, DANS
6
+
7
+ This file prepares the resources used in Signposting
8
+
9
+ It requires correspondence configuration to function well.
10
+ The configuration key used is SignpostingConf.
11
+ It is a json structure shown below
12
+
13
+ useDefaultFileType is an on/off switch during linkset creating time, it controls whether the default type is
14
+ used, which is always Dataset
15
+
16
+ The configuration can be modified during run time by the administrator.
25
17
*/
26
18
27
19
import edu .harvard .iq .dataverse .*;
@@ -48,13 +40,14 @@ public class SignpostingResources {
48
40
private static final Logger logger = Logger .getLogger (SignpostingResources .class .getCanonicalName ());
49
41
SystemConfig systemConfig ;
50
42
DatasetVersion workingDatasetVersion ;
51
- JsonObject idschemaJsonObj ;
52
43
JsonObject licJsonObj ;
53
- JsonObject citeAsJsonObj ;
44
+ JsonObject describedByJsonObj ;
54
45
Boolean useDefaultFileType ;
55
46
String defaultFileTypeValue ;
47
+ int maxAuthors ;
48
+ int maxItems ;
56
49
57
- public SignpostingResources (SystemConfig systemConfig , DatasetVersion workingDatasetVersion , String jsonSetting ){
50
+ public SignpostingResources (SystemConfig systemConfig , DatasetVersion workingDatasetVersion , String jsonSetting ) {
58
51
this .systemConfig = systemConfig ;
59
52
this .workingDatasetVersion = workingDatasetVersion ;
60
53
if (jsonSetting == null ) {
@@ -63,46 +56,47 @@ public SignpostingResources(SystemConfig systemConfig, DatasetVersion workingDat
63
56
JsonReader jsonReader = Json .createReader (new StringReader (jsonSetting ));
64
57
JsonObject spJsonSetting = jsonReader .readObject ();
65
58
jsonReader .close ();
66
- idschemaJsonObj = spJsonSetting .getJsonObject ("indetifier-schema" );
67
59
licJsonObj = spJsonSetting .getJsonObject ("license" );
68
- citeAsJsonObj = spJsonSetting .getJsonObject ("cite-as " );
60
+ describedByJsonObj = spJsonSetting .getJsonObject ("describedby " );
69
61
useDefaultFileType = spJsonSetting .getBoolean ("useDefaultFileType" , true );
70
62
defaultFileTypeValue = spJsonSetting .getString ("defaultFileTypeValue" , "https://schema.org/Dataset" );
63
+ maxAuthors = spJsonSetting .getInt ("maxAuthors" , 5 );
64
+ maxItems = spJsonSetting .getInt ("maxItems" , 5 );
71
65
}
72
66
73
67
/**
74
68
* Get identifier schema for each author
75
69
*
76
- * Author may have identifiers from different providers
77
- * ORCID: the url format is https://orcid.org/:id
78
- * ISNI: the url format is https://isni.org/isni/:id
79
- * ScopusID: the url format is https://www.scopus.com/authid/detail.uri?authorId=:id
80
- * VIAF: the url format is http://viaf.org/viaf/:id
81
- *
82
70
* For example:
83
- * if author has VIAF
84
- * Link: <http://viaf.org/viaf/:id/>; rel="author"
71
+ * if author has VIAF
72
+ * Link: <http://viaf.org/viaf/:id/>; rel="author"
85
73
*
86
- * @param datasetAuthors
87
- * @return
74
+ * @param datasetAuthors list of all DatasetAuthor object
75
+ * @return all the non empty author links in a string
88
76
*/
89
77
private String getIdentifierSchema (List <DatasetAuthor > datasetAuthors ) {
90
- StringBuilder sb = new StringBuilder () ;
78
+ String singleAuthorString ;
91
79
String identifierSchema = "" ;
92
80
93
- for (DatasetAuthor da :datasetAuthors ){
94
- if (da .getIdValue () != null && !da .getIdValue ().isEmpty ()) {
95
- sb .append ("<" ).
96
- append (idschemaJsonObj .getString (da .getIdType ())).
97
- append (da .getIdValue ()).
98
- append (">;rel=\" author\" " );
99
- if (identifierSchema == "" ) {
100
- identifierSchema = sb .toString ();
81
+ for (DatasetAuthor da : datasetAuthors ) {
82
+ logger .info (String .format (
83
+ "idtype: %s; idvalue: %s, affiliation: %s; identifierUrl: %s" ,
84
+ da .getIdType (),
85
+ da .getIdValue (),
86
+ da .getAffiliation (),
87
+ da .getIdentifierAsUrl ()
88
+ ));
89
+ if (da .getIdentifierAsUrl () != null && !da .getIdentifierAsUrl ().trim ().isEmpty ()) {
90
+ singleAuthorString = "<" + da .getIdentifierAsUrl () + ">;rel=\" author\" " ;
91
+ if (Objects .equals (identifierSchema , "" )) {
92
+ identifierSchema = singleAuthorString ;
101
93
} else {
102
- identifierSchema = String .join ("," , identifierSchema , sb . toString () );
94
+ identifierSchema = String .join ("," , identifierSchema , singleAuthorString );
103
95
}
104
96
}
105
97
}
98
+
99
+ logger .info (String .format ("identifierSchema: %s" , identifierSchema ));
106
100
return identifierSchema ;
107
101
}
108
102
@@ -111,7 +105,7 @@ private String getIdentifierSchema(List<DatasetAuthor> datasetAuthors) {
111
105
*
112
106
* @return comma delimited string
113
107
*/
114
- public String getLinks (){
108
+ public String getLinks () {
115
109
List <String > valueList = new LinkedList <>();
116
110
Dataset ds = workingDatasetVersion .getDataset ();
117
111
@@ -125,8 +119,8 @@ public String getLinks(){
125
119
valueList .add (citeAs );
126
120
}
127
121
128
- String describedby = "<" + citeAsJsonObj .getString (ds .getProtocol ()) + ds .getAuthority () + "/"
129
- + ds .getIdentifier () + ">;rel=\" describedby\" " + "; type=\" " + citeAsJsonObj .getString ("type" ) + "\" " ;
122
+ String describedby = "<" + describedByJsonObj .getString (ds .getProtocol ()) + ds .getAuthority () + "/"
123
+ + ds .getIdentifier () + ">;rel=\" describedby\" " + ";type=\" " + describedByJsonObj .getString ("type" ) + "\" " ;
130
124
describedby += ",<" + systemConfig .getDataverseSiteUrl () + "/api/datasets/export?exporter=schema.org&persistentId="
131
125
+ ds .getProtocol () + ":" + ds .getAuthority () + "/" + ds .getIdentifier () + ">;rel=\" describedby\" " + ";type=\" application/json+ld\" " ;
132
126
valueList .add (describedby );
@@ -135,8 +129,8 @@ public String getLinks(){
135
129
valueList .add (type );
136
130
137
131
// TODO: support only CC0 now, should add flexible license support when flex-terms is ready
138
- String license = "" ;
139
- if (workingDatasetVersion .getTermsOfUseAndAccess ().getLicense () == TermsOfUseAndAccess .License .CC0 ){
132
+ String license ;
133
+ if (workingDatasetVersion .getTermsOfUseAndAccess ().getLicense () == TermsOfUseAndAccess .License .CC0 ) {
140
134
// On the current Dataverse, only None and CC0. In the signposting protocol: cardinality is 1
141
135
license = "<https://creativecommons.org/publicdomain/zero/1.0/>;rel=\" license\" " ;
142
136
valueList .add (license );
@@ -151,42 +145,52 @@ public String getLinks(){
151
145
return String .join (", " , valueList );
152
146
}
153
147
154
- private JsonArrayBuilder getIdentifiersSchema (List <DatasetAuthor > datasetAuthors ){
148
+ private JsonArrayBuilder getIdentifiersSchema (List <DatasetAuthor > datasetAuthors ) {
149
+ if (datasetAuthors .size () > maxAuthors ) return null ;
155
150
JsonArrayBuilder authors = Json .createArrayBuilder ();
156
- for (DatasetAuthor da :datasetAuthors ){
157
- if (da .getIdValue () != null && !da .getIdValue ().isEmpty ()) {
158
- authors .add (jsonObjectBuilder ().add ("href" , idschemaJsonObj .getString (da .getIdType ()) + da .getIdValue ()));
151
+ boolean returnNull = true ;
152
+ for (DatasetAuthor da : datasetAuthors ) {
153
+ if (da .getIdentifierAsUrl () != null && !da .getIdentifierAsUrl ().trim ().isEmpty ()) {
154
+ authors .add (jsonObjectBuilder ().add ("href" , da .getIdentifierAsUrl ()));
155
+ returnNull = false ;
159
156
}
160
157
}
161
- return authors ;
158
+ return returnNull ? null : authors ;
159
+ }
160
+
161
+ private JsonArrayBuilder getJsonItems (List <FileMetadata > fms ) {
162
+ if (fms .size () > maxItems ) return null ;
163
+ JsonArrayBuilder items = Json .createArrayBuilder ();
164
+ for (FileMetadata fm : fms ) {
165
+ DataFile df = fm .getDataFile ();
166
+ items .add (jsonObjectBuilder ().add ("href" , getPublicDownloadUrl (df )).add ("type" , df .getContentType ()));
167
+ }
168
+
169
+ return items ;
162
170
}
163
171
164
172
public JsonArrayBuilder getJsonLinkset () {
165
173
Dataset ds = workingDatasetVersion .getDataset ();
166
- String landingPage = systemConfig .getDataverseSiteUrl () + "/dataset.xhtml?persistentId=" + ds .getProtocol () + ":" + ds .getAuthority () + "/" + ds .getIdentifier () ;
174
+ String landingPage = systemConfig .getDataverseSiteUrl () + "/dataset.xhtml?persistentId=" + ds .getProtocol () + ":" + ds .getAuthority () + "/" + ds .getIdentifier ();
167
175
JsonArrayBuilder authors = getIdentifiersSchema (workingDatasetVersion .getDatasetAuthors ());
168
176
169
- JsonArrayBuilder items = Json .createArrayBuilder ();
170
-
171
177
List <FileMetadata > fms = workingDatasetVersion .getFileMetadatas ();
172
- for (FileMetadata fm :fms ){
173
- DataFile df = fm .getDataFile ();
174
- items .add (jsonObjectBuilder ().add ("href" , getPublicDownloadUrl (df )).add ("type" ,df .getContentType ()));
175
- }
178
+ JsonArrayBuilder items = getJsonItems (fms );
176
179
177
180
String license = "" ;
178
- if (workingDatasetVersion .getTermsOfUseAndAccess ().getLicense () == TermsOfUseAndAccess .License .CC0 ){
181
+ if (workingDatasetVersion .getTermsOfUseAndAccess ().getLicense () == TermsOfUseAndAccess .License .CC0 ) {
179
182
license = licJsonObj .getString (TermsOfUseAndAccess .License .CC0 .name ());
180
183
}
181
184
182
185
JsonArrayBuilder mediaTypes = Json .createArrayBuilder ();
183
186
mediaTypes .add (
184
187
jsonObjectBuilder ().add (
185
188
"href" ,
186
- citeAsJsonObj .getJsonObject (ds .getProtocol () + ds .getAuthority () + "/" + ds .getIdentifier ())
189
+ describedByJsonObj .getString (ds .getProtocol ()) + ds .getAuthority () + "/"
190
+ + ds .getIdentifier ()
187
191
).add (
188
192
"type" ,
189
- citeAsJsonObj .getString ("type" )
193
+ describedByJsonObj .getString ("type" )
190
194
)
191
195
);
192
196
@@ -199,35 +203,45 @@ public JsonArrayBuilder getJsonLinkset() {
199
203
"application/json+ld"
200
204
)
201
205
);
202
- JsonArrayBuilder linkset = Json .createArrayBuilder ();
206
+ JsonArrayBuilder linksetJsonObj = Json .createArrayBuilder ();
203
207
JsonObjectBuilder mandatory = jsonObjectBuilder ()
204
208
.add ("anchor" , landingPage )
205
209
.add ("cite-as" , Json .createArrayBuilder ().add (jsonObjectBuilder ().add ("href" , ds .getPersistentURL ())))
206
- .add ("type" , Json .createArrayBuilder ().add (jsonObjectBuilder ().add ("href" , "https://schema.org/AboutPage" )))
207
- .add ("author" , authors )
208
- .add ("license" , jsonObjectBuilder ().add ("href" , license ))
209
- .add ("item" , items ).add ("describedby" , mediaTypes );
210
- linkset .add (mandatory );
210
+ .add ("type" , Json .createArrayBuilder ().add (jsonObjectBuilder ().add ("href" , "https://schema.org/AboutPage" )));
211
+
212
+ if (authors != null ) {
213
+ mandatory .add ("author" , authors );
214
+ }
215
+ if (license != null && !license .trim ().isEmpty ()) {
216
+ mandatory .add ("license" , jsonObjectBuilder ().add ("href" , license ));
217
+ }
218
+ if (!mediaTypes .toString ().trim ().isEmpty ()) {
219
+ mandatory .add ("describedby" , mediaTypes );
220
+ }
221
+ if (items != null ) {
222
+ mandatory .add ("item" , items );
223
+ }
224
+ linksetJsonObj .add (mandatory );
211
225
212
226
if (useDefaultFileType ) {
213
- for (FileMetadata fm : fms ){
227
+ for (FileMetadata fm : fms ) {
214
228
DataFile df = fm .getDataFile ();
215
229
JsonObjectBuilder itemAnchor = jsonObjectBuilder ().add ("anchor" , getPublicDownloadUrl (df ));
216
230
itemAnchor .add ("collection" , Json .createArrayBuilder ().add (jsonObjectBuilder ()
217
231
.add ("href" , landingPage )).add (jsonObjectBuilder ().add ("type" , defaultFileTypeValue )));
218
- linkset .add (itemAnchor );
232
+ linksetJsonObj .add (itemAnchor );
219
233
}
220
234
} else {
221
- for (FileMetadata fm : fms ){
235
+ for (FileMetadata fm : fms ) {
222
236
DataFile df = fm .getDataFile ();
223
237
JsonObjectBuilder itemAnchor = jsonObjectBuilder ().add ("anchor" , getPublicDownloadUrl (df ));
224
238
itemAnchor .add ("collection" , Json .createArrayBuilder ().add (jsonObjectBuilder ()
225
239
.add ("href" , landingPage )));
226
- linkset .add (itemAnchor );
240
+ linksetJsonObj .add (itemAnchor );
227
241
}
228
242
}
229
243
230
- return linkset ;
244
+ return linksetJsonObj ;
231
245
}
232
246
233
247
@@ -240,7 +254,7 @@ private String getPublicDownloadUrl(DataFile dataFile) {
240
254
}
241
255
242
256
if (storageIO instanceof SwiftAccessIO ) {
243
- String fileDownloadUrl = null ;
257
+ String fileDownloadUrl ;
244
258
SwiftAccessIO <DataFile > swiftIO = (SwiftAccessIO <DataFile >) storageIO ;
245
259
try {
246
260
swiftIO .open ();
@@ -249,7 +263,7 @@ private String getPublicDownloadUrl(DataFile dataFile) {
249
263
}
250
264
251
265
//if its a public install, lets just give users the permanent URL!
252
- if (systemConfig .isPublicInstall ()){
266
+ if (systemConfig .isPublicInstall ()) {
253
267
fileDownloadUrl = swiftIO .getRemoteUrl ();
254
268
} else {
255
269
//TODO: if a user has access to this file, they should be given the swift url
0 commit comments