• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IQSS / dataverse / #23953

05 Dec 2024 02:30PM UTC coverage: 22.583% (+0.01%) from 22.572%
#23953

Pull #10790

github

web-flow
Merge 7317ac969 into a36db2d7d
Pull Request #10790: fix: issues in exporters and citations for PermaLink/non-DOI PIDs

48 of 69 new or added lines in 7 files covered. (69.57%)

1 existing line in 1 file now uncovered.

19559 of 86609 relevant lines covered (22.58%)

0.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.79
/src/main/java/edu/harvard/iq/dataverse/export/ddi/DdiExportUtil.java
1
package edu.harvard.iq.dataverse.export.ddi;
2

3
import com.google.gson.Gson;
4

5
import edu.harvard.iq.dataverse.ControlledVocabularyValue;
6
import edu.harvard.iq.dataverse.DatasetFieldConstant;
7
import edu.harvard.iq.dataverse.DvObjectContainer;
8
import edu.harvard.iq.dataverse.GlobalId;
9
import edu.harvard.iq.dataverse.api.dto.DatasetDTO;
10
import edu.harvard.iq.dataverse.api.dto.DatasetVersionDTO;
11
import edu.harvard.iq.dataverse.api.dto.FieldDTO;
12
import edu.harvard.iq.dataverse.api.dto.FileDTO;
13
import edu.harvard.iq.dataverse.api.dto.MetadataBlockDTO;
14

15
import static edu.harvard.iq.dataverse.export.DDIExportServiceBean.LEVEL_FILE;
16
import static edu.harvard.iq.dataverse.export.DDIExportServiceBean.NOTE_SUBJECT_TAG;
17
import static edu.harvard.iq.dataverse.export.DDIExportServiceBean.NOTE_SUBJECT_UNF;
18
import static edu.harvard.iq.dataverse.export.DDIExportServiceBean.NOTE_SUBJECT_FILEDESCRIPTION;
19
import static edu.harvard.iq.dataverse.export.DDIExportServiceBean.NOTE_TYPE_TAG;
20
import static edu.harvard.iq.dataverse.export.DDIExportServiceBean.NOTE_TYPE_UNF;
21
import static edu.harvard.iq.dataverse.export.DDIExportServiceBean.NOTE_TYPE_FILEDESCRIPTION;
22
import edu.harvard.iq.dataverse.export.DDIExporter;
23
import edu.harvard.iq.dataverse.pidproviders.PidUtil;
24
import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
25

26

27
import edu.harvard.iq.dataverse.util.SystemConfig;
28
import edu.harvard.iq.dataverse.util.json.JsonUtil;
29
import edu.harvard.iq.dataverse.util.xml.XmlPrinter;
30
import edu.harvard.iq.dataverse.util.xml.XmlWriterUtil;
31

32
import java.io.ByteArrayOutputStream;
33
import java.io.IOException;
34
import java.io.OutputStream;
35
import java.nio.file.Files;
36
import java.nio.file.Paths;
37
import java.time.LocalDate;
38
import java.util.*;
39
import java.util.Map.Entry;
40
import java.util.logging.Level;
41
import java.util.logging.Logger;
42
import jakarta.ejb.EJB;
43
import jakarta.json.Json;
44
import jakarta.json.JsonArray;
45
import jakarta.json.JsonArrayBuilder;
46
import jakarta.json.JsonObject;
47
import jakarta.json.JsonString;
48
import jakarta.json.JsonValue;
49
import javax.xml.stream.XMLOutputFactory;
50
import javax.xml.stream.XMLStreamException;
51
import javax.xml.stream.XMLStreamWriter;
52

53
import javax.xml.parsers.DocumentBuilder;
54
import javax.xml.parsers.DocumentBuilderFactory;
55
import javax.xml.parsers.ParserConfigurationException;
56
import org.xml.sax.SAXException;
57
import org.w3c.dom.Document;
58
import org.apache.commons.lang3.StringUtils;
59

60
// For write operation
61
import javax.xml.transform.Transformer;
62
import javax.xml.transform.TransformerException;
63
import javax.xml.transform.TransformerFactory;
64
import javax.xml.transform.TransformerConfigurationException;
65
import javax.xml.transform.dom.DOMSource;
66
import javax.xml.transform.stream.StreamSource;
67
import javax.xml.transform.stream.StreamResult;
68
import java.io.InputStream;
69

70
public class DdiExportUtil {
×
71

72
    private static final Logger logger = Logger.getLogger(DdiExportUtil.class.getCanonicalName());
1✔
73
    public static final String NOTE_TYPE_TERMS_OF_USE = "DVN:TOU";
74
    public static final String NOTE_TYPE_TERMS_OF_ACCESS = "DVN:TOA";
75
    public static final String NOTE_TYPE_DATA_ACCESS_PLACE = "DVN:DAP";
76

77

78
    public static final String LEVEL_DV = "dv";
79

80
    
81
    static SettingsServiceBean settingsService;
82
    
83
    public static final String NOTE_TYPE_CONTENTTYPE = "DATAVERSE:CONTENTTYPE";
84
    public static final String NOTE_SUBJECT_CONTENTTYPE = "Content/MIME Type";
85
    public static final String CITATION_BLOCK_NAME = "citation";
86

87
    //Some tests don't send real PIDs that can be parsed
88
    //Use constant empty PID in these cases
89
    private static final String EMPTY_PID = "null:nullnullnull";
90

91
    public static String datasetDtoAsJson2ddi(String datasetDtoAsJson) {
92
        Gson gson = new Gson();
1✔
93
        DatasetDTO datasetDto = gson.fromJson(datasetDtoAsJson, DatasetDTO.class);
1✔
94
        try {
95
            return dto2ddi(datasetDto);
1✔
96
        } catch (XMLStreamException ex) {
×
97
            Logger.getLogger(DdiExportUtil.class.getName()).log(Level.SEVERE, null, ex);
×
98
            return null;
×
99
        }
100
    }
101
    
102
    // "short" ddi, without the "<fileDscr>"  and "<dataDscr>/<var>" sections:
103
    public static void datasetJson2ddi(JsonObject datasetDtoAsJson, OutputStream outputStream) throws XMLStreamException {
104
        logger.fine(JsonUtil.prettyPrint(datasetDtoAsJson.toString()));
×
105
        Gson gson = new Gson();
×
106
        DatasetDTO datasetDto = gson.fromJson(datasetDtoAsJson.toString(), DatasetDTO.class);
×
107
        dtoddi(datasetDto, outputStream);
×
108
    }
×
109
    
110
    private static String dto2ddi(DatasetDTO datasetDto) throws XMLStreamException {
111
        OutputStream outputStream = new ByteArrayOutputStream();
1✔
112
        dtoddi(datasetDto, outputStream);
1✔
113
        String xml = outputStream.toString();
1✔
114
        return XmlPrinter.prettyPrintXml(xml);
1✔
115
    }
116
    
117
    private static void dtoddi(DatasetDTO datasetDto, OutputStream outputStream) throws XMLStreamException {
118
        XMLStreamWriter xmlw = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream);
1✔
119
        xmlw.writeStartElement("codeBook");
1✔
120
        xmlw.writeDefaultNamespace("ddi:codebook:2_5");
1✔
121
        xmlw.writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
1✔
122
        xmlw.writeAttribute("xsi:schemaLocation", DDIExporter.DEFAULT_XML_NAMESPACE + " " + DDIExporter.DEFAULT_XML_SCHEMALOCATION);
1✔
123
        xmlw.writeAttribute("version", DDIExporter.DEFAULT_XML_VERSION);
1✔
124
        if(DvObjectContainer.isMetadataLanguageSet(datasetDto.getMetadataLanguage())) {
1✔
125
            xmlw.writeAttribute("xml:lang", datasetDto.getMetadataLanguage());
1✔
126
        }
127
        createStdyDscr(xmlw, datasetDto);
1✔
128
        createOtherMats(xmlw, datasetDto.getDatasetVersion().getFiles());
1✔
129
        xmlw.writeEndElement(); // codeBook
1✔
130
        xmlw.flush();
1✔
131
    }
1✔
132

133
    
134
    // "full" ddi, with the the "<fileDscr>"  and "<dataDscr>/<var>" sections: 
135
    public static void datasetJson2ddi(JsonObject datasetDtoAsJson, JsonArray fileDetails, OutputStream outputStream) throws XMLStreamException {
136
        logger.fine(JsonUtil.prettyPrint(datasetDtoAsJson.toString()));
1✔
137
        Gson gson = new Gson();
1✔
138
        DatasetDTO datasetDto = gson.fromJson(datasetDtoAsJson.toString(), DatasetDTO.class);
1✔
139
        
140
        XMLStreamWriter xmlw = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream);
1✔
141
        xmlw.writeStartElement("codeBook");
1✔
142
        xmlw.writeDefaultNamespace("ddi:codebook:2_5");
1✔
143
        xmlw.writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
1✔
144
        xmlw.writeAttribute("xsi:schemaLocation", DDIExporter.DEFAULT_XML_NAMESPACE + " " + DDIExporter.DEFAULT_XML_SCHEMALOCATION);
1✔
145
        xmlw.writeAttribute("version", DDIExporter.DEFAULT_XML_VERSION);
1✔
146
        if(DvObjectContainer.isMetadataLanguageSet(datasetDto.getMetadataLanguage())) {
1✔
147
            xmlw.writeAttribute("xml:lang", datasetDto.getMetadataLanguage());
1✔
148
        }
149
        createStdyDscr(xmlw, datasetDto);
1✔
150
        createFileDscr(xmlw, fileDetails);
1✔
151
        createDataDscr(xmlw, fileDetails);
1✔
152
        createOtherMatsFromFileMetadatas(xmlw, fileDetails);
1✔
153
        xmlw.writeEndElement(); // codeBook
1✔
154
        xmlw.flush();
1✔
155
    }
1✔
156

157
    /**
158
     * @todo This is just a stub, copied from DDIExportServiceBean. It should
159
     * produce valid DDI based on
160
     * http://guides.dataverse.org/en/latest/developers/tools.html#msv but it is
161
     * incomplete and will be worked on as part of
162
     * https://github.com/IQSS/dataverse/issues/2579 . We'll want to reference
163
     * the DVN 3.x code for creating a complete DDI.
164
     *
165
     * @todo Rename this from "study" to "dataset".
166
     */
167
    private static void createStdyDscr(XMLStreamWriter xmlw, DatasetDTO datasetDto) throws XMLStreamException {
168
        DatasetVersionDTO version = datasetDto.getDatasetVersion();
1✔
169
        String persistentProtocol = datasetDto.getProtocol();
1✔
170
        String persistentAgency = persistentProtocol;
1✔
171

172
        String persistentAuthority = datasetDto.getAuthority();
1✔
173
        String persistentId = datasetDto.getIdentifier();
1✔
174

175
        GlobalId pid = PidUtil.parseAsGlobalID(persistentProtocol, persistentAuthority, persistentId);
1✔
176
        String pidUri, pidString;
177
        if(pid != null) {
1✔
178
            pidUri = pid.asURL();
1✔
179
            pidString = pid.asString();
1✔
180
        } else {
181
            pidUri = EMPTY_PID;
1✔
182
            pidString = EMPTY_PID;
1✔
183
        }
184
        // The "persistentAgency" tag is used for the "agency" attribute of the 
185
        // <IDNo> ddi section; back in the DVN3 days we used "handle" and "DOI" 
186
        // for the 2 supported protocols, respectively. For the sake of backward
187
        // compatibility, we should probably stick with these labels: (-- L.A. 4.5)
188
        if ("hdl".equals(persistentAgency)) { 
1✔
189
            persistentAgency = "handle";
×
190
        } else if ("doi".equals(persistentAgency)) {
1✔
191
            persistentAgency = "DOI";
1✔
192
        }
193
        
194
        //docDesc Block
195
        writeDocDescElement (xmlw, datasetDto);
1✔
196
        //stdyDesc Block
197
        xmlw.writeStartElement("stdyDscr");
1✔
198
        xmlw.writeStartElement("citation");
1✔
199
        xmlw.writeStartElement("titlStmt");
1✔
200
       
201
        XmlWriterUtil.writeFullElement(xmlw, "titl", XmlWriterUtil.dto2Primitive(version, DatasetFieldConstant.title), datasetDto.getMetadataLanguage());
1✔
202
        XmlWriterUtil.writeFullElement(xmlw, "subTitl", XmlWriterUtil.dto2Primitive(version, DatasetFieldConstant.subTitle));
1✔
203
        FieldDTO altField = dto2FieldDTO( version, DatasetFieldConstant.alternativeTitle, "citation"  );
1✔
204
        if (altField != null) {
1✔
205
            writeMultipleElement(xmlw, "altTitl", altField, datasetDto.getMetadataLanguage());
1✔
206
        }
207
        
208
        xmlw.writeStartElement("IDNo");
1✔
209
        XmlWriterUtil.writeAttribute(xmlw, "agency", persistentAgency);
1✔
210
        
211
        
212
        xmlw.writeCharacters(pidString);
1✔
213
        xmlw.writeEndElement(); // IDNo
1✔
214
        writeOtherIdElement(xmlw, version);
1✔
215
        xmlw.writeEndElement(); // titlStmt
1✔
216

217
        writeAuthorsElement(xmlw, version);
1✔
218
        writeProducersElement(xmlw, version);
1✔
219
        
220
        xmlw.writeStartElement("distStmt");
1✔
221
      //The default is to add Dataverse Repository as a distributor. The excludeinstallationifset setting turns that off if there is a distributor defined in the metadata
222
        boolean distributorSet=false;
1✔
223
        MetadataBlockDTO citationDTO= version.getMetadataBlocks().get("citation");
1✔
224
        if(citationDTO!=null) {
1✔
225
            if(citationDTO.getField(DatasetFieldConstant.distributor)!=null) {
1✔
226
                distributorSet=true;
1✔
227
            }
228
        }
229
        
230
        boolean excludeRepository = settingsService.isTrueForKey(SettingsServiceBean.Key.ExportInstallationAsDistributorOnlyWhenNotSet, false);
1✔
231
        if (!StringUtils.isEmpty(datasetDto.getPublisher()) && !(excludeRepository && distributorSet)) {
1✔
232
            xmlw.writeStartElement("distrbtr");
1✔
233
            xmlw.writeAttribute("source", "archive");
1✔
234
            xmlw.writeCharacters(datasetDto.getPublisher());
1✔
235
            xmlw.writeEndElement(); //distrbtr
1✔
236
        }
237
        writeDistributorsElement(xmlw, version, datasetDto.getMetadataLanguage());
1✔
238
        writeContactsElement(xmlw, version);
1✔
239
        /* per SCHEMA, depositr comes before depDate! - L.A. */
240
        XmlWriterUtil.writeFullElement(xmlw, "depositr", XmlWriterUtil.dto2Primitive(version, DatasetFieldConstant.depositor));
1✔
241
        /* ... and depDate comes before distDate - L.A. */
242
        XmlWriterUtil.writeFullElement(xmlw, "depDate", XmlWriterUtil.dto2Primitive(version, DatasetFieldConstant.dateOfDeposit));
1✔
243
        XmlWriterUtil.writeFullElement(xmlw, "distDate", XmlWriterUtil.dto2Primitive(version, DatasetFieldConstant.distributionDate));
1✔
244

245
        xmlw.writeEndElement(); // diststmt
1✔
246

247
        writeSeriesElement(xmlw, version);
1✔
248
        xmlw.writeStartElement("holdings");
1✔
249
        XmlWriterUtil.writeAttribute(xmlw, "URI", pidUri);
1✔
250
        xmlw.writeEndElement(); //holdings
1✔
251
        
252
        xmlw.writeEndElement(); // citation
1✔
253
        //End Citation Block
254
        
255
        //Start Study Info Block
256
        // Study Info
257
        xmlw.writeStartElement("stdyInfo");
1✔
258
        
259
        writeSubjectElement(xmlw, version, datasetDto.getMetadataLanguage()); //Subject and Keywords
1✔
260
        writeAbstractElement(xmlw, version, datasetDto.getMetadataLanguage()); // Description
1✔
261
        writeSummaryDescriptionElement(xmlw, version, datasetDto.getMetadataLanguage());
1✔
262
        XmlWriterUtil.writeFullElement(xmlw, "notes", XmlWriterUtil.dto2Primitive(version, DatasetFieldConstant.notesText));
1✔
263
        ////////
264
        xmlw.writeEndElement(); // stdyInfo
1✔
265

266
        writeMethodElement(xmlw, version, datasetDto.getMetadataLanguage());
1✔
267
        writeDataAccess(xmlw , version);
1✔
268
        writeOtherStudyMaterial(xmlw , version);
1✔
269

270
        XmlWriterUtil.writeFullElement(xmlw, "notes", XmlWriterUtil.dto2Primitive(version, DatasetFieldConstant.datasetLevelErrorNotes));
1✔
271
        
272
        xmlw.writeEndElement(); // stdyDscr
1✔
273

274
    }
