3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
11 package eu
.etaxonomy
.taxeditor
.model
;
13 import java
.lang
.reflect
.InvocationTargetException
;
14 import java
.lang
.reflect
.Method
;
15 import java
.util
.Arrays
;
16 import java
.util
.List
;
19 import org
.apache
.commons
.lang
.StringUtils
;
20 import org
.hibernate
.LazyInitializationException
;
22 import eu
.etaxonomy
.cdm
.api
.service
.DefaultCategoricalDescriptionBuilder
;
23 import eu
.etaxonomy
.cdm
.api
.service
.DefaultQuantitativeDescriptionBuilder
;
24 import eu
.etaxonomy
.cdm
.api
.service
.DescriptionBuilder
;
25 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
26 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
27 import eu
.etaxonomy
.cdm
.model
.common
.Group
;
28 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
29 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
30 import eu
.etaxonomy
.cdm
.model
.common
.LanguageString
;
31 import eu
.etaxonomy
.cdm
.model
.common
.LanguageStringBase
;
32 import eu
.etaxonomy
.cdm
.model
.common
.Marker
;
33 import eu
.etaxonomy
.cdm
.model
.common
.MarkerType
;
34 import eu
.etaxonomy
.cdm
.model
.common
.OriginalSourceBase
;
35 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipBase
;
36 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipTermBase
;
37 import eu
.etaxonomy
.cdm
.model
.common
.Representation
;
38 import eu
.etaxonomy
.cdm
.model
.common
.User
;
39 import eu
.etaxonomy
.cdm
.model
.description
.CategoricalData
;
40 import eu
.etaxonomy
.cdm
.model
.description
.CommonTaxonName
;
41 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionBase
;
42 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
43 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementSource
;
44 import eu
.etaxonomy
.cdm
.model
.description
.Distribution
;
45 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
46 import eu
.etaxonomy
.cdm
.model
.description
.IndividualsAssociation
;
47 import eu
.etaxonomy
.cdm
.model
.description
.PresenceAbsenceTerm
;
48 import eu
.etaxonomy
.cdm
.model
.description
.QuantitativeData
;
49 import eu
.etaxonomy
.cdm
.model
.description
.SpecimenDescription
;
50 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
51 import eu
.etaxonomy
.cdm
.model
.description
.TaxonInteraction
;
52 import eu
.etaxonomy
.cdm
.model
.description
.TaxonNameDescription
;
53 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
54 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
55 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
56 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
57 import eu
.etaxonomy
.cdm
.model
.name
.HybridRelationship
;
58 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationship
;
59 import eu
.etaxonomy
.cdm
.model
.name
.NameTypeDesignation
;
60 import eu
.etaxonomy
.cdm
.model
.name
.SpecimenTypeDesignation
;
61 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
62 import eu
.etaxonomy
.cdm
.model
.name
.TypeDesignationBase
;
63 import eu
.etaxonomy
.cdm
.model
.name
.TypeDesignationStatusBase
;
64 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
65 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymRelationship
;
66 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
67 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationship
;
68 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
71 * <p>DescriptionHelper class.</p>
77 public class DescriptionHelper
{
80 * Returns whatever the element's title cache equivalent is,
81 * depending on its class.
83 * @param element a {@link eu.etaxonomy.cdm.model.description.DescriptionElementBase} object.
84 * @param language a {@link eu.etaxonomy.cdm.model.common.Language} object.
85 * @return a {@link java.lang.String} object.
87 public static String
getCache(DescriptionElementBase element
,
90 String mainElementLabel
= null;
91 DescriptionBase
<?
> descr
= element
.getInDescription();
93 if (descr
.isInstanceOf(TaxonDescription
.class)){
94 Taxon taxon
= CdmBase
.deproxy(descr
, TaxonDescription
.class).getTaxon();
96 mainElementLabel
= taxon
.getTitleCache();
98 }else if (descr
.isInstanceOf(SpecimenDescription
.class)){
99 SpecimenOrObservationBase
<?
> specimen
= CdmBase
.deproxy(descr
, SpecimenDescription
.class).getDescribedSpecimenOrObservation();
100 if (specimen
!= null){
101 mainElementLabel
= specimen
.getTitleCache();
103 }else if (descr
.isInstanceOf(TaxonNameDescription
.class)){
104 TaxonNameBase
<?
, ?
> name
= CdmBase
.deproxy(descr
, TaxonNameDescription
.class).getTaxonName();
106 mainElementLabel
= name
.getTitleCache();
112 if (element
instanceof TextData
) {
113 cache
= ((TextData
) element
).getText(language
);
115 if (element
instanceof CommonTaxonName
) {
116 cache
= ((CommonTaxonName
) element
).getName();
118 if (element
instanceof TaxonInteraction
) {
119 Taxon taxon2
= ((TaxonInteraction
) element
).getTaxon2();
120 if(taxon2
!= null && taxon2
.getName() != null){
121 cache
= taxon2
.getName().getTitleCache();
123 cache
= "No taxon chosen";
127 if (element
instanceof Distribution
) {
128 Distribution distribution
= (Distribution
) element
;
130 NamedArea area
= distribution
.getArea();
132 cache
= area
.getLabel();
134 PresenceAbsenceTerm status
= distribution
.getStatus();
136 cache
+= ", no status";
138 cache
+= ", " + status
.getLabel();
142 String result
= cache
== null ?
"" : cache
;
143 if (StringUtils
.isNotBlank(mainElementLabel
)){
144 result
= CdmUtils
.concat(" ", result
, "(" + mainElementLabel
+ ")");
150 * Returns whatever the element's title cache equivalent is,
151 * depending on its class, using the default language.
153 * @param element a {@link eu.etaxonomy.cdm.model.description.DescriptionElementBase} object.
154 * @return a {@link java.lang.String} object.
156 public static String
getCache(DescriptionElementBase element
) {
157 return getCache(element
, CdmStore
.getDefaultLanguage());
161 * Set whatever the element's title cache equivalent is,
162 * depending on its class.
164 * @param element a {@link eu.etaxonomy.cdm.model.description.DescriptionElementBase} object.
165 * @param value a {@link java.lang.String} object.
166 * @param language a {@link eu.etaxonomy.cdm.model.common.Language} object.
168 public static void setCache(DescriptionElementBase element
,
169 String value
, Language language
) {
170 if (element
instanceof TextData
) {
171 ((TextData
) element
).putText(language
, value
);
173 }else if (element
instanceof CommonTaxonName
) {
174 ((CommonTaxonName
) element
).setName(value
);
176 }else if (element
instanceof TaxonInteraction
) {
178 }else if(element
instanceof Distribution
){
179 MessagingUtils
.warn(DescriptionHelper
.class, "trying to set cache on distribution, don't know what to do at the moment.");
182 MessagingUtils
.warn(DescriptionHelper
.class, "No matching subclass found for DescriptionElementBase object, 'cache' not set.");
187 * Set whatever the element's title cache equivalent is,
188 * depending on its class, using the default language.
190 * @param element a {@link eu.etaxonomy.cdm.model.description.DescriptionElementBase} object.
191 * @param value a {@link java.lang.String} object.
193 public static void setCache(DescriptionElementBase element
,
195 setCache(element
, value
, CdmStore
.getDefaultLanguage());
200 * <p>getObjectDescription</p>
202 * @param element a {@link java.lang.Object} object.
203 * @return a {@link java.lang.String} object.
205 public static String
getObjectDescription(Object element
) {
206 if (element
instanceof IdentifiableEntity
) {
208 return ((IdentifiableEntity
) element
).getTitleCache();
209 }catch(LazyInitializationException e
){
210 String result
= "No Session to initialize title cache for IdentifiableEntity";
211 MessagingUtils
.error(DescriptionHelper
.class, result
, e
);
212 return "TODO: " + result
;
214 }else if (element
instanceof OriginalSourceBase
) {
216 OriginalSourceBase
<?
> originalSource
= (OriginalSourceBase
<?
>) element
;
217 // ISourceable sourcedObject = originalSource.getSourcedObj();
218 //due to #5743 the bidirectionality for sourced object had to be removed
219 String sourceObjectTitle
= "sourced object data not available (#5743)";
220 // if(sourcedObject instanceof IIdentifiableEntity){
221 // sourceObjectTitle = ((IdentifiableEntity) sourcedObject).getTitleCache();
222 // }else if(sourcedObject instanceof DescriptionElementBase){
223 // sourceObjectTitle = "Element for description: " + ((DescriptionElementBase) sourcedObject).getInDescription().getTitleCache();
225 // throw new IllegalStateException("Unknown ISourceable object for given OriginalSourceBase");
228 return CdmUtils
.concat("; ", new String
[]{originalSource
.getIdNamespace(), originalSource
.getIdInSource(), sourceObjectTitle
});
229 }catch(LazyInitializationException e
){
230 String result
= "Error initializing title cache for ISourceable of an OriginalSourceBase";
231 MessagingUtils
.error(DescriptionHelper
.class, result
, e
);
232 return "TODO: " + result
;
234 }else if (element
instanceof LanguageStringBase
) {
235 return ((LanguageStringBase
) element
).getText();
236 }else if (element
instanceof DescriptionElementBase
) {
237 return getCache((DescriptionElementBase
) element
);
238 }else if (element
instanceof RelationshipBase
<?
, ?
, ?
>) {
239 return getCache((RelationshipBase
<?
, ?
, ?
>) element
);
240 }else if (element
instanceof TypeDesignationBase
<?
>) {
241 return getCache((TypeDesignationBase
<?
>) element
);
242 }else if (element
instanceof HomotypicalGroup
) {
243 return getCache((HomotypicalGroup
) element
);
244 }else if (element
instanceof Marker
) {
245 Marker marker
= (Marker
) element
;
246 MarkerType type
= marker
.getMarkerType();
247 return (type
== null ?
"- no marker type -" : marker
.getMarkerType().getLabel()) + " (" + marker
.getFlag() + ")";
248 }else if (element
instanceof User
) {
249 User user
= (User
) element
;
250 return user
.getUsername();
251 }else if (element
instanceof Group
) {
252 Group group
= (Group
) element
;
253 return group
.getName();
255 // TODO write return texts for HomotypicalGroup, etc.
256 return element
.toString();
261 private static String
getCache(TypeDesignationBase
<?
> designation
) {
262 designation
= CdmBase
.deproxy(designation
);
263 TypeDesignationStatusBase
<?
> status
= designation
.getTypeStatus();
264 Set
<TaxonNameBase
> from
;
265 IdentifiableEntity
<?
> to
;
266 from
= designation
.getTypifiedNames();
267 if (designation
.isInstanceOf(SpecimenTypeDesignation
.class)){
268 to
= ((SpecimenTypeDesignation
)designation
).getTypeSpecimen();
269 }else if (designation
.isInstanceOf(NameTypeDesignation
.class)){
270 to
= ((NameTypeDesignation
)designation
).getTypeName();
272 throw new RuntimeException("Type Designation class not supported: " + designation
.getClass().getName());
274 String typeLabel
= null;
276 Representation typeRepr
= status
.getPreferredRepresentation(CdmStore
.getDefaultLanguage());
277 if (typeRepr
!= null){
278 typeLabel
= typeRepr
.getAbbreviatedLabel();
280 if (StringUtils
.isBlank(typeLabel
) && typeRepr
!= null){
281 typeLabel
= typeRepr
.getLabel();
283 if (StringUtils
.isBlank(typeLabel
) ){
284 typeLabel
= status
.getSymbol();
286 if (StringUtils
.isBlank(typeLabel
)){
287 typeLabel
= status
.getTitleCache();
290 if (StringUtils
.isBlank(typeLabel
)){
293 String fromString
= "";
294 for (TaxonNameBase
<?
,?
> name
: from
){
295 CdmUtils
.concat(",", fromString
, name
.getTitleCache());
297 String result
= CdmUtils
.concat(" ", new String
[]{from
== null ?
null : fromString
,
298 typeLabel
, to
== null?
null : to
.getTitleCache()});
302 private static String
getCache(RelationshipBase
<?
, ?
, ?
> rel
) {
303 rel
= CdmBase
.deproxy(rel
);
304 RelationshipTermBase
<?
> type
= rel
.getType();
305 IdentifiableEntity
<?
> from
;
306 IdentifiableEntity
<?
> to
;
307 if (rel
.isInstanceOf(SynonymRelationship
.class)){
308 from
= ((SynonymRelationship
)rel
).getSynonym();
309 to
= ((SynonymRelationship
)rel
).getAcceptedTaxon();
310 }else if (rel
.isInstanceOf(NameRelationship
.class)){
311 from
= ((NameRelationship
)rel
).getFromName();
312 to
= ((NameRelationship
)rel
).getToName();
313 }else if (rel
.isInstanceOf(HybridRelationship
.class)){
314 from
= ((HybridRelationship
)rel
).getParentName();
315 to
= ((HybridRelationship
)rel
).getHybridName();
316 }else if (rel
.isInstanceOf(TaxonRelationship
.class)){
317 from
= ((TaxonRelationship
)rel
).getFromTaxon();
318 to
= ((TaxonRelationship
)rel
).getToTaxon();
321 Method fromMethod
= rel
.getClass().getMethod("getRelatedFrom");
322 Method toMethod
= rel
.getClass().getMethod("getRelatedFrom");
323 fromMethod
.setAccessible(true);
324 toMethod
.setAccessible(true);
325 from
= (IdentifiableEntity
<?
>)fromMethod
.invoke(rel
);
326 to
= (IdentifiableEntity
<?
>)toMethod
.invoke(rel
);
327 } catch (NoSuchMethodException e
) {
328 throw new RuntimeException(e
);
329 } catch (SecurityException e
) {
330 throw new RuntimeException(e
);
331 } catch (IllegalAccessException e
) {
332 throw new RuntimeException(e
);
333 } catch (IllegalArgumentException e
) {
334 throw new RuntimeException(e
);
335 } catch (InvocationTargetException e
) {
336 throw new RuntimeException(e
);
340 String typeLabel
= null;
342 Representation typeRepr
= type
.getPreferredRepresentation(CdmStore
.getDefaultLanguage());
343 if (typeRepr
!= null){
344 typeLabel
= typeRepr
.getAbbreviatedLabel();
346 if (StringUtils
.isBlank(typeLabel
) && typeRepr
!= null){
347 typeLabel
= typeRepr
.getLabel();
349 if (StringUtils
.isBlank(typeLabel
) ){
350 typeLabel
= type
.getSymbol();
352 if (StringUtils
.isBlank(typeLabel
)){
353 typeLabel
= type
.getTitleCache();
356 if (StringUtils
.isBlank(typeLabel
)){
359 String result
= CdmUtils
.concat(" ", new String
[]{from
== null ?
null : from
.getTitleCache(),
360 typeLabel
, to
== null?
null : to
.getTitleCache()});
365 private static String
getCache(HomotypicalGroup hg
) {
367 for (TaxonNameBase
<?
,?
> tnb
: hg
.getTypifiedNames()){
368 result
= CdmUtils
.concat(", ", result
, tnb
.getTitleCache());
370 if (StringUtils
.isBlank(result
)){
371 result
= "No typified names";
377 * <p>getObjectClassname</p>
379 * @param element a {@link java.lang.Object} object.
380 * @return a {@link java.lang.String} object.
382 public static String
getObjectClassname(Object element
) {
383 return element
.getClass().getSimpleName();
387 * <p>getFeatureNodeContainerText</p>
389 * @param element a {@link eu.etaxonomy.taxeditor.model.FeatureNodeContainer} object.
390 * @return a {@link java.lang.String} object.
392 public static String
getFeatureNodeContainerText(FeatureNodeContainer element
) {
393 String result
= null;
394 if(element
.getFeatureNode() != null && element
.getFeatureNode().getFeature() != null){
395 result
= element
.getFeatureNode().getFeature().getLabel(CdmStore
.getDefaultLanguage());
397 return "No label set";
400 result
= element
.getFeatureNode().getFeature().getLabel();
406 * <p>getQuantitativeDataText</p>
408 * @param element a {@link eu.etaxonomy.cdm.model.description.QuantitativeData} object.
409 * @return a {@link java.lang.String} object.
411 public static String
getQuantitativeDataText(QuantitativeData element
) {
412 TextData textData
= quantitativeDescriptionBuilder
.build(element
, getLanguageList());
414 return textData
.getText(CdmStore
.getDefaultLanguage());
418 * <p>getCategoricalDataText</p>
420 * @param element a {@link eu.etaxonomy.cdm.model.description.CategoricalData} object.
421 * @return a {@link java.lang.String} object.
423 public static String
getCategoricalDataText(CategoricalData element
) {
424 TextData textData
= categoricalDescriptionBuilder
.build(element
, getLanguageList());
426 return textData
.getText(CdmStore
.getDefaultLanguage());
429 private static List
<Language
> getLanguageList(){
430 return Arrays
.asList(new Language
[]{CdmStore
.getDefaultLanguage()});
433 private static DescriptionBuilder
<QuantitativeData
> quantitativeDescriptionBuilder
= new DefaultQuantitativeDescriptionBuilder();
434 private static DescriptionBuilder
<CategoricalData
> categoricalDescriptionBuilder
= new DefaultCategoricalDescriptionBuilder();
438 * <p>getDistributionText</p>
440 * @param element a {@link eu.etaxonomy.cdm.model.description.Distribution} object.
441 * @return a {@link java.lang.String} object.
443 public static String
getDistributionText(Distribution element
) {
445 String text
= "EMPTY";
447 Distribution distribution
= element
;
449 NamedArea area
= distribution
.getArea();
452 text
= NamedArea
.labelWithLevel(area
, CdmStore
.getDefaultLanguage());
454 PresenceAbsenceTerm status
= distribution
.getStatus();
456 if (status
!= null) {
457 text
+= ", " + status
.getLabel();
459 text
+= ", NO STATUS";
466 * <p>getImageText</p>
468 * @param media a {@link eu.etaxonomy.cdm.model.media.Media} object.
469 * @return a {@link java.lang.String} object.
471 public static String
getImageText(Media media
) {
472 LanguageString title
= media
.getTitle(CdmStore
.getDefaultLanguage());
474 return title
.getText();
482 * <p>getElementText</p>
484 * @param element a {@link eu.etaxonomy.cdm.model.description.TextData} object.
485 * @return a {@link java.lang.String} object.
487 public static String
getElementText(TextData element
) {
489 if(element
.getFeature().equals(Feature
.CITATION())){
491 for(DescriptionElementSource source
: element
.getSources()){
492 if(source
.getCitation() != null){
493 text
+= source
.getCitation().getTitleCache();
495 if(source
.getNameUsedInSource() != null){
496 text
+= " [ " + source
.getNameUsedInSource().getTitleCache() + " ]";
499 if(CdmUtils
.isEmpty(text
)){
500 text
= "No sources provided";
503 List
<Language
> languages
= Arrays
.asList(new Language
[]{CdmStore
.getDefaultLanguage()});
504 LanguageString languageString
= element
.getPreferredLanguageString(languages
);
505 text
= languageString
!= null ? languageString
.getText() : null;
507 return CdmUtils
.isEmpty(text
) ?
"No text provided" : text
;
511 * <p>getTaxonInteractionText</p>
513 * @param element a {@link eu.etaxonomy.cdm.model.description.TaxonInteraction} object.
514 * @return a {@link java.lang.String} object.
516 public static String
getTaxonInteractionText(TaxonInteraction element
) {
518 Taxon taxon2
= element
.getTaxon2();
519 if(taxon2
!= null && taxon2
.getName() != null){
520 text
= taxon2
.getName().getTitleCache();
522 text
= "No taxon chosen";
529 * <p>getCommonNameText</p>
531 * @param commonName a {@link eu.etaxonomy.cdm.model.description.CommonTaxonName} object.
532 * @return a {@link java.lang.String} object.
534 public static String
getCommonNameText(CommonTaxonName commonName
) {
535 String name
= commonName
.getName();
536 if (name
== null || name
.length() == 0) {
537 name
= "No name provided";
539 Language language
= commonName
.getLanguage();
540 if (language
== null) {
541 name
+= " (No language provided)";
543 name
+= " (" + language
.getDescription() + ")";
549 * <p>getDescriptionText</p>
551 * @param element a {@link eu.etaxonomy.cdm.model.description.DescriptionBase} object.
552 * @return a {@link java.lang.String} object.
554 public static String
getDescriptionText(DescriptionBase element
) {
555 String text
= element
.getTitleCache();
556 if (text
== null || text
.length() == 0) {
557 text
= "No label provided";
564 * <p>getIndividualsAssociationText</p>
566 * @param element a {@link eu.etaxonomy.cdm.model.description.IndividualsAssociation} object.
567 * @return a {@link java.lang.String} object.
569 public static String
getIndividualsAssociationText(IndividualsAssociation element
) {
570 SpecimenOrObservationBase derivedUnit
= element
.getAssociatedSpecimenOrObservation();
571 if(derivedUnit
!= null){
572 return derivedUnit
.getTitleCache();
574 return "No unit chosen";
580 * @param element a {@link java.lang.Object} object.
581 * @return a {@link java.lang.String} object.
583 public static String
getLabel(Object element
){
584 String noLabelString
= "[no label]";
585 if (element
instanceof FeatureNodeContainer
){
586 return getFeatureNodeContainerText((FeatureNodeContainer
) element
);
588 else if (element
instanceof DescriptionBase
) {
589 return getDescriptionText((DescriptionBase
) element
);
591 else if(element
instanceof CategoricalData
){
592 String categoricalDataText
= getCategoricalDataText((CategoricalData
) element
);
593 if(categoricalDataText
==null || categoricalDataText
.isEmpty()){
594 categoricalDataText
= noLabelString
;
596 return categoricalDataText
;
598 else if (element
instanceof CommonTaxonName
) {
599 return getCommonNameText((CommonTaxonName
) element
);
601 else if (element
instanceof Distribution
) {
602 return getDistributionText((Distribution
) element
);
604 else if (element
instanceof IndividualsAssociation
) {
605 return getIndividualsAssociationText((IndividualsAssociation
) element
);
607 else if (element
instanceof QuantitativeData
) {
608 String quantitativeDataText
= getQuantitativeDataText((QuantitativeData
) element
);
609 if(quantitativeDataText
==null || quantitativeDataText
.isEmpty()){
610 quantitativeDataText
= noLabelString
;
612 return quantitativeDataText
;
614 else if (element
instanceof TaxonInteraction
) {
615 return getTaxonInteractionText((TaxonInteraction
) element
);
617 else if (element
instanceof TextData
) {
618 return getElementText((TextData
) element
);
621 return element
.toString();