Re-designed taxonomic tree content provider (currently set to TaxTreeContentProvider...
[taxeditor.git] / eclipseprojects / eu.etaxonomy.taxeditor / src / eu / etaxonomy / taxeditor / TaxEditorPlugin.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
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.
8 */
9
10 package eu.etaxonomy.taxeditor;
11
12 import java.net.URL;
13 import java.util.Collection;
14 import java.util.HashMap;
15 import java.util.HashSet;
16 import java.util.Map;
17 import java.util.ResourceBundle;
18 import java.util.Set;
19 import java.util.UUID;
20
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;
43
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;
63
64 /**
65 * The class controlling the plug-in life cycle.
66 *
67 * @author p.ciardelli
68 * @created 15.05.2008
69 * @version 1.0
70 */
71 public class TaxEditorPlugin extends AbstractUIPlugin {
72 private static final Logger logger = Logger
73 .getLogger(TaxEditorPlugin.class);
74
75 /**
76 * The plug-in ID
77 */
78 public static final String PLUGIN_ID = "eu.etaxonomy.taxeditor.plugin";
79 /**
80 * The shared instance
81 */
82 private static TaxEditorPlugin plugin;
83
84 private DbSchemaValidation dbSchemaValidation = DbSchemaValidation.VALIDATE;
85
86 /**
87 * The constructor
88 */
89 public TaxEditorPlugin() {
90 logger.fatal("Fatal");
91 logger.error("Error");
92 logger.debug("Debug");
93 logger.info("Info");
94 logger.warn("Warn");
95 logger.trace("Trace");
96 }
97
98 /*
99 * (non-Javadoc)
100 *
101 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
102 */
103 public void start(BundleContext context) throws Exception {
104 super.start(context);
105 plugin = this;
106
107 boolean initDatastore = false;
108
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);
114
115 // initialized = false;
116 if (!initialized) {
117 logger.warn("Initializing datastore");
118 initDatastore = true;
119
120 getPreferenceStore()
121 .setValue(ITaxEditorConstants.INITIALIZED, true);
122 } else {
123 logger.warn("Datastore already initialized");
124 }
125
126 if (initDatastore) {
127 dbSchemaValidation = DbSchemaValidation.CREATE;
128 }
129
130 cdmApp = getCdmApp();
131
132 // if (initDatastore) {
133 // initDatastore();
134 // }
135
136 }
137
138 /*
139 * (non-Javadoc)
140 *
141 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
142 */
143 public void stop(BundleContext context) throws Exception {
144 stopTransaction();
145 plugin = null;
146 super.stop(context);
147 }
148
149 void initDatastore() {
150
151 boolean useSoraya = true;
152 // useSoraya = false;
153 Taxon genusTaxon;
154 if (useSoraya) {
155 genusTaxon = getSorayasGenusTaxon();
156 } else {
157
158 BotanicalName botanicalName = BotanicalName.NewInstance(Rank
159 .GENUS());
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());
167
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);
177
178 BotanicalName botSpecies2 = BotanicalName.NewInstance(Rank
179 .SPECIES());
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);
191
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");
198
199 // Add name status to botSpecies2
200 botSpecies2.addStatus(NomenclaturalStatus
201 .NewInstance(NomenclaturalStatusType.NOVUM()));
202 logger.warn("Nom. status created");
203 }
204
205 getCdmApp().getTaxonService().saveTaxon(genusTaxon);
206
207 // System.exit(-1);
208 }
209
210 /**
211 * Returns the shared instance
212 *
213 * @return the shared instance
214 */
215 public static TaxEditorPlugin getDefault() {
216 return plugin;
217 }
218
219 /***************************************************************************
220 * CDM SERVICES
221 **************************************************************************/
222 /**
223 * All CDM services are called via the application controller
224 */
225 private CdmApplicationController cdmApp;
226 private TransactionStatus txStatus;
227
228 public CdmApplicationController getCdmApp() {
229 if (cdmApp == null) {
230 try {
231 // ICdmDataSource ds =
232 // CdmDataSource.NewH2EmbeddedInstance("cdm", "sa", "");
233 // cdmApp = CdmApplicationController
234 // .NewInstance(ds, dbSchemaValidation);
235 cdmApp = CdmApplicationController
236 .NewInstance(dbSchemaValidation);
237
238 startTransaction();
239 // Object txStatus = cdmApp.startTransaction();
240 // cdmApp.commitTransaction((TransactionStatus) txStatus);
241
242 } catch (DataSourceNotFoundException e) {
243 // TODO Auto-generated catch block
244 e.printStackTrace();
245 } catch (TermNotFoundException e) {
246 // TODO Auto-generated catch block
247 e.printStackTrace();
248 }
249 }
250 return cdmApp;
251 }
252
253 public void startTransaction() {
254 if (cdmApp != null) {
255 txStatus = cdmApp.startTransaction();
256 }
257 }
258
259 public void stopTransaction() {
260 if (txStatus != null) {
261 cdmApp.commitTransaction(txStatus);
262 txStatus = null;
263 }
264 }
265
266 private ITaxonService taxonService;
267
268 public ITaxonService getTaxonService() {
269 if (taxonService == null) {
270 taxonService = getCdmApp().getTaxonService();
271 }
272 return taxonService;
273 }
274
275 private INameService nameService;
276
277 public INameService getNameService() {
278 if (nameService == null) {
279 nameService = getCdmApp().getNameService();
280 }
281 return nameService;
282 }
283
284 /***************************************************************************
285 * OBSERVABLE LISTS
286 **************************************************************************/
287
288 private WritableList observableRecentNamesList = null;
289 private WritableList observableFavoritesList = null;
290
291 public WritableList getObservableRecentNamesList() {
292 if (observableRecentNamesList == null) {
293 observableRecentNamesList = new WritableList();
294 }
295 return observableRecentNamesList;
296 }
297
298 public WritableList getObservableFavoritesList() {
299 if (observableFavoritesList == null) {
300 observableFavoritesList = new WritableList();
301 }
302 return observableFavoritesList;
303 }
304
305 /***************************************************************************
306 * IMAGE REGISTRY
307 **************************************************************************/
308 public ImageDescriptor getImageDescriptor(String key) {
309 return getImageRegistry().getDescriptor(key);
310 }
311
312 public Image getImage(String key) {
313 return getImageRegistry().get(key);
314 }
315
316 // Resource bundle.
317 private ResourceBundle resourceBundle;
318 private FormColors formColors;
319
320 protected void initializeImageRegistry(ImageRegistry registry) {
321 registerImage(registry, ITaxEditorConstants.EDIT_ICON, "edit_16x16.ico");
322 registerImage(registry, ITaxEditorConstants.WARNING_ICON,
323 "warn_tsk.gif");
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,
348 "delete_edit.gif");
349 registerImage(registry, ITaxEditorConstants.SYNONYM_TO_TAXON_ICON,
350 "change.gif");
351 registerImage(registry, ITaxEditorConstants.OPEN_TAXON_ICON, "open.gif");
352 registerImage(registry, ITaxEditorConstants.ADD_CHILD_TAXON_ICON,
353 "new_child.gif");
354 registerImage(registry,
355 ITaxEditorConstants.SWAP_SYNONYM_AND_TAXON_ICON, "swap2.gif");
356 registerImage(registry, ITaxEditorConstants.QUICK_ADD_ICON,
357 "quick_add.gif");
358 registerImage(registry, ITaxEditorConstants.TAXON_TO_SYNONYM_ICON,
359 "tax_to_syn.gif");
360 }
361
362 private void registerImage(ImageRegistry registry, String key,
363 String fileName) {
364 try {
365 IPath path = new Path("icons/" + fileName); //$NON-NLS-1$
366 URL url = FileLocator.find(getBundle(), path, null);
367 if (url != null) {
368 ImageDescriptor desc = ImageDescriptor.createFromURL(url);
369 registry.put(key, desc);
370 }
371 } catch (Exception e) {
372 }
373 }
374
375 /***************************************************************************
376 * FONT REGISTRY
377 **************************************************************************/
378 private FontRegistry fontRegistry;
379
380 private FontRegistry getFontRegistry() {
381 if (fontRegistry == null) {
382 fontRegistry = new FontRegistry(Display.getCurrent());
383
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) });
396 }
397 return fontRegistry;
398 }
399
400 public Font getFont(String key) {
401 return getFontRegistry().get(key);
402 }
403
404 /***************************************************************************
405 * PREFERENCES
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);
412 }
413
414 /***************************************************************************
415 * TAXONOMIC TREE
416 **************************************************************************/
417
418 public ReferenceBase getSec() {
419 return getCdmApp().getReferenceService().getReferenceByUuid(
420 UUID.fromString("f3593c18-a8d2-4e51-bdad-0befbf8fb2d1"));
421 }
422
423 // private List<Taxon> sessionRootTaxa;
424 private Set<Taxon> sessionRootTaxa;
425 /**
426 * The taxonomic tree content provider observes this set for changes, and
427 * makes the appropriate changes to the tree.
428 */
429 private IObservableSet observableSessionTaxonSet;
430 /**
431 * This map of taxa to their taxonomic children is used by
432 * NameTreeContentProvider's getChildren method.
433 *
434 * key = taxon, value = key's child taxa Note that a map can have a key ==
435 * null, i.e. no parent taxon
436 */
437 private HashMap<Taxon, Set<Taxon>> sessionTaxonomicChildrenMap;
438
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);
447 }
448 logger.warn(sessionRootTaxa.size() + " taxa in root taxa");
449 return sessionRootTaxa;
450 }
451
452 private Map<Taxon, Set<Taxon>> getTaxonomicChildrenMap() {
453 if (sessionTaxonomicChildrenMap == null) {
454 sessionTaxonomicChildrenMap = new HashMap<Taxon, Set<Taxon>>();
455 }
456 return sessionTaxonomicChildrenMap;
457 }
458
459 /**
460 * Returns a set of any child taxa for this taxon that have already been
461 * requested during this session.
462 *
463 * @param parentTaxon
464 * @return
465 */
466 public Set<Taxon> getSessionTaxonomicChildren(Taxon parentTaxon) {
467 if (!getTaxonomicChildrenMap().containsKey(parentTaxon)) {
468 if (parentTaxon == null) {
469 getTaxonomicChildrenMap().put(parentTaxon, getSessionRootTaxa());
470 } else {
471
472 // BUG deleted taxon where re-appearing as NULL children
473 Set<Taxon> childTaxa = new HashSet<Taxon>();
474 for (Taxon taxon : parentTaxon.getTaxonomicChildren()) {
475 if (taxon != null) {
476 childTaxa.add(taxon);
477 }
478 }
479 getTaxonomicChildrenMap().put(parentTaxon, childTaxa);
480 }
481 }
482 return getTaxonomicChildrenMap().get(parentTaxon);
483 }
484
485 /**
486 * @return
487 */
488 public IObservableSet getObservableSessionTaxa() {
489 if (observableSessionTaxonSet == null) {
490 Realm realm = SWTObservables.getRealm(Display.getDefault());
491 observableSessionTaxonSet = new WritableSet(realm);
492 }
493 return observableSessionTaxonSet;
494 }
495
496 /**
497 * Recursive function to clear the hashmap of a taxon's children used in
498 * this session, and the childrens' children, etc.
499 *
500 * @param taxon
501 */
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);
509 }
510 getTaxonomicChildrenMap().remove(taxon);
511 getObservableSessionTaxa().removeAll(children);
512 }
513 }
514
515 /**
516 * Remove taxon from all session collections
517 *
518 * @param taxon
519 */
520 public void removeSessionTaxon(Taxon taxon) {
521
522 // Recursively remove all children, children's children, etc.
523 clearTaxonomicChildren(taxon);
524
525 Taxon parentTaxon = taxon.getTaxonomicParent();
526
527 // Remove from parent's child map, or from root taxa
528 if (parentTaxon == null) {
529 getSessionRootTaxa().remove(taxon);
530 } else {
531 getSessionTaxonomicChildren(parentTaxon).remove(taxon);
532 }
533
534 // Remove from session taxa
535 getObservableSessionTaxa().remove(taxon);
536
537 UiUtil.getTreeViewer().remove(taxon);
538 }
539
540 public void addSessionTaxa(Collection<Taxon> taxa) {
541 for (Taxon taxon : taxa) {
542 addSessionTaxon(taxon);
543 }
544 }
545
546 /**
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
549 * this session.
550 *
551 * @param taxon
552 */
553 public void addSessionTaxon(Taxon taxon) {
554
555 // Add taxon to session taxa if not already there
556 if (!(getObservableSessionTaxa().contains(taxon))) {
557 getObservableSessionTaxa().add(taxon);
558 }
559
560 Taxon parentTaxon = taxon.getTaxonomicParent();
561
562 // If taxon has no parent, add it to root taxa
563 if (parentTaxon == null) {
564 if (!(getSessionRootTaxa().contains(taxon))) {
565 getSessionRootTaxa().add(taxon);
566 }
567 }
568
569 // Add taxon to its parent's child map
570 getSessionTaxonomicChildren(parentTaxon).add(taxon);
571
572 if (taxonomicTreeView != null) {
573
574 UiUtil.getTreeViewer().remove(taxon);
575
576 if (parentTaxon == null) {
577 logger.warn("Resetting input");
578 UiUtil.getTreeViewer().setInput(getSessionRootTaxa());
579 } else {
580 UiUtil.getTreeViewer().add(parentTaxon, taxon);
581 }
582
583 }
584 }
585
586
587 private TaxonomicTreeView taxonomicTreeView;
588
589 public void setTaxonomicTree(TaxonomicTreeView taxonomicTreeView) {
590 this.taxonomicTreeView = taxonomicTreeView;
591 }
592
593 /***************************************************************************
594 * RANKS
595 **************************************************************************/
596 OrderedTermVocabulary<Rank> rankVocabulary = null;
597
598 public OrderedTermVocabulary<Rank> getRankVocabulary() {
599 if (rankVocabulary == null) {
600 rankVocabulary = getCdmApp().getNameService().getRankVocabulary();
601 }
602 return rankVocabulary;
603 }
604
605 /***************************************************************************
606 * NOMENCLATURAL STATUS
607 **************************************************************************/
608 TermVocabulary<NomenclaturalStatusType> nomStatusVocabulary = null;
609
610 public TermVocabulary<NomenclaturalStatusType> getNomStatusVocabulary() {
611 if (nomStatusVocabulary == null) {
612 nomStatusVocabulary = getCdmApp().getNameService()
613 .getStatusTypeVocabulary();
614 }
615 return nomStatusVocabulary;
616 }
617
618 /***************************************************************************
619 * NAME RELATIONS
620 **************************************************************************/
621 TermVocabulary<NameRelationshipType> nameRelationshipTypeVocabulary = null;
622
623 public TermVocabulary<NameRelationshipType> getNameRelationshipTypeVocabulary() {
624 if (nameRelationshipTypeVocabulary == null) {
625 nameRelationshipTypeVocabulary = getCdmApp().getNameService()
626 .getNameRelationshipTypeVocabulary();
627 }
628 return nameRelationshipTypeVocabulary;
629 }
630
631 public Set<NameRelationshipType> getSortedNameRelationshipTypes() {
632 return getNameRelationshipTypeVocabulary().getTermsOrderedByLabels(
633 Language.DEFAULT());
634 }
635
636 /***************************************************************************
637 * SORAYA DATA
638 **************************************************************************/
639 private Taxon getSorayasGenusTaxon() {
640
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." };
686
687 BotanicalName genusName = BotanicalName
688 .PARSED_NAME("Heterospathe Scheff.");
689
690 Taxon genusTaxon = Taxon.NewInstance(genusName, CdmUtil
691 .getSessionDefaultSec());
692
693 for (String child : children) {
694 BotanicalName speciesName = BotanicalName.PARSED_NAME(child);
695
696 Taxon childTaxon = Taxon.NewInstance(speciesName, CdmUtil
697 .getSessionDefaultSec());
698 childTaxon.setTaxonomicParent(genusTaxon, null, null);
699
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);
706 }
707
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);
712 }
713 }
714
715 return genusTaxon;
716 }
717 }