1✔
275

276
    private static void writeOtherStudyMaterial(XMLStreamWriter xmlw , DatasetVersionDTO version) throws XMLStreamException {
277
        List<String> relMaterials;
278
        List<String> relDatasets;
279
        List<String> relReferences;
280
        try {
281
            relMaterials = dto2PrimitiveList(version, DatasetFieldConstant.relatedMaterial);
1✔
282
            relDatasets = dto2PrimitiveList(version, DatasetFieldConstant.relatedDatasets);
1✔
283
            relReferences = dto2PrimitiveList(version, DatasetFieldConstant.otherReferences); 
1✔
284
        } catch (Exception e) {
×
285
            logger.warning("Exporting dataset to DDI failed for related materials element: " + e.getMessage());
×
286
            return;
×
287
        }
1✔
288
        xmlw.writeStartElement("othrStdyMat");
1✔
289
        XmlWriterUtil.writeFullElementList(xmlw, "relMat", relMaterials);
1✔
290
        XmlWriterUtil.writeFullElementList(xmlw, "relStdy", relDatasets);
1✔
291
        writeRelPublElement(xmlw, version);
1✔
292
        XmlWriterUtil.writeFullElementList(xmlw, "othRefs", relReferences);
1✔
293
        xmlw.writeEndElement(); //othrStdyMat
1✔
294
    }
1✔
295

296
    /*
297
            <xs:sequence>
298
               <xs:element ref="setAvail" minOccurs="0" maxOccurs="unbounded"/>
299
               <xs:element ref="useStmt" minOccurs="0" maxOccurs="unbounded"/>
300
               <xs:element ref="notes" minOccurs="0" maxOccurs="unbounded"/>
301
            </xs:sequence>
302
    */
303
    private static void writeDataAccess(XMLStreamWriter xmlw , DatasetVersionDTO version) throws XMLStreamException {
304
        xmlw.writeStartElement("dataAccs");
1✔
305
        
306
        xmlw.writeStartElement("setAvail");
1✔
307
        XmlWriterUtil.writeFullElement(xmlw, "accsPlac", version.getDataAccessPlace());
1✔
308
        XmlWriterUtil.writeFullElement(xmlw, "origArch", version.getOriginalArchive());
1✔
309
        XmlWriterUtil.writeFullElement(xmlw, "avlStatus", version.getAvailabilityStatus());
1✔
310
        XmlWriterUtil.writeFullElement(xmlw, "collSize", version.getSizeOfCollection());
1✔
311
        XmlWriterUtil.writeFullElement(xmlw, "complete", version.getStudyCompletion());
1✔
312
        xmlw.writeEndElement(); //setAvail
1✔
313
        
314
        xmlw.writeStartElement("useStmt");
1✔
315
        XmlWriterUtil.writeFullElement(xmlw, "confDec", version.getConfidentialityDeclaration());
1✔
316
        XmlWriterUtil.writeFullElement(xmlw, "specPerm", version.getSpecialPermissions());
1✔
317
        XmlWriterUtil.writeFullElement(xmlw, "restrctn", version.getRestrictions());
1✔
318
        XmlWriterUtil.writeFullElement(xmlw, "contact", version.getContactForAccess());
1✔
319
        XmlWriterUtil.writeFullElement(xmlw, "citReq", version.getCitationRequirements());
1✔
320
        XmlWriterUtil.writeFullElement(xmlw, "deposReq", version.getDepositorRequirements());
1✔
321
        XmlWriterUtil.writeFullElement(xmlw, "conditions", version.getConditions());
1✔
322
        XmlWriterUtil.writeFullElement(xmlw, "disclaimer", version.getDisclaimer());
1✔
323
        xmlw.writeEndElement(); //useStmt
1✔
324
        
325
        /* any <note>s: */
326
        if (version.getTermsOfAccess() != null && !version.getTermsOfAccess().trim().equals("")) {
1✔
327
            xmlw.writeStartElement("notes");
1✔
328
            xmlw.writeAttribute("type", NOTE_TYPE_TERMS_OF_ACCESS);
1✔
329
            xmlw.writeAttribute("level", LEVEL_DV);
1✔
330
            xmlw.writeCharacters(version.getTermsOfAccess());
1✔
331
            xmlw.writeEndElement(); //notes
1✔
332
        }
333
        xmlw.writeEndElement(); //dataAccs
1✔
334
    }
1✔
335
    
336
    private static void writeDocDescElement (XMLStreamWriter xmlw, DatasetDTO datasetDto) throws XMLStreamException {
337
        DatasetVersionDTO version = datasetDto.getDatasetVersion();
1✔
338
        String persistentProtocol = datasetDto.getProtocol();
1✔
339
        String persistentAgency = persistentProtocol;
1✔
340
        // The "persistentAgency" tag is used for the "agency" attribute of the 
341
        // <IDNo> ddi section; back in the DVN3 days we used "handle" and "DOI" 
342
        // for the 2 supported protocols, respectively. For the sake of backward
343
        // compatibility, we should probably stick with these labels: (-- L.A. 4.5)
344
        if ("hdl".equals(persistentAgency)) { 
1✔
345
            persistentAgency = "handle";
×
346
        } else if ("doi".equals(persistentAgency)) {
1✔
347
            persistentAgency = "DOI";
1✔
348
        }
349
        
350
        String persistentAuthority = datasetDto.getAuthority();
1✔
351
        String persistentId = datasetDto.getIdentifier();
1✔
352
        GlobalId pid = PidUtil.parseAsGlobalID(persistentProtocol, persistentAuthority, persistentId);
1✔
353
        String pidString;
354
        if(pid != null) {
1✔
355
            pidString = pid.asString();
1✔
356
        } else {
357
            pidString = EMPTY_PID;
1✔
358
        }
359

360
        xmlw.writeStartElement("docDscr");
1✔
361
        xmlw.writeStartElement("citation");
1✔
362
        xmlw.writeStartElement("titlStmt");
1✔
363
        XmlWriterUtil.writeFullElement(xmlw, "titl", XmlWriterUtil.dto2Primitive(version, DatasetFieldConstant.title), datasetDto.getMetadataLanguage());
1✔
364
        xmlw.writeStartElement("IDNo");
1✔
365
        XmlWriterUtil.writeAttribute(xmlw, "agency", persistentAgency);
1✔
366
        xmlw.writeCharacters(pidString);
1✔
367
        xmlw.writeEndElement(); // IDNo
1✔
368
        xmlw.writeEndElement(); // titlStmt
1✔
369
        xmlw.writeStartElement("distStmt");
1✔
370
        //The doc is always published by the Dataverse Repository
371
        if (!StringUtils.isEmpty(datasetDto.getPublisher())) {
1✔
372
            xmlw.writeStartElement("distrbtr");
1✔
373
            xmlw.writeAttribute("source", "archive");
1✔
374
            xmlw.writeCharacters(datasetDto.getPublisher());
1✔
375
            xmlw.writeEndElement(); // distrbtr
1✔
376
        }
377
        XmlWriterUtil.writeFullElement(xmlw, "distDate", datasetDto.getPublicationDate());
1✔
378
        
379
        xmlw.writeEndElement(); // diststmt
1✔
380
        writeVersionStatement(xmlw, version);
1✔
381
        xmlw.writeStartElement("biblCit");
1✔
382
        xmlw.writeCharacters(version.getCitation());
1✔
383
        xmlw.writeEndElement(); // biblCit
1✔
384
        xmlw.writeEndElement(); // citation      
1✔
385
        xmlw.writeEndElement(); // docDscr
1✔
386
        
387
    }
1✔
388
    
389
    private static void writeVersionStatement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO) throws XMLStreamException{
390
        xmlw.writeStartElement("verStmt");
1✔
391
        xmlw.writeAttribute("source","archive");
1✔
392
        xmlw.writeStartElement("version");
1✔
393
        XmlWriterUtil.writeAttribute(xmlw,"date", datasetVersionDTO.getReleaseTime().substring(0, 10));
1✔
394
        XmlWriterUtil.writeAttribute(xmlw,"type", datasetVersionDTO.getVersionState().toString());
1✔
395
        xmlw.writeCharacters(datasetVersionDTO.getVersionNumber().toString());
1✔
396
        xmlw.writeEndElement(); // version
1✔
397
        xmlw.writeEndElement(); // verStmt
1✔
398
    }
1✔
399
    
400
    /* From the DDI 2.5 schema: 
401
            <xs:sequence>
402
               <xs:element ref="timePrd" minOccurs="0" maxOccurs="unbounded"/>
403
               <xs:element ref="collDate" minOccurs="0" maxOccurs="unbounded"/>
404
               <xs:element ref="nation" minOccurs="0" maxOccurs="unbounded"/>
405
               <xs:element ref="geogCover" minOccurs="0" maxOccurs="unbounded"/>
406
               <xs:element ref="geogUnit" minOccurs="0" maxOccurs="unbounded"/>
407
               <xs:element ref="geoBndBox" minOccurs="0"/>
408
               <xs:element ref="boundPoly" minOccurs="0" maxOccurs="unbounded"/>
409
               <xs:element ref="anlyUnit" minOccurs="0" maxOccurs="unbounded"/>
410
               <xs:element ref="universe" minOccurs="0" maxOccurs="unbounded"/>
411
               <xs:element ref="dataKind" minOccurs="0" maxOccurs="unbounded"/>
412
            </xs:sequence>
413
    */
414
    private static void writeSummaryDescriptionElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO, String lang) throws XMLStreamException {
415
        xmlw.writeStartElement("sumDscr");
1✔
416
        FieldDTO timePeriodCoveredDTO = null;
1✔
417
        FieldDTO dateOfCollectionDTO = null;
1✔
418
        FieldDTO geographicCoverageDTO = null;
1✔
419
        FieldDTO geographicBoundingBoxDTO = null;
1✔
420
        FieldDTO unitOfAnalysisDTO = null;
1✔
421
        FieldDTO universeDTO = null;
1✔
422
        FieldDTO kindOfDataDTO = null;
1✔
423

424
        for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) {
1✔
425
            String key = entry.getKey();
1✔
426
            MetadataBlockDTO value = entry.getValue();
1✔
427

428
            if ("citation".equals(key)) {
1✔
429
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
430
                    if (DatasetFieldConstant.timePeriodCovered.equals(fieldDTO.getTypeName())) {
1✔
431
                        timePeriodCoveredDTO = fieldDTO;
1✔
432
                    }
433

434
                    if (DatasetFieldConstant.dateOfCollection.equals(fieldDTO.getTypeName())) {
1✔
435
                        dateOfCollectionDTO = fieldDTO;
1✔
436
                    }
437

438
                    if (DatasetFieldConstant.kindOfData.equals(fieldDTO.getTypeName())) {
1✔
439
                        kindOfDataDTO = fieldDTO;
1✔
440
                    }
441
                }
1✔
442
            }
443

444
            if ("geospatial".equals(key)) {
1✔
445
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
446
                    if (DatasetFieldConstant.geographicCoverage.equals(fieldDTO.getTypeName())) {
1✔
447
                        geographicCoverageDTO = fieldDTO;
1✔
448
                    }
449
                    if (DatasetFieldConstant.geographicBoundingBox.equals(fieldDTO.getTypeName())) {
1✔
450

451
                        geographicBoundingBoxDTO = fieldDTO;
1✔
452

453
                    }
454
                }
