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
.propertysheet
.name
;
12 import java
.beans
.PropertyChangeEvent
;
13 import java
.beans
.PropertyChangeListener
;
14 import java
.beans
.PropertyChangeSupport
;
15 import java
.util
.ArrayList
;
16 import java
.util
.Date
;
17 import java
.util
.List
;
19 import java
.util
.Vector
;
21 import org
.apache
.log4j
.Logger
;
22 import org
.eclipse
.ui
.views
.properties
.ComboBoxPropertyDescriptor
;
23 import org
.eclipse
.ui
.views
.properties
.IPropertyDescriptor
;
24 import org
.eclipse
.ui
.views
.properties
.IPropertySource
;
25 import org
.eclipse
.ui
.views
.properties
.PropertyDescriptor
;
26 import org
.eclipse
.ui
.views
.properties
.TextPropertyDescriptor
;
28 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
29 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
30 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
31 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
32 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
33 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
34 import eu
.etaxonomy
.cdm
.model
.reference
.Generic
;
35 import eu
.etaxonomy
.cdm
.model
.reference
.INomenclaturalReference
;
36 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
37 import eu
.etaxonomy
.taxeditor
.ITaxEditorConstants
;
38 import eu
.etaxonomy
.taxeditor
.model
.CdmSessionDataRepository
;
39 import eu
.etaxonomy
.taxeditor
.preference
.PreferencesUtil
;
40 import eu
.etaxonomy
.taxeditor
.propertysheet
.AnnotationPropertySource
;
41 import eu
.etaxonomy
.taxeditor
.propertysheet
.AnnotationsPropertyDescriptor
;
42 import eu
.etaxonomy
.taxeditor
.propertysheet
.MarkersPropertySource
;
43 import eu
.etaxonomy
.taxeditor
.propertysheet
.reference
.NomenclaturalReferencePropertySource
;
44 import eu
.etaxonomy
.taxeditor
.propertysheet
.reference
.ReferencePropertySource
;
51 public class NonViralNamePropertySource
implements IPropertySource
{
52 private static final Logger logger
= Logger
53 .getLogger(NonViralNamePropertySource
.class);
55 // The name whose properties are being displayed
58 // If this is a property with a parent, the parent's property ID
59 private String parentid
= "";
61 PropertyChangeSupport propertyChangeSupport
;
63 // Property unique keys
64 public static final String P_ID_PARSED
= "parsed";
65 public static final String P_ID_RANK
= "rank";
66 public static final String P_ID_TITLECACHE
= "titlecache";
67 public static final String P_ID_HOMOTYPICALGROUP
= "homogroup";
68 public static final String P_ID_NAMERELATIONS
= "namerelations";
69 public static final String P_ID_TYPE
= "type";
70 public static final String P_ID_ANNOTATIONS
= "annotations";
71 public static final String P_ID_NOMSTATUS
= "nomstatus";
72 public static final String P_ID_UUID
= "uuid";
73 public static final String P_ID_NUM_OF_BASES
= "numberofbases";
74 public static final String P_ID_MARKERS
= "markers";
75 public static final String P_ID_CREATED
= "created";
76 public static final String P_ID_CREATEDBY
= "createdby";
77 public static final String P_ID_NOMENCLATURAL_CODE
= "nomenclaturalcode";
78 public static final String P_ID_NOMENCLATURAL_REF
= "nomenclaturalref";
79 public static final String P_ID_NOMENCLATURAL_MICROREF
= "nomenclaturalmicroref";
81 // Property display keys
82 // Note: for an explanation of the sorting prefixes ("04:"),
83 // @see eu.etaxonomy.taxeditor.propertysheet.CustomSortPropertySheetEntry
84 public static final String P_PARSED
= "00:Parsing Status";
85 public static final String P_RANK
= "02:Rank";
86 public static final String P_TITLECACHE
= "03:Name Cache";
87 public static final String P_HOMOTYPICALGROUP
= "09:Homotypical Group";
88 public static final String P_NAMERELATIONS
= "11:Name Relations";
89 public static final String P_TYPE
= "12:Type";
90 public static final String P_ANNOTATIONS
= "14:Annotations";
91 public static final String P_NOMSTATUS
= "100:Nomenclatural Status";
92 public static final String P_UUID
= "01:UUID";
93 public static final String P_NUM_OF_BASES
= "12:Number of Bases";
94 public static final String P_MARKERS
= "13:Markers";
95 public static final String P_CREATED
= "15:Created";
96 public static final String P_CREATEDBY
= "16:Created By";
97 public static final String P_NOMENCLATURAL_CODE
= "02:Nomenclatural Code";
98 public static final String P_NOMENCLATURAL_REF
= "09:Nomenclatural Reference";
99 public static final String P_NOMENCLATURAL_MICROREF
= "10:Reference Detail";
101 protected static final String
[] TOP_LEVEL_PROPERTIES
= new String
[] {
102 P_ID_PARSED
, P_ID_RANK
, P_ID_TITLECACHE
, P_ID_ANNOTATIONS
, P_ID_NOMSTATUS
,
103 P_ID_NAMERELATIONS
, P_ID_UUID
, P_ID_NOMENCLATURAL_REF
, P_ID_NOMENCLATURAL_MICROREF
,
104 P_ID_CREATED
, P_ID_CREATEDBY
, P_ID_NOMENCLATURAL_CODE
};
106 // ***********************************************************
108 // ***********************************************************
110 String
[] P_RANK_MENU
= null;
111 private void populateRanks() {
113 // Get terms from rank vocabulary
114 List
<Rank
> ranksList
= new ArrayList
<Rank
>();
115 ranksList
.addAll(PreferencesUtil
.getPreferredRanks());
117 // Populate ranks menu labels
118 List
<String
> ranksMenuList
= new ArrayList
<String
>();
119 for (Rank rank
: ranksList
) {
120 ranksMenuList
.add(rank
.getLabel());
123 // Add an empty element for "nothing selected" in the rank drop-down
124 ranksList
.add(0, null);
125 ranksMenuList
.add(0, "");
127 // Convert rank lists to array
128 ranks
= ranksList
.toArray(new Rank
[ranksList
.size()]);
129 P_RANK_MENU
= ranksMenuList
.toArray(new String
[ranksMenuList
.size()]);
132 // ***********************************************************
133 // NOMENCLATURAL STATUS
134 // ***********************************************************
135 // static TermVocabulary<NomenclaturalStatusType> nomStatusVocabulary =
136 // TaxEditorPlugin.getDefault().getNomStatusVocabulary();
137 NomenclaturalStatusType
[] nomStatusTypes
= null;
138 String
[] P_NOMSTATUS_MENU
= null;
139 private void populateNomStatusTypes() {
141 // Get terms from nom status vocabulary
142 List
<NomenclaturalStatusType
> nomStatusTypesList
= new ArrayList
<NomenclaturalStatusType
>();
143 TermVocabulary
<NomenclaturalStatusType
> statusVocab
=
144 CdmSessionDataRepository
.getDefault().getNomStatii();
146 // If there is no status vocabulary, init type and status w empty arrays and return
147 if (statusVocab
== null) {
148 nomStatusTypes
= new NomenclaturalStatusType
[]{};
149 P_NOMSTATUS_MENU
= new String
[]{};
153 nomStatusTypesList
.addAll(statusVocab
.getTerms());
155 // Populate nom status type menu labels
156 List
<String
> nomStatusTypesMenuList
= new ArrayList
<String
>();
157 for (NomenclaturalStatusType nomStatusType
: nomStatusTypesList
) {
158 nomStatusTypesMenuList
.add(nomStatusType
.getLabel());
161 // Add an empty element for "nothing selected" in the rank drop-down
162 nomStatusTypesList
.add(0, null);
163 nomStatusTypesMenuList
.add(0, "");
165 // Convert rank lists to array
166 nomStatusTypes
= nomStatusTypesList
.toArray(new NomenclaturalStatusType
[nomStatusTypesList
.size()]);
167 P_NOMSTATUS_MENU
= nomStatusTypesMenuList
.toArray(new String
[nomStatusTypesMenuList
.size()]);
170 protected Vector
<PropertyDescriptor
> descriptors
= new Vector
<PropertyDescriptor
>();
172 * Add descriptor for a given property.
174 * Notes on Descriptor:
177 * <li>PropertyDescriptor - uneditable cell value</li>
178 * <li>ComboBoxPropertyDescriptor - dropdown list, property supplied must be integer-based</li>
179 * <li>TextPropertyDescriptor - editable cell value</li>
182 * If any descriptor calls setCategory, all descriptors w/out a category are put in
185 * <code>descriptor.setFilterFlags (new String[] { IPropertySheetEntry.FILTER_ID_EXPERT })</code> -
186 * this descriptor shown under advanced properties
190 protected void addDescriptor(String id
) {
192 // Parsed: reports whether parsing was successful
193 if (id
.equals(P_ID_PARSED
)) {
194 descriptors
.addElement(
195 new PropertyDescriptor(P_ID_PARSED
, P_PARSED
));
199 if (id
.equals(P_ID_RANK
)) {
203 descriptors
.addElement(
204 new ComboBoxPropertyDescriptor(P_ID_RANK
, P_RANK
, P_RANK_MENU
));
208 if (id
.equals(P_ID_TITLECACHE
)) {
209 descriptors
.addElement(
210 new PropertyDescriptor(P_ID_TITLECACHE
, P_TITLECACHE
));
214 if (id
.equals(P_ID_HOMOTYPICALGROUP
)) {
215 descriptors
.addElement(
216 new PropertyDescriptor(P_ID_HOMOTYPICALGROUP
, P_HOMOTYPICALGROUP
));
219 // Name relations, listed in custom property descriptor
220 if (id
.equals(P_ID_NAMERELATIONS
)) {
221 descriptors
.addElement(
222 new NameRelationsPropertyDescriptor(P_ID_NAMERELATIONS
, P_NAMERELATIONS
, name
) {
223 protected void saveNameRelations(Set set
) {
224 setPropertyValue(P_ID_NAMERELATIONS
, set
);
231 if (id
.equals(P_ID_TYPE
)) {
232 descriptors
.addElement(
233 new PropertyDescriptor(P_ID_TYPE
, P_TYPE
));
236 // Annotations, listed in custom property descriptor
237 if (id
.equals(P_ID_ANNOTATIONS
)) {
238 descriptors
.addElement(
239 new AnnotationsPropertyDescriptor(P_ID_ANNOTATIONS
, P_ANNOTATIONS
, name
) {
240 protected void saveAnnotations(Set set
) {
241 setPropertyValue(P_ID_ANNOTATIONS
, set
);
247 // Nomenclatural status
248 if (id
.equals(P_ID_NOMSTATUS
)) {
249 if (nomStatusTypes
== null) {
250 populateNomStatusTypes();
252 descriptors
.addElement(
253 new ComboBoxPropertyDescriptor(P_ID_NOMSTATUS
, P_NOMSTATUS
, P_NOMSTATUS_MENU
));
257 if (id
.equals(P_ID_UUID
)) {
258 descriptors
.addElement(
259 new PropertyDescriptor(P_ID_UUID
, P_UUID
));
263 if (id
.equals(P_ID_MARKERS
)) {
264 descriptors
.addElement(
265 new PropertyDescriptor(P_ID_MARKERS
, P_MARKERS
));
268 // Taxon bases referring to this name
269 if (id
.equals(P_ID_NUM_OF_BASES
)) {
270 descriptors
.addElement(
271 new PropertyDescriptor(P_ID_NUM_OF_BASES
, P_NUM_OF_BASES
));
274 // Object created when
275 if (id
.equals(P_ID_CREATED
)) {
276 descriptors
.addElement(
277 new PropertyDescriptor(P_ID_CREATED
, P_CREATED
));
281 if (id
.equals(P_ID_CREATEDBY
)) {
282 descriptors
.addElement(
283 new PropertyDescriptor(P_ID_CREATEDBY
, P_CREATEDBY
));
286 // Nomenclatural code used by parser
287 if (id
.equals(P_ID_NOMENCLATURAL_CODE
)) {
288 descriptors
.addElement(
289 new PropertyDescriptor(P_ID_NOMENCLATURAL_CODE
, P_NOMENCLATURAL_CODE
));
292 // Nomenclatural reference
293 if (id
.equals(P_ID_NOMENCLATURAL_REF
)) {
294 descriptors
.addElement(
295 new PropertyDescriptor(P_ID_NOMENCLATURAL_REF
,P_NOMENCLATURAL_REF
));
299 if (id
.equals(P_ID_NOMENCLATURAL_MICROREF
)) {
300 descriptors
.addElement(
301 new TextPropertyDescriptor(P_ID_NOMENCLATURAL_MICROREF
,P_NOMENCLATURAL_MICROREF
));
306 * Constructor for top level property fields. All fields that are not subfields
307 * should be listed here.
310 public NonViralNamePropertySource(NonViralName name
) {
311 this(name
, null, TOP_LEVEL_PROPERTIES
);
314 public NonViralNamePropertySource(NonViralName name
,
315 String parentid
, String
[] keys
) {
317 this.parentid
= parentid
;
318 for (String key
: keys
) {
323 public Object
getEditableValue() {
327 public IPropertyDescriptor
[] getPropertyDescriptors() {
328 return (IPropertyDescriptor
[]) descriptors
.toArray(
329 new IPropertyDescriptor
[descriptors
.size()]);
332 public Object
getPropertyValue(Object id
) {
334 // Parsed: reports whether parsing was successful
335 if (id
.equals(P_ID_PARSED
)) {
336 return name
.getHasProblem() == true ?
"problem" : "parsed" ;
340 if (id
.equals(P_ID_RANK
)) {
341 if (this.name
.getRank() == null) {
344 Rank rank
= this.name
.getRank();
345 for (int i
= 0; i
< ranks
.length
; i
++) {
346 if (ranks
[i
] == null) continue;
347 if (rank
.getUuid().equals(ranks
[i
].getUuid()))
354 if (id
.equals(P_ID_TITLECACHE
)) {
356 // If the name has not been parsed, only show the title cache
357 if (name
.getRank() == null) {
358 return CdmUtils
.Nz(name
.getTitleCache());
361 // Create property source for submenu
362 ScientificNamePropertySource nameFieldsPropertySource
= new ScientificNamePropertySource(name
);
364 // Add listener to notify name of all changes to nom. reference
365 nameFieldsPropertySource
.addPropertyChangeListener(new PropertyChangeListener() {
366 public void propertyChange(PropertyChangeEvent evt
) {
367 // if (evt.getNewValue() instanceof INomenclaturalReference) {
368 // name.setNomenclaturalReference((INomenclaturalReference) evt.getNewValue());
372 return nameFieldsPropertySource
;
377 if (id
.equals(P_ID_HOMOTYPICALGROUP
)) {
378 return CdmUtils
.Nz(name
.getHomotypicalGroup().getUuid().toString());
381 // Annotations, listed in custom property descriptor
382 if (id
.equals(P_ID_ANNOTATIONS
)) {
383 return new AnnotationPropertySource(name
.getAnnotations());
386 // Nomenclatural status
387 if (id
.equals(P_ID_NOMSTATUS
)) {
388 // return new NomStatusPropertySource(name.getStatus());
389 // if (this.name.getRank() == null) return 0;
390 Set
<NomenclaturalStatus
> nomStatusSet
= this.name
.getStatus();
392 if (nomStatusSet
== null || nomStatusSet
.size() == 0) {
395 // TODO for now, only showing first nom status - change!
396 NomenclaturalStatus nomStatus
= (NomenclaturalStatus
) nomStatusSet
.toArray()[0];
397 for (int i
= 0; i
< nomStatusTypes
.length
; i
++) {
398 if (nomStatusTypes
[i
] == null) continue;
399 if (nomStatus
.getType().getUuid().equals(nomStatusTypes
[i
].getUuid()))
405 // Name relations, popup to edit list
406 if (id
.equals(P_ID_NAMERELATIONS
)) {
407 return new NameRelationsPropertySource(name
, name
.getNameRelations());
411 if (id
.equals(P_ID_TYPE
)) {
416 if (id
.equals(P_ID_UUID
)) {
417 return CdmUtils
.Nz(name
.getUuid().toString());
421 if (id
.equals(P_ID_MARKERS
)) {
422 return new MarkersPropertySource(name
.getMarkers());
425 // Taxon bases referring to this name
426 if (id
.equals(P_ID_NUM_OF_BASES
)) {
427 return name
.getTaxonBases().size();
431 if (id
.equals(P_ID_CREATED
)) {
432 if (name
.getCreated() == null) {
435 return formatDate(name
.getCreated().toDate());
439 // Object created when
440 if (id
.equals(P_ID_CREATEDBY
)) {
441 if (name
.getCreatedBy() == null) {
444 return CdmUtils
.Nz(name
.getCreatedBy().generateTitle());
448 // Nomenclatural code used by parser
449 if (id
.equals(P_ID_NOMENCLATURAL_CODE
)) {
450 // Only shown if extending classes don't handle P_ID_NOMENCLATURAL_CODE
451 return "none (nonviral name)";
454 // Nomenclatural reference
455 if (id
.equals(P_ID_NOMENCLATURAL_REF
)) {
457 ReferenceBase nomRef
= (ReferenceBase
) name
.getNomenclaturalReference();
459 // Create nom. reference as necessary
460 if (nomRef
== null) {
461 nomRef
= Generic
.NewInstance();
464 // Create property source for submenu
465 ReferencePropertySource nomRefPropertySource
= new NomenclaturalReferencePropertySource(nomRef
);
467 // Add listener to notify name of all changes to nom. reference
468 nomRefPropertySource
.addPropertyChangeListener(new PropertyChangeListener() {
469 public void propertyChange(PropertyChangeEvent evt
) {
470 if (evt
.getNewValue() instanceof INomenclaturalReference
) {
471 name
.setNomenclaturalReference((INomenclaturalReference
) evt
.getNewValue());
475 return nomRefPropertySource
;
480 if (id
.equals(P_ID_NOMENCLATURAL_MICROREF
)) {
481 return CdmUtils
.Nz(name
.getNomenclaturalMicroReference());
487 private Object
formatDate(Date date
) {
488 return String
.format("%1$tm-%1$td-%1$tY %1$tH:%1$tM:%1$tS", date
);
491 public boolean isPropertySet(Object id
) {
495 public void resetPropertyValue(Object id
) {}
498 * Any editable fields are set in the object here.
500 * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
502 public void setPropertyValue(Object id
, Object value
) {
504 // Since this is only called when the property value changes,
505 // it is a reliable place to fire the name's property change
507 name
.firePropertyChange(ITaxEditorConstants
.PROPERTY_SHEET_CHANGE
, null, null);
510 if (id
.equals(P_ID_RANK
)) {
511 int index
= ((Integer
) value
).intValue();
512 name
.setRank(ranks
[index
]);
515 // Nomenclatural status
516 if (id
.equals(P_ID_NOMSTATUS
)) {
517 NomenclaturalStatus nomStatus
;
518 int index
= ((Integer
) value
).intValue();
519 Set
<NomenclaturalStatus
> nomStatusSet
= name
.getStatus();
521 if (nomStatusSet
.size() > 0) {
522 nomStatus
= (NomenclaturalStatus
) nomStatusSet
.toArray()[0];
525 nomStatusSet
.remove(nomStatus
);
527 nomStatus
.setType(nomStatusTypes
[index
]);
531 nomStatus
= NomenclaturalStatus
.NewInstance(nomStatusTypes
[index
]);
532 name
.addStatus(nomStatus
);
537 if (id
.equals(P_ID_MARKERS
)) {
541 // Nomenclatural reference
542 if (id
.equals(P_ID_NOMENCLATURAL_REF
)) {
543 if (value
instanceof INomenclaturalReference
) {
544 name
.setNomenclaturalReference((INomenclaturalReference
) value
);
549 if (id
.equals(P_ID_NOMENCLATURAL_MICROREF
)) {
550 name
.setNomenclaturalMicroReference((String
) value
);
553 // If there is no rank, generated caches will be blank, wiping out the freetext area
554 if (name
.getRank() != null) {
556 // Reset both caches to reflect property sheet changes
557 name
.setTitleCache(name
.generateTitle(), false);
558 name
.setFullTitleCache(name
.generateFullTitle(), false);
561 // name.firePropertyChange(ITaxEditorConstants.REFRESH_NAMEVIEWER, null, null);
566 * Any node with children must override {@link java.lang.Object#toString()}
567 * to display its name correctly
569 * @see java.lang.Object#toString()
571 public String
toString() {
572 if (parentid
== null || parentid
.equals("")) {
575 if (parentid
.equals(P_ID_TITLECACHE
)) {
576 return name
.getTitleCache();
578 if (parentid
.equals(P_ID_NOMENCLATURAL_REF
)) {
579 INomenclaturalReference nomenclaturalReference
= name
.getNomenclaturalReference();
580 if (nomenclaturalReference
== null) {
583 String microReference
= name
.getNomenclaturalMicroReference();
584 return CdmUtils
.Nz(nomenclaturalReference
.getNomenclaturalCitation(microReference
));
586 return super.toString();
589 public void addPropertyChangeListener(
590 PropertyChangeListener listener
) {
591 this.propertyChangeSupport
.addPropertyChangeListener(listener
);