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
;
13 import java
.util
.Collection
;
14 import java
.util
.HashMap
;
15 import java
.util
.HashSet
;
17 import java
.util
.ResourceBundle
;
19 import java
.util
.UUID
;
21 import org
.apache
.log4j
.Logger
;
22 import org
.eclipse
.core
.databinding
.observable
.Realm
;
23 import org
.eclipse
.core
.databinding
.observable
.list
.WritableList
;
24 import org
.eclipse
.core
.databinding
.observable
.set
.IObservableSet
;
25 import org
.eclipse
.core
.databinding
.observable
.set
.WritableSet
;
26 import org
.eclipse
.core
.runtime
.FileLocator
;
27 import org
.eclipse
.core
.runtime
.IPath
;
28 import org
.eclipse
.core
.runtime
.Path
;
29 import org
.eclipse
.jface
.databinding
.swt
.SWTObservables
;
30 import org
.eclipse
.jface
.preference
.IPreferenceStore
;
31 import org
.eclipse
.jface
.resource
.FontRegistry
;
32 import org
.eclipse
.jface
.resource
.ImageDescriptor
;
33 import org
.eclipse
.jface
.resource
.ImageRegistry
;
34 import org
.eclipse
.swt
.SWT
;
35 import org
.eclipse
.swt
.graphics
.Font
;
36 import org
.eclipse
.swt
.graphics
.FontData
;
37 import org
.eclipse
.swt
.graphics
.Image
;
38 import org
.eclipse
.swt
.widgets
.Display
;
39 import org
.eclipse
.ui
.forms
.FormColors
;
40 import org
.eclipse
.ui
.plugin
.AbstractUIPlugin
;
41 import org
.osgi
.framework
.BundleContext
;
42 import org
.springframework
.transaction
.TransactionStatus
;
44 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationController
;
45 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
46 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
47 import eu
.etaxonomy
.cdm
.database
.DataSourceNotFoundException
;
48 import eu
.etaxonomy
.cdm
.database
.DbSchemaValidation
;
49 import eu
.etaxonomy
.cdm
.model
.agent
.Person
;
50 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
51 import eu
.etaxonomy
.cdm
.model
.common
.OrderedTermVocabulary
;
52 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
53 import eu
.etaxonomy
.cdm
.model
.common
.init
.TermNotFoundException
;
54 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
55 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationshipType
;
56 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
57 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
58 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
59 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
60 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
61 import eu
.etaxonomy
.taxeditor
.model
.CdmUtil
;
62 import eu
.etaxonomy
.taxeditor
.view
.TaxonomicTreeView
;
65 * The class controlling the plug-in life cycle.
71 public class TaxEditorPlugin
extends AbstractUIPlugin
{
72 private static final Logger logger
= Logger
73 .getLogger(TaxEditorPlugin
.class);
78 public static final String PLUGIN_ID
= "eu.etaxonomy.taxeditor.plugin";
82 private static TaxEditorPlugin plugin
;
84 private DbSchemaValidation dbSchemaValidation
= DbSchemaValidation
.VALIDATE
;
89 public TaxEditorPlugin() {
90 logger
.fatal("Fatal");
91 logger
.error("Error");
92 logger
.debug("Debug");
95 logger
.trace("Trace");
101 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
103 public void start(BundleContext context
) throws Exception
{
104 super.start(context
);
107 boolean initDatastore
= false;
109 // If the preferences INITIALIZED has not been set, the IF clause
110 // will return false, i.e. datastore will be initialized first
111 // time the application is run after being installed.
112 boolean initialized
= getPreferenceStore()
113 .getBoolean(ITaxEditorConstants
.INITIALIZED
);
115 // initialized = false;
117 logger
.warn("Initializing datastore");
118 initDatastore
= true;
121 .setValue(ITaxEditorConstants
.INITIALIZED
, true);
123 logger
.warn("Datastore already initialized");
127 dbSchemaValidation
= DbSchemaValidation
.CREATE
;
130 cdmApp
= getCdmApp();
132 // if (initDatastore) {
141 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
143 public void stop(BundleContext context
) throws Exception
{
149 void initDatastore() {
151 boolean useSoraya
= true;
152 // useSoraya = false;
155 genusTaxon
= getSorayasGenusTaxon();
158 BotanicalName botanicalName
= BotanicalName
.NewInstance(Rank
160 botanicalName
.setTitleCache("Hieracium L.");
161 botanicalName
.setGenusOrUninomial("Hieracium");
162 botanicalName
.setCombinationAuthorTeam(Person
.NewInstance());
163 botanicalName
.getCombinationAuthorTeam()
164 .setNomenclaturalTitle("L.");
165 genusTaxon
= Taxon
.NewInstance(botanicalName
, CdmUtil
166 .getSessionDefaultSec());
168 BotanicalName botSpecies
= BotanicalName
169 .NewInstance(Rank
.SPECIES());
170 botSpecies
.setTitleCache("Hieracium asturianum Pau");
171 botSpecies
.setGenusOrUninomial("Hieracium");
172 botSpecies
.setSpecificEpithet("asturianum");
173 botSpecies
.setCombinationAuthorTeam(Person
.NewInstance());
174 botSpecies
.getCombinationAuthorTeam().setNomenclaturalTitle("Pau");
175 Taxon childTaxon
= Taxon
.NewInstance(botSpecies
, null);
176 childTaxon
.setTaxonomicParent(genusTaxon
, null, null);
178 BotanicalName botSpecies2
= BotanicalName
.NewInstance(Rank
180 botSpecies2
.setTitleCache("Hieracium wolffii Zahn");
181 botSpecies2
.setGenusOrUninomial("Hieracium");
182 botSpecies2
.setSpecificEpithet("wolffii");
183 botSpecies2
.setCombinationAuthorTeam(Person
.NewInstance());
184 botSpecies2
.getCombinationAuthorTeam()
185 .setNomenclaturalTitle("Zahn");
186 Taxon childTaxon2
= Taxon
.NewInstance(botSpecies2
, CdmUtil
187 .getSessionDefaultSec());
188 // childTaxon2.setName(botSpecies2);
189 // childTaxon2.setSec(null);
190 childTaxon2
.setTaxonomicParent(genusTaxon
, null, null);
192 // Add some name relations to botSpecies2
193 botSpecies2
.addRelationshipFromName(botSpecies
,
194 NameRelationshipType
.BASIONYM(), null);
195 botSpecies2
.addRelationshipToName(botSpecies
, NameRelationshipType
196 .REPLACED_SYNONYM(), null);
197 logger
.warn("Name relations created");
199 // Add name status to botSpecies2
200 botSpecies2
.addStatus(NomenclaturalStatus
201 .NewInstance(NomenclaturalStatusType
.NOVUM()));
202 logger
.warn("Nom. status created");
205 getCdmApp().getTaxonService().saveTaxon(genusTaxon
);
211 * Returns the shared instance
213 * @return the shared instance
215 public static TaxEditorPlugin
getDefault() {
219 /***************************************************************************
221 **************************************************************************/
223 * All CDM services are called via the application controller
225 private CdmApplicationController cdmApp
;
226 private TransactionStatus txStatus
;
228 public CdmApplicationController
getCdmApp() {
229 if (cdmApp
== null) {
231 // ICdmDataSource ds =
232 // CdmDataSource.NewH2EmbeddedInstance("cdm", "sa", "");
233 // cdmApp = CdmApplicationController
234 // .NewInstance(ds, dbSchemaValidation);
235 cdmApp
= CdmApplicationController
236 .NewInstance(dbSchemaValidation
);
239 // Object txStatus = cdmApp.startTransaction();
240 // cdmApp.commitTransaction((TransactionStatus) txStatus);
242 } catch (DataSourceNotFoundException e
) {
243 // TODO Auto-generated catch block
245 } catch (TermNotFoundException e
) {
246 // TODO Auto-generated catch block
253 public void startTransaction() {
254 if (cdmApp
!= null) {
255 txStatus
= cdmApp
.startTransaction();
259 public void stopTransaction() {
260 if (txStatus
!= null) {
261 cdmApp
.commitTransaction(txStatus
);
266 private ITaxonService taxonService
;
268 public ITaxonService
getTaxonService() {
269 if (taxonService
== null) {
270 taxonService
= getCdmApp().getTaxonService();
275 private INameService nameService
;
277 public INameService
getNameService() {
278 if (nameService
== null) {
279 nameService
= getCdmApp().getNameService();
284 /***************************************************************************
286 **************************************************************************/
288 private WritableList observableRecentNamesList
= null;
289 private WritableList observableFavoritesList
= null;
291 public WritableList
getObservableRecentNamesList() {
292 if (observableRecentNamesList
== null) {
293 observableRecentNamesList
= new WritableList();
295 return observableRecentNamesList
;
298 public WritableList
getObservableFavoritesList() {
299 if (observableFavoritesList
== null) {
300 observableFavoritesList
= new WritableList();
302 return observableFavoritesList
;
305 /***************************************************************************
307 **************************************************************************/
308 public ImageDescriptor
getImageDescriptor(String key
) {
309 return getImageRegistry().getDescriptor(key
);
312 public Image
getImage(String key
) {
313 return getImageRegistry().get(key
);
317 private ResourceBundle resourceBundle
;
318 private FormColors formColors
;
320 protected void initializeImageRegistry(ImageRegistry registry
) {
321 registerImage(registry
, ITaxEditorConstants
.EDIT_ICON
, "edit_16x16.ico");
322 registerImage(registry
, ITaxEditorConstants
.WARNING_ICON
,
324 registerImage(registry
, ITaxEditorConstants
.ACCEPTED_TAXON_ICON
,
325 "accepted_small.gif");
326 registerImage(registry
, ITaxEditorConstants
.HOMOTYPIC_SYN_ICON
,
327 "homosyn_no_bg.gif");
328 registerImage(registry
,
329 ITaxEditorConstants
.HOMOTYPIC_SYN_ORIGINAL_ICON
,
330 "homosyn_original_no_bg.gif");
331 registerImage(registry
, ITaxEditorConstants
.HETEROTYPIC_SYN_ICON
,
332 "heterosyn_no_bg.gif");
333 registerImage(registry
,
334 ITaxEditorConstants
.HETEROTYPIC_SYN_ORIGINAL_ICON
,
335 "heterosyn_original_no_bg.gif");
336 registerImage(registry
, ITaxEditorConstants
.MISAPPLIED_NAME_ICON
,
337 "misapplied_no_bg.gif");
338 registerImage(registry
, ITaxEditorConstants
.AUTONYM_ICON
,
339 "autonym_no_bg.gif");
340 registerImage(registry
, ITaxEditorConstants
.BASIONYM_ICON
,
341 "basionym_no_bg.gif");
342 registerImage(registry
, ITaxEditorConstants
.ORTHOGRAPHIC_VARIANT_ICON
,
343 "orthovariant_no_bg.gif");
344 registerImage(registry
, ITaxEditorConstants
.DB_ICON
, "db.gif");
345 registerImage(registry
, ITaxEditorConstants
.MOVE_ICON
,
346 "correction_change.gif");
347 registerImage(registry
, ITaxEditorConstants
.ACTIVE_DELETE_ICON
,
349 registerImage(registry
, ITaxEditorConstants
.SYNONYM_TO_TAXON_ICON
,
351 registerImage(registry
, ITaxEditorConstants
.OPEN_TAXON_ICON
, "open.gif");
352 registerImage(registry
, ITaxEditorConstants
.ADD_CHILD_TAXON_ICON
,
354 registerImage(registry
,
355 ITaxEditorConstants
.SWAP_SYNONYM_AND_TAXON_ICON
, "swap2.gif");
356 registerImage(registry
, ITaxEditorConstants
.QUICK_ADD_ICON
,
358 registerImage(registry
, ITaxEditorConstants
.TAXON_TO_SYNONYM_ICON
,
362 private void registerImage(ImageRegistry registry
, String key
,
365 IPath path
= new Path("icons/" + fileName
); //$NON-NLS-1$
366 URL url
= FileLocator
.find(getBundle(), path
, null);
368 ImageDescriptor desc
= ImageDescriptor
.createFromURL(url
);
369 registry
.put(key
, desc
);
371 } catch (Exception e
) {
375 /***************************************************************************
377 **************************************************************************/
378 private FontRegistry fontRegistry
;
380 private FontRegistry
getFontRegistry() {
381 if (fontRegistry
== null) {
382 fontRegistry
= new FontRegistry(Display
.getCurrent());
384 fontRegistry
.put(ITaxEditorConstants
.DATASOURCE_FONT
,
385 new FontData
[] { new FontData("Arial", 8, SWT
.NONE
) });
386 fontRegistry
.put(ITaxEditorConstants
.MENU_ITEM_ITALICS_FONT
,
387 new FontData
[] { new FontData("Arial", 9, SWT
.ITALIC
) });
388 fontRegistry
.put(ITaxEditorConstants
.ACCEPTED_TAXON_FONT
,
389 new FontData
[] { new FontData("Georgia", 12, SWT
.NONE
) });
390 fontRegistry
.put(ITaxEditorConstants
.SYNONYM_FONT
,
391 new FontData
[] { new FontData("Georgia", 10, SWT
.NONE
) });
392 fontRegistry
.put(ITaxEditorConstants
.MISAPPLIEDNAME_FONT
,
393 new FontData
[] { new FontData("Georgia", 10, SWT
.NONE
) });
394 fontRegistry
.put(ITaxEditorConstants
.CHOOSE_NAME_TEXT_FONT
,
395 new FontData
[] { new FontData("Arial", 12, SWT
.BOLD
) });
400 public Font
getFont(String key
) {
401 return getFontRegistry().get(key
);
404 /***************************************************************************
406 **************************************************************************/
407 protected void initializeDefaultPreferences(IPreferenceStore store
) {
408 // Platform.getPreferencesService().getBoolean(qualifier, key,
409 // defaultValue, contexts)
410 store
.setDefault(ITaxEditorConstants
.CODE_PREFERENCE
,
411 ITaxEditorConstants
.DEFAULT_CODE_PREFERENCE
);
414 /***************************************************************************
416 **************************************************************************/
418 public ReferenceBase
getSec() {
419 return getCdmApp().getReferenceService().getReferenceByUuid(
420 UUID
.fromString("f3593c18-a8d2-4e51-bdad-0befbf8fb2d1"));
423 // private List<Taxon> sessionRootTaxa;
424 private Set
<Taxon
> sessionRootTaxa
;
426 * The taxonomic tree content provider observes this set for changes, and
427 * makes the appropriate changes to the tree.
429 private IObservableSet observableSessionTaxonSet
;
431 * This map of taxa to their taxonomic children is used by
432 * NameTreeContentProvider's getChildren method.
434 * key = taxon, value = key's child taxa Note that a map can have a key ==
435 * null, i.e. no parent taxon
437 private HashMap
<Taxon
, Set
<Taxon
>> sessionTaxonomicChildrenMap
;
439 public Set
<Taxon
> getSessionRootTaxa() {
440 // public List<Taxon> getSessionRootTaxa() {
441 if (sessionRootTaxa
== null) {
442 // sessionRootTaxa = new ArrayList<Taxon>();
443 sessionRootTaxa
= new HashSet
<Taxon
>();
444 sessionRootTaxa
.addAll(getCdmApp().getTaxonService().getRootTaxa(
445 getSec(), null, false));
446 addSessionTaxa(sessionRootTaxa
);
448 logger
.warn(sessionRootTaxa
.size() + " taxa in root taxa");
449 return sessionRootTaxa
;
452 private Map
<Taxon
, Set
<Taxon
>> getTaxonomicChildrenMap() {
453 if (sessionTaxonomicChildrenMap
== null) {
454 sessionTaxonomicChildrenMap
= new HashMap
<Taxon
, Set
<Taxon
>>();
456 return sessionTaxonomicChildrenMap
;
460 * Returns a set of any child taxa for this taxon that have already been
461 * requested during this session.
466 public Set
<Taxon
> getSessionTaxonomicChildren(Taxon parentTaxon
) {
467 if (!getTaxonomicChildrenMap().containsKey(parentTaxon
)) {
468 if (parentTaxon
== null) {
469 getTaxonomicChildrenMap().put(parentTaxon
, getSessionRootTaxa());
472 // BUG deleted taxon where re-appearing as NULL children
473 Set
<Taxon
> childTaxa
= new HashSet
<Taxon
>();
474 for (Taxon taxon
: parentTaxon
.getTaxonomicChildren()) {
476 childTaxa
.add(taxon
);
479 getTaxonomicChildrenMap().put(parentTaxon
, childTaxa
);
482 return getTaxonomicChildrenMap().get(parentTaxon
);
488 public IObservableSet
getObservableSessionTaxa() {
489 if (observableSessionTaxonSet
== null) {
490 Realm realm
= SWTObservables
.getRealm(Display
.getDefault());
491 observableSessionTaxonSet
= new WritableSet(realm
);
493 return observableSessionTaxonSet
;
497 * Recursive function to clear the hashmap of a taxon's children used in
498 * this session, and the childrens' children, etc.
502 private void clearTaxonomicChildren(Taxon taxon
) {
503 Set
<Taxon
> children
= getSessionTaxonomicChildren(taxon
);
504 if (children
!= null) {
505 logger
.warn(children
.size() + " children in "
506 + CdmUtil
.getDisplayName(taxon
));
507 for (Taxon child
: children
) {
508 clearTaxonomicChildren(child
);
510 getTaxonomicChildrenMap().remove(taxon
);
511 getObservableSessionTaxa().removeAll(children
);
516 * Remove taxon from all session collections
520 public void removeSessionTaxon(Taxon taxon
) {
522 // Recursively remove all children, children's children, etc.
523 clearTaxonomicChildren(taxon
);
525 Taxon parentTaxon
= taxon
.getTaxonomicParent();
527 // Remove from parent's child map, or from root taxa
528 if (parentTaxon
== null) {
529 getSessionRootTaxa().remove(taxon
);
531 getSessionTaxonomicChildren(parentTaxon
).remove(taxon
);
534 // Remove from session taxa
535 getObservableSessionTaxa().remove(taxon
);
537 UiUtil
.getTreeViewer().remove(taxon
);
540 public void addSessionTaxa(Collection
<Taxon
> taxa
) {
541 for (Taxon taxon
: taxa
) {
542 addSessionTaxon(taxon
);
547 * Whenever a taxon is opened, either for editing or for display in the
548 * taxonomic tree, it should be added to the collections of taxa used during
553 public void addSessionTaxon(Taxon taxon
) {
555 // Add taxon to session taxa if not already there
556 if (!(getObservableSessionTaxa().contains(taxon
))) {
557 getObservableSessionTaxa().add(taxon
);
560 Taxon parentTaxon
= taxon
.getTaxonomicParent();
562 // If taxon has no parent, add it to root taxa
563 if (parentTaxon
== null) {
564 if (!(getSessionRootTaxa().contains(taxon
))) {
565 getSessionRootTaxa().add(taxon
);
569 // Add taxon to its parent's child map
570 getSessionTaxonomicChildren(parentTaxon
).add(taxon
);
572 if (taxonomicTreeView
!= null) {
574 UiUtil
.getTreeViewer().remove(taxon
);
576 if (parentTaxon
== null) {
577 logger
.warn("Resetting input");
578 UiUtil
.getTreeViewer().setInput(getSessionRootTaxa());
580 UiUtil
.getTreeViewer().add(parentTaxon
, taxon
);
587 private TaxonomicTreeView taxonomicTreeView
;
589 public void setTaxonomicTree(TaxonomicTreeView taxonomicTreeView
) {
590 this.taxonomicTreeView
= taxonomicTreeView
;
593 /***************************************************************************
595 **************************************************************************/
596 OrderedTermVocabulary
<Rank
> rankVocabulary
= null;
598 public OrderedTermVocabulary
<Rank
> getRankVocabulary() {
599 if (rankVocabulary
== null) {
600 rankVocabulary
= getCdmApp().getNameService().getRankVocabulary();
602 return rankVocabulary
;
605 /***************************************************************************
606 * NOMENCLATURAL STATUS
607 **************************************************************************/
608 TermVocabulary
<NomenclaturalStatusType
> nomStatusVocabulary
= null;
610 public TermVocabulary
<NomenclaturalStatusType
> getNomStatusVocabulary() {
611 if (nomStatusVocabulary
== null) {
612 nomStatusVocabulary
= getCdmApp().getNameService()
613 .getStatusTypeVocabulary();
615 return nomStatusVocabulary
;
618 /***************************************************************************
620 **************************************************************************/
621 TermVocabulary
<NameRelationshipType
> nameRelationshipTypeVocabulary
= null;
623 public TermVocabulary
<NameRelationshipType
> getNameRelationshipTypeVocabulary() {
624 if (nameRelationshipTypeVocabulary
== null) {
625 nameRelationshipTypeVocabulary
= getCdmApp().getNameService()
626 .getNameRelationshipTypeVocabulary();
628 return nameRelationshipTypeVocabulary
;
631 public Set
<NameRelationshipType
> getSortedNameRelationshipTypes() {
632 return getNameRelationshipTypeVocabulary().getTermsOrderedByLabels(
636 /***************************************************************************
638 **************************************************************************/
639 private Taxon
getSorayasGenusTaxon() {
641 String
[] children
= new String
[] {
642 "Heterospathe annectens H.E.Moore",
643 "Heterospathe arfakiana (Becc.) H.E.Moore",
644 "Heterospathe brevicaulis Fernando",
645 "Heterospathe cagayanensis Becc.",
646 "Heterospathe califrons Fernando, Palms 45: 118 (2001).",
647 "Heterospathe clemensiae (Burret) H.E.Moore",
648 "Heterospathe delicatula H.E.Moore",
649 "Heterospathe dransfieldii Fernando",
650 "Heterospathe elata Scheff.",
651 "Heterospathe elata var. elata.",
652 "Heterospathe elata var. guamensis Becc.",
653 "Heterospathe elata var. palauensis (Becc.) Becc.",
654 "Heterospathe elegans (Becc.) Becc.",
655 "Heterospathe elmeri Becc.",
656 "Heterospathe glabra (Burret) H.E.Moore",
657 "Heterospathe glauca (Scheff.) H.E.Moore",
658 "Heterospathe humilis Becc.",
659 "Heterospathe intermedia (Becc.) Fernando",
660 "Heterospathe kajewskii Burret",
661 "Heterospathe ledermanniana Becc.",
662 "Heterospathe lepidota H.E.Moore",
663 "Heterospathe longipes (H.E.Moore) Norup",
664 "Heterospathe macgregorii (Becc.) H.E.Moore",
665 "Heterospathe micrantha (Becc.) H.E.Moore",
666 "Heterospathe minor Burret",
667 "Heterospathe muelleriana (Becc.) Becc.",
668 "Heterospathe negrosensis Becc.",
669 "Heterospathe obriensis (Becc.) H.E.Moore",
670 "Heterospathe palauensis Becc.",
671 "Heterospathe parviflora Essig",
672 "Heterospathe philippinensis (Becc.) Becc.",
673 // "Heterospathe phillipsii D.Fuller & Dowe", // <--------------
674 "Heterospathe pilosa (Burret) Burret",
675 "Heterospathe pisifera (Gaertn.) Burret",
676 "Heterospathe pulchra H.E.Moore",
677 "Heterospathe ramulosa Burret",
678 "Heterospathe salomonensis Becc.",
679 "Heterospathe scitula Fernando", "Heterospathe sensisi Becc.",
680 "Heterospathe sibuyanensis Becc.",
681 "Heterospathe sphaerocarpa Burret",
682 "Heterospathe trispatha Fernando",
683 "Heterospathe uniformis Dowe",
684 "Heterospathe versteegiana Becc.",
685 "Heterospathe woodfordiana Becc." };
687 BotanicalName genusName
= BotanicalName
688 .PARSED_NAME("Heterospathe Scheff.");
690 Taxon genusTaxon
= Taxon
.NewInstance(genusName
, CdmUtil
691 .getSessionDefaultSec());
693 for (String child
: children
) {
694 BotanicalName speciesName
= BotanicalName
.PARSED_NAME(child
);
696 Taxon childTaxon
= Taxon
.NewInstance(speciesName
, CdmUtil
697 .getSessionDefaultSec());
698 childTaxon
.setTaxonomicParent(genusTaxon
, null, null);
700 if (child
.equals("Heterospathe elegans (Becc.) Becc.")) {
701 BotanicalName basionym
= BotanicalName
702 .PARSED_NAME("Barkerwebbia elegans Becc.");
703 speciesName
.addRelationshipFromName(basionym
,
704 NameRelationshipType
.BASIONYM(), null);
705 childTaxon
.addHomotypicSynonymName(basionym
, null, null);
708 if (child
.equals("Heterospathe humilis Becc.")) {
709 BotanicalName synonymName
= BotanicalName
710 .PARSED_NAME("Barkerwebbia humilis (Becc.) Becc. ex Martelli");
711 childTaxon
.addHomotypicSynonymName(synonymName
, null, null);