001/*
002 * Copyright 2020 Global Biodiversity Information Facility (GBIF)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.gbif.api.model.occurrence;
017
018import org.gbif.api.util.IsoDateParsingUtils.IsoDateFormat;
019import org.gbif.api.vocabulary.Extension;
020import org.gbif.dwc.terms.DcTerm;
021import org.gbif.dwc.terms.DwcTerm;
022import org.gbif.dwc.terms.GbifTerm;
023import org.gbif.dwc.terms.IucnTerm;
024import org.gbif.dwc.terms.Term;
025import org.gbif.dwc.terms.TermFactory;
026import org.gbif.dwc.terms.UnknownTerm;
027
028import java.io.IOException;
029import java.util.ArrayList;
030import java.util.Date;
031import java.util.HashMap;
032import java.util.List;
033import java.util.Map;
034import java.util.UUID;
035
036import org.apache.commons.text.RandomStringGenerator;
037import org.junit.jupiter.api.Test;
038
039import com.fasterxml.jackson.annotation.JsonInclude;
040import com.fasterxml.jackson.databind.DeserializationFeature;
041import com.fasterxml.jackson.databind.ObjectMapper;
042import com.fasterxml.jackson.databind.SerializationFeature;
043
044import static org.junit.jupiter.api.Assertions.assertEquals;
045import static org.junit.jupiter.api.Assertions.assertFalse;
046import static org.junit.jupiter.api.Assertions.assertNotNull;
047import static org.junit.jupiter.api.Assertions.assertTrue;
048
049public class VerbatimOccurrenceTest {
050
051  @Test
052  public void testFieldUpdate() {
053    VerbatimOccurrence occ = new VerbatimOccurrence();
054    String catNum = "abc123";
055    occ.setVerbatimField(DwcTerm.catalogNumber, catNum);
056    assertEquals(catNum, occ.getVerbatimField(DwcTerm.catalogNumber));
057
058    String catNum2 = "qwer";
059    occ.setVerbatimField(DwcTerm.catalogNumber, catNum2);
060    assertEquals(catNum2, occ.getVerbatimField(DwcTerm.catalogNumber));
061  }
062
063  @Test
064  public void testHasField() {
065    VerbatimOccurrence occ = new VerbatimOccurrence();
066
067    occ.setVerbatimField(DwcTerm.catalogNumber, "abc123");
068    assertTrue(occ.hasVerbatimField(DwcTerm.catalogNumber));
069    assertFalse(occ.hasVerbatimField(DwcTerm.institutionCode));
070
071    occ.setVerbatimField(DwcTerm.catalogNumber, " ");
072    assertTrue(occ.hasVerbatimField(DwcTerm.catalogNumber));
073
074    occ.setVerbatimField(DwcTerm.catalogNumber, "");
075    assertFalse(occ.hasVerbatimField(DwcTerm.catalogNumber));
076
077    occ.setVerbatimField(DwcTerm.catalogNumber, null);
078    assertFalse(occ.hasVerbatimField(DwcTerm.catalogNumber));
079  }
080
081  @Test
082  public void testFieldFromTermFactory() {
083    VerbatimOccurrence occ = new VerbatimOccurrence();
084    String prefix = "t_";
085    String colName = "t_dwc:basisOfRecord";
086    Term term = TermFactory.instance().findTerm(colName.substring(prefix.length()));
087    occ.setVerbatimField(term, "PreservedSpecimen");
088    assertEquals(1, occ.getVerbatimFields().size());
089    assertTrue(occ.hasVerbatimField(DwcTerm.basisOfRecord));
090    assertEquals("PreservedSpecimen", occ.getVerbatimField(DwcTerm.basisOfRecord));
091  }
092
093  @Test
094  public void testJsonSerde() throws IOException {
095    ObjectMapper mapper = new ObjectMapper();
096
097    VerbatimOccurrence verb = new VerbatimOccurrence();
098    verb.setVerbatimField(DwcTerm.institutionCode, "IC");
099    verb.setVerbatimField(DwcTerm.collectionCode, "BUGS");
100    verb.setVerbatimField(DwcTerm.catalogNumber, "MD10782");
101
102    String json = mapper.writeValueAsString(verb);
103    VerbatimOccurrence deser = mapper.readValue(json, VerbatimOccurrence.class);
104    assertEquals(verb, deser);
105    for (DwcTerm term : DwcTerm.values()) {
106      assertEquals(verb.getVerbatimField(term), deser.getVerbatimField(term));
107    }
108  }
109
110  @Test
111  public void testJsonSerdeAllFields() throws IOException {
112    ObjectMapper mapper = new ObjectMapper();
113
114    VerbatimOccurrence verb = new VerbatimOccurrence();
115    verb.setKey(123L);
116    String termPrefix = "I am Jack's ";
117    for (Term term : DwcTerm.values()) {
118      verb.setVerbatimField(term, termPrefix + term);
119    }
120    for (Term term : DcTerm.values()) {
121      verb.setVerbatimField(term, termPrefix + term);
122    }
123    for (Term term : GbifTerm.values()) {
124      verb.setVerbatimField(term, termPrefix + term);
125    }
126    for (Term term : IucnTerm.values()) {
127      verb.setVerbatimField(term, termPrefix + term);
128    }
129
130    String json = mapper.writeValueAsString(verb);
131    VerbatimOccurrence deser = mapper.readValue(json, VerbatimOccurrence.class);
132    assertEquals(verb, deser);
133    for (Term term : DwcTerm.values()) {
134      assertTrue(deser.hasVerbatimField(term));
135      assertEquals(termPrefix + term, deser.getVerbatimField(term));
136    }
137    for (Term term : DcTerm.values()) {
138      assertTrue(deser.hasVerbatimField(term));
139      assertEquals(termPrefix + term, deser.getVerbatimField(term));
140    }
141    for (Term term : GbifTerm.values()) {
142      assertTrue(deser.hasVerbatimField(term));
143      assertEquals(termPrefix + term, deser.getVerbatimField(term));
144    }
145    for (Term term : IucnTerm.values()) {
146      assertTrue(deser.hasVerbatimField(term));
147      assertEquals(termPrefix + term, deser.getVerbatimField(term));
148    }
149  }
150
151  @Test
152  public void testVerbatimMapSerde() throws Exception {
153    ObjectMapper mapper = new ObjectMapper();
154    mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
155    mapper.enable(SerializationFeature.INDENT_OUTPUT);
156    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
157
158    VerbatimOccurrence v = new VerbatimOccurrence();
159    v.setKey(7L);
160    v.setLastParsed(new Date());
161    v.setDatasetKey(UUID.randomUUID());
162
163    char [][] alphabeticPairs = {{'a','z'},{'A','Z'}};
164    char [][] alphanumericPairs = {{'a','z'},{'A','Z'},{'0','9'}};
165    RandomStringGenerator generatorAlphabetic = new RandomStringGenerator.Builder()
166        .withinRange(alphabeticPairs)
167        .build();
168    RandomStringGenerator generatorAlphanumeric = new RandomStringGenerator.Builder()
169        .withinRange(alphanumericPairs)
170        .build();
171
172    for (Term term : DwcTerm.values()) {
173
174      v.setVerbatimField(term, generatorAlphabetic.generate(20));
175    }
176    final int numDwcTerms = v.getVerbatimFields().size();
177
178    for (Term term : DcTerm.values()) {
179      v.setVerbatimField(term, generatorAlphabetic.generate(20));
180    }
181    final int numDcTerms = v.getVerbatimFields().size() - numDwcTerms;
182
183    for (Term term : GbifTerm.values()) {
184      v.setVerbatimField(term, generatorAlphabetic.generate(20));
185    }
186    final int numGbifTerms = v.getVerbatimFields().size() - numDwcTerms - numDcTerms;
187
188    for (Term term : IucnTerm.values()) {
189      v.setVerbatimField(term, generatorAlphanumeric.generate(20));
190    }
191    final int numIucnTerms = v.getVerbatimFields().size() - numDwcTerms - numDcTerms - numGbifTerms;
192
193    v.setVerbatimField(DwcTerm.scientificName, "Abies alba");
194    v.setVerbatimField(DwcTerm.collectionCode, "BUGS");
195    v.setVerbatimField(DwcTerm.catalogNumber, "MD10782");
196    v.setVerbatimField(UnknownTerm.build("http://rs.un.org/terms/temperatur"), generatorAlphabetic.generate(30));
197    v.setVerbatimField(UnknownTerm.build("http://rs.un.org/terms/co2"), generatorAlphabetic.generate(30));
198    v.setVerbatimField(UnknownTerm.build("http://rs.un.org/terms/modified"), new Date().toString());
199    v.setVerbatimField(UnknownTerm.build("http://rs.un.org/terms/scientificName"),
200      generatorAlphabetic.generate(30));
201    final int numOtherTerms = v.getVerbatimFields().size() - numDwcTerms - numDcTerms - numGbifTerms - numIucnTerms;
202
203    final int numTerms = v.getVerbatimFields().size();
204
205    assertEquals(numTerms, numDwcTerms + numDcTerms + numGbifTerms + numIucnTerms + numOtherTerms);
206
207    String json = mapper.writeValueAsString(v);
208    System.out.println(json);
209
210    VerbatimOccurrence v2 = mapper.readValue(json, VerbatimOccurrence.class);
211    // 5 terms
212    assertEquals(numTerms, v2.getVerbatimFields().size());
213
214  }
215
216  @Test
217  public void testVerbatimExtensionsMapSerde() throws Exception {
218    ObjectMapper mapper = new ObjectMapper();
219    mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
220    mapper.enable(SerializationFeature.INDENT_OUTPUT);
221    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
222
223    Map<Term, String> verbatimRecord = new HashMap<Term, String>();
224    verbatimRecord.put(DcTerm.created, "2021-10-25");
225    verbatimRecord.put(DcTerm.creator, "fede");
226    verbatimRecord.put(DcTerm.description, "testDescription");
227    verbatimRecord.put(DcTerm.format, "jpg");
228    verbatimRecord.put(DcTerm.license, "licenseTest");
229    verbatimRecord.put(DcTerm.publisher, "publisherTest");
230    verbatimRecord.put(DcTerm.title, "titleTest");
231    verbatimRecord.put(DcTerm.references, "http://www.gbif.org/");
232    verbatimRecord.put(DcTerm.identifier, "http://www.gbif.org/");
233
234    VerbatimOccurrence v = new VerbatimOccurrence();
235    v.setKey(7L);
236    v.setLastParsed(new Date());
237    v.setDatasetKey(UUID.randomUUID());
238    Map<String, List<Map<Term, String>>> extensions = new HashMap<>();
239    List<Map<Term, String>> verbatimRecords = new ArrayList<>();
240    verbatimRecords.add(verbatimRecord);
241    extensions.put(Extension.MULTIMEDIA.getRowType(), verbatimRecords);
242    v.setExtensions(extensions);
243
244    String json = mapper.writeValueAsString(v);
245    System.out.println(json);
246
247    VerbatimOccurrence v2 = mapper.readValue(json, VerbatimOccurrence.class);
248    assertNotNull(v2.getExtensions());
249    assertFalse(v2.getExtensions().get(Extension.MULTIMEDIA.getRowType()).isEmpty());
250    assertEquals(v2.getExtensions().get(Extension.MULTIMEDIA.getRowType()).get(0), verbatimRecord);
251  }
252}