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
.TaxonNameBase
;
33 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
34 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
35 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymRelationshipType
;
36 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
37 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
38 import eu
.etaxonomy
.taxeditor
.TaxEditorPlugin
;
39 import eu
.etaxonomy
.taxeditor
.controller
.GlobalController
;
40 import eu
.etaxonomy
.taxeditor
.navigation
.SearchResult
;
47 public class CdmUtil
{
48 private static final Logger logger
= Logger
.getLogger(CdmUtil
.class);
51 * Checks whether synonym's name is the basionym for ALL names
58 public static boolean isSynonymGroupBasionym(Synonym synonym
) {
60 TaxonNameBase synonymName
= synonym
.getName();
61 return isNameGroupBasionym(synonymName
);
65 * Checks whether name is the basionym for ALL names
71 public static boolean isNameGroupBasionym(TaxonNameBase name
) {
76 HomotypicalGroup homotypicalGroup
= name
.getHomotypicalGroup();
77 if (homotypicalGroup
== null) {
81 Set
<TaxonNameBase
> typifiedNames
= homotypicalGroup
.getTypifiedNames();
83 // Check whether there are any other names in the group
84 if (typifiedNames
.size() == 1) {
88 boolean isBasionymToAll
= true;
90 for (TaxonNameBase taxonName
: typifiedNames
) {
91 if (!taxonName
.equals(name
)) {
92 if (!isNameBasionymOf(name
, taxonName
)) {
101 * Checks whether a basionym relationship exists between fromName and toName.
107 public static boolean isNameBasionymOf(TaxonNameBase fromName
, TaxonNameBase toName
) {
108 Set
<NameRelationship
> relations
= toName
.getRelationsToThisName();
109 for (NameRelationship relation
: relations
) {
110 if (relation
.getType().equals(NameRelationshipType
.BASIONYM()) &&
111 relation
.getFromName().equals(fromName
)) {
119 * Creates a basionym relationship between basionymName and
120 * each name in its homotypic group.
122 * @param basionymName
124 public static void setGroupBasionym(TaxonNameBase basionymName
) {
125 HomotypicalGroup homotypicalGroup
= basionymName
.getHomotypicalGroup();
126 if (homotypicalGroup
== null) {
129 for (TaxonNameBase name
: homotypicalGroup
.getTypifiedNames()) {
130 if (!name
.equals(basionymName
)) {
132 // First check whether the relationship already exists
133 if (!isNameBasionymOf(basionymName
, name
)) {
136 name
.addRelationshipFromName(basionymName
,
137 NameRelationshipType
.BASIONYM(), null);
144 * Removes all basionym relationships between basionymName and
145 * the names in its homotypic group.
147 * @param basionymName
149 public static void removeGroupBasionym(TaxonNameBase basionymName
) {
150 HomotypicalGroup homotypicalGroup
= basionymName
.getHomotypicalGroup();
151 Set
<NameRelationship
> relations
= basionymName
.getRelationsFromThisName();
152 Set
<NameRelationship
> removeRelations
= new HashSet
<NameRelationship
>();
154 for (NameRelationship relation
: relations
) {
156 // If this is a basionym relation, and toName is in the homotypical group,
157 // remove the relationship.
158 if (relation
.getType().equals(NameRelationshipType
.BASIONYM()) &&
159 relation
.getToName().getHomotypicalGroup().equals(homotypicalGroup
)) {
160 removeRelations
.add(relation
);
164 // Removing relations from a set through which we are iterating causes a
165 // ConcurrentModificationException. Therefore, we delete the targeted
166 // relations in a second step.
167 for (NameRelationship relation
: removeRelations
) {
168 basionymName
.removeNameRelationship(relation
);
173 * Checks whether name belongs to the same homotypic group as taxon's name.
179 public static boolean isNameHomotypic(TaxonNameBase name
, Taxon taxon
) {
180 TaxonNameBase taxonName
= taxon
.getName();
181 if (taxonName
== null || name
== null) {
184 HomotypicalGroup homotypicGroup
= taxonName
.getHomotypicalGroup();
185 if (homotypicGroup
== null) {
188 if (homotypicGroup
.equals(name
.getHomotypicalGroup())) {
195 * Returns whatever is currently considered the display name for Taxon
196 * objects. Currently titleCache.
201 public static String
getDisplayName(TaxonBase taxonBase
) {
202 TaxonNameBase name
= taxonBase
.getName();
203 return getDisplayName(name
);
210 public static String
getDisplayName(TaxonNameBase name
) {
212 return name
.getTitleCache();
217 public static String
getDisplayNameWithRef(TaxonBase taxonBase
) {
218 TaxonNameBase name
= taxonBase
.getName();
220 if (name
.getFullTitleCache() == null || name
.getFullTitleCache().length() == 0) {
221 return CdmUtils
.Nz(name
.getTitleCache());
223 return name
.getFullTitleCache();
231 * @param newAcceptedTaxon
234 * @param citationMicroReference
236 public static void makeTaxonSynonym(Taxon oldTaxon
, Taxon newAcceptedTaxon
,
237 SynonymRelationshipType synonymType
, ReferenceBase citation
,
238 String citationMicroReference
) {
239 ITaxonService taxonService
= getTaxonService();
240 taxonService
.makeTaxonSynonym(oldTaxon
, newAcceptedTaxon
, synonymType
,
241 citation
, citationMicroReference
);
248 public static List
<TaxonNameBase
> searchNameString(String searchText
) {
249 List
<TaxonNameBase
> resultsSet
= new ArrayList
<TaxonNameBase
>();
250 resultsSet
.addAll(getNameService()
251 .getNamesByName(searchText
.replace("*", "%")));
255 public static SearchResult
searchTaxaByName(String name
) {
256 SearchResult searchResult
= new SearchResult();
258 ITaxonServiceConfigurator configurator
= new TaxonServiceConfiguratorImpl();
260 configurator
.setSearchString(name
.replace("*", "%"));
261 configurator
.setDoTaxa(true);
262 // configurator.setDoNamesWithoutTaxa(true);
263 configurator
.setDoSynonyms(true);
264 configurator
.setPageNumber(1);
265 // TODO currently limit results to 1000 for now
266 configurator
.setPageSize(1000);
268 List
<IdentifiableEntity
> result
= getTaxonService().findTaxaAndNames(configurator
).getRecords();
270 searchResult
.addAll(result
);
274 private static CdmApplicationController
getApplicationController() {
275 return TaxEditorPlugin
.getDefault().getApplicationController();
278 public static INameService
getNameService() {
279 return getApplicationController().getNameService();
282 public static ITaxonService
getTaxonService() {
283 return getApplicationController().getTaxonService();
286 public static IReferenceService
getReferenceService() {
287 return getApplicationController().getReferenceService();
295 public static Set
<TaxonNameBase
> getNameByNameForTaxonContext(String searchText
, Taxon taxon
) {
296 Set
<TaxonNameBase
> resultsSet
= new HashSet
<TaxonNameBase
>();
297 resultsSet
.addAll(getNameService().getNamesByName
298 (searchText
.replace("*", "%"), taxon
));
303 * Converts a <code>String</code> whose format is either a valid year
304 * or two valid years with the format "XXXX-XXXX" into a TimePeriod.
306 * @see #getValidYear(String yearStr)
309 * @throws NumberFormatException
311 public static TimePeriod
convertTimePeriod(String refYear
) throws NumberFormatException
{
313 if (refYear
== null || ("").equals(refYear
)){
317 TimePeriod datePublished
= TimePeriod
.NewInstance();
319 // In case format is "xxxx-xxxx"
320 String
[] years
= refYear
.split("-");
322 // Unlikely case of "xxxx-xxxx-xxxx..."
323 if (years
.length
> 2) {
324 throw new NumberFormatException();
328 datePublished
.setStartYear(getValidYear(years
[0]));
330 // Format is "xxxx-xxxx"
331 if (years
.length
== 2) {
332 datePublished
.setEndYear(getValidYear(years
[1]));
335 return datePublished
;
340 * Checks whether a <code>String</code> is a valid year between
341 * 1750 and 2030. Throws a <code>NumberFormatException</code> if not.
345 * @throws NumberFormatException
347 public static Integer
getValidYear(String yearStr
) throws NumberFormatException
{
349 Integer yearInt
= null;
351 // Try casting string - don't catch number format exception
353 yearInt
= new Integer(yearStr
);
354 } catch (ClassCastException e
) {
355 throw new NumberFormatException();
358 // Is year in valid range?
359 if (yearInt
< 1750 || yearInt
> 2030) {
360 throw new NumberFormatException();
367 * Searches for references by string. "%" is used as a wildcard.
372 public static List
getReferencesByTitle(String reference
) {
374 reference
= reference
.replace("*", "%");
375 List resultsList
= null;
377 resultsList
= getReferenceService().getReferencesByTitle(reference
);
378 } catch (RuntimeException e
) {
379 MessageDialog
.openError(GlobalController
.getShell(), "Search reference error",
380 "Reference search returned an error. This could be a Hibernate concurrency problem. " +
381 "Please try saving your work, then searching again.");
388 * Returns true if <code>taxon</code> belongs to the children, grandchildren,
389 * etc. of <code>checkTaxon</code>.
395 public static boolean isTaxonChildOfTaxon(Taxon taxon
, Taxon checkTaxon
) {
397 // Traverse all checkTaxon's children
398 for (Taxon childTaxon
: checkTaxon
.getTaxonomicChildren()) {
400 if (childTaxon
.equals(taxon
)) {
404 // Compare taxon with childTaxon's children
405 if (isTaxonChildOfTaxon(taxon
, childTaxon
)) {