91d592be450686e4f0716ffbbc1842e281723cd0
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / taxon / TaxonComparator.java
1 /**
2 * Copyright (C) 2007 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
10 package eu.etaxonomy.cdm.model.taxon;
11
12 import java.io.Serializable;
13 import java.util.Comparator;
14 import java.util.Iterator;
15 import java.util.Set;
16
17 import org.apache.log4j.Logger;
18
19 import org.joda.time.DateTime;
20
21 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
22 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
23 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
24 import eu.etaxonomy.cdm.model.name.ZoologicalName;
25 import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
26 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
27
28 /**
29 * This class makes available a method to compare two {@link TaxonBase taxa} by
30 * comparing the publication dates of the corresponding {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon names}.
31 *
32 * @author a.mueller
33 * @created 11.06.2008
34 * @version 1.0
35 */
36 public class TaxonComparator implements Comparator<TaxonBase>, Serializable {
37 private static final Logger logger = Logger.getLogger(TaxonComparator.class);
38
39 /* (non-Javadoc)
40 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
41 */
42 /**
43 * Returns an integer generated by comparing the {@link eu.etaxonomy.cdm.model.name.INomenclaturalReference#getYear() publication years}
44 * of both {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon names} used in the given {@link TaxonBase taxa}.
45 * Returns a negative value if the publication year corresponding to the
46 * first given taxon precedes the publication year corresponding to the
47 * second given taxon. Returns a positive value if the contrary is true and
48 * 0 if both publication years and the date, when they are created, are identical. In case one of the publication
49 * years is "null" and the other is not, the "empty" publication year will
50 * be considered to be always preceded by the "not null" publication year.
51 * If both publication years are "null" the creation date is used for the comparison
52 *
53 *
54 * @see java.lang.String#compareTo(String)
55 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
56 */
57 public int compare(TaxonBase taxonBase1, TaxonBase taxonBase2) {
58 int result;
59 //boolean invalOrNudForTaxon1 = false;
60 //boolean invalOrNudForTaxon2 = false;
61
62 boolean invalTaxon1 = false;
63 boolean invalTaxon2 = false;
64 boolean nudumTaxon1 = false;
65 boolean nudumTaxon2 = false;
66
67 //if a taxon has nomenclatural status "nom. inval." or "nom. nud."
68 //TODO: überprüfen!!!
69 Set status = taxonBase1.getName().getStatus();
70 Iterator iterator = status.iterator();
71 if (iterator.hasNext()){
72 NomenclaturalStatus nomStatus1 = (NomenclaturalStatus) iterator.next();
73 Set status2 = taxonBase2.getName().getStatus();
74 iterator = status2.iterator(); // is that right? or better iterator = status2.iterator(); ???
75 if (iterator.hasNext()){
76 NomenclaturalStatus nomStatus2 = (NomenclaturalStatus)iterator.next();
77 /*
78 if (nomStatus1.getType().equals(NomenclaturalStatusType.NUDUM()) ||
79 nomStatus1.getType().equals(NomenclaturalStatusType.INVALID())){
80 invalOrNudForTaxon1 = true;
81 }
82 if (nomStatus2.getType().equals(NomenclaturalStatusType.NUDUM()) || nomStatus2.getType().equals(NomenclaturalStatusType.INVALID())){
83 invalOrNudForTaxon2 = true;
84 }
85 if (invalOrNudForTaxon1 && !invalOrNudForTaxon2){
86 return 1;
87 }else if (!invalOrNudForTaxon1 && invalOrNudForTaxon2){
88 return -1;
89 }
90 else{ // both taxon are invalid or nudum
91 //result = 0;
92 }
93 */
94 // #####
95 if (nomStatus1.getType().equals(NomenclaturalStatusType.INVALID())){
96 invalTaxon1 = true;
97 }
98 if (nomStatus1.getType().equals(NomenclaturalStatusType.NUDUM())){
99 nudumTaxon1 = true;
100 }
101 if (nomStatus2.getType().equals(NomenclaturalStatusType.INVALID())){
102 invalTaxon2 = true;
103 }
104 if (nomStatus2.getType().equals(NomenclaturalStatusType.NUDUM())){
105 nudumTaxon2 = true;
106 }
107 if (nudumTaxon1 && !nudumTaxon2){
108 return 1;
109 }else if (nudumTaxon1 && nudumTaxon2){
110 //continue
111 }else if (invalTaxon1 && !nudumTaxon2){
112 if (invalTaxon2){
113 //continue
114 }else{
115 return 1;
116 }
117 }else if (nudumTaxon2 && !nudumTaxon1){
118 return -1;
119 }else if(invalTaxon2){
120 return -1;
121 }
122 // #####
123
124
125 }else{//if taxonbase2.getName().getStatus = NULL and taxonbase2 not
126 return 1;
127 }
128 }else{//if taxonbase1.getName().getStatus = NULL
129 iterator = taxonBase2.getName().getStatus().iterator();
130 if (!iterator.hasNext()){
131 //if (taxonBase2.getName().getStatus() == null){ // both are null, continue checking
132 }else{
133 return -1;
134 }
135 }
136
137 Integer intDate1 = getIntegerDate(taxonBase1);
138 Integer intDate2 = getIntegerDate(taxonBase2);
139
140 if (intDate1 == null && intDate2 == null){
141 result = 0;
142 }else if (intDate1 == null){
143 return 1;
144 }else if (intDate2 == null){
145 return -1;
146 }else{
147 result = intDate1.compareTo(intDate2);
148 }
149
150 if (result == 0){
151 TaxonNameBase taxName1 = taxonBase1.getName();
152 TaxonNameBase taxName2 = taxonBase2.getName();
153
154 return taxName1.compareTo(taxName2);
155
156 }
157
158 if (result == 0){
159 DateTime date11 = taxonBase1.getCreated();
160 DateTime date12 = taxonBase2.getCreated();
161 if (date11 == null && date12 == null) {
162 return 0;
163 }
164 if (date11 == null) {
165 return 1;
166 }
167 if (date12 == null) {
168 return -1;
169 }
170 result = date11.compareTo(date12);
171 }
172
173 //for ticket #393 if the publication year is the same, the order is alphabetically
174
175 if (result == 0){
176 TaxonNameBase taxName1 = taxonBase1.getName();
177 TaxonNameBase taxName2 = taxonBase2.getName();
178
179 return taxName1.compareTo(taxName2);
180
181 }
182
183 return result;
184
185 }
186
187
188 private Integer getIntegerDate(TaxonBase taxonBase){
189 Integer result;
190
191 if (taxonBase == null){
192 result = null;
193 }else{
194 TaxonNameBase name = taxonBase.getName();
195 if (name == null){
196 result = null;
197 }else{
198 if (name instanceof ZoologicalName){
199
200 result = (((ZoologicalName)name).getPublicationYear());
201 }else{
202 ReferenceBase ref = (ReferenceBase) name.getNomenclaturalReference();
203 if (ref == null){
204 result = null;
205 }else{
206 if (ref.getDatePublished() == null){
207 if (ref.getInReference() == null){
208 result = null;
209 }else{
210 result = ref.getInReference().getDatePublished().getStartYear();
211 }
212 }else{
213 result = ref.getDatePublished().getStartYear();
214 }
215 }
216 }
217 }
218 }
219
220 return result;
221 }
222
223 @SuppressWarnings("unchecked")
224 @Deprecated
225 private String getDate(TaxonBase taxonBase){
226 String result = null;
227 if (taxonBase == null){
228 result = null;
229 }else{
230 TaxonNameBase name = taxonBase.getName();
231 if (name == null){
232 result = null;
233 }else{
234 if (name instanceof ZoologicalName){
235
236 result = String.valueOf(((ZoologicalName)name).getPublicationYear());
237 }else{
238 INomenclaturalReference ref = name.getNomenclaturalReference();
239 if (ref == null){
240 result = null;
241 }else{
242 result = ref.getYear();
243 }
244 }
245 }
246 }
247 if (result != null){
248 result = result.trim();
249 }
250 if ("".equals(result)){
251 result = null;
252 }
253 return result;
254 }
255
256 }