1✔
455
            }
456

457
            if ("socialscience".equals(key)) {
1✔
458
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
459
                    if (DatasetFieldConstant.universe.equals(fieldDTO.getTypeName())) {
1✔
460
                        universeDTO = fieldDTO;
1✔
461
                    }
462
                    if (DatasetFieldConstant.unitOfAnalysis.equals(fieldDTO.getTypeName())) {
1✔
463
                        unitOfAnalysisDTO = fieldDTO;
1✔
464
                    }
465
                }
1✔
466
            }
467
        }
1✔
468
        /* Finally, we can write the fields we have collected, in the correct order: -L.A.*/
469

470
        if (timePeriodCoveredDTO != null) {
1✔
471
            String dateValStart = "";
1✔
472
            String dateValEnd = "";
1✔
473
            Integer per = 0;
1✔
474
            for (HashSet<FieldDTO> foo : timePeriodCoveredDTO.getMultipleCompound()) {
1✔
475
                per++;
1✔
476
                for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
477
                    FieldDTO next = iterator.next();
1✔
478
                    if (DatasetFieldConstant.timePeriodCoveredStart.equals(next.getTypeName())) {
1✔
479
                        dateValStart = next.getSinglePrimitive();
1✔
480
                    }
481
                    if (DatasetFieldConstant.timePeriodCoveredEnd.equals(next.getTypeName())) {
1✔
482
                        dateValEnd = next.getSinglePrimitive();
1✔
483
                    }
484
                }
1✔
485
                if (!dateValStart.isEmpty()) {
1✔
486
                    writeDateElement(xmlw, "timePrd", "P" + per.toString(), "start", dateValStart);
1✔
487
                }
488
                if (!dateValEnd.isEmpty()) {
1✔
489
                    writeDateElement(xmlw, "timePrd", "P" + per.toString(), "end", dateValEnd);
1✔
490
                }
491
            }
1✔
492
        }
493

494
        if (dateOfCollectionDTO != null) {
1✔
495
            String dateValStart = "";
1✔
496
            String dateValEnd = "";
1✔
497
            Integer coll = 0;
1✔
498
            for (HashSet<FieldDTO> foo : dateOfCollectionDTO.getMultipleCompound()) {
1✔
499
                coll++;
1✔
500
                for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
501
                    FieldDTO next = iterator.next();
1✔
502
                    if (DatasetFieldConstant.dateOfCollectionStart.equals(next.getTypeName())) {
1✔
503
                        dateValStart = next.getSinglePrimitive();
1✔
504
                    }
505
                    if (DatasetFieldConstant.dateOfCollectionEnd.equals(next.getTypeName())) {
1✔
506
                        dateValEnd = next.getSinglePrimitive();
1✔
507
                    }
508
                }
1✔
509
                if (!dateValStart.isEmpty()) {
1✔
510
                    writeDateElement(xmlw, "collDate", "P" + coll.toString(), "start", dateValStart);
1✔
511
                }
512
                if (!dateValEnd.isEmpty()) {
1✔
513
                    writeDateElement(xmlw, "collDate", "P" + coll.toString(), "end", dateValEnd);
1✔
514
                }
515
            }
1✔
516
        }
517

518
        /* <nation> and <geogCover> come next, in that order. -L.A. */
519
        if (geographicCoverageDTO != null) {
1✔
520

521
            List<String> nationList = new ArrayList<>();
1✔
522
            List<String> geogCoverList = new ArrayList<>();
1✔
523

524
            for (HashSet<FieldDTO> foo : geographicCoverageDTO.getMultipleCompound()) {
1✔
525
                for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
526
                    FieldDTO next = iterator.next();
1✔
527
                    /* our "country" field maps 1:1 to the DDI "<nation>": */
528
                    if (DatasetFieldConstant.country.equals(next.getTypeName())) {
1✔
529
                        nationList.add(next.getSinglePrimitive());
1✔
530
                    }
531
                    /* city, state and otherGeographicCoverage all exported as "<geogCover>": */
532
                    if (DatasetFieldConstant.city.equals(next.getTypeName())
1✔
533
                            || DatasetFieldConstant.state.equals(next.getTypeName())
1✔
534
                            || DatasetFieldConstant.otherGeographicCoverage.equals(next.getTypeName())) {
1✔
535
                        geogCoverList.add(next.getSinglePrimitive());
1✔
536
                    }
537
                }
1✔
538
            }
1✔
539

540
            /**
541
             * And now we can write all the fields encountered, first the
542
             * "<nation>" entries, then all the "<geogCover>" ones:
543
             */
544
            for (String nationEntry : nationList) {
1✔
545
                XmlWriterUtil.writeFullElement(xmlw, "nation", nationEntry);
1✔
546
            }
1✔
547
            for (String geogCoverEntry : geogCoverList) {
1✔
548
                XmlWriterUtil.writeFullElement(xmlw, "geogCover", geogCoverEntry);
1✔
549
            }
1✔
550
        }
551

552
        XmlWriterUtil.writeFullElementList(xmlw, "geogUnit", dto2PrimitiveList(datasetVersionDTO, DatasetFieldConstant.geographicUnit));
1✔
553

554
        /* Only 1 geoBndBox is allowed in the DDI.
555
           So, I'm just going to arbitrarily use the first one, and ignore the rest! -L.A. */
556
        if (geographicBoundingBoxDTO != null) {
1✔
557
            HashSet<FieldDTO> bndBoxSet = geographicBoundingBoxDTO.getMultipleCompound().get(0);
1✔
558
            xmlw.writeStartElement("geoBndBox");
1✔
559
            HashMap<String, String> geoBndBoxMap = new HashMap<>();
1✔
560
            for (FieldDTO next : bndBoxSet) {
1✔
561
                if (DatasetFieldConstant.westLongitude.equals(next.getTypeName())) {
1✔
562
                    geoBndBoxMap.put("westBL", next.getSinglePrimitive());
1✔
563
                }
564
                if (DatasetFieldConstant.eastLongitude.equals(next.getTypeName())) {
1✔
565
                    geoBndBoxMap.put("eastBL", next.getSinglePrimitive());
1✔
566
                }
567
                if (DatasetFieldConstant.northLatitude.equals(next.getTypeName())) {
1✔
568
                    geoBndBoxMap.put("northBL", next.getSinglePrimitive());
1✔
569
                }
570
                if (DatasetFieldConstant.southLatitude.equals(next.getTypeName())) {
1✔
571
                    geoBndBoxMap.put("southBL", next.getSinglePrimitive());
1✔
572
                }
573
            }
1✔
574

575
            /* Once again, order is important! */
576
 /*
577
                        <xs:sequence>
578
                            <xs:element ref="westBL"/>
579
                            <xs:element ref="eastBL"/>
580
                            <xs:element ref="southBL"/>
581
                            <xs:element ref="northBL"/>
582
                        </xs:sequence>
583
             */
584
            if (geoBndBoxMap.get("westBL") != null) {
1✔
585
                XmlWriterUtil.writeFullElement(xmlw, "westBL", geoBndBoxMap.get("westBL"));
1✔
586
            }
587
            if (geoBndBoxMap.get("eastBL") != null) {
1✔
588
                XmlWriterUtil.writeFullElement(xmlw, "eastBL", geoBndBoxMap.get("eastBL"));
1✔
589
            }
590
            if (geoBndBoxMap.get("southBL") != null) {
1✔
591
                XmlWriterUtil.writeFullElement(xmlw, "southBL", geoBndBoxMap.get("southBL"));
1✔
592
            }
593
            if (geoBndBoxMap.get("northBL") != null) {
1✔
594
                XmlWriterUtil.writeFullElement(xmlw, "northBL", geoBndBoxMap.get("northBL"));
1✔
595
            }
596

597
            xmlw.writeEndElement();
1✔
598
        }
599

600
        /* analyUnit: */
601
        if (unitOfAnalysisDTO != null) {
1✔
602
            XmlWriterUtil.writeI18NElementList(xmlw, "anlyUnit", unitOfAnalysisDTO.getMultipleVocab(), "unitOfAnalysis", unitOfAnalysisDTO.getTypeClass(), "socialscience", lang);
1✔
603

604
        }
605

606
        /* universe: */
607
        if (universeDTO != null) {
1✔
608
            writeMultipleElement(xmlw, "universe", universeDTO, lang);
1✔
609
        }
610

611
        /* finally, any "kind of data" entries: */
612
        if (kindOfDataDTO != null) {
1✔
613
            writeMultipleElement(xmlw, "dataKind", kindOfDataDTO, lang);
1✔
614
        }
615

616
        xmlw.writeEndElement(); //sumDscr     
1✔
617
    }
1✔
618
    
619
    private static void writeMultipleElement(XMLStreamWriter xmlw, String element, FieldDTO fieldDTO, String lang) throws XMLStreamException {
620
        for (String value : fieldDTO.getMultiplePrimitive()) {
1✔
621
            //Write multiple lang vals for controlled vocab, otherwise don't include any lang tag
622
            XmlWriterUtil.writeFullElement(xmlw, element, value, fieldDTO.isControlledVocabularyField() ? lang : null);
1✔
623
        }
1✔
624
    }
1✔
625
    
626
    private static void writeDateElement(XMLStreamWriter xmlw, String element, String cycle, String event, String dateIn) throws XMLStreamException {
627

628
        xmlw.writeStartElement(element);
1✔
629
        XmlWriterUtil.writeAttribute(xmlw, "cycle",  cycle);
1✔
630
        XmlWriterUtil.writeAttribute(xmlw, "event", event);
1✔
631
        XmlWriterUtil.writeAttribute(xmlw, "date", dateIn);
1✔
632
        xmlw.writeCharacters(dateIn);
1✔
633
        xmlw.writeEndElement(); 
1✔
634

635
    }
1✔
636
    
637
    /**
638
     * Again, <dataColl> is an xs:sequence - order is important and must follow
639
     * the schema. -L.A.
640
     * <xs:sequence>
641
     * <xs:element ref="timeMeth" minOccurs="0" maxOccurs="unbounded"/>
642
     * <xs:element ref="dataCollector" minOccurs="0" maxOccurs="unbounded"/>
643
     * <xs:element ref="collectorTraining" minOccurs="0" maxOccurs="unbounded"/>
644
     * <xs:element ref="frequenc" minOccurs="0" maxOccurs="unbounded"/>
645
     * <xs:element ref="sampProc" minOccurs="0" maxOccurs="unbounded"/>
646
     * <xs:element ref="sampleFrame" minOccurs="0" maxOccurs="unbounded"/>
647
     * <xs:element ref="targetSampleSize" minOccurs="0" maxOccurs="unbounded"/>
648
     * <xs:element ref="deviat" minOccurs="0" maxOccurs="unbounded"/>
649
     * <xs:element ref="collMode" minOccurs="0" maxOccurs="unbounded"/>
650
     * <xs:element ref="resInstru" minOccurs="0" maxOccurs="unbounded"/>
651
     * <xs:element ref="instrumentDevelopment" minOccurs="0" maxOccurs="unbounded"/>
652
     * <xs:element ref="sources" minOccurs="0"/>
653
     * <xs:element ref="collSitu" minOccurs="0" maxOccurs="unbounded"/>
654
     * <xs:element ref="actMin" minOccurs="0" maxOccurs="unbounded"/>
655
     * <xs:element ref="ConOps" minOccurs="0" maxOccurs="unbounded"/>
656
     * <xs:element ref="weight" minOccurs="0" maxOccurs="unbounded"/>
657
     * <xs:element ref="cleanOps" minOccurs="0" maxOccurs="unbounded"/>
658
     * </xs:sequence>
659
     */
660
    private static void writeMethodElement(XMLStreamWriter xmlw , DatasetVersionDTO version, String lang) throws XMLStreamException{
661
        xmlw.writeStartElement("method");
1✔
662
        xmlw.writeStartElement("dataColl");
1✔
663
        XmlWriterUtil.writeI18NElement(xmlw, "timeMeth", version, DatasetFieldConstant.timeMethod,lang);
1✔
664
        XmlWriterUtil.writeI18NElement(xmlw, "dataCollector", version, DatasetFieldConstant.dataCollector, lang);
1✔
665
        XmlWriterUtil.writeI18NElement(xmlw, "collectorTraining", version, DatasetFieldConstant.collectorTraining, lang);
1✔
666
        XmlWriterUtil.writeI18NElement(xmlw, "frequenc", version, DatasetFieldConstant.frequencyOfDataCollection, lang);
1✔
667
        XmlWriterUtil.writeI18NElement(xmlw, "sampProc", version, DatasetFieldConstant.samplingProcedure, lang);
1✔
668

669
        writeTargetSampleElement(xmlw, version);
1✔
670

671
        XmlWriterUtil.writeI18NElement(xmlw, "deviat", version, DatasetFieldConstant.deviationsFromSampleDesign, lang);
1✔
672

673
        /* <collMode> comes before <sources>: */
674
        FieldDTO collModeFieldDTO = dto2FieldDTO(version, DatasetFieldConstant.collectionMode, "socialscience");
1✔
675
        if (collModeFieldDTO != null) {
1✔
676
            // This field was made multiple as of 5.10
677
            // Below is a backward compatibility check allowing export to work in 
678
            // an instance where the metadata block has not been updated yet.
679
            if (collModeFieldDTO.getMultiple()) {
1✔
680
                XmlWriterUtil.writeI18NElementList(xmlw, "collMode", collModeFieldDTO.getMultipleVocab(), DatasetFieldConstant.collectionMode, collModeFieldDTO.getTypeClass(), "socialscience", lang);
1✔
681
            } else {
682
                XmlWriterUtil.writeI18NElement(xmlw, "collMode", version, DatasetFieldConstant.collectionMode, lang);
×
683
            }
684
        }
685
        /* and so does <resInstru>: */
686
        XmlWriterUtil.writeI18NElement(xmlw, "resInstru", version, DatasetFieldConstant.researchInstrument, lang);
1✔
687
        xmlw.writeStartElement("sources");
1✔
688
        XmlWriterUtil.writeFullElementList(xmlw, "dataSrc", dto2PrimitiveList(version, DatasetFieldConstant.dataSources));
1✔
689
        XmlWriterUtil.writeI18NElement(xmlw, "srcOrig", version, DatasetFieldConstant.originOfSources, lang);
1✔
690
        XmlWriterUtil.writeI18NElement(xmlw, "srcChar", version, DatasetFieldConstant.characteristicOfSources, lang);
1✔
691
        XmlWriterUtil.writeI18NElement(xmlw, "srcDocu", version, DatasetFieldConstant.accessToSources, lang);
1✔
692
        xmlw.writeEndElement(); //sources
1✔
693

694
        
695
        XmlWriterUtil.writeI18NElement(xmlw, "collSitu", version, DatasetFieldConstant.dataCollectionSituation, lang);
1✔
696
        XmlWriterUtil.writeI18NElement(xmlw, "actMin", version, DatasetFieldConstant.actionsToMinimizeLoss, lang);
1✔
697
        /* "<ConOps>" has the uppercase C: */
698
        XmlWriterUtil.writeI18NElement(xmlw, "ConOps", version, DatasetFieldConstant.controlOperations, lang);
1✔
699
        XmlWriterUtil.writeI18NElement(xmlw, "weight", version, DatasetFieldConstant.weighting, lang);
1✔
700
        XmlWriterUtil.writeI18NElement(xmlw, "cleanOps", version, DatasetFieldConstant.cleaningOperations, lang);
1✔
701

702
        xmlw.writeEndElement(); //dataColl
1✔
703
        /* <notes> before <anlyInfo>: */
704
        writeNotesElement(xmlw, version);
1✔
705

706
        xmlw.writeStartElement("anlyInfo");
1✔
707
        //XmlWriterUtil.writeFullElement(xmlw, "anylInfo", dto2Primitive(version, DatasetFieldConstant.datasetLevelErrorNotes));
708
        XmlWriterUtil.writeI18NElement(xmlw, "respRate", version, DatasetFieldConstant.responseRate, lang);
1✔
709
        XmlWriterUtil.writeI18NElement(xmlw, "EstSmpErr", version, DatasetFieldConstant.samplingErrorEstimates, lang);
1✔
710
        XmlWriterUtil.writeI18NElement(xmlw, "dataAppr", version, DatasetFieldConstant.otherDataAppraisal, lang);
1✔
711
        xmlw.writeEndElement(); //anlyInfo
1✔
712
        
713
        xmlw.writeEndElement();//method
1✔
714
    }
