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
.ITaxEditorConstants
;
39 import eu
.etaxonomy
.taxeditor
.controller
.PreferencesController
;
40 import eu
.etaxonomy
.taxeditor
.model
.CdmSessionDataRepository
;
41 import eu
.etaxonomy
.taxeditor
.propertysheet
.AnnotationPropertySource
;
42 import eu
.etaxonomy
.taxeditor
.propertysheet
.AnnotationsPropertyDescriptor
;
43 import eu
.etaxonomy
.taxeditor
.propertysheet
.MarkersPropertySource
;
44 import eu
.etaxonomy
.taxeditor
.propertysheet
.reference
.NomenclaturalReferencePropertySource
;
45 import eu
.etaxonomy
.taxeditor
.propertysheet
.reference
.ReferencePropertySource
;
52 public class NonViralNamePropertySource
implements IPropertySource
{
53 private static final Logger logger
= Logger
54 .getLogger(NonViralNamePropertySource
.class);
56 // The name whose properties are being displayed
59 // If this is a property with a parent, the parent's property ID
60 private String parentid
= "";
62 PropertyChangeSupport propertyChangeSupport
;
64 // Property unique keys
65 public static final String P_ID_PARSED
= "parsed";
66 public static final String P_ID_RANK
= "rank";
67 public static final String P_ID_TITLECACHE
= "titlecache";
68 public static final String P_ID_HOMOTYPICALGROUP
= "homogroup";
69 public static final String P_ID_NAMERELATIONS
= "namerelations";
70 public static final String P_ID_TYPE
= "type";
71 public static final String P_ID_ANNOTATIONS
= "annotations";
72 public static final String P_ID_NOMSTATUS
= "nomstatus";
73 public static final String P_ID_UUID
= "uuid";
74 public static final String P_ID_NUM_OF_BASES
= "numberofbases";
75 public static final String P_ID_MARKERS
= "markers";
76 public static final String P_ID_CREATED
= "created";
77 public static final String P_ID_CREATEDBY
= "createdby";
78 public static final String P_ID_NOMENCLATURAL_CODE
= "nomenclaturalcode";
79 public static final String P_ID_NOMENCLATURAL_REF
= "nomenclaturalref";
80 public static final String P_ID_NOMENCLATURAL_MICROREF
= "nomenclaturalmicroref";
82 // Property display keys
83 // Note: for an explanation of the sorting prefixes ("04:"),
84 // @see eu.etaxonomy.taxeditor.propertysheet.CustomSortPropertySheetEntry
85 public static final String P_PARSED
= "00:Parsing Status";
86 public static final String P_RANK
= "02:Rank";
87 public static final String P_TITLECACHE
= "03:Name Cache";
88 public static final String P_HOMOTYPICALGROUP
= "09:Homotypical Group";
89 public static final String P_NAMERELATIONS
= "11:Name Relations";
90 public static final String P_TYPE
= "12:Type";
91 public static final String P_ANNOTATIONS
= "14:Annotations";
92 public static final String P_NOMSTATUS
= "100:Nomenclatural Status";
93 public static final String P_UUID
= "01:UUID";
94 public static final String P_NUM_OF_BASES
= "12:Number of Bases";
95 public static final String P_MARKERS
= "13:Markers";
96 public static final String P_CREATED
= "15:Created";
97 public static final String P_CREATEDBY
= "16:Created By";
98 public static final String P_NOMENCLATURAL_CODE
= "02:Nomenclatural Code";
99 public static final String P_NOMENCLATURAL_REF
= "09:Nomenclatural Reference";
100 public static final String P_NOMENCLATURAL_MICROREF
= "10:Reference Detail";
102 protected static final String
[] TOP_LEVEL_PROPERTIES
= new String
[] {
103 P_ID_PARSED
, P_ID_RANK
, P_ID_TITLECACHE
, P_ID_ANNOTATIONS
, P_ID_NOMSTATUS
,
104 P_ID_NAMERELATIONS
, P_ID_UUID
, P_ID_NOMENCLATURAL_REF
, P_ID_NOMENCLATURAL_MICROREF
,
105 P_ID_CREATED
, P_ID_CREATEDBY
, P_ID_NOMENCLATURAL_CODE
};
107 // ***********************************************************
109 // ***********************************************************
111 String
[] P_RANK_MENU
= null;
112 private void populateRanks() {
114 // Get terms from rank vocabulary
115 List
<Rank
> ranksList
= new ArrayList
<Rank
>();
116 ranksList
.addAll(PreferencesController
.getPreferredRanks());
118 // Populate ranks menu labels
119 List
<String
> ranksMenuList
= new ArrayList
<String
>();
120 for (Rank rank
: ranksList
) {
121 ranksMenuList
.add(rank
.getLabel());
124 // Add an empty element for "nothing selected" in the rank drop-down
125 ranksList
.add(0, null);
126 ranksMenuList
.add(0, "");
128 // Convert rank lists to array
129 ranks
= ranksList
.toArray(new Rank
[ranksList
.size()]);
130 P_RANK_MENU
= ranksMenuList
.toArray(new String
[ranksMenuList
.size()]);
133 // ***********************************************************
134 // NOMENCLATURAL STATUS
135 // ***********************************************************
136 // static TermVocabulary<NomenclaturalStatusType> nomStatusVocabulary =
137 // TaxEditorPlugin.getDefault().getNomStatusVocabulary();
138 NomenclaturalStatusType
[] nomStatusTypes
= null;
139 String
[] P_NOMSTATUS_MENU
= null;
140 private void populateNomStatusTypes() {
142 // Get terms from nom status vocabulary
143 List
<NomenclaturalStatusType
> nomStatusTypesList
= new ArrayList
<NomenclaturalStatusType
>();
144 TermVocabulary
<NomenclaturalStatusType
> statusVocab
=
145 CdmSessionDataRepository
.getDefault().getNomStatus();
147 // If there is no status vocabulary, init type and status w empty arrays and return
148 if (statusVocab
== null) {
149 nomStatusTypes
= new NomenclaturalStatusType
[]{};
150 P_NOMSTATUS_MENU
= new String
[]{};
154 nomStatusTypesList
.addAll(statusVocab
.getTerms());
156 // Populate nom status type menu labels
157 List
<String
> nomStatusTypesMenuList
= new ArrayList
<String
>();
158 for (NomenclaturalStatusType nomStatusType
: nomStatusTypesList
) {
159 nomStatusTypesMenuList
.add(nomStatusType
.getLabel());
162 // Add an empty element for "nothing selected" in the rank drop-down
163 nomStatusTypesList
.add(0, null);
164 nomStatusTypesMenuList
.add(0, "");
166 // Convert rank lists to array
167 nomStatusTypes
= nomStatusTypesList
.toArray(new NomenclaturalStatusType
[nomStatusTypesList
.size()]);
168 P_NOMSTATUS_MENU
= nomStatusTypesMenuList
.toArray(new String
[nomStatusTypesMenuList
.size()]);
171 protected Vector
<PropertyDescriptor
> descriptors
= new Vector
<PropertyDescriptor
>();
173 * Add descriptor for a given property.
175 * Notes on Descriptor:
178 * <li>PropertyDescriptor - uneditable cell value</li>
179 * <li>ComboBoxPropertyDescriptor - dropdown list, property supplied must be integer-based</li>
180 * <li>TextPropertyDescriptor - editable cell value</li>
183 * If any descriptor calls setCategory, all descriptors w/out a category are put in
186 * <code>descriptor.setFilterFlags (new String[] { IPropertySheetEntry.FILTER_ID_EXPERT })</code> -
187 * this descriptor shown under advanced properties
191 protected void addDescriptor(String id
) {
193 // Parsed: reports whether parsing was successful
194 if (id
.equals(P_ID_PARSED
)) {
195 descriptors
.addElement(
196 new PropertyDescriptor(P_ID_PARSED
, P_PARSED
));
200 if (id
.equals(P_ID_RANK
)) {
204 descriptors
.addElement(
205 new ComboBoxPropertyDescriptor(P_ID_RANK
, P_RANK
, P_RANK_MENU
));
209 if (id
.equals(P_ID_TITLECACHE
)) {
210 descriptors
.addElement(
211 new PropertyDescriptor(P_ID_TITLECACHE
, P_TITLECACHE
));
215 if (id
.equals(P_ID_HOMOTYPICALGROUP
)) {
216 descriptors
.addElement(
217 new PropertyDescriptor(P_ID_HOMOTYPICALGROUP
, P_HOMOTYPICALGROUP
));
220 // Name relations, listed in custom property descriptor
221 if (id
.equals(P_ID_NAMERELATIONS
)) {
222 descriptors
.addElement(
223 new NameRelationsPropertyDescriptor(P_ID_NAMERELATIONS
, P_NAMERELATIONS
, name
) {
224 protected void saveNameRelations(Set set
) {
225 setPropertyValue(P_ID_NAMERELATIONS
, set
);
232 if (id
.equals(P_ID_TYPE
)) {
233 descriptors
.addElement(
234 new PropertyDescriptor(P_ID_TYPE
, P_TYPE
));
237 // Annotations, listed in custom property descriptor
238 if (id
.equals(P_ID_ANNOTATIONS
)) {
239 descriptors
.addElement(
240 new AnnotationsPropertyDescriptor(P_ID_ANNOTATIONS
, P_ANNOTATIONS
, name
) {
241 protected void saveAnnotations(Set set
) {
242 setPropertyValue(P_ID_ANNOTATIONS
, set
);
248 // Nomenclatural status
249 if (id
.equals(P_ID_NOMSTATUS
)) {
250 if (nomStatusTypes
== null) {
251 populateNomStatusTypes();
253 descriptors
.addElement(
254 new ComboBoxPropertyDescriptor(P_ID_NOMSTATUS
, P_NOMSTATUS
, P_NOMSTATUS_MENU
));
258 if (id
.equals(P_ID_UUID
)) {
259 descriptors
.addElement(
260 new PropertyDescriptor(P_ID_UUID
, P_UUID
));
264 if (id
.equals(P_ID_MARKERS
)) {
265 descriptors
.addElement(
266 new PropertyDescriptor(P_ID_MARKERS
, P_MARKERS
));
269 // Taxon bases referring to this name
270 if (id
.equals(P_ID_NUM_OF_BASES
)) {
271 descriptors
.addElement(
272 new PropertyDescriptor(P_ID_NUM_OF_BASES
, P_NUM_OF_BASES
));
275 // Object created when
276 if (id
.equals(P_ID_CREATED
)) {
277 descriptors
.addElement(
278 new PropertyDescriptor(P_ID_CREATED
, P_CREATED
));
282 if (id
.equals(P_ID_CREATEDBY
)) {
283 descriptors
.addElement(
284 new PropertyDescriptor(P_ID_CREATEDBY
, P_CREATEDBY
));
287 // Nomenclatural code used by parser
288 if (id
.equals(P_ID_NOMENCLATURAL_CODE
)) {
289 descriptors
.addElement(
290 new PropertyDescriptor(P_ID_NOMENCLATURAL_CODE
, P_NOMENCLATURAL_CODE
));
293 // Nomenclatural reference
294 if (id
.equals(P_ID_NOMENCLATURAL_REF
)) {
295 descriptors
.addElement(
296 new PropertyDescriptor(P_ID_NOMENCLATURAL_REF
,P_NOMENCLATURAL_REF
));
300 if (id
.equals(P_ID_NOMENCLATURAL_MICROREF
)) {
301 descriptors
.addElement(
302 new TextPropertyDescriptor(P_ID_NOMENCLATURAL_MICROREF
,P_NOMENCLATURAL_MICROREF
));
307 * Constructor for top level property fields. All fields that are not subfields
308 * should be listed here.
311 public NonViralNamePropertySource(NonViralName name
) {
312 this(name
, null, TOP_LEVEL_PROPERTIES
);
315 public NonViralNamePropertySource(NonViralName name
,
316 String parentid
, String
[] keys
) {
318 this.parentid
= parentid
;
319 for (String key
: keys
) {
324 public Object
getEditableValue() {
325 return CdmUtils
.Nz(name
.getTitleCache());
328 public IPropertyDescriptor
[] getPropertyDescriptors() {
329 return (IPropertyDescriptor
[]) descriptors
.toArray(
330 new IPropertyDescriptor
[descriptors
.size()]);
333 public Object
getPropertyValue(Object id
) {
335 // Parsed: reports whether parsing was successful
336 if (id
.equals(P_ID_PARSED
)) {
337 return name
.getHasProblem() == true ?
"problem" : "parsed" ;
341 if (id
.equals(P_ID_RANK
)) {
342 if (this.name
.getRank() == null) {
345 Rank rank
= this.name
.getRank();
346 for (int i
= 0; i
< ranks
.length
; i
++) {
347 if (ranks
[i
] == null) continue;
348 if (rank
.getUuid().equals(ranks
[i
].getUuid()))
355 if (id
.equals(P_ID_TITLECACHE
)) {
357 // If the name has not been parsed, only show the title cache
358 if (name
.getRank() == null) {
359 return CdmUtils
.Nz(name
.getTitleCache());
362 // Create property source for submenu
363 ScientificNamePropertySource nameFieldsPropertySource
= new ScientificNamePropertySource(name
);
365 // Add listener to notify name of all changes to nom. reference
366 nameFieldsPropertySource
.addPropertyChangeListener(new PropertyChangeListener() {
367 public void propertyChange(PropertyChangeEvent evt
) {
368 // if (evt.getNewValue() instanceof INomenclaturalReference) {
369 // name.setNomenclaturalReference((INomenclaturalReference) evt.getNewValue());
373 return nameFieldsPropertySource
;
378 if (id
.equals(P_ID_HOMOTYPICALGROUP
)) {
379 return CdmUtils
.Nz(name
.getHomotypicalGroup().getUuid().toString());
382 // Annotations, listed in custom property descriptor
383 // if (id.equals(P_ID_ANNOTATIONS)) {
384 // return new AnnotationPropertySource(name.getAnnotations());
387 // Nomenclatural status
388 if (id
.equals(P_ID_NOMSTATUS
)) {
389 // return new NomStatusPropertySource(name.getStatus());
390 // if (this.name.getRank() == null) return 0;
391 Set
<NomenclaturalStatus
> nomStatusSet
= this.name
.getStatus();
393 if (nomStatusSet
== null || nomStatusSet
.size() == 0) {
396 // TODO for now, only showing first nom status - change!
397 NomenclaturalStatus nomStatus
= (NomenclaturalStatus
) nomStatusSet
.toArray()[0];
398 for (int i
= 0; i
< nomStatusTypes
.length
; i
++) {
399 if (nomStatusTypes
[i
] == null) continue;
400 if (nomStatus
.getType().getUuid().equals(nomStatusTypes
[i
].getUuid()))
406 // Name relations, popup to edit list
407 if (id
.equals(P_ID_NAMERELATIONS
)) {
408 return new NameRelationsPropertySource(name
, name
.getNameRelations());
412 if (id
.equals(P_ID_TYPE
)) {
417 if (id
.equals(P_ID_UUID
)) {
418 return CdmUtils
.Nz(name
.getUuid().toString());
422 if (id
.equals(P_ID_MARKERS
)) {
423 return new MarkersPropertySource(name
.getMarkers());
426 // Taxon bases referring to this name
427 if (id
.equals(P_ID_NUM_OF_BASES
)) {
428 return name
.getTaxonBases().size();
432 if (id
.equals(P_ID_CREATED
)) {
433 if (name
.getCreated() == null) {
436 return formatDate(name
.getCreated().toDate());
440 // Object created when
441 if (id
.equals(P_ID_CREATEDBY
)) {
442 if (name
.getCreatedBy() == null) {
445 return CdmUtils
.Nz(((IIdentifiableEntity
) name
.getCreatedBy()).generateTitle());
449 // Nomenclatural code used by parser
450 if (id
.equals(P_ID_NOMENCLATURAL_CODE
)) {
451 // Only shown if extending classes don't handle P_ID_NOMENCLATURAL_CODE
452 return "none (nonviral name)";
455 // Nomenclatural reference
456 if (id
.equals(P_ID_NOMENCLATURAL_REF
)) {
458 ReferenceBase nomRef
= (ReferenceBase
) name
.getNomenclaturalReference();
460 // Create nom. reference as necessary
461 if (nomRef
== null) {
462 nomRef
= Generic
.NewInstance();
465 // Create property source for submenu
466 ReferencePropertySource nomRefPropertySource
= new NomenclaturalReferencePropertySource(nomRef
);
468 // Add listener to notify name of all changes to nom. reference
469 nomRefPropertySource
.addPropertyChangeListener(new PropertyChangeListener() {
470 public void propertyChange(PropertyChangeEvent evt
) {
471 if (evt
.getNewValue() instanceof INomenclaturalReference
) {
472 name
.setNomenclaturalReference((ReferenceBase
) evt
.getNewValue());
476 return nomRefPropertySource
;
481 if (id
.equals(P_ID_NOMENCLATURAL_MICROREF
)) {
482 return CdmUtils
.Nz(name
.getNomenclaturalMicroReference());
488 private Object
formatDate(Date date
) {
489 return String
.format("%1$tm-%1$td-%1$tY %1$tH:%1$tM:%1$tS", date
);
492 public boolean isPropertySet(Object id
) {
496 public void resetPropertyValue(Object id
) {}
499 * Any editable fields are set in the object here.
501 * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
503 public void setPropertyValue(Object id
, Object value
) {
505 // Since this is only called when the property value changes,
506 // it is a reliable place to fire the name's property change
508 name
.firePropertyChange(ITaxEditorConstants
.PROPERTY_SHEET_CHANGE
, null, null);
511 if (id
.equals(P_ID_RANK
)) {
512 int index
= ((Integer
) value
).intValue();
513 name
.setRank(ranks
[index
]);
516 // Nomenclatural status
517 if (id
.equals(P_ID_NOMSTATUS
)) {
518 NomenclaturalStatus nomStatus
;
519 int index
= ((Integer
) value
).intValue();
520 Set
<NomenclaturalStatus
> nomStatusSet
= name
.getStatus();
522 if (nomStatusSet
.size() > 0) {
523 nomStatus
= (NomenclaturalStatus
) nomStatusSet
.toArray()[0];
526 nomStatusSet
.remove(nomStatus
);
528 nomStatus
.setType(nomStatusTypes
[index
]);
532 nomStatus
= NomenclaturalStatus
.NewInstance(nomStatusTypes
[index
]);
533 name
.addStatus(nomStatus
);
538 if (id
.equals(P_ID_MARKERS
)) {
542 // Nomenclatural reference
543 if (id
.equals(P_ID_NOMENCLATURAL_REF
)) {
544 if (value
instanceof INomenclaturalReference
) {
545 name
.setNomenclaturalReference((ReferenceBase
) value
);
550 if (id
.equals(P_ID_NOMENCLATURAL_MICROREF
)) {
551 name
.setNomenclaturalMicroReference((String
) value
);
554 // If there is no rank, generated caches will be blank, wiping out the freetext area
555 if (name
.getRank() != null) {
557 // Reset both caches to reflect property sheet changes
558 name
.setTitleCache(name
.generateTitle(), false);
559 name
.setFullTitleCache(name
.generateFullTitle(), false);
562 // name.firePropertyChange(ITaxEditorConstants.REFRESH_NAMEVIEWER, null, null);
567 * Any node with children must override {@link java.lang.Object#toString()}
568 * to display its name correctly
570 * @see java.lang.Object#toString()
572 public String
toString() {
573 if (parentid
== null || parentid
.equals("")) {
576 if (parentid
.equals(P_ID_TITLECACHE
)) {
577 return name
.getTitleCache();
579 if (parentid
.equals(P_ID_NOMENCLATURAL_REF
)) {
580 INomenclaturalReference nomenclaturalReference
= (INomenclaturalReference
) name
.getNomenclaturalReference();
581 if (nomenclaturalReference
== null) {
584 String microReference
= name
.getNomenclaturalMicroReference();
585 return CdmUtils
.Nz(nomenclaturalReference
.getNomenclaturalCitation(microReference
));
587 return super.toString();
590 public void addPropertyChangeListener(
591 PropertyChangeListener listener
) {
592 this.propertyChangeSupport
.addPropertyChangeListener(listener
);