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
.resource
.FontRegistry
;
31 import org
.eclipse
.jface
.resource
.ImageDescriptor
;
32 import org
.eclipse
.jface
.resource
.ImageRegistry
;
33 import org
.eclipse
.swt
.SWT
;
34 import org
.eclipse
.swt
.graphics
.Color
;
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
.IDescriptionService
;
46 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
47 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
48 import eu
.etaxonomy
.cdm
.database
.CdmDataSource
;
49 import eu
.etaxonomy
.cdm
.database
.DataSourceNotFoundException
;
50 import eu
.etaxonomy
.cdm
.database
.DbSchemaValidation
;
51 import eu
.etaxonomy
.cdm
.database
.ICdmDataSource
;
52 import eu
.etaxonomy
.cdm
.model
.agent
.Person
;
53 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
54 import eu
.etaxonomy
.cdm
.model
.common
.OrderedTermVocabulary
;
55 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
56 import eu
.etaxonomy
.cdm
.model
.common
.init
.TermNotFoundException
;
57 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
58 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationshipType
;
59 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
60 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
61 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
62 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
63 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
64 import eu
.etaxonomy
.taxeditor
.model
.CdmUtil
;
65 import eu
.etaxonomy
.taxeditor
.navigation
.TaxonomicTreeViewer
;
68 * The class controlling the plug-in life cycle.
71 * <li>Initializes datastore as necessary.</li>
72 * <li>Initializes default preferences.</li>
73 * <li>Gateway to CDM service layer.</li>
74 * <li>Stores taxa for application session.</li>
75 * <li>Stores registries for colors, fonts, images.</li>
82 public class TaxEditorPlugin
extends AbstractUIPlugin
{
83 private static final Logger logger
= Logger
84 .getLogger(TaxEditorPlugin
.class);
89 public static final String PLUGIN_ID
= "eu.etaxonomy.taxeditor.plugin";
93 private static TaxEditorPlugin plugin
;
95 // private DbSchemaValidation dbSchemaValidation = DbSchemaValidation.VALIDATE;
96 private DbSchemaValidation dbSchemaValidation
= DbSchemaValidation
.UPDATE
;
101 public TaxEditorPlugin() {
102 logger
.fatal("Fatal");
103 logger
.error("Error");
104 logger
.debug("Debug");
107 logger
.trace("Trace");
113 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
115 public void start(BundleContext context
) throws Exception
{
116 super.start(context
);
119 boolean initDatastore
= false;
121 // If the preferences INITIALIZED has not been set, the IF clause
122 // will return false, i.e. datastore will be initialized first
123 // time the application is run after being installed.
124 boolean initialized
= false;
125 if (getPreferenceStore()
126 .contains(ITaxEditorConstants
.INITIALIZED
)) {
127 initialized
= getPreferenceStore().getBoolean(
128 ITaxEditorConstants
.INITIALIZED
);
133 logger
.warn("Initializing datastore");
135 dbSchemaValidation
= DbSchemaValidation
.CREATE
;
137 if (getPreferenceStore().getBoolean(
138 ITaxEditorConstants
.INITIALIZE_W_TESTDATA
)) {
140 getPreferenceStore().setValue(
141 ITaxEditorConstants
.INITIALIZE_W_TESTDATA
, false);
145 .setValue(ITaxEditorConstants
.INITIALIZED
, true);
148 cdmApp
= getCdmApp();
154 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
156 public void stop(BundleContext context
) throws Exception
{
164 void initDatastore() {
166 boolean useSoraya
= true;
167 // useSoraya = false;
170 genusTaxon
= getSorayasGenusTaxon();
173 BotanicalName botanicalName
= BotanicalName
.NewInstance(Rank
175 botanicalName
.setTitleCache("Hieracium L.");
176 botanicalName
.setGenusOrUninomial("Hieracium");
177 botanicalName
.setCombinationAuthorTeam(Person
.NewInstance());
178 botanicalName
.getCombinationAuthorTeam()
179 .setNomenclaturalTitle("L.");
180 genusTaxon
= Taxon
.NewInstance(botanicalName
, CdmUtil
181 .getSessionDefaultSec());
183 BotanicalName botSpecies
= BotanicalName
184 .NewInstance(Rank
.SPECIES());
185 botSpecies
.setTitleCache("Hieracium asturianum Pau");
186 botSpecies
.setGenusOrUninomial("Hieracium");
187 botSpecies
.setSpecificEpithet("asturianum");
188 botSpecies
.setCombinationAuthorTeam(Person
.NewInstance());
189 botSpecies
.getCombinationAuthorTeam().setNomenclaturalTitle("Pau");
190 Taxon childTaxon
= Taxon
.NewInstance(botSpecies
, null);
191 childTaxon
.setTaxonomicParent(genusTaxon
, null, null);
193 BotanicalName botSpecies2
= BotanicalName
.NewInstance(Rank
195 botSpecies2
.setTitleCache("Hieracium wolffii Zahn");
196 botSpecies2
.setGenusOrUninomial("Hieracium");
197 botSpecies2
.setSpecificEpithet("wolffii");
198 botSpecies2
.setCombinationAuthorTeam(Person
.NewInstance());
199 botSpecies2
.getCombinationAuthorTeam()
200 .setNomenclaturalTitle("Zahn");
201 Taxon childTaxon2
= Taxon
.NewInstance(botSpecies2
, CdmUtil
202 .getSessionDefaultSec());
203 // childTaxon2.setName(botSpecies2);
204 // childTaxon2.setSec(null);
205 childTaxon2
.setTaxonomicParent(genusTaxon
, null, null);
207 // Add some name relations to botSpecies2
208 botSpecies2
.addRelationshipFromName(botSpecies
,
209 NameRelationshipType
.BASIONYM(), null);
210 botSpecies2
.addRelationshipToName(botSpecies
, NameRelationshipType
211 .REPLACED_SYNONYM(), null);
212 logger
.warn("Name relations created");
214 // Add name status to botSpecies2
215 botSpecies2
.addStatus(NomenclaturalStatus
216 .NewInstance(NomenclaturalStatusType
.NOVUM()));
217 logger
.warn("Nom. status created");
220 getCdmApp().getTaxonService().saveTaxon(genusTaxon
);
226 * Returns the shared instance
228 * @return the shared instance
230 public static TaxEditorPlugin
getDefault() {
234 /***************************************************************************
236 **************************************************************************/
238 * All CDM services are called via the application controller
240 private CdmApplicationController cdmApp
;
241 private TransactionStatus txStatus
;
243 public CdmApplicationController
getCdmApp() {
244 if (cdmApp
== null) {
247 CdmDataSource
.NewH2EmbeddedInstance("cdm", "sa", "");
248 // CdmDataSource.NewMySqlInstance("192.168.2.10", "cdm_editor_test1", "edit", "wp5");
250 cdmApp
= CdmApplicationController
251 .NewInstance(ds
, dbSchemaValidation
);
253 // cdmApp = CdmApplicationController
254 // .NewInstance(dbSchemaValidation);
257 // Object txStatus = cdmApp.startTransaction();
259 // cdmApp.commitTransaction((TransactionStatus) txStatus);
261 } catch (DataSourceNotFoundException e
) {
262 // TODO Auto-generated catch block
264 } catch (TermNotFoundException e
) {
265 // TODO Auto-generated catch block
272 public void startTransaction() {
273 if (cdmApp
!= null) {
274 txStatus
= cdmApp
.startTransaction();
278 public void commitTransaction() {
279 if (txStatus
!= null) {
280 cdmApp
.commitTransaction(txStatus
);
285 private ITaxonService taxonService
;
287 public ITaxonService
getTaxonService() {
288 if (taxonService
== null) {
289 taxonService
= getCdmApp().getTaxonService();
294 private INameService nameService
;
296 public INameService
getNameService() {
297 if (nameService
== null) {
298 nameService
= getCdmApp().getNameService();
303 private IDescriptionService descriptionService
;
305 public IDescriptionService
getDescriptionService() {
306 if (descriptionService
== null) {
307 descriptionService
= getCdmApp().getDescriptionService();
309 return descriptionService
;
313 /***************************************************************************
315 **************************************************************************/
317 private WritableList observableRecentNamesList
= null;
318 private WritableList observableFavoritesList
= null;
320 public WritableList
getObservableRecentNamesList() {
321 if (observableRecentNamesList
== null) {
322 observableRecentNamesList
= new WritableList();
324 return observableRecentNamesList
;
327 public WritableList
getObservableFavoritesList() {
328 if (observableFavoritesList
== null) {
329 observableFavoritesList
= new WritableList();
331 return observableFavoritesList
;
334 /***************************************************************************
336 **************************************************************************/
337 public ImageDescriptor
getImageDescriptor(String key
) {
338 return getImageRegistry().getDescriptor(key
);
341 public Image
getImage(String key
) {
342 return getImageRegistry().get(key
);
346 private ResourceBundle resourceBundle
;
347 private FormColors formColors
;
349 protected void initializeImageRegistry(ImageRegistry registry
) {
350 registerImage(registry
, ITaxEditorConstants
.EDIT_ICON
, "edit_16x16.ico");
351 registerImage(registry
, ITaxEditorConstants
.WARNING_ICON
,
353 registerImage(registry
, ITaxEditorConstants
.BLACK_SQUARE_ICON
,
354 "accepted_small.gif");
355 registerImage(registry
, ITaxEditorConstants
.HOMOTYPIC_SYN_ICON
,
356 "homosyn_no_bg.gif");
357 registerImage(registry
,
358 ITaxEditorConstants
.HOMOTYPIC_SYN_ORIGINAL_ICON
,
359 "homosyn_original_no_bg.gif");
360 registerImage(registry
, ITaxEditorConstants
.HETEROTYPIC_SYN_ICON
,
361 "heterosyn_no_bg.gif");
362 registerImage(registry
,
363 ITaxEditorConstants
.HETEROTYPIC_SYN_ORIGINAL_ICON
,
364 "heterosyn_original_no_bg.gif");
365 registerImage(registry
, ITaxEditorConstants
.MISAPPLIED_NAME_ICON
,
366 "misapplied_no_bg.gif");
367 registerImage(registry
, ITaxEditorConstants
.AUTONYM_ICON
,
368 "autonym_no_bg.gif");
369 registerImage(registry
, ITaxEditorConstants
.BASIONYM_ICON
,
370 "basionym_no_bg.gif");
371 registerImage(registry
, ITaxEditorConstants
.ORTHOGRAPHIC_VARIANT_ICON
,
372 "orthovariant_no_bg.gif");
373 registerImage(registry
, ITaxEditorConstants
.DB_ICON
, "db.gif");
374 registerImage(registry
, ITaxEditorConstants
.MOVE_ICON
,
375 "correction_change.gif");
376 registerImage(registry
, ITaxEditorConstants
.ACTIVE_DELETE_ICON
,
378 registerImage(registry
, ITaxEditorConstants
.SYNONYM_TO_TAXON_ICON
,
380 registerImage(registry
, ITaxEditorConstants
.OPEN_TAXON_ICON
, "open.gif");
381 registerImage(registry
, ITaxEditorConstants
.ADD_CHILD_TAXON_ICON
,
383 registerImage(registry
,
384 ITaxEditorConstants
.SWAP_SYNONYM_AND_TAXON_ICON
, "swap2.gif");
385 registerImage(registry
, ITaxEditorConstants
.QUICK_ADD_ICON
,
387 registerImage(registry
, ITaxEditorConstants
.TAXON_TO_SYNONYM_ICON
,
391 private void registerImage(ImageRegistry registry
, String key
,
394 IPath path
= new Path("icons/" + fileName
); //$NON-NLS-1$
395 URL url
= FileLocator
.find(getBundle(), path
, null);
397 ImageDescriptor desc
= ImageDescriptor
.createFromURL(url
);
398 registry
.put(key
, desc
);
400 } catch (Exception e
) {
404 /***************************************************************************
406 **************************************************************************/
407 private FontRegistry fontRegistry
;
409 private FontRegistry
getFontRegistry() {
410 if (fontRegistry
== null) {
411 fontRegistry
= new FontRegistry(Display
.getCurrent());
413 fontRegistry
.put(ITaxEditorConstants
.DATASOURCE_FONT
,
414 new FontData
[] { new FontData("Arial", 8, SWT
.NONE
) });
415 fontRegistry
.put(ITaxEditorConstants
.MENU_ITEM_ITALICS_FONT
,
416 new FontData
[] { new FontData("Arial", 9, SWT
.ITALIC
) });
417 fontRegistry
.put(ITaxEditorConstants
.ACCEPTED_TAXON_FONT
,
418 new FontData
[] { new FontData("Georgia", 12, SWT
.NONE
) });
419 fontRegistry
.put(ITaxEditorConstants
.SYNONYM_FONT
,
420 new FontData
[] { new FontData("Georgia", 10, SWT
.NONE
) });
421 fontRegistry
.put(ITaxEditorConstants
.MISAPPLIEDNAME_FONT
,
422 new FontData
[] { new FontData("Georgia", 10, SWT
.NONE
) });
423 fontRegistry
.put(ITaxEditorConstants
.CHOOSE_NAME_TEXT_FONT
,
424 new FontData
[] { new FontData("Arial", 12, SWT
.BOLD
) });
425 fontRegistry
.put(ITaxEditorConstants
.DEFAULT_PROMPT_FONT
,
426 new FontData
[] { new FontData("Georgia", 10, SWT
.ITALIC
) });
431 public Font
getFont(String key
) {
432 return getFontRegistry().get(key
);
435 /***************************************************************************
437 **************************************************************************/
438 private static HashMap
<String
, Color
> colorMap
;
440 public Color
getColor(String key
) {
441 return getColorMap().get(key
);
444 private HashMap
<String
, Color
> getColorMap() {
445 if (colorMap
== null) {
446 colorMap
= new HashMap
<String
, Color
>();
448 colorMap
.put(ITaxEditorConstants
.GROUP_GRAY_BKG_COLOR
,
449 new Color(null, 240, 240, 240));
454 private void disposeColors() {
455 if (colorMap
== null) {
458 for (Color color
: colorMap
.values()) {
464 /***************************************************************************
466 **************************************************************************/
468 public ReferenceBase
getSec() {
469 return getCdmApp().getReferenceService().getReferenceByUuid(
470 UUID
.fromString("f3593c18-a8d2-4e51-bdad-0befbf8fb2d1"));
473 private Set
<Taxon
> sessionRootTaxa
;
475 * The taxonomic tree content provider observes this set for changes, and
476 * makes the appropriate changes to the tree.
478 private IObservableSet observableSessionTaxonSet
;
480 * This map of taxa to their taxonomic children is used by
481 * NameTreeContentProvider's getChildren method.
483 * key = taxon, value = key's child taxa Note that a map can have a key ==
484 * null, i.e. no parent taxon
486 private HashMap
<Taxon
, Set
<Taxon
>> sessionTaxonomicChildrenMap
;
488 public Set
<Taxon
> getSessionRootTaxa() {
489 if (sessionRootTaxa
== null) {
491 sessionRootTaxa
= new HashSet
<Taxon
>();
492 sessionRootTaxa
.addAll(getCdmApp().getTaxonService().getRootTaxa(
493 getSec(), null, false));
494 // sessionRootTaxa.addAll(getCdmApp().getTaxonService().getRootTaxa(
495 // getSec(), null, true));
496 addSessionTaxa(sessionRootTaxa
);
499 return sessionRootTaxa
;
502 private Map
<Taxon
, Set
<Taxon
>> getTaxonomicChildrenMap() {
503 if (sessionTaxonomicChildrenMap
== null) {
504 sessionTaxonomicChildrenMap
= new HashMap
<Taxon
, Set
<Taxon
>>();
506 return sessionTaxonomicChildrenMap
;
510 * Returns a set of any child taxa for this taxon that have already been
511 * requested during this session.
516 public Set
<Taxon
> getSessionTaxonomicChildren(Taxon parentTaxon
) {
517 if (!getTaxonomicChildrenMap().containsKey(parentTaxon
)) {
518 if (parentTaxon
== null) {
519 getTaxonomicChildrenMap().put(parentTaxon
, getSessionRootTaxa());
522 // BUG deleted taxon were re-appearing as NULL children
523 Set
<Taxon
> childTaxa
= new HashSet
<Taxon
>();
525 // TransactionStatus tx = getCdmApp().startTransaction();
526 // getCdmApp().getTaxonService().saveTaxon(parentTaxon);
527 for (Taxon taxon
: parentTaxon
.getTaxonomicChildren()) {
529 childTaxa
.add(taxon
);
532 // getCdmApp().commitTransaction(tx);
534 getTaxonomicChildrenMap().put(parentTaxon
, childTaxa
);
537 return getTaxonomicChildrenMap().get(parentTaxon
);
543 public IObservableSet
getObservableSessionTaxa() {
544 if (observableSessionTaxonSet
== null) {
545 Realm realm
= SWTObservables
.getRealm(Display
.getDefault());
546 observableSessionTaxonSet
= new WritableSet(realm
);
548 return observableSessionTaxonSet
;
552 * Recursive function to clear the hashmap of a taxon's children used in
553 * this session, and the childrens' children, etc.
557 private void clearTaxonomicChildren(Taxon taxon
) {
558 Set
<Taxon
> children
= getSessionTaxonomicChildren(taxon
);
559 if (children
!= null) {
560 for (Taxon child
: children
) {
561 clearTaxonomicChildren(child
);
563 getTaxonomicChildrenMap().remove(taxon
);
564 getObservableSessionTaxa().removeAll(children
);
569 * Remove taxon from all session collections
573 public void removeSessionTaxon(Taxon taxon
) {
575 // Recursively remove all children, children's children, etc.
576 clearTaxonomicChildren(taxon
);
578 Taxon parentTaxon
= taxon
.getTaxonomicParent();
580 // Remove from parent's child map, or from root taxa
581 if (parentTaxon
== null) {
582 getSessionRootTaxa().remove(taxon
);
584 getSessionTaxonomicChildren(parentTaxon
).remove(taxon
);
587 // Remove from session taxa
588 getObservableSessionTaxa().remove(taxon
);
590 UiUtil
.getTreeViewer().remove(taxon
);
593 public void addSessionTaxa(Collection
<Taxon
> taxa
) {
594 for (Taxon taxon
: taxa
) {
595 addSessionTaxon(taxon
);
600 * Whenever a taxon is opened, either for editing or for display in the
601 * taxonomic tree, it should be added to the collections of taxa used during
606 public void addSessionTaxon(Taxon taxon
) {
608 // Add taxon to session taxa if not already there
609 if (!(getObservableSessionTaxa().contains(taxon
))) {
610 getObservableSessionTaxa().add(taxon
);
613 Taxon parentTaxon
= taxon
.getTaxonomicParent();
615 // If taxon has no parent, add it to root taxa
616 if (parentTaxon
== null) {
617 if (!(getSessionRootTaxa().contains(taxon
))) {
618 getSessionRootTaxa().add(taxon
);
622 // Add taxon to its parent's child map
623 getSessionTaxonomicChildren(parentTaxon
).add(taxon
);
625 TaxonomicTreeViewer viewer
= UiUtil
.getTreeViewer();
627 if (viewer
!= null) {
629 if (parentTaxon
== null) {
630 viewer
.setInput(getSessionRootTaxa());
632 viewer
.add(parentTaxon
, taxon
);
639 // private TaxonomicTreeView taxonomicTreeView;
641 // public void setTaxonomicTree(TaxonomicTreeView taxonomicTreeView) {
642 // this.taxonomicTreeView = taxonomicTreeView;
645 /***************************************************************************
647 **************************************************************************/
648 OrderedTermVocabulary
<Rank
> rankVocabulary
= null;
650 public OrderedTermVocabulary
<Rank
> getRankVocabulary() {
651 if (rankVocabulary
== null) {
652 rankVocabulary
= getCdmApp().getNameService().getRankVocabulary();
654 return rankVocabulary
;
657 /***************************************************************************
658 * NOMENCLATURAL STATUS
659 **************************************************************************/
660 TermVocabulary
<NomenclaturalStatusType
> nomStatusVocabulary
= null;
662 public TermVocabulary
<NomenclaturalStatusType
> getNomStatusVocabulary() {
663 if (nomStatusVocabulary
== null) {
664 nomStatusVocabulary
= getCdmApp().getNameService()
665 .getStatusTypeVocabulary();
667 return nomStatusVocabulary
;
670 /***************************************************************************
672 **************************************************************************/
673 TermVocabulary
<NameRelationshipType
> nameRelationshipTypeVocabulary
= null;
675 public TermVocabulary
<NameRelationshipType
> getNameRelationshipTypeVocabulary() {
676 if (nameRelationshipTypeVocabulary
== null) {
677 nameRelationshipTypeVocabulary
= getCdmApp().getNameService()
678 .getNameRelationshipTypeVocabulary();
680 return nameRelationshipTypeVocabulary
;
683 public Set
<NameRelationshipType
> getSortedNameRelationshipTypes() {
684 return getNameRelationshipTypeVocabulary().getTermsOrderedByLabels(
688 /***************************************************************************
690 **************************************************************************/
691 private Taxon
getSorayasGenusTaxon() {
693 String
[] children
= new String
[] {
694 "Heterospathe annectens H.E.Moore",
695 "Heterospathe arfakiana (Becc.) H.E.Moore",
696 "Heterospathe brevicaulis Fernando",
697 "Heterospathe cagayanensis Becc.",
698 "Heterospathe califrons Fernando, Palms 45: 118 (2001).",
699 "Heterospathe clemensiae (Burret) H.E.Moore",
700 "Heterospathe delicatula H.E.Moore",
701 "Heterospathe dransfieldii Fernando",
702 "Heterospathe elata Scheff.",
703 "Heterospathe elata var. elata.",
704 "Heterospathe elata var. guamensis Becc.",
705 "Heterospathe elata var. palauensis (Becc.) Becc.",
706 "Heterospathe elegans (Becc.) Becc.",
707 "Heterospathe elmeri Becc.",
708 "Heterospathe glabra (Burret) H.E.Moore",
709 "Heterospathe glauca (Scheff.) H.E.Moore",
710 "Heterospathe humilis Becc.",
711 "Heterospathe intermedia (Becc.) Fernando",
712 "Heterospathe kajewskii Burret",
713 "Heterospathe ledermanniana Becc.",
714 "Heterospathe lepidota H.E.Moore",
715 "Heterospathe longipes (H.E.Moore) Norup",
716 "Heterospathe macgregorii (Becc.) H.E.Moore",
717 "Heterospathe micrantha (Becc.) H.E.Moore",
718 "Heterospathe minor Burret",
719 "Heterospathe muelleriana (Becc.) Becc.",
720 "Heterospathe negrosensis Becc.",
721 "Heterospathe obriensis (Becc.) H.E.Moore",
722 "Heterospathe palauensis Becc.",
723 "Heterospathe parviflora Essig",
724 "Heterospathe philippinensis (Becc.) Becc.",
725 // "Heterospathe phillipsii D.Fuller & Dowe", // <--------------
726 "Heterospathe pilosa (Burret) Burret",
727 "Heterospathe pisifera (Gaertn.) Burret",
728 "Heterospathe pulchra H.E.Moore",
729 "Heterospathe ramulosa Burret",
730 "Heterospathe salomonensis Becc.",
731 "Heterospathe scitula Fernando", "Heterospathe sensisi Becc.",
732 "Heterospathe sibuyanensis Becc.",
733 "Heterospathe sphaerocarpa Burret",
734 "Heterospathe trispatha Fernando",
735 "Heterospathe uniformis Dowe",
736 "Heterospathe versteegiana Becc.",
737 "Heterospathe woodfordiana Becc." };
739 BotanicalName genusName
= BotanicalName
740 .PARSED_NAME("Heterospathe Scheff.");
742 Taxon genusTaxon
= Taxon
.NewInstance(genusName
, CdmUtil
743 .getSessionDefaultSec());
745 for (String child
: children
) {
746 BotanicalName speciesName
= BotanicalName
.PARSED_NAME(child
);
748 Taxon childTaxon
= Taxon
.NewInstance(speciesName
, CdmUtil
749 .getSessionDefaultSec());
750 childTaxon
.setTaxonomicParent(genusTaxon
, null, null);
752 if (child
.equals("Heterospathe elegans (Becc.) Becc.")) {
753 BotanicalName basionym
= BotanicalName
754 .PARSED_NAME("Barkerwebbia elegans Becc.");
755 speciesName
.addRelationshipFromName(basionym
,
756 NameRelationshipType
.BASIONYM(), null);
757 childTaxon
.addHomotypicSynonymName(basionym
, null, null);
760 if (child
.equals("Heterospathe humilis Becc.")) {
761 BotanicalName synonymName
= BotanicalName
762 .PARSED_NAME("Barkerwebbia humilis (Becc.) Becc. ex Martelli");
763 childTaxon
.addHomotypicSynonymName(synonymName
, null, null);