1✔
715
    
716
    private static void writeSubjectElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO, String lang) throws XMLStreamException{ 
717
        
718
        //Key Words and Topic Classification
719
        Locale defaultLocale = Locale.getDefault();
1✔
720
        xmlw.writeStartElement("subject");
1✔
721
        for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) {
1✔
722
            String key = entry.getKey();
1✔
723
            MetadataBlockDTO value = entry.getValue();
1✔
724
            if (CITATION_BLOCK_NAME.equals(key)) {
1✔
725
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
726
                    if (DatasetFieldConstant.subject.equals(fieldDTO.getTypeName())) {
1✔
727
                        XmlWriterUtil.writeI18NElementList(xmlw, "keyword", fieldDTO.getMultipleVocab(), "subject",
1✔
728
                                fieldDTO.getTypeClass(), "citation", lang);
1✔
729
                    }
730

731
                    if (DatasetFieldConstant.keyword.equals(fieldDTO.getTypeName())) {
1✔
732
                        boolean isCVV = false;
1✔
733
                        for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) {
1✔
734
                            String keywordValue = "";
1✔
735
                            String keywordVocab = "";
1✔
736
                            String keywordURI = "";
1✔
737
                            for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
738
                                FieldDTO next = iterator.next();
1✔
739
                                if (DatasetFieldConstant.keywordValue.equals(next.getTypeName())) {
1✔
740
                                    if (next.isControlledVocabularyField()) {
1✔
741
                                        isCVV = true;
×
742
                                    }
743
                                    keywordValue = next.getSinglePrimitive();
1✔
744
                                }
745
                                if (DatasetFieldConstant.keywordVocab.equals(next.getTypeName())) {
1✔
746
                                    keywordVocab = next.getSinglePrimitive();
1✔
747
                                }
748
                                if (DatasetFieldConstant.keywordVocabURI.equals(next.getTypeName())) {
1✔
749
                                    keywordURI = next.getSinglePrimitive();
1✔
750
                                }
751
                            }
1✔
752
                            if (!keywordValue.isEmpty()) {
1✔
753
                                xmlw.writeStartElement("keyword");
1✔
754
                                XmlWriterUtil.writeAttribute(xmlw, "vocab", keywordVocab);
1✔
755
                                XmlWriterUtil.writeAttribute(xmlw, "vocabURI", keywordURI);
1✔
756
                                if (lang != null && isCVV) {
1✔
757
                                    XmlWriterUtil.writeAttribute(xmlw, "xml:lang", defaultLocale.getLanguage());
×
758
                                    xmlw.writeCharacters(ControlledVocabularyValue.getLocaleStrValue(keywordValue,
×
759
                                            DatasetFieldConstant.keywordValue, CITATION_BLOCK_NAME, defaultLocale,
760
                                            true));
761
                                } else {
762
                                    xmlw.writeCharacters(keywordValue);
1✔
763
                                }
764
                                xmlw.writeEndElement(); // Keyword
1✔
765
                                if (lang != null && isCVV && !defaultLocale.getLanguage().equals(lang)) {
1✔
766
                                    String translatedValue = ControlledVocabularyValue.getLocaleStrValue(keywordValue,
×
767
                                            DatasetFieldConstant.keywordValue, CITATION_BLOCK_NAME, new Locale(lang),
768
                                            false);
769
                                    if (translatedValue != null) {
×
770
                                        xmlw.writeStartElement("keyword");
×
771
                                        XmlWriterUtil.writeAttribute(xmlw, "vocab", keywordVocab);
×
772
                                        XmlWriterUtil.writeAttribute(xmlw, "vocabURI", keywordURI);
×
773
                                        XmlWriterUtil.writeAttribute(xmlw, "xml:lang", lang);
×
774
                                        xmlw.writeCharacters(translatedValue);
×
775
                                        xmlw.writeEndElement(); // Keyword
×
776
                                    }
777
                                }
778
                            }
779
                        }
1✔
780
                    }
781
                    if (DatasetFieldConstant.topicClassification.equals(fieldDTO.getTypeName())) {
1✔
782
                        boolean isCVV = false;
1✔
783
                        for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) {
1✔
784
                            String topicClassificationValue = "";
1✔
785
                            String topicClassificationVocab = "";
1✔
786
                            String topicClassificationURI = "";
1✔
787
                            for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
788
                                FieldDTO next = iterator.next();
1✔
789
                                if (DatasetFieldConstant.topicClassValue.equals(next.getTypeName())) {
1✔
790
                                    // Currently getSingleVocab() is the same as getSinglePrimitive() so this works
791
                                    // for either case
792
                                    topicClassificationValue = next.getSinglePrimitive();
1✔
793
                                    if (next.isControlledVocabularyField()) {
1✔
794
                                        isCVV = true;
×
795
                                    }
796
                                }
797
                                if (DatasetFieldConstant.topicClassVocab.equals(next.getTypeName())) {
1✔
798
                                    topicClassificationVocab = next.getSinglePrimitive();
1✔
799
                                }
800
                                if (DatasetFieldConstant.topicClassVocabURI.equals(next.getTypeName())) {
1✔
801
                                    topicClassificationURI = next.getSinglePrimitive();
1✔
802
                                }
803
                            }
1✔
804
                            if (!topicClassificationValue.isEmpty()) {
1✔
805
                                xmlw.writeStartElement("topcClas");
1✔
806
                                XmlWriterUtil.writeAttribute(xmlw, "vocab", topicClassificationVocab);
1✔
807
                                XmlWriterUtil.writeAttribute(xmlw, "vocabURI", topicClassificationURI);
1✔
808
                                if (lang != null && isCVV) {
1✔
809
                                    XmlWriterUtil.writeAttribute(xmlw, "xml:lang", defaultLocale.getLanguage());
×
810
                                    xmlw.writeCharacters(ControlledVocabularyValue.getLocaleStrValue(
×
811
                                            topicClassificationValue, DatasetFieldConstant.topicClassValue,
812
                                            CITATION_BLOCK_NAME, defaultLocale, true));
813
                                } else {
814
                                    xmlw.writeCharacters(topicClassificationValue);
1✔
815
                                }
816
                                xmlw.writeEndElement(); // topcClas
1✔
817
                                if (lang != null && isCVV && !defaultLocale.getLanguage().equals(lang)) {
1✔
818
                                    String translatedValue = ControlledVocabularyValue.getLocaleStrValue(
×
819
                                            topicClassificationValue, DatasetFieldConstant.topicClassValue,
820
                                            CITATION_BLOCK_NAME, new Locale(lang), false);
821
                                    if (translatedValue != null) {
×
822
                                        xmlw.writeStartElement("topcClas");
×
823
                                        XmlWriterUtil.writeAttribute(xmlw, "vocab", topicClassificationVocab);
×
824
                                        XmlWriterUtil.writeAttribute(xmlw, "vocabURI", topicClassificationURI);
×
825
                                        XmlWriterUtil.writeAttribute(xmlw, "xml:lang", lang);
×
826
                                        xmlw.writeCharacters(translatedValue);
×
827
                                        xmlw.writeEndElement(); // topcClas
×
828
                                    }
829
                                }
830
                            }
831
                        }
1✔
832
                    }
833
                }
1✔
834
            }
835
        }
1✔
836
        xmlw.writeEndElement(); // subject       
1✔
837
    }
1✔
838

839
    private static void writeAuthorsElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO) throws XMLStreamException {
840

841
        for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) {
1✔
842
            String key = entry.getKey();
1✔
843
            MetadataBlockDTO value = entry.getValue();
1✔
844
            if ("citation".equals(key)) {
1✔
845
                xmlw.writeStartElement("rspStmt");
1✔
846
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
847
                    if (DatasetFieldConstant.author.equals(fieldDTO.getTypeName())) {
1✔
848
                        String authorName = "";
1✔
849
                        String authorAffiliation = "";
1✔
850
                        for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) {
1✔
851
                            for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
852
                                FieldDTO next = iterator.next();
1✔
853
                                if (DatasetFieldConstant.authorName.equals(next.getTypeName())) {
1✔
854
                                    authorName =  next.getSinglePrimitive();
1✔
855
                                }
856
                                if (DatasetFieldConstant.authorAffiliation.equals(next.getTypeName())) {
1✔
857
                                    authorAffiliation =  next.getSinglePrimitive();
1✔
858
                                }
859
                            }
1✔
860
                            if (!authorName.isEmpty()){
1✔
861
                                xmlw.writeStartElement("AuthEnty"); 
1✔
862
                                XmlWriterUtil.writeAttribute(xmlw,"affiliation",authorAffiliation);
1✔
863
                                xmlw.writeCharacters(authorName);
1✔
864
                                xmlw.writeEndElement(); //AuthEnty
1✔
865
                            }
866
                        }
1✔
867

868
                    } else if (DatasetFieldConstant.contributor.equals(fieldDTO.getTypeName())) {
1✔
869
                        String contributorName = "";
1✔
870
                        String contributorType = "";
1✔
871
                        for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) {
1✔
872
                            for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
873
                                FieldDTO next = iterator.next();
1✔
874
                                if (DatasetFieldConstant.contributorName.equals(next.getTypeName())) {
1✔
875
                                    contributorName =  next.getSinglePrimitive();
1✔
876
                                }
877
                                if (DatasetFieldConstant.contributorType.equals(next.getTypeName())) {
1✔
878
                                    contributorType =  next.getSinglePrimitive();
1✔
879
                                }
880
                            }
1✔
881
                            if (!contributorName.isEmpty()){
1✔
882
                                xmlw.writeStartElement("othId");
1✔
883
                                XmlWriterUtil.writeAttribute(xmlw,"role", contributorType);
1✔
884
                                xmlw.writeCharacters(contributorName);
1✔
885
                                xmlw.writeEndElement(); //othId
1✔
886
                            }
887
                        }
1✔
888
                    }
889
                }
1✔
890
                xmlw.writeEndElement(); //rspStmt
1✔
891
            }
892

893
        }
1✔
894
    }
1✔
895
    
896
    private static void writeContactsElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO) throws XMLStreamException {
897

898
        for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) {
1✔
899
            String key = entry.getKey();
1✔
900
            MetadataBlockDTO value = entry.getValue();
1✔
901
            if ("citation".equals(key)) {
1✔
902
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
903
                    if (DatasetFieldConstant.datasetContact.equals(fieldDTO.getTypeName())) {
1✔
904
                        String datasetContactName = "";
1✔
905
                        String datasetContactAffiliation = "";
1✔
906
                        String datasetContactEmail = "";
1✔
907
                        for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) {
1✔
908
                            for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
909
                                FieldDTO next = iterator.next();
1✔
910
                                if (DatasetFieldConstant.datasetContactName.equals(next.getTypeName())) {
1✔
911
                                    datasetContactName =  next.getSinglePrimitive();
1✔
912
                                }
913
                                if (DatasetFieldConstant.datasetContactAffiliation.equals(next.getTypeName())) {
1✔
914
                                    datasetContactAffiliation =  next.getSinglePrimitive();
1✔
915
                                }
916
                                if (DatasetFieldConstant.datasetContactEmail.equals(next.getTypeName())) {
1✔
917
                                    datasetContactEmail = next.getSinglePrimitive();
1✔
918
                                }
919
                            }
1✔
920
                            // TODO: Since datasetContactEmail is a required field but datasetContactName is not consider not checking if datasetContactName is empty so we can write out datasetContactEmail.
921
                            if (!datasetContactName.isEmpty()){
1✔
922
                                xmlw.writeStartElement("contact"); 
1✔
923
                                XmlWriterUtil.writeAttribute(xmlw,"affiliation",datasetContactAffiliation);
1✔
924
                                XmlWriterUtil.writeAttribute(xmlw,"email",datasetContactEmail);
1✔
925
                                xmlw.writeCharacters(datasetContactName);
1✔
926
                                xmlw.writeEndElement(); //AuthEnty
1✔
927
                            }
928
                        }
1✔
929
                    }
