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
.Color
;
36 import org
.eclipse
.swt
.graphics
.Font
;
37 import org
.eclipse
.swt
.graphics
.FontData
;
38 import org
.eclipse
.swt
.graphics
.Image
;
39 import org
.eclipse
.swt
.widgets
.Display
;
40 import org
.eclipse
.ui
.forms
.FormColors
;
41 import org
.eclipse
.ui
.plugin
.AbstractUIPlugin
;
42 import org
.osgi
.framework
.BundleContext
;
43 import org
.springframework
.transaction
.TransactionStatus
;
45 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationController
;
46 import eu
.etaxonomy
.cdm
.api
.service
.IDescriptionService
;
47 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
48 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
49 import eu
.etaxonomy
.cdm
.database
.CdmDataSource
;
50 import eu
.etaxonomy
.cdm
.database
.DataSourceNotFoundException
;
51 import eu
.etaxonomy
.cdm
.database
.DbSchemaValidation
;
52 import eu
.etaxonomy
.cdm
.database
.ICdmDataSource
;
53 import eu
.etaxonomy
.cdm
.model
.agent
.Person
;
54 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
55 import eu
.etaxonomy
.cdm
.model
.common
.OrderedTermVocabulary
;
56 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
57 import eu
.etaxonomy
.cdm
.model
.common
.init
.TermNotFoundException
;
58 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
59 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
60 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationshipType
;
61 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
62 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
63 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
64 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
65 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
66 import eu
.etaxonomy
.taxeditor
.model
.CdmUtil
;
67 import eu
.etaxonomy
.taxeditor
.navigation
.TaxonomicTreeView
;
70 * The class controlling the plug-in life cycle.
73 * <li>Initializes datastore as necessary.</li>
74 * <li>Initializes default preferences.</li>
75 * <li>Gateway to CDM service layer.</li>
76 * <li>Stores taxa for application session.</li>
77 * <li>Stores registries for colors, fonts, images.</li>
84 public class TaxEditorPlugin
extends AbstractUIPlugin
{
85 private static final Logger logger
= Logger
86 .getLogger(TaxEditorPlugin
.class);
91 public static final String PLUGIN_ID
= "eu.etaxonomy.taxeditor.plugin";
95 private static TaxEditorPlugin plugin
;
97 // private DbSchemaValidation dbSchemaValidation = DbSchemaValidation.VALIDATE;
98 private DbSchemaValidation dbSchemaValidation
= DbSchemaValidation
.UPDATE
;
103 public TaxEditorPlugin() {
104 logger
.fatal("Fatal");
105 logger
.error("Error");
106 logger
.debug("Debug");
109 logger
.trace("Trace");
115 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
117 public void start(BundleContext context
) throws Exception
{
118 super.start(context
);
121 boolean initDatastore
= false;
123 // If the preferences INITIALIZED has not been set, the IF clause
124 // will return false, i.e. datastore will be initialized first
125 // time the application is run after being installed.
126 boolean initialized
= getPreferenceStore()
127 .getBoolean(ITaxEditorConstants
.INITIALIZED
);
129 // initialized = false; // to re-init db, uncomment this line
131 logger
.warn("Initializing datastore");
132 initDatastore
= true;
135 .setValue(ITaxEditorConstants
.INITIALIZED
, true);
137 logger
.warn("Datastore already initialized");
141 dbSchemaValidation
= DbSchemaValidation
.CREATE
;
145 cdmApp
= getCdmApp();
147 // if (initDatastore) {
156 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
158 public void stop(BundleContext context
) throws Exception
{
166 void initDatastore() {
168 boolean useSoraya
= true;
169 // useSoraya = false;
172 genusTaxon
= getSorayasGenusTaxon();
175 BotanicalName botanicalName
= BotanicalName
.NewInstance(Rank
177 botanicalName
.setTitleCache("Hieracium L.");
178 botanicalName
.setGenusOrUninomial("Hieracium");
179 botanicalName
.setCombinationAuthorTeam(Person
.NewInstance());
180 botanicalName
.getCombinationAuthorTeam()
181 .setNomenclaturalTitle("L.");
182 genusTaxon
= Taxon
.NewInstance(botanicalName
, CdmUtil
183 .getSessionDefaultSec());
185 BotanicalName botSpecies
= BotanicalName
186 .NewInstance(Rank
.SPECIES());
187 botSpecies
.setTitleCache("Hieracium asturianum Pau");
188 botSpecies
.setGenusOrUninomial("Hieracium");
189 botSpecies
.setSpecificEpithet("asturianum");
190 botSpecies
.setCombinationAuthorTeam(Person
.NewInstance());
191 botSpecies
.getCombinationAuthorTeam().setNomenclaturalTitle("Pau");
192 Taxon childTaxon
= Taxon
.NewInstance(botSpecies
, null);
193 childTaxon
.setTaxonomicParent(genusTaxon
, null, null);
195 BotanicalName botSpecies2
= BotanicalName
.NewInstance(Rank
197 botSpecies2
.setTitleCache("Hieracium wolffii Zahn");
198 botSpecies2
.setGenusOrUninomial("Hieracium");
199 botSpecies2
.setSpecificEpithet("wolffii");
200 botSpecies2
.setCombinationAuthorTeam(Person
.NewInstance());
201 botSpecies2
.getCombinationAuthorTeam()
202 .setNomenclaturalTitle("Zahn");
203 Taxon childTaxon2
= Taxon
.NewInstance(botSpecies2
, CdmUtil
204 .getSessionDefaultSec());
205 // childTaxon2.setName(botSpecies2);
206 // childTaxon2.setSec(null);
207 childTaxon2
.setTaxonomicParent(genusTaxon
, null, null);
209 // Add some name relations to botSpecies2
210 botSpecies2
.addRelationshipFromName(botSpecies
,
211 NameRelationshipType
.BASIONYM(), null);
212 botSpecies2
.addRelationshipToName(botSpecies
, NameRelationshipType
213 .REPLACED_SYNONYM(), null);
214 logger
.warn("Name relations created");
216 // Add name status to botSpecies2
217 botSpecies2
.addStatus(NomenclaturalStatus
218 .NewInstance(NomenclaturalStatusType
.NOVUM()));
219 logger
.warn("Nom. status created");
222 getCdmApp().getTaxonService().saveTaxon(genusTaxon
);
228 * Returns the shared instance
230 * @return the shared instance
232 public static TaxEditorPlugin
getDefault() {
236 /***************************************************************************
238 **************************************************************************/
240 * All CDM services are called via the application controller
242 private CdmApplicationController cdmApp
;
243 private TransactionStatus txStatus
;
245 public CdmApplicationController
getCdmApp() {
246 if (cdmApp
== null) {
249 CdmDataSource
.NewH2EmbeddedInstance("cdm", "sa", "");
250 // CdmDataSource.NewMySqlInstance("192.168.2.10", "cdm_test_andreasM2", "edit", "wp5");
252 // Is this the problem?
253 cdmApp
= CdmApplicationController
254 .NewInstance(ds
, dbSchemaValidation
);
257 // cdmApp = CdmApplicationController
258 // .NewInstance(dbSchemaValidation);
261 Object txStatus
= cdmApp
.startTransaction();
262 // cdmApp.commitTransaction((TransactionStatus) txStatus);
264 } catch (DataSourceNotFoundException e
) {
265 // TODO Auto-generated catch block
267 } catch (TermNotFoundException e
) {
268 // TODO Auto-generated catch block
275 public void startTransaction() {
276 if (cdmApp
!= null) {
277 txStatus
= cdmApp
.startTransaction();
281 public void stopTransaction() {
282 if (txStatus
!= null) {
283 cdmApp
.commitTransaction(txStatus
);
288 private ITaxonService taxonService
;
290 public ITaxonService
getTaxonService() {
291 if (taxonService
== null) {
292 taxonService
= getCdmApp().getTaxonService();
297 private INameService nameService
;
299 public INameService
getNameService() {
300 if (nameService
== null) {
301 nameService
= getCdmApp().getNameService();
306 private IDescriptionService descriptionService
;
308 public IDescriptionService
getDescriptionService() {
309 if (descriptionService
== null) {
310 descriptionService
= getCdmApp().getDescriptionService();
312 return descriptionService
;
316 /***************************************************************************
318 **************************************************************************/
320 private WritableList observableRecentNamesList
= null;
321 private WritableList observableFavoritesList
= null;
323 public WritableList
getObservableRecentNamesList() {
324 if (observableRecentNamesList
== null) {
325 observableRecentNamesList
= new WritableList();
327 return observableRecentNamesList
;
330 public WritableList
getObservableFavoritesList() {
331 if (observableFavoritesList
== null) {
332 observableFavoritesList
= new WritableList();
334 return observableFavoritesList
;
337 /***************************************************************************
339 **************************************************************************/
340 public ImageDescriptor
getImageDescriptor(String key
) {
341 return getImageRegistry().getDescriptor(key
);
344 public Image
getImage(String key
) {
345 return getImageRegistry().get(key
);
349 private ResourceBundle resourceBundle
;
350 private FormColors formColors
;
352 protected void initializeImageRegistry(ImageRegistry registry
) {
353 registerImage(registry
, ITaxEditorConstants
.EDIT_ICON
, "edit_16x16.ico");
354 registerImage(registry
, ITaxEditorConstants
.WARNING_ICON
,
356 registerImage(registry
, ITaxEditorConstants
.BLACK_SQUARE_ICON
,
357 "accepted_small.gif");
358 registerImage(registry
, ITaxEditorConstants
.HOMOTYPIC_SYN_ICON
,
359 "homosyn_no_bg.gif");
360 registerImage(registry
,
361 ITaxEditorConstants
.HOMOTYPIC_SYN_ORIGINAL_ICON
,
362 "homosyn_original_no_bg.gif");
363 registerImage(registry
, ITaxEditorConstants
.HETEROTYPIC_SYN_ICON
,
364 "heterosyn_no_bg.gif");
365 registerImage(registry
,
366 ITaxEditorConstants
.HETEROTYPIC_SYN_ORIGINAL_ICON
,
367 "heterosyn_original_no_bg.gif");
368 registerImage(registry
, ITaxEditorConstants
.MISAPPLIED_NAME_ICON
,
369 "misapplied_no_bg.gif");
370 registerImage(registry
, ITaxEditorConstants
.AUTONYM_ICON
,
371 "autonym_no_bg.gif");
372 registerImage(registry
, ITaxEditorConstants
.BASIONYM_ICON
,
373 "basionym_no_bg.gif");
374 registerImage(registry
, ITaxEditorConstants
.ORTHOGRAPHIC_VARIANT_ICON
,
375 "orthovariant_no_bg.gif");
376 registerImage(registry
, ITaxEditorConstants
.DB_ICON
, "db.gif");
377 registerImage(registry
, ITaxEditorConstants
.MOVE_ICON
,
378 "correction_change.gif");
379 registerImage(registry
, ITaxEditorConstants
.ACTIVE_DELETE_ICON
,
381 registerImage(registry
, ITaxEditorConstants
.SYNONYM_TO_TAXON_ICON
,
383 registerImage(registry
, ITaxEditorConstants
.OPEN_TAXON_ICON
, "open.gif");
384 registerImage(registry
, ITaxEditorConstants
.ADD_CHILD_TAXON_ICON
,
386 registerImage(registry
,
387 ITaxEditorConstants
.SWAP_SYNONYM_AND_TAXON_ICON
, "swap2.gif");
388 registerImage(registry
, ITaxEditorConstants
.QUICK_ADD_ICON
,
390 registerImage(registry
, ITaxEditorConstants
.TAXON_TO_SYNONYM_ICON
,
394 private void registerImage(ImageRegistry registry
, String key
,
397 IPath path
= new Path("icons/" + fileName
); //$NON-NLS-1$
398 URL url
= FileLocator
.find(getBundle(), path
, null);
400 ImageDescriptor desc
= ImageDescriptor
.createFromURL(url
);
401 registry
.put(key
, desc
);
403 } catch (Exception e
) {
407 /***************************************************************************
409 **************************************************************************/
410 private FontRegistry fontRegistry
;
412 private FontRegistry
getFontRegistry() {
413 if (fontRegistry
== null) {
414 fontRegistry
= new FontRegistry(Display
.getCurrent());
416 fontRegistry
.put(ITaxEditorConstants
.DATASOURCE_FONT
,
417 new FontData
[] { new FontData("Arial", 8, SWT
.NONE
) });
418 fontRegistry
.put(ITaxEditorConstants
.MENU_ITEM_ITALICS_FONT
,
419 new FontData
[] { new FontData("Arial", 9, SWT
.ITALIC
) });
420 fontRegistry
.put(ITaxEditorConstants
.ACCEPTED_TAXON_FONT
,
421 new FontData
[] { new FontData("Georgia", 12, SWT
.NONE
) });
422 fontRegistry
.put(ITaxEditorConstants
.SYNONYM_FONT
,
423 new FontData
[] { new FontData("Georgia", 10, SWT
.NONE
) });
424 fontRegistry
.put(ITaxEditorConstants
.MISAPPLIEDNAME_FONT
,
425 new FontData
[] { new FontData("Georgia", 10, SWT
.NONE
) });
426 fontRegistry
.put(ITaxEditorConstants
.CHOOSE_NAME_TEXT_FONT
,
427 new FontData
[] { new FontData("Arial", 12, SWT
.BOLD
) });
428 fontRegistry
.put(ITaxEditorConstants
.DEFAULT_PROMPT_FONT
,
429 new FontData
[] { new FontData("Georgia", 10, SWT
.ITALIC
) });
434 public Font
getFont(String key
) {
435 return getFontRegistry().get(key
);
438 /***************************************************************************
440 **************************************************************************/
441 private static HashMap
<String
, Color
> colorMap
;
443 public Color
getColor(String key
) {
444 return getColorMap().get(key
);
447 private HashMap
<String
, Color
> getColorMap() {
448 if (colorMap
== null) {
449 colorMap
= new HashMap
<String
, Color
>();
451 colorMap
.put(ITaxEditorConstants
.GROUP_GRAY_BKG_COLOR
,
452 new Color(null, 246, 246, 246));
457 private void disposeColors() {
458 for (Color color
: colorMap
.values()) {
464 /***************************************************************************
466 **************************************************************************/
468 * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeDefaultPreferences(org.eclipse.jface.preference.IPreferenceStore)
470 protected void initializeDefaultPreferences(IPreferenceStore store
) {
471 // Platform.getPreferencesService().getBoolean(qualifier, key,
472 // defaultValue, contexts)
473 store
.setDefault(ITaxEditorConstants
.CODE_PREFERENCE
,
474 ITaxEditorConstants
.DEFAULT_CODE_PREFERENCE
);
476 // Set preferences to display all features
477 TermVocabulary
<Feature
> features
= descriptionService
.getDefaultFeatureVocabulary();
478 for (Feature feature
: features
) {
479 String preferenceKey
= ITaxEditorConstants
.FEATURE_PREFERENCE
481 . concat(feature
.getUuid().toString());
482 store
.setDefault(preferenceKey
, true);
487 /***************************************************************************
489 **************************************************************************/
491 public ReferenceBase
getSec() {
492 return getCdmApp().getReferenceService().getReferenceByUuid(
493 UUID
.fromString("f3593c18-a8d2-4e51-bdad-0befbf8fb2d1"));
496 private Set
<Taxon
> sessionRootTaxa
;
498 * The taxonomic tree content provider observes this set for changes, and
499 * makes the appropriate changes to the tree.
501 private IObservableSet observableSessionTaxonSet
;
503 * This map of taxa to their taxonomic children is used by
504 * NameTreeContentProvider's getChildren method.
506 * key = taxon, value = key's child taxa Note that a map can have a key ==
507 * null, i.e. no parent taxon
509 private HashMap
<Taxon
, Set
<Taxon
>> sessionTaxonomicChildrenMap
;
511 public Set
<Taxon
> getSessionRootTaxa() {
512 if (sessionRootTaxa
== null) {
513 sessionRootTaxa
= new HashSet
<Taxon
>();
514 // sessionRootTaxa.addAll(getCdmApp().getTaxonService().getRootTaxa(
515 // getSec(), null, false));
516 sessionRootTaxa
.addAll(getCdmApp().getTaxonService().getRootTaxa(
517 getSec(), null, true));
518 addSessionTaxa(sessionRootTaxa
);
520 return sessionRootTaxa
;
523 private Map
<Taxon
, Set
<Taxon
>> getTaxonomicChildrenMap() {
524 if (sessionTaxonomicChildrenMap
== null) {
525 sessionTaxonomicChildrenMap
= new HashMap
<Taxon
, Set
<Taxon
>>();
527 return sessionTaxonomicChildrenMap
;
531 * Returns a set of any child taxa for this taxon that have already been
532 * requested during this session.
537 public Set
<Taxon
> getSessionTaxonomicChildren(Taxon parentTaxon
) {
538 if (!getTaxonomicChildrenMap().containsKey(parentTaxon
)) {
539 if (parentTaxon
== null) {
540 getTaxonomicChildrenMap().put(parentTaxon
, getSessionRootTaxa());
543 // BUG deleted taxon were re-appearing as NULL children
544 Set
<Taxon
> childTaxa
= new HashSet
<Taxon
>();
545 for (Taxon taxon
: parentTaxon
.getTaxonomicChildren()) {
547 childTaxa
.add(taxon
);
550 getTaxonomicChildrenMap().put(parentTaxon
, childTaxa
);
553 return getTaxonomicChildrenMap().get(parentTaxon
);
559 public IObservableSet
getObservableSessionTaxa() {
560 if (observableSessionTaxonSet
== null) {
561 Realm realm
= SWTObservables
.getRealm(Display
.getDefault());
562 observableSessionTaxonSet
= new WritableSet(realm
);
564 return observableSessionTaxonSet
;
568 * Recursive function to clear the hashmap of a taxon's children used in
569 * this session, and the childrens' children, etc.
573 private void clearTaxonomicChildren(Taxon taxon
) {
574 Set
<Taxon
> children
= getSessionTaxonomicChildren(taxon
);
575 if (children
!= null) {
576 for (Taxon child
: children
) {
577 clearTaxonomicChildren(child
);
579 getTaxonomicChildrenMap().remove(taxon
);
580 getObservableSessionTaxa().removeAll(children
);
585 * Remove taxon from all session collections
589 public void removeSessionTaxon(Taxon taxon
) {
591 // Recursively remove all children, children's children, etc.
592 clearTaxonomicChildren(taxon
);
594 Taxon parentTaxon
= taxon
.getTaxonomicParent();
596 // Remove from parent's child map, or from root taxa
597 if (parentTaxon
== null) {
598 getSessionRootTaxa().remove(taxon
);
600 getSessionTaxonomicChildren(parentTaxon
).remove(taxon
);
603 // Remove from session taxa
604 getObservableSessionTaxa().remove(taxon
);
606 UiUtil
.getTreeViewer().remove(taxon
);
609 public void addSessionTaxa(Collection
<Taxon
> taxa
) {
610 for (Taxon taxon
: taxa
) {
611 addSessionTaxon(taxon
);
616 * Whenever a taxon is opened, either for editing or for display in the
617 * taxonomic tree, it should be added to the collections of taxa used during
622 public void addSessionTaxon(Taxon taxon
) {
624 // Add taxon to session taxa if not already there
625 if (!(getObservableSessionTaxa().contains(taxon
))) {
626 getObservableSessionTaxa().add(taxon
);
629 Taxon parentTaxon
= taxon
.getTaxonomicParent();
631 // If taxon has no parent, add it to root taxa
632 if (parentTaxon
== null) {
633 if (!(getSessionRootTaxa().contains(taxon
))) {
634 getSessionRootTaxa().add(taxon
);
638 // Add taxon to its parent's child map
639 getSessionTaxonomicChildren(parentTaxon
).add(taxon
);
641 if (taxonomicTreeView
!= null) {
643 UiUtil
.getTreeViewer().remove(taxon
);
645 if (parentTaxon
== null) {
646 UiUtil
.getTreeViewer().setInput(getSessionRootTaxa());
648 UiUtil
.getTreeViewer().add(parentTaxon
, taxon
);
655 private TaxonomicTreeView taxonomicTreeView
;
657 public void setTaxonomicTree(TaxonomicTreeView taxonomicTreeView
) {
658 this.taxonomicTreeView
= taxonomicTreeView
;
661 /***************************************************************************
663 **************************************************************************/
664 OrderedTermVocabulary
<Rank
> rankVocabulary
= null;
666 public OrderedTermVocabulary
<Rank
> getRankVocabulary() {
667 if (rankVocabulary
== null) {
668 rankVocabulary
= getCdmApp().getNameService().getRankVocabulary();
670 return rankVocabulary
;
673 /***************************************************************************
674 * NOMENCLATURAL STATUS
675 **************************************************************************/
676 TermVocabulary
<NomenclaturalStatusType
> nomStatusVocabulary
= null;
678 public TermVocabulary
<NomenclaturalStatusType
> getNomStatusVocabulary() {
679 if (nomStatusVocabulary
== null) {
680 nomStatusVocabulary
= getCdmApp().getNameService()
681 .getStatusTypeVocabulary();
683 return nomStatusVocabulary
;
686 /***************************************************************************
688 **************************************************************************/
689 TermVocabulary
<NameRelationshipType
> nameRelationshipTypeVocabulary
= null;
691 public TermVocabulary
<NameRelationshipType
> getNameRelationshipTypeVocabulary() {
692 if (nameRelationshipTypeVocabulary
== null) {
693 nameRelationshipTypeVocabulary
= getCdmApp().getNameService()
694 .getNameRelationshipTypeVocabulary();
696 return nameRelationshipTypeVocabulary
;
699 public Set
<NameRelationshipType
> getSortedNameRelationshipTypes() {
700 return getNameRelationshipTypeVocabulary().getTermsOrderedByLabels(
704 /***************************************************************************
706 **************************************************************************/
707 private Taxon
getSorayasGenusTaxon() {
709 String
[] children
= new String
[] {
710 "Heterospathe annectens H.E.Moore",
711 "Heterospathe arfakiana (Becc.) H.E.Moore",
712 "Heterospathe brevicaulis Fernando",
713 "Heterospathe cagayanensis Becc.",
714 "Heterospathe califrons Fernando, Palms 45: 118 (2001).",
715 "Heterospathe clemensiae (Burret) H.E.Moore",
716 "Heterospathe delicatula H.E.Moore",
717 "Heterospathe dransfieldii Fernando",
718 "Heterospathe elata Scheff.",
719 "Heterospathe elata var. elata.",
720 "Heterospathe elata var. guamensis Becc.",
721 "Heterospathe elata var. palauensis (Becc.) Becc.",
722 "Heterospathe elegans (Becc.) Becc.",
723 "Heterospathe elmeri Becc.",
724 "Heterospathe glabra (Burret) H.E.Moore",
725 "Heterospathe glauca (Scheff.) H.E.Moore",
726 "Heterospathe humilis Becc.",
727 "Heterospathe intermedia (Becc.) Fernando",
728 "Heterospathe kajewskii Burret",
729 "Heterospathe ledermanniana Becc.",
730 "Heterospathe lepidota H.E.Moore",
731 "Heterospathe longipes (H.E.Moore) Norup",
732 "Heterospathe macgregorii (Becc.) H.E.Moore",
733 "Heterospathe micrantha (Becc.) H.E.Moore",
734 "Heterospathe minor Burret",
735 "Heterospathe muelleriana (Becc.) Becc.",
736 "Heterospathe negrosensis Becc.",
737 "Heterospathe obriensis (Becc.) H.E.Moore",
738 "Heterospathe palauensis Becc.",
739 "Heterospathe parviflora Essig",
740 "Heterospathe philippinensis (Becc.) Becc.",
741 // "Heterospathe phillipsii D.Fuller & Dowe", // <--------------
742 "Heterospathe pilosa (Burret) Burret",
743 "Heterospathe pisifera (Gaertn.) Burret",
744 "Heterospathe pulchra H.E.Moore",
745 "Heterospathe ramulosa Burret",
746 "Heterospathe salomonensis Becc.",
747 "Heterospathe scitula Fernando", "Heterospathe sensisi Becc.",
748 "Heterospathe sibuyanensis Becc.",
749 "Heterospathe sphaerocarpa Burret",
750 "Heterospathe trispatha Fernando",
751 "Heterospathe uniformis Dowe",
752 "Heterospathe versteegiana Becc.",
753 "Heterospathe woodfordiana Becc." };
755 BotanicalName genusName
= BotanicalName
756 .PARSED_NAME("Heterospathe Scheff.");
758 Taxon genusTaxon
= Taxon
.NewInstance(genusName
, CdmUtil
759 .getSessionDefaultSec());
761 for (String child
: children
) {
762 BotanicalName speciesName
= BotanicalName
.PARSED_NAME(child
);
764 Taxon childTaxon
= Taxon
.NewInstance(speciesName
, CdmUtil
765 .getSessionDefaultSec());
766 childTaxon
.setTaxonomicParent(genusTaxon
, null, null);
768 if (child
.equals("Heterospathe elegans (Becc.) Becc.")) {
769 BotanicalName basionym
= BotanicalName
770 .PARSED_NAME("Barkerwebbia elegans Becc.");
771 speciesName
.addRelationshipFromName(basionym
,
772 NameRelationshipType
.BASIONYM(), null);
773 childTaxon
.addHomotypicSynonymName(basionym
, null, null);
776 if (child
.equals("Heterospathe humilis Becc.")) {
777 BotanicalName synonymName
= BotanicalName
778 .PARSED_NAME("Barkerwebbia humilis (Becc.) Becc. ex Martelli");
779 childTaxon
.addHomotypicSynonymName(synonymName
, null, null);