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
.eclipse
.ui
.views
.properties
.ComboBoxPropertyDescriptor
;
22 import org
.eclipse
.ui
.views
.properties
.IPropertyDescriptor
;
23 import org
.eclipse
.ui
.views
.properties
.PropertyDescriptor
;
24 import org
.eclipse
.ui
.views
.properties
.TextPropertyDescriptor
;
26 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
27 import eu
.etaxonomy
.cdm
.model
.common
.IIdentifiableEntity
;
28 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
29 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
30 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
31 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
32 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
33 import eu
.etaxonomy
.cdm
.model
.reference
.Generic
;
34 import eu
.etaxonomy
.cdm
.model
.reference
.INomenclaturalReference
;
35 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
36 import eu
.etaxonomy
.taxeditor
.propertysheet
.AnnotationsPropertyDescriptor
;
37 import eu
.etaxonomy
.taxeditor
.propertysheet
.ICdmBasePropertySource
;
38 import eu
.etaxonomy
.taxeditor
.propertysheet
.MarkersPropertySource
;
39 import eu
.etaxonomy
.taxeditor
.propertysheet
.reference
.NomenclaturalReferencePropertySource
;
40 import eu
.etaxonomy
.taxeditor
.propertysheet
.reference
.ReferencePropertySource
;
41 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
42 import eu
.etaxonomy
.taxeditor
.store
.preference
.PreferencesUtil
;
49 public class NonViralNamePropertySource
implements ICdmBasePropertySource
{
51 // The name whose properties are being displayed
54 // If this is a property with a parent, the parent's property ID
55 private String parentid
= "";
57 PropertyChangeSupport propertyChangeSupport
;
59 // Property unique keys
60 public static final String P_ID_PARSED
= "parsed";
61 public static final String P_ID_RANK
= "rank";
62 public static final String P_ID_TITLECACHE
= "titlecache";
63 public static final String P_ID_HOMOTYPICALGROUP
= "homogroup";
64 public static final String P_ID_NAMERELATIONS
= "namerelations";
65 public static final String P_ID_TYPE
= "type";
66 public static final String P_ID_ANNOTATIONS
= "annotations";
67 public static final String P_ID_NOMSTATUS
= "nomstatus";
68 public static final String P_ID_UUID
= "uuid";
69 public static final String P_ID_NUM_OF_BASES
= "numberofbases";
70 public static final String P_ID_MARKERS
= "markers";
71 public static final String P_ID_CREATED
= "created";
72 public static final String P_ID_CREATEDBY
= "createdby";
73 public static final String P_ID_NOMENCLATURAL_CODE
= "nomenclaturalcode";
74 public static final String P_ID_NOMENCLATURAL_REF
= "nomenclaturalref";
75 public static final String P_ID_NOMENCLATURAL_MICROREF
= "nomenclaturalmicroref";
77 // Property display keys
78 public static final String P_PARSED
= "Parsing Status";
79 public static final String P_RANK
= "Rank";
80 public static final String P_TITLECACHE
= "Name Cache";
81 public static final String P_HOMOTYPICALGROUP
= "Homotypical Group";
82 public static final String P_NAMERELATIONS
= "Name Relations";
83 public static final String P_TYPE
= "Type";
84 public static final String P_ANNOTATIONS
= "Annotations";
85 public static final String P_NOMSTATUS
= "Nomenclatural Status";
86 public static final String P_UUID
= "UUID";
87 public static final String P_NUM_OF_BASES
= "Number of Bases";
88 public static final String P_MARKERS
= "Markers";
89 public static final String P_CREATED
= "Created";
90 public static final String P_CREATEDBY
= "Created By";
91 public static final String P_NOMENCLATURAL_CODE
= "Nomenclatural Code";
92 public static final String P_NOMENCLATURAL_REF
= "Nomenclatural Reference";
93 public static final String P_NOMENCLATURAL_MICROREF
= "Reference Detail";
95 protected static final String
[] TOP_LEVEL_PROPERTIES
= new String
[] {
98 P_ID_NOMENCLATURAL_CODE
,
101 P_ID_NOMENCLATURAL_REF
,
102 P_ID_NOMENCLATURAL_MICROREF
,
109 // ***********************************************************
111 // ***********************************************************
113 String
[] P_RANK_MENU
= null;
114 private void populateRanks() {
116 // Get terms from rank vocabulary
117 List
<Rank
> ranksList
= new ArrayList
<Rank
>();
118 ranksList
.addAll(PreferencesUtil
.getPreferredRanks());
120 // Populate ranks menu labels
121 List
<String
> ranksMenuList
= new ArrayList
<String
>();
122 for (Rank rank
: ranksList
) {
123 ranksMenuList
.add(rank
.getLabel());
126 // Add an empty element for "nothing selected" in the rank drop-down
127 ranksList
.add(0, null);
128 ranksMenuList
.add(0, "");
130 // Convert rank lists to array
131 ranks
= ranksList
.toArray(new Rank
[ranksList
.size()]);
132 P_RANK_MENU
= ranksMenuList
.toArray(new String
[ranksMenuList
.size()]);
135 // ***********************************************************
136 // NOMENCLATURAL STATUS
137 // ***********************************************************
138 // static TermVocabulary<NomenclaturalStatusType> nomStatusVocabulary =
139 // TaxEditorPlugin.getDefault().getNomStatusVocabulary();
140 NomenclaturalStatusType
[] nomStatusTypes
= null;
141 String
[] P_NOMSTATUS_MENU
= null;
142 private void populateNomStatusTypes() {
144 // Get terms from nom status vocabulary
145 List
<NomenclaturalStatusType
> nomStatusTypesList
= new ArrayList
<NomenclaturalStatusType
>();
146 TermVocabulary
<NomenclaturalStatusType
> statusVocab
=
147 CdmStore
.getDefault().getNomStatus();
149 // If there is no status vocabulary, init type and status w empty arrays and return
150 if (statusVocab
== null) {
151 nomStatusTypes
= new NomenclaturalStatusType
[]{};
152 P_NOMSTATUS_MENU
= new String
[]{};
156 nomStatusTypesList
.addAll(statusVocab
.getTerms());
158 // Populate nom status type menu labels
159 List
<String
> nomStatusTypesMenuList
= new ArrayList
<String
>();
160 for (NomenclaturalStatusType nomStatusType
: nomStatusTypesList
) {
161 nomStatusTypesMenuList
.add(nomStatusType
.getLabel());
164 // Add an empty element for "nothing selected" in the rank drop-down
165 nomStatusTypesList
.add(0, null);
166 nomStatusTypesMenuList
.add(0, "");
168 // Convert rank lists to array
169 nomStatusTypes
= nomStatusTypesList
.toArray(new NomenclaturalStatusType
[nomStatusTypesList
.size()]);
170 P_NOMSTATUS_MENU
= nomStatusTypesMenuList
.toArray(new String
[nomStatusTypesMenuList
.size()]);
173 protected Vector
<PropertyDescriptor
> descriptors
= new Vector
<PropertyDescriptor
>();
175 * Add descriptor for a given property.
177 * Notes on Descriptor:
180 * <li>PropertyDescriptor - uneditable cell value</li>
181 * <li>ComboBoxPropertyDescriptor - dropdown list, property supplied must be integer-based</li>
182 * <li>TextPropertyDescriptor - editable cell value</li>
185 * If any descriptor calls setCategory, all descriptors w/out a category are put in
188 * <code>descriptor.setFilterFlags (new String[] { IPropertySheetEntry.FILTER_ID_EXPERT })</code> -
189 * this descriptor shown under advanced properties
193 protected void addDescriptor(String id
) {
195 // Parsed: reports whether parsing was successful
196 if (id
.equals(P_ID_PARSED
)) {
197 descriptors
.addElement(
198 new PropertyDescriptor(P_ID_PARSED
, P_PARSED
));
202 if (id
.equals(P_ID_RANK
)) {
206 descriptors
.addElement(
207 new EditorComboBoxPropertyDescriptor(P_ID_RANK
, P_RANK
, P_RANK_MENU
));
211 if (id
.equals(P_ID_TITLECACHE
)) {
212 descriptors
.addElement(
213 new PropertyDescriptor(P_ID_TITLECACHE
, P_TITLECACHE
));
217 if (id
.equals(P_ID_HOMOTYPICALGROUP
)) {
218 descriptors
.addElement(
219 new PropertyDescriptor(P_ID_HOMOTYPICALGROUP
, P_HOMOTYPICALGROUP
));
222 // Name relations, listed in custom property descriptor
223 if (id
.equals(P_ID_NAMERELATIONS
)) {
224 descriptors
.addElement(
225 new NameRelationsPropertyDescriptor(P_ID_NAMERELATIONS
, P_NAMERELATIONS
, name
)
230 if (id
.equals(P_ID_TYPE
)) {
231 descriptors
.addElement(
232 new PropertyDescriptor(P_ID_TYPE
, P_TYPE
));
235 // Annotations, listed in custom property descriptor
236 if (id
.equals(P_ID_ANNOTATIONS
)) {
237 descriptors
.addElement(
238 new AnnotationsPropertyDescriptor(P_ID_ANNOTATIONS
, P_ANNOTATIONS
, name
) {
239 protected void saveAnnotations(Set set
) {
240 setPropertyValue(P_ID_ANNOTATIONS
, set
);
246 // Nomenclatural status
247 if (id
.equals(P_ID_NOMSTATUS
)) {
248 if (nomStatusTypes
== null) {
249 populateNomStatusTypes();
251 descriptors
.addElement(
252 new ComboBoxPropertyDescriptor(P_ID_NOMSTATUS
, P_NOMSTATUS
, P_NOMSTATUS_MENU
));
256 if (id
.equals(P_ID_UUID
)) {
257 descriptors
.addElement(
258 new PropertyDescriptor(P_ID_UUID
, P_UUID
));
262 if (id
.equals(P_ID_MARKERS
)) {
263 descriptors
.addElement(
264 new PropertyDescriptor(P_ID_MARKERS
, P_MARKERS
));
267 // Taxon bases referring to this name
268 if (id
.equals(P_ID_NUM_OF_BASES
)) {
269 descriptors
.addElement(
270 new PropertyDescriptor(P_ID_NUM_OF_BASES
, P_NUM_OF_BASES
));
273 // Object created when
274 if (id
.equals(P_ID_CREATED
)) {
275 descriptors
.addElement(
276 new PropertyDescriptor(P_ID_CREATED
, P_CREATED
));
280 if (id
.equals(P_ID_CREATEDBY
)) {
281 descriptors
.addElement(
282 new PropertyDescriptor(P_ID_CREATEDBY
, P_CREATEDBY
));
285 // Nomenclatural code used by parser
286 if (id
.equals(P_ID_NOMENCLATURAL_CODE
)) {
287 descriptors
.addElement(
288 new PropertyDescriptor(P_ID_NOMENCLATURAL_CODE
, P_NOMENCLATURAL_CODE
));
291 // Nomenclatural reference
292 if (id
.equals(P_ID_NOMENCLATURAL_REF
)) {
293 descriptors
.addElement(
294 new PropertyDescriptor(P_ID_NOMENCLATURAL_REF
,P_NOMENCLATURAL_REF
));
298 if (id
.equals(P_ID_NOMENCLATURAL_MICROREF
)) {
299 descriptors
.addElement(
300 new TextPropertyDescriptor(P_ID_NOMENCLATURAL_MICROREF
,P_NOMENCLATURAL_MICROREF
));
305 * Constructor for top level property fields. All fields that are not subfields
306 * should be listed here.
309 public NonViralNamePropertySource(NonViralName
<?
> name
) {
310 this(name
, null, TOP_LEVEL_PROPERTIES
);
313 public NonViralNamePropertySource(NonViralName
<?
> name
,
314 String parentid
, String
[] keys
) {
316 this.parentid
= parentid
;
317 for (String key
: keys
) {
322 public Object
getEditableValue() {
326 public IPropertyDescriptor
[] getPropertyDescriptors() {
327 return (IPropertyDescriptor
[]) descriptors
.toArray(
328 new IPropertyDescriptor
[descriptors
.size()]);
331 public Object
getPropertyValue(Object id
) {
333 // Parsed: reports whether parsing was successful
334 if (id
.equals(P_ID_PARSED
)) {
335 return name
.getHasProblem() == true ?
"problem" : "parsed" ;
339 if (id
.equals(P_ID_RANK
)) {
340 if (this.name
.getRank() == null) {
343 Rank rank
= this.name
.getRank();
344 for (int i
= 0; i
< ranks
.length
; i
++) {
345 if (ranks
[i
] == null) continue;
346 if (rank
.getUuid().equals(ranks
[i
].getUuid()))
353 if (id
.equals(P_ID_TITLECACHE
)) {
355 // If the name has not been parsed, only show the title cache
356 if (name
.getRank() == null) {
357 return CdmUtils
.Nz(name
.getTitleCache());
360 // Create property source for submenu
361 ScientificNamePropertySource nameFieldsPropertySource
= new ScientificNamePropertySource(name
);
363 // Add listener to notify name of all changes to nom. reference
364 nameFieldsPropertySource
.addPropertyChangeListener(new PropertyChangeListener() {
365 public void propertyChange(PropertyChangeEvent evt
) {
366 // if (evt.getNewValue() instanceof INomenclaturalReference) {
367 // name.setNomenclaturalReference((INomenclaturalReference) evt.getNewValue());
371 return nameFieldsPropertySource
;
376 if (id
.equals(P_ID_HOMOTYPICALGROUP
)) {
377 return CdmUtils
.Nz(name
.getHomotypicalGroup().getUuid().toString());
380 // Annotations, listed in custom property descriptor
381 // if (id.equals(P_ID_ANNOTATIONS)) {
382 // return new AnnotationPropertySource(name.getAnnotations());
385 // Nomenclatural status
386 if (id
.equals(P_ID_NOMSTATUS
)) {
387 // return new NomStatusPropertySource(name.getStatus());
388 // if (this.name.getRank() == null) return 0;
389 Set
<NomenclaturalStatus
> nomStatusSet
= this.name
.getStatus();
391 if (nomStatusSet
== null || nomStatusSet
.size() == 0) {
394 // TODO for now, only showing first nom status - change!
395 NomenclaturalStatus nomStatus
= (NomenclaturalStatus
) nomStatusSet
.toArray()[0];
396 for (int i
= 0; i
< nomStatusTypes
.length
; i
++) {
397 if (nomStatusTypes
[i
] == null) continue;
398 if (nomStatus
.getType().getUuid().equals(nomStatusTypes
[i
].getUuid()))
404 // Name relations, popup to edit list
405 if (id
.equals(P_ID_NAMERELATIONS
)) {
406 return new NameRelationsPropertySource(name
, name
.getNameRelations());
410 if (id
.equals(P_ID_TYPE
)) {
415 if (id
.equals(P_ID_UUID
)) {
416 return CdmUtils
.Nz(name
.getUuid().toString());
420 if (id
.equals(P_ID_MARKERS
)) {
421 return new MarkersPropertySource(name
.getMarkers());
424 // Taxon bases referring to this name
425 if (id
.equals(P_ID_NUM_OF_BASES
)) {
426 return name
.getTaxonBases().size();
430 if (id
.equals(P_ID_CREATED
)) {
431 if (name
.getCreated() == null) {
434 return formatDate(name
.getCreated().toDate());
438 // Object created when
439 if (id
.equals(P_ID_CREATEDBY
)) {
440 if (name
.getCreatedBy() == null) {
443 return CdmUtils
.Nz(((IIdentifiableEntity
) name
.getCreatedBy()).generateTitle());
447 // Nomenclatural code used by parser
448 if (id
.equals(P_ID_NOMENCLATURAL_CODE
)) {
449 // Only shown if extending classes don't handle P_ID_NOMENCLATURAL_CODE
450 return "none (nonviral name)";
453 // Nomenclatural reference
454 if (id
.equals(P_ID_NOMENCLATURAL_REF
)) {
456 ReferenceBase
<?
> nomRef
= (ReferenceBase
<?
>) name
.getNomenclaturalReference();
458 // Create nom. reference as necessary
459 if (nomRef
== null) {
460 nomRef
= Generic
.NewInstance();
463 // Create property source for submenu
464 ReferencePropertySource nomRefPropertySource
= new NomenclaturalReferencePropertySource(nomRef
);
466 // Add listener to notify name of all changes to nom. reference
467 nomRefPropertySource
.addPropertyChangeListener(new PropertyChangeListener() {
468 public void propertyChange(PropertyChangeEvent evt
) {
469 if (evt
.getNewValue() instanceof INomenclaturalReference
) {
470 name
.setNomenclaturalReference((ReferenceBase
<?
>) evt
.getNewValue());
474 return nomRefPropertySource
;
479 if (id
.equals(P_ID_NOMENCLATURAL_MICROREF
)) {
480 return CdmUtils
.Nz(name
.getNomenclaturalMicroReference());
486 private Object
formatDate(Date date
) {
487 return String
.format("%1$tm-%1$td-%1$tY %1$tH:%1$tM:%1$tS", date
);
490 public boolean isPropertySet(Object id
) {
494 public void resetPropertyValue(Object id
) {}
497 * Any editable fields are set in the object here.
499 * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
501 public void setPropertyValue(Object id
, Object value
) {
503 // Since this is only called when the property value changes,
504 // it is a reliable place to fire the name's property change
506 // name.firePropertyChange(Resources.PROPERTY_SHEET_CHANGE, null, null);
509 if (id
.equals(P_ID_RANK
)) {
510 int index
= ((Integer
) value
).intValue();
511 name
.setRank(ranks
[index
]);
514 // Nomenclatural status
515 if (id
.equals(P_ID_NOMSTATUS
)) {
516 NomenclaturalStatus nomStatus
;
517 int index
= ((Integer
) value
).intValue();
518 Set
<NomenclaturalStatus
> nomStatusSet
= name
.getStatus();
520 if (nomStatusSet
.size() > 0) {
521 nomStatus
= (NomenclaturalStatus
) nomStatusSet
.toArray()[0];
524 nomStatusSet
.remove(nomStatus
);
526 nomStatus
.setType(nomStatusTypes
[index
]);
530 nomStatus
= NomenclaturalStatus
.NewInstance(nomStatusTypes
[index
]);
531 name
.addStatus(nomStatus
);
536 if (id
.equals(P_ID_MARKERS
)) {
540 // Nomenclatural reference
541 if (id
.equals(P_ID_NOMENCLATURAL_REF
)) {
542 if (value
instanceof INomenclaturalReference
) {
543 name
.setNomenclaturalReference((ReferenceBase
<?
>) value
);
548 if (id
.equals(P_ID_NOMENCLATURAL_MICROREF
)) {
549 name
.setNomenclaturalMicroReference((String
) value
);
552 // If there is no rank, generated caches will be blank, wiping out the freetext area
553 if (name
.getRank() != null) {
555 // Reset both caches to reflect property sheet changes
556 if (!name
.isProtectedTitleCache()) {
557 name
.setTitleCache(name
.generateTitle(), false);
560 if (!name
.isProtectedFullTitleCache()) {
561 name
.setFullTitleCache(name
.generateFullTitle(), false);
565 // name.firePropertyChange(ITaxEditorConstants.REFRESH_NAMEVIEWER, null, null);
570 * Any node with children must override {@link java.lang.Object#toString()}
571 * to display its name correctly
573 * @see java.lang.Object#toString()
575 public String
toString() {
576 if (parentid
== null || parentid
.equals("")) {
579 if (parentid
.equals(P_ID_TITLECACHE
)) {
580 return name
.getTitleCache();
582 if (parentid
.equals(P_ID_NOMENCLATURAL_REF
)) {
583 INomenclaturalReference nomenclaturalReference
= (INomenclaturalReference
) name
.getNomenclaturalReference();
584 if (nomenclaturalReference
== null) {
587 String microReference
= name
.getNomenclaturalMicroReference();
588 return CdmUtils
.Nz(nomenclaturalReference
.getNomenclaturalCitation(microReference
));
590 return super.toString();
593 public void addPropertyChangeListener(
594 PropertyChangeListener listener
) {
595 this.propertyChangeSupport
.addPropertyChangeListener(listener
);