930
                }
1✔
931
            }
932
        }
1✔
933
    }
1✔
934
    
935
    private static void writeProducersElement(XMLStreamWriter xmlw, DatasetVersionDTO version) throws XMLStreamException {
936
        xmlw.writeStartElement("prodStmt");
1✔
937
        for (Map.Entry<String, MetadataBlockDTO> entry : version.getMetadataBlocks().entrySet()) {
1✔
938
            String key = entry.getKey();
1✔
939
            MetadataBlockDTO value = entry.getValue();
1✔
940

941
            if ("citation".equals(key)) {
1✔
942
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
943
                    if (DatasetFieldConstant.producer.equals(fieldDTO.getTypeName())) {
1✔
944

945
                        for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) {
1✔
946
                            String producerName = "";
1✔
947
                            String producerAffiliation = "";
1✔
948
                            String producerAbbreviation = "";
1✔
949
                            String producerLogo = "";
1✔
950
                            for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
951
                                FieldDTO next = iterator.next();
1✔
952
                                if (DatasetFieldConstant.producerName.equals(next.getTypeName())) {
1✔
953
                                    producerName = next.getSinglePrimitive();
1✔
954
                                }
955
                                if (DatasetFieldConstant.producerAffiliation.equals(next.getTypeName())) {
1✔
956
                                    producerAffiliation = next.getSinglePrimitive();
1✔
957
                                }
958
                                if (DatasetFieldConstant.producerAbbreviation.equals(next.getTypeName())) {
1✔
959
                                    producerAbbreviation = next.getSinglePrimitive();
1✔
960
                                }
961
                                if (DatasetFieldConstant.producerLogo.equals(next.getTypeName())) {
1✔
962
                                    producerLogo = next.getSinglePrimitive();
1✔
963
                                }
964
                            }
1✔
965
                            if (!producerName.isEmpty()) {
1✔
966
                                xmlw.writeStartElement("producer");
1✔
967
                                XmlWriterUtil.writeAttribute(xmlw, "affiliation", producerAffiliation);
1✔
968
                                XmlWriterUtil.writeAttribute(xmlw, "abbr", producerAbbreviation);
1✔
969
                                //XmlWriterUtil.writeAttribute(xmlw, "role", producerLogo);
970
                                xmlw.writeCharacters(producerName);
1✔
971
                                xmlw.writeEndElement(); //AuthEnty
1✔
972
                            }
973
                        }
1✔
974
                        
975
                    }
976
                }
1✔
977
            }
978
        }
1✔
979
        XmlWriterUtil.writeFullElement(xmlw, "prodDate", XmlWriterUtil.dto2Primitive(version, DatasetFieldConstant.productionDate));
1✔
980
        // productionPlace was made multiple as of 5.14:
981
        // (a quick backward compatibility check was added to dto2PrimitiveList(),
982
        // see the method for details)
983

984
        FieldDTO  prodPlac = dto2FieldDTO( version, DatasetFieldConstant.productionPlace, "citation"  );
1✔
985
        if (prodPlac != null) {
1✔
986
            writeMultipleElement(xmlw, "prodPlac", prodPlac, null);
1✔
987
        }
988
        writeSoftwareElement(xmlw, version);
1✔
989
  
990
        writeGrantElement(xmlw, version);
1✔
991
        xmlw.writeEndElement(); //prodStmt
1✔
992
    }
1✔
993
    
994
    private static void writeDistributorsElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO, String lang) throws XMLStreamException {
995
        for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) {
1✔
996
            String key = entry.getKey();
1✔
997
            MetadataBlockDTO value = entry.getValue();
1✔
998
            if ("citation".equals(key)) {
1✔
999
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
1000
                    if (DatasetFieldConstant.distributor.equals(fieldDTO.getTypeName())) {
1✔
1001
                        //xmlw.writeStartElement("distrbtr");
1002
                        for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) {
1✔
1003
                            String distributorName = "";
1✔
1004
                            String distributorAffiliation = "";
1✔
1005
                            String distributorAbbreviation = "";
1✔
1006
                            String distributorURL = "";
1✔
1007
                            for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
1008
                                FieldDTO next = iterator.next();
1✔
1009
                                if (DatasetFieldConstant.distributorName.equals(next.getTypeName())) {
1✔
1010
                                    distributorName = next.getSinglePrimitive();
1✔
1011
                                }
1012
                                if (DatasetFieldConstant.distributorAffiliation.equals(next.getTypeName())) {
1✔
1013
                                    distributorAffiliation = next.getSinglePrimitive();
1✔
1014
                                }
1015
                                if (DatasetFieldConstant.distributorAbbreviation.equals(next.getTypeName())) {
1✔
1016
                                    distributorAbbreviation = next.getSinglePrimitive();
1✔
1017
                                }
1018
                                if (DatasetFieldConstant.distributorURL.equals(next.getTypeName())) {
1✔
1019
                                    distributorURL = next.getSinglePrimitive();
1✔
1020
                                }
1021
                            }
1✔
1022
                            if (!distributorName.isEmpty()) {
1✔
1023
                                xmlw.writeStartElement("distrbtr");
1✔
1024
                                if(DvObjectContainer.isMetadataLanguageSet(lang)) {
1✔
1025
                                    xmlw.writeAttribute("xml:lang", lang);
1✔
1026
                                }
1027
                                XmlWriterUtil.writeAttribute(xmlw, "affiliation", distributorAffiliation);
1✔
1028
                                XmlWriterUtil.writeAttribute(xmlw, "abbr", distributorAbbreviation);
1✔
1029
                                XmlWriterUtil.writeAttribute(xmlw, "URI", distributorURL);
1✔
1030
                                xmlw.writeCharacters(distributorName);
1✔
1031
                                xmlw.writeEndElement(); //AuthEnty
1✔
1032
                            }
1033
                        }
1✔
1034
                        //xmlw.writeEndElement(); //rspStmt
1035
                    }
1036

1037
                }
1✔
1038
            }
1039
        }
1✔
1040
    }
1✔
1041
    
1042
    private static void writeRelPublElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO) throws XMLStreamException {
1043
        for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) {
1✔
1044
            String key = entry.getKey();
1✔
1045
            MetadataBlockDTO value = entry.getValue();
1✔
1046
            if ("citation".equals(key)) {
1✔
1047
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
1048
                    if (DatasetFieldConstant.publication.equals(fieldDTO.getTypeName())) {
1✔
1049
                        for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) {
1✔
1050
                            String pubString = "";
1✔
1051
                            String citation = "";
1✔
1052
                            String IDType = "";
1✔
1053
                            String IDNo = "";
1✔
1054
                            String url = "";
1✔
1055
                            for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
1056
                                FieldDTO next = iterator.next();
1✔
1057
                                if (DatasetFieldConstant.publicationCitation.equals(next.getTypeName())) {
1✔
1058
                                    citation =  next.getSinglePrimitive();
1✔
1059
                                }
1060
                                if (DatasetFieldConstant.publicationIDType.equals(next.getTypeName())) {
1✔
1061
                                    IDType =  next.getSinglePrimitive();
1✔
1062
                                }
1063
                                if (DatasetFieldConstant.publicationIDNumber.equals(next.getTypeName())) {
1✔
1064
                                    IDNo =   next.getSinglePrimitive();
1✔
1065
                                }
1066
                                if (DatasetFieldConstant.publicationURL.equals(next.getTypeName())) {
1✔
1067
                                    url =  next.getSinglePrimitive();
1✔
1068
                                }
1069
                            }
1✔
1070
                            if (citation != null && !citation.trim().equals("")) {
1✔
1071
                                xmlw.writeStartElement("relPubl");
1✔
1072
                                xmlw.writeStartElement("citation");
1✔
1073
                                /* <xs:sequence>
1074
                                    <xs:element ref="titlStmt"/>
1075
                                    <xs:element ref="rspStmt" minOccurs="0"/>
1076
                                    <xs:element ref="prodStmt" minOccurs="0"/>
1077
                                    <xs:element ref="distStmt" minOccurs="0"/>
1078
                                    <xs:element ref="serStmt" minOccurs="0" maxOccurs="unbounded"/>
1079
                                    <xs:element ref="verStmt" minOccurs="0" maxOccurs="unbounded"/>
1080
                                    <xs:element ref="biblCit" minOccurs="0" maxOccurs="unbounded"/>
1081
                                    <xs:element ref="holdings" minOccurs="0" maxOccurs="unbounded"/>
1082
                                    <xs:element ref="notes" minOccurs="0" maxOccurs="unbounded"/>
1083
                                    <xs:group ref="dc:elementsAndRefinementsGroup"/>
1084
                                   </xs:sequence>
1085
                                 (In other words - titlStmt is mandatory! -L.A.)
1086
                                */
1087
                                xmlw.writeStartElement("titlStmt");
1✔
1088
                                XmlWriterUtil.writeFullElement(xmlw, "titl", citation);
1✔
1089
                                if (IDNo != null && !IDNo.trim().equals("")) {
1✔
1090

1091
                                    xmlw.writeStartElement("IDNo");
1✔
1092
                                    if (IDType != null && !IDType.trim().equals("")) {
1✔
1093
                                        xmlw.writeAttribute("agency", IDType);
1✔
1094
                                    }
1095
                                    xmlw.writeCharacters(IDNo);
1✔
1096
                                    xmlw.writeEndElement(); //IDNo
1✔
1097
                                }
1098
                                xmlw.writeEndElement(); // titlStmt
1✔
1099

1100

1101
                                XmlWriterUtil.writeFullElement(xmlw,"biblCit",citation);
1✔
1102
                                xmlw.writeEndElement(); //citation
1✔
1103
                                if (url != null && !url.trim().equals("") ) {
1✔
1104
                                    xmlw.writeStartElement("ExtLink");
1✔
1105
                                    xmlw.writeAttribute("URI", url);
1✔
1106
                                    xmlw.writeEndElement(); //ExtLink
1✔
1107
                                }
1108
                                xmlw.writeEndElement(); //relPubl
1✔
1109
                            }
1110
                        }
1✔
1111
                    }
1112
                }
1✔
1113
            }
1114
        }
1✔
1115
    }
1✔
1116
    
1117
    private static String appendCommaSeparatedValue(String inVal, String next) {
1118
        if (!next.isEmpty()) {
×
1119
            if (!inVal.isEmpty()) {
×
1120
                return inVal + ", " + next;
×
1121
            } else {
1122
                return next;
×
1123
            }
1124
        }
1125
        return inVal;
×
1126
    }
1127
    
1128
    private static void writeAbstractElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO, String lang) throws XMLStreamException {
1129
        for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) {
1✔
1130
            String key = entry.getKey();
1✔
1131
            MetadataBlockDTO value = entry.getValue();
1✔
1132
            if ("citation".equals(key)) {
1✔
1133
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
1134
                    if (DatasetFieldConstant.description.equals(fieldDTO.getTypeName())) {
1✔
1135
                        String descriptionText = "";
1✔
1136
                        String descriptionDate = "";
1✔
1137
                        for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) {
1✔
1138
                            for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
1139
                                FieldDTO next = iterator.next();
1✔
1140
                                if (DatasetFieldConstant.descriptionText.equals(next.getTypeName())) {
1✔
1141
                                    descriptionText =  next.getSinglePrimitive();
1✔
1142
                                }
1143
                                if (DatasetFieldConstant.descriptionDate.equals(next.getTypeName())) {
1✔
1144
                                    descriptionDate =  next.getSinglePrimitive();
1✔
1145
                                }
1146
                            }
1✔
1147
                            if (!descriptionText.isEmpty()){
1✔
1148
                                xmlw.writeStartElement("abstract"); 
1✔
1149
                                XmlWriterUtil.writeAttribute(xmlw,"date",descriptionDate);
1✔
1150
                                if(DvObjectContainer.isMetadataLanguageSet(lang)) {
1✔
1151
                                    xmlw.writeAttribute("xml:lang", lang);
1✔
1152
                                }
1153
                                xmlw.writeCharacters(descriptionText);
1✔
1154
                                xmlw.writeEndElement(); //abstract
1✔
1155
                            }
1156
                        }
1✔
1157
                    }
1158
                }
1✔
1159
            }
1160
        }
1✔
1161
    }
1✔
1162

1163
    private static void writeGrantElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO) throws XMLStreamException {
1164
        for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) {
1✔
1165
            String key = entry.getKey();
1✔
1166
            MetadataBlockDTO value = entry.getValue();
1✔
1167
            if ("citation".equals(key)) {
1✔
1168
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
1169
                    if (DatasetFieldConstant.grantNumber.equals(fieldDTO.getTypeName())) {
1✔
1170
                        String grantNumber = "";
1✔
1171
                        String grantAgency = "";
1✔
1172
                        for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) {
1✔
1173
                            for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
1174
                                FieldDTO next = iterator.next();
1✔
1175
                                if (DatasetFieldConstant.grantNumberValue.equals(next.getTypeName())) {
1✔
1176
                                    grantNumber =  next.getSinglePrimitive();
1✔
1177
                                }
1178
                                if (DatasetFieldConstant.grantNumberAgency.equals(next.getTypeName())) {
1✔
1179
                                    grantAgency =  next.getSinglePrimitive();
1✔
1180
                                }
1181
                            }
1✔
1182
                            if (!grantNumber.isEmpty()){
1✔
1183
                                xmlw.writeStartElement("grantNo"); 
1✔
1184
                                XmlWriterUtil.writeAttribute(xmlw,"agency",grantAgency);
1✔
1185
                                xmlw.writeCharacters(grantNumber);
1✔
1186
                                xmlw.writeEndElement(); //grantno
1✔
1187
                            }
1188
                        }
1✔
1189
                    }
1190
                }
1✔
1191
            }
1192
        }
1✔
1193
    }
1✔
1194
    
