2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.taxeditor
.model
;
12 import java
.util
.ArrayList
;
13 import java
.util
.HashSet
;
14 import java
.util
.List
;
17 import org
.apache
.log4j
.Logger
;
18 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
20 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationController
;
21 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
22 import eu
.etaxonomy
.cdm
.api
.service
.IReferenceService
;
23 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
24 import eu
.etaxonomy
.cdm
.api
.service
.config
.ITaxonServiceConfigurator
;
25 import eu
.etaxonomy
.cdm
.api
.service
.config
.impl
.TaxonServiceConfiguratorImpl
;
26 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
27 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
28 import eu
.etaxonomy
.cdm
.model
.common
.TimePeriod
;
29 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
30 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationship
;
31 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationshipType
;
32 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
33 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
34 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
35 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
36 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymRelationshipType
;
37 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
38 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
39 import eu
.etaxonomy
.taxeditor
.TaxEditorPlugin
;
40 import eu
.etaxonomy
.taxeditor
.controller
.GlobalController
;
41 import eu
.etaxonomy
.taxeditor
.navigation
.SearchResult
;
48 public class CdmUtil
{
49 private static final Logger logger
= Logger
.getLogger(CdmUtil
.class);
52 * Checks whether synonym's name is the basionym for ALL names
59 public static boolean isSynonymGroupBasionym(Synonym synonym
) {
61 TaxonNameBase synonymName
= synonym
.getName();
62 return isNameGroupBasionym(synonymName
);
66 * Checks whether name is the basionym for ALL names
72 public static boolean isNameGroupBasionym(TaxonNameBase name
) {
77 HomotypicalGroup homotypicalGroup
= name
.getHomotypicalGroup();
78 if (homotypicalGroup
== null) {
82 Set
<TaxonNameBase
> typifiedNames
= homotypicalGroup
.getTypifiedNames();
84 // Check whether there are any other names in the group
85 if (typifiedNames
.size() == 1) {
89 boolean isBasionymToAll
= true;
91 for (TaxonNameBase taxonName
: typifiedNames
) {
92 if (!taxonName
.equals(name
)) {
93 if (!isNameBasionymOf(name
, taxonName
)) {
102 * Checks whether a basionym relationship exists between fromName and toName.
108 public static boolean isNameBasionymOf(TaxonNameBase fromName
, TaxonNameBase toName
) {
109 Set
<NameRelationship
> relations
= toName
.getRelationsToThisName();
110 for (NameRelationship relation
: relations
) {
111 if (relation
.getType().equals(NameRelationshipType
.BASIONYM()) &&
112 relation
.getFromName().equals(fromName
)) {
120 * Creates a basionym relationship between basionymName and
121 * each name in its homotypic group.
123 * @param basionymName
125 public static void setGroupBasionym(TaxonNameBase basionymName
) {
126 HomotypicalGroup homotypicalGroup
= basionymName
.getHomotypicalGroup();
127 if (homotypicalGroup
== null) {
130 for (TaxonNameBase name
: homotypicalGroup
.getTypifiedNames()) {
131 if (!name
.equals(basionymName
)) {
133 // First check whether the relationship already exists
134 if (!isNameBasionymOf(basionymName
, name
)) {
137 name
.addRelationshipFromName(basionymName
,
138 NameRelationshipType
.BASIONYM(), null);
145 * Removes all basionym relationships between basionymName and
146 * the names in its homotypic group.
148 * @param basionymName
150 public static void removeGroupBasionym(TaxonNameBase basionymName
) {
151 HomotypicalGroup homotypicalGroup
= basionymName
.getHomotypicalGroup();
152 Set
<NameRelationship
> relations
= basionymName
.getRelationsFromThisName();
153 Set
<NameRelationship
> removeRelations
= new HashSet
<NameRelationship
>();
155 for (NameRelationship relation
: relations
) {
157 // If this is a basionym relation, and toName is in the homotypical group,
158 // remove the relationship.
159 if (relation
.getType().equals(NameRelationshipType
.BASIONYM()) &&
160 relation
.getToName().getHomotypicalGroup().equals(homotypicalGroup
)) {
161 removeRelations
.add(relation
);
165 // Removing relations from a set through which we are iterating causes a
166 // ConcurrentModificationException. Therefore, we delete the targeted
167 // relations in a second step.
168 for (NameRelationship relation
: removeRelations
) {
169 basionymName
.removeNameRelationship(relation
);
174 * Checks whether name belongs to the same homotypic group as taxon's name.
180 public static boolean isNameHomotypic(TaxonNameBase name
, Taxon taxon
) {
181 TaxonNameBase taxonName
= taxon
.getName();
182 if (taxonName
== null || name
== null) {
185 HomotypicalGroup homotypicGroup
= taxonName
.getHomotypicalGroup();
186 if (homotypicGroup
== null) {
189 if (homotypicGroup
.equals(name
.getHomotypicalGroup())) {
196 * Returns whatever is currently considered the display name for Taxon
197 * objects. Currently titleCache.
202 public static String
getDisplayName(TaxonBase taxonBase
) {
203 TaxonNameBase name
= taxonBase
.getName();
204 return getDisplayName(name
);
211 public static String
getDisplayName(TaxonNameBase name
) {
213 return name
.getTitleCache();
218 public static String
getDisplayNameWithRef(TaxonBase taxonBase
) {
219 TaxonNameBase name
= taxonBase
.getName();
221 if (name
.getFullTitleCache() == null || name
.getFullTitleCache().length() == 0) {
222 return CdmUtils
.Nz(name
.getTitleCache());
224 return name
.getFullTitleCache();
232 * @param newAcceptedTaxon
235 * @param citationMicroReference
237 public static void makeTaxonSynonym(Taxon oldTaxon
, Taxon newAcceptedTaxon
,
238 SynonymRelationshipType synonymType
, ReferenceBase citation
,
239 String citationMicroReference
) {
240 ITaxonService taxonService
= getTaxonService();
241 taxonService
.makeTaxonSynonym(oldTaxon
, newAcceptedTaxon
, synonymType
,
242 citation
, citationMicroReference
);
249 public static List
<TaxonNameBase
> searchNameString(String searchText
) {
250 List
<TaxonNameBase
> resultsSet
= new ArrayList
<TaxonNameBase
>();
251 resultsSet
.addAll(getNameService()
252 .getNamesByName(searchText
.replace("*", "%")));
256 public static SearchResult
searchTaxaByName(String name
) {
257 SearchResult searchResult
= new SearchResult();
259 ITaxonServiceConfigurator configurator
= new TaxonServiceConfiguratorImpl();
261 configurator
.setSearchString(name
.replace("*", "%"));
262 configurator
.setDoTaxa(true);
263 configurator
.setDoNamesWithoutTaxa(true);
264 configurator
.setDoSynonyms(true);
265 configurator
.setPageNumber(1);
266 // TODO currently limit results to 1000 for now
267 configurator
.setPageSize(1000);
269 List
<IdentifiableEntity
> result
= getTaxonService().findTaxaAndNames(configurator
).getRecords();
271 searchResult
.addAll(result
);
275 private static CdmApplicationController
getApplicationController() {
276 return TaxEditorPlugin
.getDefault().getApplicationController();
279 public static INameService
getNameService() {
280 return getApplicationController().getNameService();
283 public static ITaxonService
getTaxonService() {
284 return getApplicationController().getTaxonService();
287 public static IReferenceService
getReferenceService() {
288 return getApplicationController().getReferenceService();
296 public static Set
<TaxonNameBase
> getNameByNameForTaxonContext(String searchText
, Taxon taxon
) {
297 Set
<TaxonNameBase
> resultsSet
= new HashSet
<TaxonNameBase
>();
298 resultsSet
.addAll(getNameService().getNamesByName
299 (searchText
.replace("*", "%"), taxon
));
304 * Converts a <code>String</code> whose format is either a valid year
305 * or two valid years with the format "XXXX-XXXX" into a TimePeriod.
307 * @see #getValidYear(String yearStr)
310 * @throws NumberFormatException
312 public static TimePeriod
convertTimePeriod(String refYear
) throws NumberFormatException
{
314 if (refYear
== null || ("").equals(refYear
)){
318 TimePeriod datePublished
= TimePeriod
.NewInstance();
320 // In case format is "xxxx-xxxx"
321 String
[] years
= refYear
.split("-");
323 // Unlikely case of "xxxx-xxxx-xxxx..."
324 if (years
.length
> 2) {
325 throw new NumberFormatException();
329 datePublished
.setStartYear(getValidYear(years
[0]));
331 // Format is "xxxx-xxxx"
332 if (years
.length
== 2) {
333 datePublished
.setEndYear(getValidYear(years
[1]));
336 return datePublished
;
341 * Checks whether a <code>String</code> is a valid year between
342 * 1750 and 2030. Throws a <code>NumberFormatException</code> if not.
346 * @throws NumberFormatException
348 public static Integer
getValidYear(String yearStr
) throws NumberFormatException
{
350 Integer yearInt
= null;
352 // Try casting string - don't catch number format exception
354 yearInt
= new Integer(yearStr
);
355 } catch (ClassCastException e
) {
356 throw new NumberFormatException();
359 // Is year in valid range?
360 if (yearInt
< 1750 || yearInt
> 2030) {
361 throw new NumberFormatException();
368 * Searches for references by string. "%" is used as a wildcard.
373 public static List
getReferencesByTitle(String reference
) {
375 reference
= reference
.replace("*", "%");
376 List resultsList
= null;
378 resultsList
= getReferenceService().getReferencesByTitle(reference
);
379 } catch (RuntimeException e
) {
380 MessageDialog
.openError(GlobalController
.getShell(), "Search reference error",
381 "Reference search returned an error. This could be a Hibernate concurrency problem. " +
382 "Please try saving your work, then searching again.");
389 * Returns true if <code>taxon</code> belongs to the children, grandchildren,
390 * etc. of <code>checkTaxon</code>.
396 public static boolean isTaxonChildOfTaxon(Taxon taxon
, Taxon checkTaxon
) {
398 // Traverse all checkTaxon's children
399 for (Taxon childTaxon
: checkTaxon
.getTaxonomicChildren()) {
401 if (childTaxon
.equals(taxon
)) {
405 // Compare taxon with childTaxon's children
406 if (isTaxonChildOfTaxon(taxon
, childTaxon
)) {
418 public static boolean isNameSupraSpecific(TaxonNameBase name
) {
420 if (name
== null || name
.getRank() == null) {
424 if (name
.getRank().isHigher(Rank
.SPECIES())) {
425 // if (name.isInfraGeneric() || name.isSupraGeneric() || name.isGenus()) {