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
.User
;
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
.cdm
.strategy
.parser
.ParserProblem
;
37 import eu
.etaxonomy
.taxeditor
.preference
.PreferencesUtil
;
38 import eu
.etaxonomy
.taxeditor
.propertysheet
.AnnotationPropertySource
;
39 import eu
.etaxonomy
.taxeditor
.propertysheet
.AnnotationsPropertyDescriptor
;
40 import eu
.etaxonomy
.taxeditor
.propertysheet
.ICdmBasePropertySource
;
41 import eu
.etaxonomy
.taxeditor
.propertysheet
.MarkersPropertySource
;
42 import eu
.etaxonomy
.taxeditor
.propertysheet
.reference
.NomenclaturalReferencePropertySource
;
43 import eu
.etaxonomy
.taxeditor
.propertysheet
.reference
.ReferencePropertySource
;
50 public class NonViralNamePropertySource
implements ICdmBasePropertySource
{
52 // The name whose properties are being displayed
55 // If this is a property with a parent, the parent's property ID
56 private String parentid
= "";
58 PropertyChangeSupport propertyChangeSupport
;
60 // Property unique keys
61 public static final String P_ID_PARSED
= "parsed";
62 public static final String P_ID_RANK
= "rank";
63 public static final String P_ID_TITLECACHE
= "titlecache";
64 public static final String P_ID_HOMOTYPICALGROUP
= "homogroup";
65 public static final String P_ID_NAMERELATIONS
= "namerelations";
66 public static final String P_ID_TYPE
= "type";
67 public static final String P_ID_ANNOTATIONS
= "annotations";
68 public static final String P_ID_NOMSTATUS
= "nomstatus";
69 public static final String P_ID_UUID
= "uuid";
70 public static final String P_ID_NUM_OF_BASES
= "numberofbases";
71 public static final String P_ID_MARKERS
= "markers";
72 public static final String P_ID_CREATED
= "created";
73 public static final String P_ID_CREATEDBY
= "createdby";
74 public static final String P_ID_NOMENCLATURAL_CODE
= "nomenclaturalcode";
75 public static final String P_ID_NOMENCLATURAL_REF
= "nomenclaturalref";
76 public static final String P_ID_NOMENCLATURAL_MICROREF
= "nomenclaturalmicroref";
78 // Property display keys
79 public static final String P_PARSED
= "Parsing Status";
80 public static final String P_RANK
= "Rank";
81 public static final String P_TITLECACHE
= "Name Cache";
82 public static final String P_HOMOTYPICALGROUP
= "Homotypical Group";
83 public static final String P_NAMERELATIONS
= "Name Relations";
84 public static final String P_TYPE
= "Type";
85 public static final String P_ANNOTATIONS
= "Annotations";
86 public static final String P_NOMSTATUS
= "Nomenclatural Status";
87 public static final String P_UUID
= "UUID";
88 public static final String P_NUM_OF_BASES
= "Number of Bases";
89 public static final String P_MARKERS
= "Markers";
90 public static final String P_CREATED
= "Created";
91 public static final String P_CREATEDBY
= "Created By";
92 public static final String P_NOMENCLATURAL_CODE
= "Nomenclatural Code";
93 public static final String P_NOMENCLATURAL_REF
= "Nomenclatural Reference";
94 public static final String P_NOMENCLATURAL_MICROREF
= "Reference Detail";
96 protected static final String
[] TOP_LEVEL_PROPERTIES
= new String
[] {
99 P_ID_NOMENCLATURAL_CODE
,
102 P_ID_NOMENCLATURAL_REF
,
103 P_ID_NOMENCLATURAL_MICROREF
,
110 // ***********************************************************
112 // ***********************************************************
114 String
[] P_RANK_MENU
= null;
115 private void populateRanks() {
117 // Get terms from rank vocabulary
118 List
<Rank
> ranksList
= new ArrayList
<Rank
>();
119 ranksList
.addAll(PreferencesUtil
.getPreferredRanks());
121 // Populate ranks menu labels
122 List
<String
> ranksMenuList
= new ArrayList
<String
>();
123 for (Rank rank
: ranksList
) {
124 ranksMenuList
.add(rank
.getLabel());
127 // Add an empty element for "nothing selected" in the rank drop-down
128 ranksList
.add(0, null);
129 ranksMenuList
.add(0, "");
131 // Convert rank lists to array
132 ranks
= ranksList
.toArray(new Rank
[ranksList
.size()]);
133 P_RANK_MENU
= ranksMenuList
.toArray(new String
[ranksMenuList
.size()]);
136 // ***********************************************************
137 // NOMENCLATURAL STATUS
138 // ***********************************************************
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 List
<NomenclaturalStatusType
> statusVocab
= PreferencesUtil
.getPreferredNomenclaturalStatusTypes();
148 // If there is no status vocabulary, init type and status w empty arrays and return
149 if (statusVocab
== null) {
150 nomStatusTypes
= new NomenclaturalStatusType
[]{};
151 P_NOMSTATUS_MENU
= new String
[]{};
155 nomStatusTypesList
.addAll(statusVocab
);
157 // Populate nom status type menu labels
158 List
<String
> nomStatusTypesMenuList
= new ArrayList
<String
>();
159 for (NomenclaturalStatusType nomStatusType
: nomStatusTypesList
) {
160 nomStatusTypesMenuList
.add(nomStatusType
.getLabel());
163 // Add an empty element for "nothing selected" in the rank drop-down
164 nomStatusTypesList
.add(0, null);
165 nomStatusTypesMenuList
.add(0, "");
167 // Convert rank lists to array
168 nomStatusTypes
= nomStatusTypesList
.toArray(new NomenclaturalStatusType
[nomStatusTypesList
.size()]);
169 P_NOMSTATUS_MENU
= nomStatusTypesMenuList
.toArray(new String
[nomStatusTypesMenuList
.size()]);
172 protected Vector
<PropertyDescriptor
> descriptors
= new Vector
<PropertyDescriptor
>();
174 * Add descriptor for a given property.
176 * Notes on Descriptor:
179 * <li>PropertyDescriptor - uneditable cell value</li>
180 * <li>ComboBoxPropertyDescriptor - dropdown list, property supplied must be integer-based</li>
181 * <li>TextPropertyDescriptor - editable cell value</li>
184 * If any descriptor calls setCategory, all descriptors w/out a category are put in
187 * <code>descriptor.setFilterFlags (new String[] { IPropertySheetEntry.FILTER_ID_EXPERT })</code> -
188 * this descriptor shown under advanced properties
192 protected void addDescriptor(String id
) {
194 // Parsed: reports whether parsing was successful
195 if (id
.equals(P_ID_PARSED
)) {
196 descriptors
.addElement(
197 new PropertyDescriptor(P_ID_PARSED
, P_PARSED
));
201 if (id
.equals(P_ID_RANK
)) {
205 descriptors
.addElement(
206 new EditorComboBoxPropertyDescriptor(P_ID_RANK
, P_RANK
, P_RANK_MENU
));
210 if (id
.equals(P_ID_TITLECACHE
)) {
211 descriptors
.addElement(
212 new PropertyDescriptor(P_ID_TITLECACHE
, P_TITLECACHE
));
216 if (id
.equals(P_ID_HOMOTYPICALGROUP
)) {
217 descriptors
.addElement(
218 new PropertyDescriptor(P_ID_HOMOTYPICALGROUP
, P_HOMOTYPICALGROUP
));
221 // Name relations, listed in custom property descriptor
222 if (id
.equals(P_ID_NAMERELATIONS
)) {
223 descriptors
.addElement(
224 new NameRelationsPropertyDescriptor(P_ID_NAMERELATIONS
, P_NAMERELATIONS
, name
)
229 if (id
.equals(P_ID_TYPE
)) {
230 descriptors
.addElement(
231 new PropertyDescriptor(P_ID_TYPE
, P_TYPE
));
234 // Annotations, listed in custom property descriptor
235 if (id
.equals(P_ID_ANNOTATIONS
)) {
236 descriptors
.addElement(
237 new AnnotationsPropertyDescriptor(P_ID_ANNOTATIONS
, P_ANNOTATIONS
, name
) {
238 protected void saveAnnotations(Set set
) {
239 setPropertyValue(P_ID_ANNOTATIONS
, set
);
245 // Nomenclatural status
246 if (id
.equals(P_ID_NOMSTATUS
)) {
247 if (nomStatusTypes
== null) {
248 populateNomStatusTypes();
250 descriptors
.addElement(
251 new ComboBoxPropertyDescriptor(P_ID_NOMSTATUS
, P_NOMSTATUS
, P_NOMSTATUS_MENU
));
255 if (id
.equals(P_ID_UUID
)) {
256 descriptors
.addElement(
257 new PropertyDescriptor(P_ID_UUID
, P_UUID
));
261 if (id
.equals(P_ID_MARKERS
)) {
262 descriptors
.addElement(
263 new PropertyDescriptor(P_ID_MARKERS
, P_MARKERS
));
266 // Taxon bases referring to this name
267 if (id
.equals(P_ID_NUM_OF_BASES
)) {
268 descriptors
.addElement(
269 new PropertyDescriptor(P_ID_NUM_OF_BASES
, P_NUM_OF_BASES
));
272 // Object created when
273 if (id
.equals(P_ID_CREATED
)) {
274 descriptors
.addElement(
275 new PropertyDescriptor(P_ID_CREATED
, P_CREATED
));
279 if (id
.equals(P_ID_CREATEDBY
)) {
280 descriptors
.addElement(
281 new PropertyDescriptor(P_ID_CREATEDBY
, P_CREATEDBY
));
284 // Nomenclatural code used by parser
285 if (id
.equals(P_ID_NOMENCLATURAL_CODE
)) {
286 descriptors
.addElement(
287 new PropertyDescriptor(P_ID_NOMENCLATURAL_CODE
, P_NOMENCLATURAL_CODE
));
290 // Nomenclatural reference
291 if (id
.equals(P_ID_NOMENCLATURAL_REF
)) {
292 descriptors
.addElement(
293 new PropertyDescriptor(P_ID_NOMENCLATURAL_REF
,P_NOMENCLATURAL_REF
));
297 if (id
.equals(P_ID_NOMENCLATURAL_MICROREF
)) {
298 descriptors
.addElement(
299 new TextPropertyDescriptor(P_ID_NOMENCLATURAL_MICROREF
,P_NOMENCLATURAL_MICROREF
));
304 * Constructor for top level property fields. All fields that are not subfields
305 * should be listed here.
308 public NonViralNamePropertySource(NonViralName
<?
> name
) {
309 this(name
, null, TOP_LEVEL_PROPERTIES
);
312 public NonViralNamePropertySource(NonViralName
<?
> name
,
313 String parentid
, String
[] keys
) {
315 this.parentid
= parentid
;
316 for (String key
: keys
) {
321 public Object
getEditableValue() {
325 public IPropertyDescriptor
[] getPropertyDescriptors() {
326 return (IPropertyDescriptor
[]) descriptors
.toArray(
327 new IPropertyDescriptor
[descriptors
.size()]);
330 public Object
getPropertyValue(Object id
) {
332 // Parsed: reports whether parsing was successful
333 if (id
.equals(P_ID_PARSED
)) {
335 for (ParserProblem problem
: name
.getParsingProblems()) {
336 str
= str
== null ? problem
.toString() : str
+ problem
.toString();
338 return str
== null ?
"parsed" : str
;
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
);
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
);
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(name
.getCreatedBy().getUsername());
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
);
601 public NonViralName
<?
> getName() {