1195
    private static void writeOtherIdElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO) throws XMLStreamException {
1196
        for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) {
1✔
1197
            String key = entry.getKey();
1✔
1198
            MetadataBlockDTO value = entry.getValue();
1✔
1199
            if ("citation".equals(key)) {
1✔
1200
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
1201
                    if (DatasetFieldConstant.otherId.equals(fieldDTO.getTypeName())) {
1✔
1202
                        String otherId = "";
1✔
1203
                        String otherIdAgency = "";
1✔
1204
                        for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) {
1✔
1205
                            for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
1206
                                FieldDTO next = iterator.next();
1✔
1207
                                if (DatasetFieldConstant.otherIdValue.equals(next.getTypeName())) {
1✔
1208
                                    otherId =  next.getSinglePrimitive();
1✔
1209
                                }
1210
                                if (DatasetFieldConstant.otherIdAgency.equals(next.getTypeName())) {
1✔
1211
                                    otherIdAgency =  next.getSinglePrimitive();
1✔
1212
                                }
1213
                            }
1✔
1214
                            if (!otherId.isEmpty()){
1✔
1215
                                xmlw.writeStartElement("IDNo"); 
1✔
1216
                                XmlWriterUtil.writeAttribute(xmlw,"agency",otherIdAgency);
1✔
1217
                                xmlw.writeCharacters(otherId);
1✔
1218
                                xmlw.writeEndElement(); //IDNo
1✔
1219
                            }
1220
                        }
1✔
1221
                    }
1222
                }
1✔
1223
            }
1224
        }
1✔
1225
    }
1✔
1226
    
1227
    private static void writeSoftwareElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO) throws XMLStreamException {
1228
        for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) {
1✔
1229
            String key = entry.getKey();
1✔
1230
            MetadataBlockDTO value = entry.getValue();
1✔
1231
            if ("citation".equals(key)) {
1✔
1232
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
1233
                    if (DatasetFieldConstant.software.equals(fieldDTO.getTypeName())) {
1✔
1234
                        String softwareName = "";
1✔
1235
                        String softwareVersion = "";
1✔
1236
                        for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) {
1✔
1237
                            for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
1238
                                FieldDTO next = iterator.next();
1✔
1239
                                if (DatasetFieldConstant.softwareName.equals(next.getTypeName())) {
1✔
1240
                                    softwareName =  next.getSinglePrimitive();
1✔
1241
                                }
1242
                                if (DatasetFieldConstant.softwareVersion.equals(next.getTypeName())) {
1✔
1243
                                    softwareVersion =  next.getSinglePrimitive();
1✔
1244
                                }
1245
                            }
1✔
1246
                            if (!softwareName.isEmpty()){
1✔
1247
                                xmlw.writeStartElement("software"); 
1✔
1248
                                XmlWriterUtil.writeAttribute(xmlw,"version",softwareVersion);
1✔
1249
                                xmlw.writeCharacters(softwareName);
1✔
1250
                                xmlw.writeEndElement(); //software
1✔
1251
                            }
1252
                        }
1✔
1253
                    }
1254
                }
1✔
1255
            }
1256
        }
1✔
1257
    }
1✔
1258
    
1259
    private static void writeSeriesElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO) throws XMLStreamException {
1260
        for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) {
1✔
1261
            String key = entry.getKey();
1✔
1262
            MetadataBlockDTO value = entry.getValue();
1✔
1263
            if ("citation".equals(key)) {               
1✔
1264
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
1265
                    if (DatasetFieldConstant.series.equals(fieldDTO.getTypeName())) {
1✔
1266
                        String seriesName = "";
1✔
1267
                        String seriesInformation = "";
1✔
1268
                        for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) {
1✔
1269
                            xmlw.writeStartElement("serStmt");
1✔
1270
                            for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
1271
                                FieldDTO next = iterator.next();
1✔
1272
                                if (DatasetFieldConstant.seriesName.equals(next.getTypeName())) {
1✔
1273
                                    seriesName = next.getSinglePrimitive();
1✔
1274
                                }
1275
                                if (DatasetFieldConstant.seriesInformation.equals(next.getTypeName())) {
1✔
1276
                                    seriesInformation = next.getSinglePrimitive();
1✔
1277
                                }
1278
                            }
1✔
1279
                            if (!seriesName.isEmpty()) {
1✔
1280
                                xmlw.writeStartElement("serName");
1✔
1281
                                xmlw.writeCharacters(seriesName);
1✔
1282
                                xmlw.writeEndElement(); //serName
1✔
1283
                            }
1284
                            if (!seriesInformation.isEmpty()) {
1✔
1285
                                xmlw.writeStartElement("serInfo");
1✔
1286
                                xmlw.writeCharacters(seriesInformation);
1✔
1287
                                xmlw.writeEndElement(); //serInfo
1✔
1288
                            }
1289
                            xmlw.writeEndElement(); //serStmt
1✔
1290
                        }
1✔
1291
                    }
1292
                }
1✔
1293
            }
1294
        }
1✔
1295
    }
1✔
1296
    
1297
    private static void writeTargetSampleElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO) throws XMLStreamException {
1298
        for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) {
1✔
1299
            String key = entry.getKey();
1✔
1300
            MetadataBlockDTO value = entry.getValue();
1✔
1301
            if ("socialscience".equals(key)) {
1✔
1302
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
1303
                    if (DatasetFieldConstant.targetSampleSize.equals(fieldDTO.getTypeName())) {
1✔
1304
                        xmlw.writeStartElement("targetSampleSize");
1✔
1305
                        String sizeFormula = "";
1✔
1306
                        String actualSize = "";
1✔
1307
                        Set<FieldDTO> foo = fieldDTO.getSingleCompound();
1✔
1308
                        for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
1309
                            FieldDTO next = iterator.next();
1✔
1310
                            if (DatasetFieldConstant.targetSampleSizeFormula.equals(next.getTypeName())) {
1✔
1311
                                sizeFormula = next.getSinglePrimitive();
1✔
1312
                            }
1313
                            if (DatasetFieldConstant.targetSampleActualSize.equals(next.getTypeName())) {
1✔
1314
                                actualSize = next.getSinglePrimitive();
1✔
1315
                            }
1316
                        }
1✔
1317
                        /* <sampleSize> must come before <sampleSizeFormula>! -L.A. */
1318
                        if (!actualSize.isEmpty()) {
1✔
1319
                            xmlw.writeStartElement("sampleSize");
1✔
1320
                            xmlw.writeCharacters(actualSize);
1✔
1321
                            xmlw.writeEndElement(); //sampleSize
1✔
1322
                        }
1323
                        if (!sizeFormula.isEmpty()) {
1✔
1324
                            xmlw.writeStartElement("sampleSizeFormula");
1✔
1325
                            xmlw.writeCharacters(sizeFormula);
1✔
1326
                            xmlw.writeEndElement(); //sampleSizeFormula
1✔
1327
                        }
1328
                        
1329
                        xmlw.writeEndElement(); // targetSampleSize
1✔
1330
                    }
1331
                }
1✔
1332
            }
1333
        }
1✔
1334
    }
1✔
1335
    
1336
    private static void writeNotesElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO) throws XMLStreamException {
1337
        for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) {
1✔
1338
            String key = entry.getKey();
1✔
1339
            MetadataBlockDTO value = entry.getValue();
1✔
1340
            if ("socialscience".equals(key)) {
1✔
1341
                for (FieldDTO fieldDTO : value.getFields()) {
1✔
1342
                    if (DatasetFieldConstant.socialScienceNotes.equals(fieldDTO.getTypeName())) {
1✔
1343
                        String notesText = "";
1✔
1344
                        String notesType = "";
1✔
1345
                        String notesSubject= "";
1✔
1346
                        Set<FieldDTO> foo = fieldDTO.getSingleCompound();
1✔
1347
                        for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) {
1✔
1348
                            FieldDTO next = iterator.next();
1✔
1349
                            if (DatasetFieldConstant.socialScienceNotesText.equals(next.getTypeName())) {
1✔
1350
                                notesText = next.getSinglePrimitive();
1✔
1351
                            }
1352
                            if (DatasetFieldConstant.socialScienceNotesType.equals(next.getTypeName())) {
1✔
1353
                                notesType = next.getSinglePrimitive();
1✔
1354
                            }
1355
                            if (DatasetFieldConstant.socialScienceNotesSubject.equals(next.getTypeName())) {
1✔
1356
                                notesSubject = next.getSinglePrimitive();
1✔
1357
                            }
1358
                        }
1✔
1359
                        if (!notesText.isEmpty()) {
1✔
1360
                            xmlw.writeStartElement("notes");
1✔
1361
                            XmlWriterUtil.writeAttribute(xmlw,"type",notesType);
1✔
1362
                            XmlWriterUtil.writeAttribute(xmlw,"subject",notesSubject);
1✔
1363
                            xmlw.writeCharacters(notesText);
1✔
1364
                            xmlw.writeEndElement(); 
1✔
1365
                        }
1366
                    }
1367
                }
1✔
1368
            }
1369
        }
1✔
1370
    }
1✔
1371
    
1372
    // TODO: 
1373
    // see if there's more information that we could encode in this otherMat. 
1374
    // contentType? Unfs and such? (in the "short" DDI that is being used for 
1375
    // harvesting *all* files are encoded as otherMats; even tabular ones.
1376
    private static void createOtherMats(XMLStreamWriter xmlw, List<FileDTO> fileDtos) throws XMLStreamException {
1377
        // The preferred URL for this dataverse, for cooking up the file access API links:
1378
        String dataverseUrl = SystemConfig.getDataverseSiteUrlStatic();
1✔
1379
        
1380
        for (FileDTO fileDTo : fileDtos) {
1✔
1381
            // We'll continue using the scheme we've used before, in DVN2-3: non-tabular files are put into otherMat,
1382
            // tabular ones - in fileDscr sections. (fileDscr sections have special fields for numbers of variables
1383
            // and observations, etc.)
1384
            if (fileDTo.getDataFile().getDataTables() == null || fileDTo.getDataFile().getDataTables().isEmpty()) {
1✔
1385
                xmlw.writeStartElement("otherMat");
1✔
1386
                XmlWriterUtil.writeAttribute(xmlw, "ID", "f" + fileDTo.getDataFile().getId());
1✔
1387
                String pidURL = fileDTo.getDataFile().getPidURL();
1✔
1388
                if (pidURL != null && !pidURL.isEmpty()){
1✔
1389
                    xmlw.writeAttribute("URI", pidURL);
×
1390
                } else {
1391
                    xmlw.writeAttribute("URI", dataverseUrl + "/api/access/datafile/" + fileDTo.getDataFile().getId());
1✔
1392
                }
1393
                xmlw.writeAttribute("level", "datafile");
1✔
1394
                xmlw.writeStartElement("labl");
1✔
1395
                xmlw.writeCharacters(fileDTo.getDataFile().getFilename());
1✔
1396
                xmlw.writeEndElement(); // labl
1✔
1397
                writeFileDescription(xmlw, fileDTo);
1✔
1398
                // there's no readily available field in the othermat section 
1399
                // for the content type (aka mime type); so we'll store it in this
1400
                // specially formatted notes section:
1401
                String contentType = fileDTo.getDataFile().getContentType();
1✔
1402
                if (!StringUtilisEmpty(contentType)) {
1✔
1403
                    xmlw.writeStartElement("notes");
1✔
1404
                    xmlw.writeAttribute("level", LEVEL_FILE);
1✔
1405
                    xmlw.writeAttribute("type", NOTE_TYPE_CONTENTTYPE);
1✔
1406
                    xmlw.writeAttribute("subject", NOTE_SUBJECT_CONTENTTYPE);
1✔
1407
                    xmlw.writeCharacters(contentType);
1✔
1408
                    xmlw.writeEndElement(); // notes
1✔
1409
                }
1410
                xmlw.writeEndElement(); // otherMat
1✔
1411
            }
1412
        }
1✔
1413
    }
1✔
1414
    
1415
    // An alternative version of the createOtherMats method - this one is used 
1416
    // when a "full" DDI is being cooked; just like the fileDscr and data/var sections methods, 
1417
    // it operates on the list of FileMetadata entities, not on File DTOs. This is because
1418
    // DTOs do not support "tabular", variable-level metadata yet. And we need to be able to 
1419
    // tell if this file is in fact tabular data - so that we know if it needs an
1420
    // otherMat, or a fileDscr section. 
1421
    // -- L.A. 4.5 
1422
    
1423
    private static void createOtherMatsFromFileMetadatas(XMLStreamWriter xmlw, JsonArray fileDetails) throws XMLStreamException {
1424
        // The preferred URL for this dataverse, for cooking up the file access API links:
1425
        String dataverseUrl = SystemConfig.getDataverseSiteUrlStatic();
1✔
1426
        
1427
        for (int i=0;i<fileDetails.size();i++) {
1✔
1428
            JsonObject fileJson = fileDetails.getJsonObject(i);
×
1429
            // We'll continue using the scheme we've used before, in DVN2-3: non-tabular files are put into otherMat,
1430
            // tabular ones - in fileDscr sections. (fileDscr sections have special fields for numbers of variables
1431
            // and observations, etc.)
1432
            if (!fileJson.containsKey("dataTables")) {
×
1433
                xmlw.writeStartElement("otherMat");
×
1434
                xmlw.writeAttribute("ID", "f" + fileJson.getJsonNumber(("id").toString()));
×
1435
                if (fileJson.containsKey("pidUrl")){
×
NEW
1436
                    XmlWriterUtil.writeAttribute(xmlw, "URI",  fileJson.getString("pidUrl"));
×
1437
                }  else {
NEW
1438
                    xmlw.writeAttribute("URI", dataverseUrl + "/api/access/datafile/" + fileJson.getJsonNumber("id").toString());
×
1439
                }
1440

1441
                xmlw.writeAttribute("level", "datafile");
×
1442
                xmlw.writeStartElement("labl");
×
1443
                xmlw.writeCharacters(fileJson.getString("filename"));
×
1444
                xmlw.writeEndElement(); // labl
×
1445
                
1446
                if (fileJson.containsKey("description")) {
×
1447
                    xmlw.writeStartElement("txt");
×
1448
                    xmlw.writeCharacters(fileJson.getString("description"));
×
1449
                    xmlw.writeEndElement(); // txt
×
1450
                }
1451
                // there's no readily available field in the othermat section 
1452
                // for the content type (aka mime type); so we'll store it in this
1453
                // specially formatted notes section:
1454
                if (fileJson.containsKey("contentType")) {
×
1455
                    xmlw.writeStartElement("notes");
×
1456
                    xmlw.writeAttribute("level", LEVEL_FILE);
×
1457
                    xmlw.writeAttribute("type", NOTE_TYPE_CONTENTTYPE);
×
1458
                    xmlw.writeAttribute("subject", NOTE_SUBJECT_CONTENTTYPE);
×
1459
                    xmlw.writeCharacters(fileJson.getString("contentType"));
×
1460
                    xmlw.writeEndElement(); // notes
×
1461
                }
1462
                xmlw.writeEndElement(); // otherMat
×
1463
            }
1464
        }
1465
    }
