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
.IIdentifiableEntity
;
30 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
31 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
32 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
33 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
34 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
35 import eu
.etaxonomy
.cdm
.model
.reference
.Generic
;
36 import eu
.etaxonomy
.cdm
.model
.reference
.INomenclaturalReference
;
37 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
38 import eu
.etaxonomy
.taxeditor
.propertysheet
.AnnotationsPropertyDescriptor
;
39 import eu
.etaxonomy
.taxeditor
.propertysheet
.MarkersPropertySource
;
40 import eu
.etaxonomy
.taxeditor
.propertysheet
.reference
.NomenclaturalReferencePropertySource
;
41 import eu
.etaxonomy
.taxeditor
.propertysheet
.reference
.ReferencePropertySource
;
42 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
43 import eu
.etaxonomy
.taxeditor
.store
.preference
.PreferencesUtil
;
50 public class NonViralNamePropertySource
implements IPropertySource
{
51 private static final Logger logger
= Logger
52 .getLogger(NonViralNamePropertySource
.class);
54 // The name whose properties are being displayed
57 // If this is a property with a parent, the parent's property ID
58 private String parentid
= "";
60 PropertyChangeSupport propertyChangeSupport
;
62 // Property unique keys
63 public static final String P_ID_PARSED
= "parsed";
64 public static final String P_ID_RANK
= "rank";
65 public static final String P_ID_TITLECACHE
= "titlecache";
66 public static final String P_ID_HOMOTYPICALGROUP
= "homogroup";
67 public static final String P_ID_NAMERELATIONS
= "namerelations";
68 public static final String P_ID_TYPE
= "type";
69 public static final String P_ID_ANNOTATIONS
= "annotations";
70 public static final String P_ID_NOMSTATUS
= "nomstatus";
71 public static final String P_ID_UUID
= "uuid";
72 public static final String P_ID_NUM_OF_BASES
= "numberofbases";
73 public static final String P_ID_MARKERS
= "markers";
74 public static final String P_ID_CREATED
= "created";
75 public static final String P_ID_CREATEDBY
= "createdby";
76 public static final String P_ID_NOMENCLATURAL_CODE
= "nomenclaturalcode";
77 public static final String P_ID_NOMENCLATURAL_REF
= "nomenclaturalref";
78 public static final String P_ID_NOMENCLATURAL_MICROREF
= "nomenclaturalmicroref";
80 // Property display keys
81 public static final String P_PARSED
= "Parsing Status";
82 public static final String P_RANK
= "Rank";
83 public static final String P_TITLECACHE
= "Name Cache";
84 public static final String P_HOMOTYPICALGROUP
= "Homotypical Group";
85 public static final String P_NAMERELATIONS
= "Name Relations";
86 public static final String P_TYPE
= "Type";
87 public static final String P_ANNOTATIONS
= "Annotations";
88 public static final String P_NOMSTATUS
= "Nomenclatural Status";
89 public static final String P_UUID
= "UUID";
90 public static final String P_NUM_OF_BASES
= "Number of Bases";
91 public static final String P_MARKERS
= "Markers";
92 public static final String P_CREATED
= "Created";
93 public static final String P_CREATEDBY
= "Created By";
94 public static final String P_NOMENCLATURAL_CODE
= "Nomenclatural Code";
95 public static final String P_NOMENCLATURAL_REF
= "Nomenclatural Reference";
96 public static final String P_NOMENCLATURAL_MICROREF
= "Reference Detail";
98 protected static final String
[] TOP_LEVEL_PROPERTIES
= new String
[] {
101 P_ID_NOMENCLATURAL_CODE
,
104 P_ID_NOMENCLATURAL_REF
,
105 P_ID_NOMENCLATURAL_MICROREF
,
112 // ***********************************************************
114 // ***********************************************************
116 String
[] P_RANK_MENU
= null;
117 private void populateRanks() {
119 // Get terms from rank vocabulary
120 List
<Rank
> ranksList
= new ArrayList
<Rank
>();
121 ranksList
.addAll(PreferencesUtil
.getPreferredRanks());
123 // Populate ranks menu labels
124 List
<String
> ranksMenuList
= new ArrayList
<String
>();
125 for (Rank rank
: ranksList
) {
126 ranksMenuList
.add(rank
.getLabel());
129 // Add an empty element for "nothing selected" in the rank drop-down
130 ranksList
.add(0, null);
131 ranksMenuList
.add(0, "");
133 // Convert rank lists to array
134 ranks
= ranksList
.toArray(new Rank
[ranksList
.size()]);
135 P_RANK_MENU
= ranksMenuList
.toArray(new String
[ranksMenuList
.size()]);
138 // ***********************************************************
139 // NOMENCLATURAL STATUS
140 // ***********************************************************
141 // static TermVocabulary<NomenclaturalStatusType> nomStatusVocabulary =
142 // TaxEditorPlugin.getDefault().getNomStatusVocabulary();
143 NomenclaturalStatusType
[] nomStatusTypes
= null;
144 String
[] P_NOMSTATUS_MENU
= null;
145 private void populateNomStatusTypes() {
147 // Get terms from nom status vocabulary
148 List
<NomenclaturalStatusType
> nomStatusTypesList
= new ArrayList
<NomenclaturalStatusType
>();
149 TermVocabulary
<NomenclaturalStatusType
> statusVocab
=
150 CdmStore
.getDefault().getNomStatus();
152 // If there is no status vocabulary, init type and status w empty arrays and return
153 if (statusVocab
== null) {
154 nomStatusTypes
= new NomenclaturalStatusType
[]{};
155 P_NOMSTATUS_MENU
= new String
[]{};
159 nomStatusTypesList
.addAll(statusVocab
.getTerms());
161 // Populate nom status type menu labels
162 List
<String
> nomStatusTypesMenuList
= new ArrayList
<String
>();
163 for (NomenclaturalStatusType nomStatusType
: nomStatusTypesList
) {
164 nomStatusTypesMenuList
.add(nomStatusType
.getLabel());
167 // Add an empty element for "nothing selected" in the rank drop-down
168 nomStatusTypesList
.add(0, null);
169 nomStatusTypesMenuList
.add(0, "");
171 // Convert rank lists to array
172 nomStatusTypes
= nomStatusTypesList
.toArray(new NomenclaturalStatusType
[nomStatusTypesList
.size()]);
173 P_NOMSTATUS_MENU
= nomStatusTypesMenuList
.toArray(new String
[nomStatusTypesMenuList
.size()]);
176 protected Vector
<PropertyDescriptor
> descriptors
= new Vector
<PropertyDescriptor
>();
178 * Add descriptor for a given property.
180 * Notes on Descriptor:
183 * <li>PropertyDescriptor - uneditable cell value</li>
184 * <li>ComboBoxPropertyDescriptor - dropdown list, property supplied must be integer-based</li>
185 * <li>TextPropertyDescriptor - editable cell value</li>
188 * If any descriptor calls setCategory, all descriptors w/out a category are put in
191 * <code>descriptor.setFilterFlags (new String[] { IPropertySheetEntry.FILTER_ID_EXPERT })</code> -
192 * this descriptor shown under advanced properties
196 protected void addDescriptor(String id
) {
198 // Parsed: reports whether parsing was successful
199 if (id
.equals(P_ID_PARSED
)) {
200 descriptors
.addElement(
201 new PropertyDescriptor(P_ID_PARSED
, P_PARSED
));
205 if (id
.equals(P_ID_RANK
)) {
209 descriptors
.addElement(
210 new EditorComboBoxPropertyDescriptor(P_ID_RANK
, P_RANK
, P_RANK_MENU
));
214 if (id
.equals(P_ID_TITLECACHE
)) {
215 descriptors
.addElement(
216 new PropertyDescriptor(P_ID_TITLECACHE
, P_TITLECACHE
));
220 if (id
.equals(P_ID_HOMOTYPICALGROUP
)) {
221 descriptors
.addElement(
222 new PropertyDescriptor(P_ID_HOMOTYPICALGROUP
, P_HOMOTYPICALGROUP
));
225 // Name relations, listed in custom property descriptor
226 if (id
.equals(P_ID_NAMERELATIONS
)) {
227 descriptors
.addElement(
228 new NameRelationsPropertyDescriptor(P_ID_NAMERELATIONS
, P_NAMERELATIONS
, name
)
233 if (id
.equals(P_ID_TYPE
)) {
234 descriptors
.addElement(
235 new PropertyDescriptor(P_ID_TYPE
, P_TYPE
));
238 // Annotations, listed in custom property descriptor
239 if (id
.equals(P_ID_ANNOTATIONS
)) {
240 descriptors
.addElement(
241 new AnnotationsPropertyDescriptor(P_ID_ANNOTATIONS
, P_ANNOTATIONS
, name
) {
242 protected void saveAnnotations(Set set
) {
243 setPropertyValue(P_ID_ANNOTATIONS
, set
);
249 // Nomenclatural status
250 if (id
.equals(P_ID_NOMSTATUS
)) {
251 if (nomStatusTypes
== null) {
252 populateNomStatusTypes();
254 descriptors
.addElement(
255 new ComboBoxPropertyDescriptor(P_ID_NOMSTATUS
, P_NOMSTATUS
, P_NOMSTATUS_MENU
));
259 if (id
.equals(P_ID_UUID
)) {
260 descriptors
.addElement(
261 new PropertyDescriptor(P_ID_UUID
, P_UUID
));
265 if (id
.equals(P_ID_MARKERS
)) {
266 descriptors
.addElement(
267 new PropertyDescriptor(P_ID_MARKERS
, P_MARKERS
));
270 // Taxon bases referring to this name
271 if (id
.equals(P_ID_NUM_OF_BASES
)) {
272 descriptors
.addElement(
273 new PropertyDescriptor(P_ID_NUM_OF_BASES
, P_NUM_OF_BASES
));
276 // Object created when
277 if (id
.equals(P_ID_CREATED
)) {
278 descriptors
.addElement(
279 new PropertyDescriptor(P_ID_CREATED
, P_CREATED
));
283 if (id
.equals(P_ID_CREATEDBY
)) {
284 descriptors
.addElement(
285 new PropertyDescriptor(P_ID_CREATEDBY
, P_CREATEDBY
));
288 // Nomenclatural code used by parser
289 if (id
.equals(P_ID_NOMENCLATURAL_CODE
)) {
290 descriptors
.addElement(
291 new PropertyDescriptor(P_ID_NOMENCLATURAL_CODE
, P_NOMENCLATURAL_CODE
));
294 // Nomenclatural reference
295 if (id
.equals(P_ID_NOMENCLATURAL_REF
)) {
296 descriptors
.addElement(
297 new PropertyDescriptor(P_ID_NOMENCLATURAL_REF
,P_NOMENCLATURAL_REF
));
301 if (id
.equals(P_ID_NOMENCLATURAL_MICROREF
)) {
302 descriptors
.addElement(
303 new TextPropertyDescriptor(P_ID_NOMENCLATURAL_MICROREF
,P_NOMENCLATURAL_MICROREF
));
308 * Constructor for top level property fields. All fields that are not subfields
309 * should be listed here.
312 public NonViralNamePropertySource(NonViralName name
) {
313 this(name
, null, TOP_LEVEL_PROPERTIES
);
316 public NonViralNamePropertySource(NonViralName name
,
317 String parentid
, String
[] keys
) {
319 this.parentid
= parentid
;
320 for (String key
: keys
) {
325 public Object
getEditableValue() {
329 public IPropertyDescriptor
[] getPropertyDescriptors() {
330 return (IPropertyDescriptor
[]) descriptors
.toArray(
331 new IPropertyDescriptor
[descriptors
.size()]);
334 public Object
getPropertyValue(Object id
) {
336 // Parsed: reports whether parsing was successful
337 if (id
.equals(P_ID_PARSED
)) {
338 return name
.getHasProblem() == true ?
"problem" : "parsed" ;
342 if (id
.equals(P_ID_RANK
)) {
343 if (this.name
.getRank() == null) {
346 Rank rank
= this.name
.getRank();
347 for (int i
= 0; i
< ranks
.length
; i
++) {
348 if (ranks
[i
] == null) continue;
349 if (rank
.getUuid().equals(ranks
[i
].getUuid()))
356 if (id
.equals(P_ID_TITLECACHE
)) {
358 // If the name has not been parsed, only show the title cache
359 if (name
.getRank() == null) {
360 return CdmUtils
.Nz(name
.getTitleCache());
363 // Create property source for submenu
364 ScientificNamePropertySource nameFieldsPropertySource
= new ScientificNamePropertySource(name
);
366 // Add listener to notify name of all changes to nom. reference
367 nameFieldsPropertySource
.addPropertyChangeListener(new PropertyChangeListener() {
368 public void propertyChange(PropertyChangeEvent evt
) {
369 // if (evt.getNewValue() instanceof INomenclaturalReference) {
370 // name.setNomenclaturalReference((INomenclaturalReference) evt.getNewValue());
374 return nameFieldsPropertySource
;
379 if (id
.equals(P_ID_HOMOTYPICALGROUP
)) {
380 return CdmUtils
.Nz(name
.getHomotypicalGroup().getUuid().toString());
383 // Annotations, listed in custom property descriptor
384 // if (id.equals(P_ID_ANNOTATIONS)) {
385 // return new AnnotationPropertySource(name.getAnnotations());
388 // Nomenclatural status
389 if (id
.equals(P_ID_NOMSTATUS
)) {
390 // return new NomStatusPropertySource(name.getStatus());
391 // if (this.name.getRank() == null) return 0;
392 Set
<NomenclaturalStatus
> nomStatusSet
= this.name
.getStatus();
394 if (nomStatusSet
== null || nomStatusSet
.size() == 0) {
397 // TODO for now, only showing first nom status - change!
398 NomenclaturalStatus nomStatus
= (NomenclaturalStatus
) nomStatusSet
.toArray()[0];
399 for (int i
= 0; i
< nomStatusTypes
.length
; i
++) {
400 if (nomStatusTypes
[i
] == null) continue;
401 if (nomStatus
.getType().getUuid().equals(nomStatusTypes
[i
].getUuid()))
407 // Name relations, popup to edit list
408 if (id
.equals(P_ID_NAMERELATIONS
)) {
409 return new NameRelationsPropertySource(name
, name
.getNameRelations());
413 if (id
.equals(P_ID_TYPE
)) {
418 if (id
.equals(P_ID_UUID
)) {
419 return CdmUtils
.Nz(name
.getUuid().toString());
423 if (id
.equals(P_ID_MARKERS
)) {
424 return new MarkersPropertySource(name
.getMarkers());
427 // Taxon bases referring to this name
428 if (id
.equals(P_ID_NUM_OF_BASES
)) {
429 return name
.getTaxonBases().size();
433 if (id
.equals(P_ID_CREATED
)) {
434 if (name
.getCreated() == null) {
437 return formatDate(name
.getCreated().toDate());
441 // Object created when
442 if (id
.equals(P_ID_CREATEDBY
)) {
443 if (name
.getCreatedBy() == null) {
446 return CdmUtils
.Nz(((IIdentifiableEntity
) name
.getCreatedBy()).generateTitle());
450 // Nomenclatural code used by parser
451 if (id
.equals(P_ID_NOMENCLATURAL_CODE
)) {
452 // Only shown if extending classes don't handle P_ID_NOMENCLATURAL_CODE
453 return "none (nonviral name)";
456 // Nomenclatural reference
457 if (id
.equals(P_ID_NOMENCLATURAL_REF
)) {
459 ReferenceBase nomRef
= (ReferenceBase
) name
.getNomenclaturalReference();
461 // Create nom. reference as necessary
462 if (nomRef
== null) {
463 nomRef
= Generic
.NewInstance();
466 // Create property source for submenu
467 ReferencePropertySource nomRefPropertySource
= new NomenclaturalReferencePropertySource(nomRef
);
469 // Add listener to notify name of all changes to nom. reference
470 nomRefPropertySource
.addPropertyChangeListener(new PropertyChangeListener() {
471 public void propertyChange(PropertyChangeEvent evt
) {
472 if (evt
.getNewValue() instanceof INomenclaturalReference
) {
473 name
.setNomenclaturalReference((ReferenceBase
) evt
.getNewValue());
477 return nomRefPropertySource
;
482 if (id
.equals(P_ID_NOMENCLATURAL_MICROREF
)) {
483 return CdmUtils
.Nz(name
.getNomenclaturalMicroReference());
489 private Object
formatDate(Date date
) {
490 return String
.format("%1$tm-%1$td-%1$tY %1$tH:%1$tM:%1$tS", date
);
493 public boolean isPropertySet(Object id
) {
497 public void resetPropertyValue(Object id
) {}
500 * Any editable fields are set in the object here.
502 * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
504 public void setPropertyValue(Object id
, Object value
) {
506 // Since this is only called when the property value changes,
507 // it is a reliable place to fire the name's property change
509 // name.firePropertyChange(Resources.PROPERTY_SHEET_CHANGE, null, null);
512 if (id
.equals(P_ID_RANK
)) {
513 int index
= ((Integer
) value
).intValue();
514 name
.setRank(ranks
[index
]);
517 // Nomenclatural status
518 if (id
.equals(P_ID_NOMSTATUS
)) {
519 NomenclaturalStatus nomStatus
;
520 int index
= ((Integer
) value
).intValue();
521 Set
<NomenclaturalStatus
> nomStatusSet
= name
.getStatus();
523 if (nomStatusSet
.size() > 0) {
524 nomStatus
= (NomenclaturalStatus
) nomStatusSet
.toArray()[0];
527 nomStatusSet
.remove(nomStatus
);
529 nomStatus
.setType(nomStatusTypes
[index
]);
533 nomStatus
= NomenclaturalStatus
.NewInstance(nomStatusTypes
[index
]);
534 name
.addStatus(nomStatus
);
539 if (id
.equals(P_ID_MARKERS
)) {
543 // Nomenclatural reference
544 if (id
.equals(P_ID_NOMENCLATURAL_REF
)) {
545 if (value
instanceof INomenclaturalReference
) {
546 name
.setNomenclaturalReference((ReferenceBase
) value
);
551 if (id
.equals(P_ID_NOMENCLATURAL_MICROREF
)) {
552 name
.setNomenclaturalMicroReference((String
) value
);
555 // If there is no rank, generated caches will be blank, wiping out the freetext area
556 if (name
.getRank() != null) {
558 // Reset both caches to reflect property sheet changes
559 if (!name
.isProtectedTitleCache()) {
560 name
.setTitleCache(name
.generateTitle(), false);
563 if (!name
.isProtectedFullTitleCache()) {
564 name
.setFullTitleCache(name
.generateFullTitle(), false);
568 // name.firePropertyChange(ITaxEditorConstants.REFRESH_NAMEVIEWER, null, null);
573 * Any node with children must override {@link java.lang.Object#toString()}
574 * to display its name correctly
576 * @see java.lang.Object#toString()
578 public String
toString() {
579 if (parentid
== null || parentid
.equals("")) {
582 if (parentid
.equals(P_ID_TITLECACHE
)) {
583 return name
.getTitleCache();
585 if (parentid
.equals(P_ID_NOMENCLATURAL_REF
)) {
586 INomenclaturalReference nomenclaturalReference
= (INomenclaturalReference
) name
.getNomenclaturalReference();
587 if (nomenclaturalReference
== null) {
590 String microReference
= name
.getNomenclaturalMicroReference();
591 return CdmUtils
.Nz(nomenclaturalReference
.getNomenclaturalCitation(microReference
));
593 return super.toString();
596 public void addPropertyChangeListener(
597 PropertyChangeListener listener
) {
598 this.propertyChangeSupport
.addPropertyChangeListener(listener
);