ref #10271 add error handling and avoid NPE for unhandled name relationship types
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / coldp / ColDpExportTransformer.java
1 /**
2 * Copyright (C) 2023 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.cdm.io.coldp;
10
11 import org.apache.logging.log4j.LogManager;
12 import org.apache.logging.log4j.Logger;
13
14 import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
15 import eu.etaxonomy.cdm.io.common.mapping.out.ExportTransformerBase;
16 import eu.etaxonomy.cdm.model.common.Language;
17 import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
18 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
19 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
20 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
21 import eu.etaxonomy.cdm.model.name.Rank;
22 import eu.etaxonomy.cdm.model.reference.Reference;
23 import eu.etaxonomy.cdm.model.reference.ReferenceType;
24 import eu.etaxonomy.cdm.model.term.Representation;
25
26 /**
27 * @author a.mueller
28 * @date 17.07.2023
29 */
30 public class ColDpExportTransformer extends ExportTransformerBase {
31
32 private static final long serialVersionUID = -527652844010832994L;
33
34 @SuppressWarnings("unused")
35 private static final Logger logger = LogManager.getLogger();
36
37 //maps to http://api.checklistbank.org/vocab/distributionstatus
38 @Override
39 public String getCacheByPresenceAbsenceTerm(PresenceAbsenceTerm status) throws UndefinedTransformerMethodException {
40 if (status == null) {
41 return null;
42 }
43 if (status.isAnyNative()) {
44 return "native";
45 }
46 if (status.isAnyIntroduced()) {
47 return "alien";
48 }
49 return "uncertain";
50 }
51
52 @SuppressWarnings("incomplete-switch") //we ignore this warning as the enumeration should always be completely covered, otherwise an error will be shown if we do not add a default state. This is wanted behavior here.
53 @Override
54 public String getCacheByReferenceType(Reference ref) throws UndefinedTransformerMethodException {
55 if (ref == null || ref.getType() == null) {
56 return null;
57 }
58 ReferenceType refType = ref.getType();
59 switch (refType) {
60 case Article:
61 case Journal: //should not happen
62 return "article";
63 case Book:
64 case PrintSeries: //should not happen
65 return "book";
66 case BookSection:
67 return "chapter";
68 case CdDvd:
69 return "dataset"; //TODO
70 case Database:
71 return "dataset"; //TODO
72 case InProceedings:
73 return "paper conference";
74 case Map:
75 return "map";
76 case Patent:
77 return "patent";
78 case PersonalCommunication:
79 return "personal communication";
80 case Proceedings:
81 return "paper conference";
82 case Report:
83 return "report";
84 case Thesis:
85 return "thesis";
86 case WebPage:
87 return "webpage";
88 case Generic:
89 case Section:
90 if (ref.getInReference() != null) {
91 return getCacheByReferenceType(ref.getInReference());
92 }else {
93 return null;
94 }
95 }
96 return null;
97 }
98
99 @Override
100 public String getCacheByNomStatus(NomenclaturalStatusType nomStatusType) {
101 if (nomStatusType == null) {
102 return null;
103 //specific status
104 }else if (nomStatusType.equals(NomenclaturalStatusType.CONSERVED())) {
105 return "conserved";
106 }else if (nomStatusType.equals(NomenclaturalStatusType.REJECTED())) {
107 return "rejected";
108 }else if (nomStatusType.equals(NomenclaturalStatusType.DOUBTFUL())) {
109 return "doubtful";
110 }else if (nomStatusType.equals(NomenclaturalStatusType.INED())) {
111 return "manuscript";
112 //general status
113 }else if (nomStatusType.isLegitimate()) {
114 return "acceptable";
115 }else if (nomStatusType.isIllegitimate()) {
116 return "nomen illegitimum";
117 }else if (nomStatusType.isInvalid()) {
118 return "not established";
119 }
120
121 return null;
122 }
123
124 @SuppressWarnings("incomplete-switch") //we ignore this warning as the enumeration should always be completely covered, otherwise an error will be shown if we do not add a default state. This is wanted behavior here.
125 @Override
126 public String getCacheByNomenclaturalCode(NomenclaturalCode nomenclaturalCode) throws UndefinedTransformerMethodException {
127 if (nomenclaturalCode == null) {
128 return null;
129 }
130 switch (nomenclaturalCode) {
131 case NonViral:
132 return null; //TODO
133 case ICNAFP:
134 case Fungi:
135 return "ICN"; //"botanical";
136 case ICNCP:
137 return "ICNCP"; //"cultivars";
138 case ICNP:
139 return "ICNP"; //"bacterial";
140 case ICVCN:
141 return "ICVCN"; //"virus";
142 case ICZN:
143 return "ICZN"; //"zoological";
144 }
145 return null;
146 }
147
148 @Override
149 public String getCacheByRank(Rank rank) throws UndefinedTransformerMethodException {
150 if (rank == null) {
151 return null;
152 }
153 Representation preferredRep = rank.getPreferredRepresentation(Language.ENGLISH());
154 if (preferredRep != null) {
155 return preferredRep.getLabel() == null ? null :preferredRep.getLabel().toLowerCase();
156 }else {
157 return rank.getTitleCache().toLowerCase();
158 }
159 //TODO maybe we still need to adapt some ranks
160 }
161
162 public static enum ColDpNameRelType{
163 BASIONYM("basionym", 0),
164 SPELLING_CORRECTION("spelling correction", 0),
165 EMENDATION("spelling correction", 1),
166 BASED_ON("based on", 0),
167 REPLACEMENT_NAME("replacement name", 0),
168 CONSERVED("conserved", 0),
169 LATER_HOMONYM("later homonym", 0),
170 SUPERFLUOUS("superfluous", 1),
171 //TODO others
172
173 ;
174 private String label;
175 private int direction;
176 ColDpNameRelType(String label, int direction){
177 this.label = label;
178 this.direction = direction;
179 }
180 public String getLabel() {
181 return label;
182 }
183 public int getDirection() {
184 return direction;
185 }
186 }
187
188 public ColDpNameRelType getColDpNameRelTypeByNameRelationType(NameRelationshipType nameRelType) {
189 if (nameRelType == null) {
190 return null;
191 }
192 if (nameRelType.getUuid().equals(NameRelationshipType.uuidBasionym)){
193 return ColDpNameRelType.BASIONYM;
194 } else if (nameRelType.getUuid().equals(NameRelationshipType.uuidOrthographicVariant)) {
195 return ColDpNameRelType.SPELLING_CORRECTION;
196 } else if (nameRelType.getUuid().equals(NameRelationshipType.uuidEmendation)) {
197 return ColDpNameRelType.EMENDATION;
198 } else if (nameRelType.getUuid().equals(NameRelationshipType.uuidValidatedByName)
199 || nameRelType.getUuid().equals(NameRelationshipType.uuidLaterValidatedByName)) {
200 return ColDpNameRelType.BASED_ON;
201 } else if (nameRelType.getUuid().equals(NameRelationshipType.uuidReplacedSynonym)) {
202 return ColDpNameRelType.REPLACEMENT_NAME;
203 } else if (nameRelType.getUuid().equals(NameRelationshipType.uuidConservedAgainst)) {
204 return ColDpNameRelType.CONSERVED;
205 } else if (nameRelType.getUuid().equals(NameRelationshipType.uuidLaterHomonym)
206 || nameRelType.getUuid().equals(NameRelationshipType.uuidTreatedAsLaterHomonym)) {
207 return ColDpNameRelType.LATER_HOMONYM;
208 } else if (nameRelType.getUuid().equals(NameRelationshipType.uuidLaterIsonym)
209 //only for future merged, currently it will never match as the type is different
210 || nameRelType.getUuid().equals(NomenclaturalStatusType.uuidSuperfluous)) {
211 return ColDpNameRelType.SUPERFLUOUS;
212 } else {
213 //TODO misspelling, alternative name, blocking name for, avoids homonym of, unspecific "non"
214 String warning = "Name relationship type not yet handled by COL-DP: " + nameRelType.getTitleCache();
215 //TODO handle warning, is currently handled in calling method
216 Representation preferredRep = nameRelType.getPreferredRepresentation(Language.ENGLISH());
217 // if (preferredRep != null) {
218 // return preferredRep.getLabel() == null ? null :preferredRep.getLabel().toLowerCase();
219 // }else {
220 // return nameRelType.getTitleCache().toLowerCase();
221 // }
222 return null;
223 }
224 }
225 }