1✔
1466
    
1467
    private static void writeFileDescription(XMLStreamWriter xmlw, FileDTO fileDTo) throws XMLStreamException {
1468
        xmlw.writeStartElement("txt");
1✔
1469
        String description = fileDTo.getDataFile().getDescription();
1✔
1470
        if (description != null) {
1✔
1471
            xmlw.writeCharacters(description);
1✔
1472
        }
1473
        xmlw.writeEndElement(); // txt
1✔
1474
    }
1✔
1475
    
1476

1477
    
1478
    private static List<String> dto2PrimitiveList(DatasetVersionDTO datasetVersionDTO, String datasetFieldTypeName) {
1479
        for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) {
1✔
1480
            MetadataBlockDTO value = entry.getValue();
1✔
1481
            for (FieldDTO fieldDTO : value.getFields()) {
1✔
1482
                if (datasetFieldTypeName.equals(fieldDTO.getTypeName())) {
1✔
1483
                    // This hack is here to make sure the export does not blow 
1484
                    // up on an instance that upgraded to a Dataverse version
1485
                    // where a certain primitive has been made multiple, but has
1486
                    // not yet update the block. 
1487
                    if (fieldDTO.getMultiple() != null && fieldDTO.getMultiple()) {
1✔
1488
                        return fieldDTO.getMultiplePrimitive();
1✔
1489
                    } else {
1490
                        return Arrays.asList(fieldDTO.getSinglePrimitive());
×
1491
                    }
1492
                }
1493
            }
1✔
1494
        }
1✔
1495
        return null;
1✔
1496
    }
1497
    
1498
    private static FieldDTO dto2FieldDTO(DatasetVersionDTO datasetVersionDTO, String datasetFieldTypeName, String metadataBlockName) {
1499
        MetadataBlockDTO block = datasetVersionDTO.getMetadataBlocks().get(metadataBlockName);
1✔
1500
        if (block != null) {
1✔
1501
            for (FieldDTO fieldDTO : block.getFields()) {
1✔
1502
                if (datasetFieldTypeName.equals(fieldDTO.getTypeName())) {
1✔
1503
                    return fieldDTO;
1✔
1504
                }
1505
            }
1✔
1506
        }
1507
        return null;
1✔
1508
    }
1509

1510

1511
    private static boolean StringUtilisEmpty(String str) {
1512
        if (str == null || str.trim().equals("")) {
1✔
1513
            return true;
×
1514
        }
1515
        return false;
1✔
1516
    }
1517

1518
    private static void saveJsonToDisk(String datasetVersionAsJson) throws IOException {
1519
        Files.write(Paths.get("/tmp/out.json"), datasetVersionAsJson.getBytes());
×
1520
    }
×
1521
    
1522
    
1523
    
1524
    
1525
    // Methods specific to the tabular data ("<dataDscr>") section. 
1526
    // Note that these do NOT operate on DTO objects, but instead directly 
1527
    // on Dataverse DataVariable, DataTable, etc. objects. 
1528
    // This is because for this release (4.5) we are recycling the already available 
1529
    // code, and this is what we got. (We already have DTO objects for DataTable, 
1530
    // and DataVariable, etc., but the current version JsonPrinter.jsonAsDatasetDto() 
1531
    // does not produce JSON for these objects - it stops at DataFile. Eventually 
1532
    // we want all of our objects to be exportable as JSON, and then all the exports
1533
    // can go through the same DTO state... But we don't have time for it now; 
1534
    // plus, the structure of file-level metadata is currently being re-designed, 
1535
    // so we probably should not invest any time into it right now). -- L.A. 4.5
1536
    
1537
    public static void createDataDscr(XMLStreamWriter xmlw, JsonArray fileDetails) throws XMLStreamException {
1538

1539
        if (fileDetails.isEmpty()) {
1✔
1540
            return;
1✔
1541
        }
1542

1543
        boolean tabularData = false;
×
1544

1545
        // we're not writing the opening <dataDscr> tag until we find an actual 
1546
        // tabular datafile.
1547
        for (int i=0;i<fileDetails.size();i++) {
×
1548
            JsonObject fileJson = fileDetails.getJsonObject(i);
×
1549

1550
            /**
1551
             * Previously (in Dataverse 5.3 and below) the dataDscr section was
1552
             * included for restricted files but that meant that summary
1553
             * statistics were exposed. (To get at these statistics, API users
1554
             * should instead use the "Data Variable Metadata Access" endpoint.)
1555
             * These days we skip restricted files to avoid this exposure.
1556
             */
1557
            if (fileJson.containsKey("restricted") && fileJson.getBoolean("restricted")) {
×
1558
                continue;
×
1559
            }
1560
            if(fileJson.containsKey("embargo")) {
×
1561
             String dateString = fileJson.getJsonObject("embargo").getString("dateAvailable");
×
1562
             LocalDate endDate = LocalDate.parse(dateString);
×
1563
             if (endDate != null && endDate.isAfter(LocalDate.now())) {
×
1564
                 //Embargo is active so skip
1565
                 continue;
×
1566
             }
1567
            }
1568
        
1569
            if (fileJson.containsKey("dataTables")) {
×
1570
                if (!tabularData) {
×
1571
                    xmlw.writeStartElement("dataDscr");
×
1572
                    tabularData = true;
×
1573
                }
1574
                if(fileJson.containsKey("varGroups")) {
×
1575
                    JsonArray varGroups = fileJson.getJsonArray("varGroups");
×
1576
                    for (int j=0;j<varGroups.size();j++){
×
1577
                        createVarGroupDDI(xmlw, varGroups.getJsonObject(j));
×
1578
                    }
1579
                }
1580
                JsonObject dataTable = fileJson.getJsonArray("dataTables").getJsonObject(0);
×
1581
                JsonArray vars = dataTable.getJsonArray("dataVariables");
×
1582
                if (vars != null) {
×
1583
                    for (int j = 0; j < vars.size(); j++) {
×
1584
                        createVarDDI(xmlw, vars.getJsonObject(j), fileJson.getJsonNumber("id").toString(),
×
1585
                                fileJson.getJsonNumber("fileMetadataId").toString());
×
1586
                    }
1587
                }
1588
            }
1589
        }
1590

1591
        if (tabularData) {
×
1592
            xmlw.writeEndElement(); // dataDscr
×
1593
        }
1594
    }
×
1595
    private static void createVarGroupDDI(XMLStreamWriter xmlw, JsonObject varGrp) throws XMLStreamException {
1596
        xmlw.writeStartElement("varGrp");
×
1597
        xmlw.writeAttribute("ID", "VG" + varGrp.getJsonNumber("id").toString());
×
1598
        String vars = "";
×
1599
        JsonArray varsInGroup = varGrp.getJsonArray("dataVariableIds");
×
1600
        for (int j=0;j<varsInGroup.size();j++){
×
1601
            vars = vars + " v" + varsInGroup.getString(j);
×
1602
        }
1603
        vars = vars.trim();
×
1604
        XmlWriterUtil.writeAttribute(xmlw, "var", vars );
×
1605

1606

1607
        if (varGrp.containsKey("label")) {
×
1608
            xmlw.writeStartElement("labl");
×
1609
            xmlw.writeCharacters(varGrp.getString("label"));
×
1610
            xmlw.writeEndElement(); // group label (labl)
×
1611
        }
1612

1613
        xmlw.writeEndElement(); //varGrp
×
1614
    }
×
1615
    
1616
    private static void createVarDDI(XMLStreamWriter xmlw, JsonObject dvar, String fileId, String fileMetadataId) throws XMLStreamException {
1617
        xmlw.writeStartElement("var");
×
1618
        xmlw.writeAttribute("ID", "v" + dvar.getJsonNumber("id").toString());
×
1619
        XmlWriterUtil.writeAttribute(xmlw, "name", dvar.getString("name"));
×
1620

1621
        JsonObject vm = null;
×
1622
        JsonArray vmArray = dvar.getJsonArray("variableMetadata"); 
×
1623
        for (int i=0;i< vmArray.size();i++) {
×
1624
            JsonObject curVm =vmArray.getJsonObject(i); 
×
1625
            if (curVm.containsKey("fileMetadataId") && curVm.getString("fileMetadataId").equals(fileMetadataId) ){
×
1626
                vm = curVm;
×
1627
                break;
×
1628
            }
1629
        }
1630

1631
        if (dvar.containsKey("numberOfDecimalPoints")) {
×
1632
            XmlWriterUtil.writeAttribute(xmlw, "dcml", dvar.getJsonNumber("numberOfDecimalPoints").toString());
×
1633
        }
1634

1635
        if (dvar.getBoolean("isOrderedCategorical")) {
×
1636
            xmlw.writeAttribute("nature", "ordinal");
×
1637
        }
1638

1639
        if (dvar.containsKey("variableIntervalType")) {
×
1640
            XmlWriterUtil.writeAttribute(xmlw, "intrvl", dvar.getString("variableIntervalType"));
×
1641
        }
1642

1643
        if (vm != null) {
×
1644
            if (vm.getBoolean("isWeightvar")) {
×
1645
                xmlw.writeAttribute("wgt", "wgt");
×
1646
            }
1647
            if (vm.containsKey("isWeighted") && vm.containsKey("weightVariableId")) {
×
1648
                xmlw.writeAttribute("wgt-var", "v"+vm.getString("weightVariableId"));
×
1649
            }
1650
        }
1651

1652
        // location
1653
        xmlw.writeEmptyElement("location");
×
1654
        if (dvar.containsKey("fileStartPosition")) {
×
1655
            XmlWriterUtil.writeAttribute(xmlw, "StartPos", dvar.getJsonNumber("fileStartPosition").toString());
×
1656
        }
1657
        if (dvar.containsKey("fileEndPosition")) {
×
1658
            XmlWriterUtil.writeAttribute(xmlw, "EndPos", dvar.getJsonNumber("fileEndPosition").toString());
×
1659
        }
1660
        if (dvar.containsKey("recordSegmentNumber")) {
×
1661
            XmlWriterUtil.writeAttribute(xmlw, "RecSegNo", dvar.getJsonNumber("recordSegmentNumber").toString());
×
1662
        }
1663

1664
        xmlw.writeAttribute("fileid", "f" + fileId);
×
1665

1666
        // labl
1667
        if ((vm == null || !vm.containsKey("label"))) {
×
1668
            if(dvar.containsKey("label")) {
×
1669
                xmlw.writeStartElement("labl");
×
1670
                xmlw.writeAttribute("level", "variable");
×
1671
                xmlw.writeCharacters(dvar.getString("label"));
×
1672
                xmlw.writeEndElement(); //labl
×
1673
            }
1674
        } else {
1675
            xmlw.writeStartElement("labl");
×
1676
            xmlw.writeAttribute("level", "variable");
×
1677
            xmlw.writeCharacters(vm.getString("label"));
×
1678
            xmlw.writeEndElement(); //labl
×
1679
        }
1680

1681
        if (vm != null) {
×
1682
            if (vm.containsKey("literalQuestion") || vm.containsKey("interviewInstruction") || vm.containsKey("postQuestion")) {
×
1683
                xmlw.writeStartElement("qstn");
×
1684
                if (vm.containsKey("literalQuestion")) {
×
1685
                    xmlw.writeStartElement("qstnLit");
×
1686
                    xmlw.writeCharacters(vm.getString("literalQuestion"));
×
1687
                    xmlw.writeEndElement(); // qstnLit
×
1688
                }
1689
                if (vm.containsKey("interviewInstruction")) {
×
1690
                    xmlw.writeStartElement("ivuInstr");
×
1691
                    xmlw.writeCharacters(vm.getString("interviewInstruction"));
×
1692
                    xmlw.writeEndElement(); //ivuInstr
×
1693
                }
1694
                if (vm.containsKey("postQuestion")) {
×
1695
                    xmlw.writeStartElement("postQTxt");
×
1696
                    xmlw.writeCharacters(vm.getString("postQuestion"));
×
1697
                    xmlw.writeEndElement(); //ivuInstr
×
1698
                }
1699
                xmlw.writeEndElement(); //qstn
×
1700
            }
1701
        }
1702

1703
        // invalrng
1704
        if (dvar.containsKey("invalidRanges")) {
×
1705
            boolean invalrngAdded = false;
×
1706
            JsonArray ranges = dvar.getJsonArray("invalidRanges");
×
1707
            for (int i = 0; i < ranges.size(); i++) {
×
1708
                JsonObject range = ranges.getJsonObject(0);
×
1709
                // if (range.getBeginValueType() != null &&
1710
                // range.getBeginValueType().getName().equals(DB_VAR_RANGE_TYPE_POINT)) {
1711
                if (range.getBoolean("hasBeginValueType") && range.getBoolean("isBeginValueTypePoint")) {
×
1712
                    if (range.containsKey("beginValue")) {
×
1713
                        invalrngAdded = XmlWriterUtil.writeOpenTagIfNeeded(xmlw, "invalrng", invalrngAdded);
×
1714
                        xmlw.writeEmptyElement("item");
×
1715
                        XmlWriterUtil.writeAttribute(xmlw, "VALUE", range.getString("beginValue"));
×
1716
                    }
1717
                } else {
1718
                    invalrngAdded = XmlWriterUtil.writeOpenTagIfNeeded(xmlw, "invalrng", invalrngAdded);
×
1719
                    xmlw.writeEmptyElement("range");
×
1720
                    if (range.getBoolean("hasBeginValueType") && range.containsKey("beginValue")) {
×
1721
                        if (range.getBoolean("isBeginValueTypeMin")) {
×
1722
                            XmlWriterUtil.writeAttribute(xmlw, "min", range.getString("beginValue"));
×
1723
                        } else if (range.getBoolean("isBeginValueTypeMinExcl")) {
×
1724
                            XmlWriterUtil.writeAttribute(xmlw, "minExclusive", range.getString("beginValue"));
×
1725
                        }
1726
                    }
1727
                    if (range.getBoolean("hasEndValueType") && range.containsKey("endValue")) {
×
1728
                        if (range.getBoolean("isEndValueTypeMax")) {
×
1729
                            XmlWriterUtil.writeAttribute(xmlw, "max", range.getString("endValue"));
×
1730
                        } else if (range.getBoolean("isEndValueTypeMaxExcl")) {
×
1731
                            XmlWriterUtil.writeAttribute(xmlw, "maxExclusive", range.getString("endValue"));
×
1732
                        }
1733
                    }
1734
                }
1735
            }
1736
            if (invalrngAdded) {
×
1737
                xmlw.writeEndElement(); // invalrng
×
1738
            }
1739
        }
1740

1741
        //universe
1742
        if (vm != null) {
×
1743
            if (vm.containsKey("universe")) {
×
1744
                xmlw.writeStartElement("universe");
×
1745
                xmlw.writeCharacters(vm.getString("universe"));
×
1746
                xmlw.writeEndElement(); //universe
×
1747
            }
1748
        }
1749

1750
        // sum stats
1751
        if (dvar.containsKey("summaryStatistics")) {
×
1752
            for (Entry<String, JsonValue> sumStat : dvar.getJsonObject("summaryStatistics").entrySet()) {
×
1753
                xmlw.writeStartElement("sumStat");
×
1754
                XmlWriterUtil.writeAttribute(xmlw, "type", sumStat.getKey());
×
1755
                xmlw.writeCharacters(((JsonString)sumStat.getValue()).getString());
×
1756
                xmlw.writeEndElement(); // sumStat
×
1757
            }
×
1758
        }
1759

1760
        // categories
1761
        if (dvar.containsKey("variableCategories")) {
×
1762
            JsonArray varCats = dvar.getJsonArray("variableCategories");
×
1763
            for (int i = 0; i < varCats.size(); i++) {
×
1764
                JsonObject varCat = varCats.getJsonObject(i);
×
1765
                xmlw.writeStartElement("catgry");
×
1766
                if (varCat.getBoolean("isMissing")) {
×
1767
                    xmlw.writeAttribute("missing", "Y");
×
1768
                }
1769

1770
                // catValu
1771
                xmlw.writeStartElement("catValu");
×
1772
                xmlw.writeCharacters(varCat.getString("value"));
×
1773
                xmlw.writeEndElement(); // catValu
×
1774

1775
                // label
1776
                if (varCat.containsKey("label")) {
×
1777
                    xmlw.writeStartElement("labl");
×
1778
                    xmlw.writeAttribute("level", "category");
×
1779
                    xmlw.writeCharacters(varCat.getString("label"));
×
1780
                    xmlw.writeEndElement(); // labl
×
1781
                }
1782

1783
                // catStat
1784
                if (varCat.containsKey("frequency")) {
×
1785
                    xmlw.writeStartElement("catStat");
×
1786
                    xmlw.writeAttribute("type", "freq");
×
1787
                    Double freq = varCat.getJsonNumber("frequency").doubleValue();
×
1788
                    // if frequency is actually a long value, we want to write "100" instead of
1789
                    // "100.0"
1790
                    if (Math.floor(freq) == freq) {
×
1791
                        xmlw.writeCharacters(Long.valueOf(freq.longValue()).toString());
×
1792
                    } else {
1793
                        xmlw.writeCharacters(freq.toString());
×
1794
                    }
1795
                    xmlw.writeEndElement(); // catStat
×
1796
                }
1797

1798
                // catStat weighted freq
1799
                if (vm != null && vm.getBoolean("isWeighted")) {
×
1800
                    JsonArray catMetas = vm.getJsonArray("categoryMetadatas");
×
1801
                    for (int j = 0; i < catMetas.size(); j++) {
×
1802
                        JsonObject cm = catMetas.getJsonObject(j);
×
1803
                        if (cm.getString("categoryValue").equals(varCat.getString("value"))) {
×
1804
                            xmlw.writeStartElement("catStat");
×
1805
                            xmlw.writeAttribute("wgtd", "wgtd");
×
1806
                            xmlw.writeAttribute("type", "freq");
×
1807
                            xmlw.writeCharacters(cm.getJsonNumber("wFreq").toString());
×
1808
                            xmlw.writeEndElement(); // catStat
×
1809
                            break;
×
1810
                        }
1811
                    }
1812
                }
1813

1814
                xmlw.writeEndElement(); // catgry
×
1815
            }
1816
        }
1817

1818

1819
        // varFormat
1820
        xmlw.writeEmptyElement("varFormat");
×
1821
        if(dvar.containsKey("variableFormatType")) {
×
1822
            XmlWriterUtil.writeAttribute(xmlw, "type", dvar.getString("variableFormatType").toLowerCase());
×
1823
        } else {
1824
            throw new XMLStreamException("Illegal Variable Format Type!");
×
1825
        }
1826
        if(dvar.containsKey("format")) {
×
1827
            XmlWriterUtil.writeAttribute(xmlw, "formatname", dvar.getString("format"));
×
1828
        }
1829
        //experiment writeAttribute(xmlw, "schema", dv.getFormatSchema());
1830
        if(dvar.containsKey("formatCategory")) {
×
1831
            XmlWriterUtil.writeAttribute(xmlw, "category", dvar.getString("formatCategory"));
×
1832
        }
1833

1834
        // notes
1835
        if (dvar.containsKey("UNF") && !dvar.getString("UNF").isBlank()) {
×
1836
            xmlw.writeStartElement("notes");
×
1837
            xmlw.writeAttribute("subject", "Universal Numeric Fingerprint");
×
1838
            xmlw.writeAttribute("level", "variable");
×
1839
            xmlw.writeAttribute("type", "Dataverse:UNF");
×
1840
            xmlw.writeCharacters(dvar.getString("UNF"));
×
1841
            xmlw.writeEndElement(); //notes
×
1842
        }
1843

1844
        if (vm != null) {
×
1845
            if (vm.containsKey("notes")) {
×
1846
                xmlw.writeStartElement("notes");
×
1847
                xmlw.writeCData(vm.getString("notes"));
×
1848
                xmlw.writeEndElement(); //notes CDATA
×
1849
            }
1850
        }
1851

1852

1853

1854
        xmlw.writeEndElement(); //var
×
1855

1856
    }
×
1857
    
1858
    private static void createFileDscr(XMLStreamWriter xmlw, JsonArray fileDetails) throws XMLStreamException {
1859
        String dataverseUrl = SystemConfig.getDataverseSiteUrlStatic();
1✔
1860
        for (int i =0;i<fileDetails.size();i++) {
1✔
1861
            JsonObject fileJson = fileDetails.getJsonObject(i);
×
1862
            //originalFileFormat is one of several keys that only exist for tabular data
1863
            if (fileJson.containsKey("originalFileFormat")) {
×
1864
                JsonObject dt = null;
×
1865
                if (fileJson.containsKey("dataTables")) {
×
1866
                    dt = fileJson.getJsonArray("dataTables").getJsonObject(0);
×
1867
                }
1868
                xmlw.writeStartElement("fileDscr");
×
1869
                String fileId = fileJson.getJsonNumber("id").toString();
×
1870
                xmlw.writeAttribute("ID", "f" + fileId);
×
1871
                xmlw.writeAttribute("URI", dataverseUrl + "/api/access/datafile/" + fileId);
×
1872

1873
                xmlw.writeStartElement("fileTxt");
×
1874
                xmlw.writeStartElement("fileName");
×
1875
                xmlw.writeCharacters(fileJson.getString("filename"));
×
1876
                xmlw.writeEndElement(); // fileName
×
1877

1878
                if (dt != null && (dt.containsKey("caseQuantity") || dt.containsKey("varQuantity")
×
1879
                        || dt.containsKey("recordsPerCase"))) {
×
1880
                    xmlw.writeStartElement("dimensns");
×
1881

1882
                    if (dt.containsKey("caseQuantity")) {
×
1883
                        xmlw.writeStartElement("caseQnty");
×
1884
                        xmlw.writeCharacters(dt.getJsonNumber("caseQuantity").toString());
×
1885
                        xmlw.writeEndElement(); // caseQnty
×
1886
                    }
1887

1888
                    if (dt.containsKey("varQuantity")) {
×
1889
                        xmlw.writeStartElement("varQnty");
×
1890
                        xmlw.writeCharacters(dt.getJsonNumber("varQuantity").toString());
×
1891
                        xmlw.writeEndElement(); // varQnty
×
1892
                    }
1893

1894
                    if (dt.containsKey("recordsPerCase")) {
×
1895
                        xmlw.writeStartElement("recPrCas");
×
1896
                        xmlw.writeCharacters(dt.getJsonNumber("recordsPerCase").toString());
×
1897
                        xmlw.writeEndElement(); // recPrCas
×
1898
                    }
1899

1900
                    xmlw.writeEndElement(); // dimensns
×
1901
                }
1902

1903
                xmlw.writeStartElement("fileType");
×
1904
                xmlw.writeCharacters(fileJson.getString("contentType"));
×
1905
                xmlw.writeEndElement(); // fileType
×
1906

1907
                xmlw.writeEndElement(); // fileTxt
×
1908

1909
                // various notes:
1910
                // this specially formatted note section is used to store the UNF
1911
                // (Universal Numeric Fingerprint) signature:
1912
                if ((dt!=null) && (dt.containsKey("UNF") && !dt.getString("UNF").isBlank())) {
×
1913
                    xmlw.writeStartElement("notes");
×
1914
                    xmlw.writeAttribute("level", LEVEL_FILE);
×
1915
                    xmlw.writeAttribute("type", NOTE_TYPE_UNF);
×
1916
                    xmlw.writeAttribute("subject", NOTE_SUBJECT_UNF);
×
1917
                    xmlw.writeCharacters(dt.getString("UNF"));
×
1918
                    xmlw.writeEndElement(); // notes
×
1919
                }
1920

1921
                // If any tabular tags are present, each is formatted in a 
1922
                // dedicated note:
1923
                if (fileJson.containsKey("tabularTags")) {
×
1924
                    JsonArray tags = fileJson.getJsonArray("tabularTags");
×
1925
                    for (int j = 0; j < tags.size(); j++) {
×
1926
                        xmlw.writeStartElement("notes");
×
1927
                        xmlw.writeAttribute("level", LEVEL_FILE);
×
1928
                        xmlw.writeAttribute("type", NOTE_TYPE_TAG);
×
1929
                        xmlw.writeAttribute("subject", NOTE_SUBJECT_TAG);
×
1930
                        xmlw.writeCharacters(tags.getString(j));
×
1931
                        xmlw.writeEndElement(); // notes
×
1932
                    }
1933
                }
1934
                
1935
                // Adding a dedicated node for the description entry (for 
1936
                // non-tabular files we format it under the <txt> field)
1937
                if (fileJson.containsKey("description")) {
×
1938
                    xmlw.writeStartElement("notes");
×
1939
                    xmlw.writeAttribute("level", LEVEL_FILE);
×
1940
                    xmlw.writeAttribute("type", NOTE_TYPE_FILEDESCRIPTION);
×
1941
                    xmlw.writeAttribute("subject", NOTE_SUBJECT_FILEDESCRIPTION);
×
1942
                    xmlw.writeCharacters(fileJson.getString("description"));
×
1943
                    xmlw.writeEndElement(); // notes
×
1944
                }
1945

1946
                // TODO: add the remaining fileDscr elements!
1947
                xmlw.writeEndElement(); // fileDscr
×
1948
            }
1949
        }
1950
    }
1✔
1951
    
1952
    
1953

1954

1955

1956
    public static void datasetHtmlDDI(InputStream datafile, OutputStream outputStream) throws XMLStreamException {
1957
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
1✔
1958

1959
        try {
1960
            Document document;
1961
            InputStream  styleSheetInput = DdiExportUtil.class.getClassLoader().getResourceAsStream("edu/harvard/iq/dataverse/codebook2-0.xsl");
1✔
1962

1963
            DocumentBuilder builder = factory.newDocumentBuilder();
1✔
1964
            document = builder.parse(datafile);
1✔
1965

1966
            // Use a Transformer for output
1967
            TransformerFactory tFactory = TransformerFactory.newInstance();
1✔
1968
            StreamSource stylesource = new StreamSource(styleSheetInput);
1✔
1969
            Transformer transformer = tFactory.newTransformer(stylesource);
1✔
1970

1971
            DOMSource source = new DOMSource(document);
1✔
1972
            StreamResult result = new StreamResult(outputStream);
1✔
1973
            transformer.transform(source, result);
1✔
1974
        } catch (TransformerConfigurationException tce) {
×
1975
            // Error generated by the parser
1976
            logger.severe("Transformer Factory error" + "   " + tce.getMessage());
×
1977
        } catch (TransformerException te) {
×
1978
            // Error generated by the parser
1979
            logger.severe("Transformation error" + "   " + te.getMessage());
×
1980

1981
        } catch (SAXException sxe) {
×
1982
            // Error generated by this application
1983
            // (or a parser-initialization error)
1984
            logger.severe("SAX error " + sxe.getMessage());
×
1985

1986
        } catch (ParserConfigurationException pce) {
×
1987
            // Parser with specified options can't be built
1988
            logger.severe("Parser configuration error " + pce.getMessage());
×
1989
        } catch (IOException ioe) {
×
1990
            // I/O error
1991
            logger.warning("I/O error " + ioe.getMessage());
×
1992
        }
1✔
1993

1994
    }
1✔
1995

1996
    public static void injectSettingsService(SettingsServiceBean settingsSvc) {
1997
        settingsService=settingsSvc;
1✔
1998
    }
1✔
1999

2000
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc