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
.ArrayList
;
14 import java
.util
.Collection
;
15 import java
.util
.HashMap
;
16 import java
.util
.HashSet
;
17 import java
.util
.List
;
19 import java
.util
.ResourceBundle
;
21 import java
.util
.UUID
;
23 import org
.apache
.log4j
.Logger
;
24 import org
.eclipse
.core
.databinding
.observable
.Realm
;
25 import org
.eclipse
.core
.databinding
.observable
.list
.WritableList
;
26 import org
.eclipse
.core
.databinding
.observable
.set
.IObservableSet
;
27 import org
.eclipse
.core
.databinding
.observable
.set
.WritableSet
;
28 import org
.eclipse
.core
.runtime
.FileLocator
;
29 import org
.eclipse
.core
.runtime
.IPath
;
30 import org
.eclipse
.core
.runtime
.Path
;
31 import org
.eclipse
.jface
.databinding
.swt
.SWTObservables
;
32 import org
.eclipse
.jface
.preference
.IPreferenceStore
;
33 import org
.eclipse
.jface
.resource
.FontRegistry
;
34 import org
.eclipse
.jface
.resource
.ImageDescriptor
;
35 import org
.eclipse
.jface
.resource
.ImageRegistry
;
36 import org
.eclipse
.swt
.SWT
;
37 import org
.eclipse
.swt
.graphics
.Font
;
38 import org
.eclipse
.swt
.graphics
.FontData
;
39 import org
.eclipse
.swt
.graphics
.Image
;
40 import org
.eclipse
.swt
.widgets
.Display
;
41 import org
.eclipse
.ui
.forms
.FormColors
;
42 import org
.eclipse
.ui
.plugin
.AbstractUIPlugin
;
43 import org
.osgi
.framework
.BundleContext
;
45 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationController
;
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
.OrderedTermVocabulary
;
51 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
52 import eu
.etaxonomy
.cdm
.model
.common
.init
.TermNotFoundException
;
53 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
54 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationshipType
;
55 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
56 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
57 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
58 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
59 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
60 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
61 import eu
.etaxonomy
.taxeditor
.model
.CdmUtil
;
64 * The class controlling the plug-in life cycle.
70 public class TaxEditorPlugin
extends AbstractUIPlugin
{
71 private static final Logger logger
= Logger
.getLogger(TaxEditorPlugin
.class);
76 public static final String PLUGIN_ID
= "eu.etaxonomy.taxeditor.plugin";
80 private static TaxEditorPlugin plugin
;
82 private DbSchemaValidation dbSchemaValidation
= DbSchemaValidation
.VALIDATE
;
86 public TaxEditorPlugin() {
87 logger
.fatal("Fatal");
88 logger
.error("Error");
89 logger
.debug("Debug");
92 logger
.trace("Trace");
94 boolean initDatastore
= false;
95 // initDatastore = true;
97 dbSchemaValidation
= DbSchemaValidation
.CREATE
;
100 cdmApp
= getCdmApp();
108 void initDatastore() {
110 boolean useSoraya
= true;
111 // useSoraya = false;
114 genusTaxon
= getSorayasGenusTaxon();
117 BotanicalName botanicalName
= BotanicalName
.NewInstance(Rank
.GENUS());
118 botanicalName
.setTitleCache("Hieracium L.");
119 botanicalName
.setGenusOrUninomial("Hieracium");
120 botanicalName
.setCombinationAuthorTeam(Person
.NewInstance());
121 botanicalName
.getCombinationAuthorTeam().setNomenclaturalTitle("L.");
122 genusTaxon
= Taxon
.NewInstance(botanicalName
, CdmUtil
.getSessionDefaultSec());
124 BotanicalName botSpecies
= BotanicalName
.NewInstance(Rank
.SPECIES());
125 botSpecies
.setTitleCache("Hieracium asturianum Pau");
126 botSpecies
.setGenusOrUninomial("Hieracium");
127 botSpecies
.setSpecificEpithet("asturianum");
128 botSpecies
.setCombinationAuthorTeam(Person
.NewInstance());
129 botSpecies
.getCombinationAuthorTeam().setNomenclaturalTitle("Pau");
130 Taxon childTaxon
= Taxon
.NewInstance(botSpecies
, null);
131 childTaxon
.setTaxonomicParent(genusTaxon
, null, null);
133 BotanicalName botSpecies2
= BotanicalName
.NewInstance(Rank
.SPECIES());
134 botSpecies2
.setTitleCache("Hieracium wolffii Zahn");
135 botSpecies2
.setGenusOrUninomial("Hieracium");
136 botSpecies2
.setSpecificEpithet("wolffii");
137 botSpecies2
.setCombinationAuthorTeam(Person
.NewInstance());
138 botSpecies2
.getCombinationAuthorTeam().setNomenclaturalTitle("Zahn");
139 Taxon childTaxon2
= Taxon
.NewInstance(botSpecies2
, CdmUtil
.getSessionDefaultSec());
140 // childTaxon2.setName(botSpecies2);
141 // childTaxon2.setSec(null);
142 childTaxon2
.setTaxonomicParent(genusTaxon
, null, null);
144 // Add some name relations to botSpecies2
145 botSpecies2
.addRelationshipFromName(botSpecies
, NameRelationshipType
.BASIONYM(), null);
146 botSpecies2
.addRelationshipToName(botSpecies
, NameRelationshipType
.REPLACED_SYNONYM(), null);
147 logger
.warn("Name relations created");
149 // Add name status to botSpecies2
150 botSpecies2
.addStatus(NomenclaturalStatus
.NewInstance(NomenclaturalStatusType
.NOVUM()));
151 logger
.warn("Nom. status created");
154 getCdmApp().getTaxonService().saveTaxon(genusTaxon
);
161 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
163 public void start(BundleContext context
) throws Exception
{
164 super.start(context
);
170 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
172 public void stop(BundleContext context
) throws Exception
{
178 * Returns the shared instance
180 * @return the shared instance
182 public static TaxEditorPlugin
getDefault() {
186 /* ***************************************************************************************
188 ************************************************************************************** */
190 * All CDM services are called via the application controller
192 private CdmApplicationController cdmApp
;
194 public CdmApplicationController
getCdmApp() {
195 if (cdmApp
== null) {
197 cdmApp
= CdmApplicationController
.NewInstance(dbSchemaValidation
);
198 } catch (DataSourceNotFoundException e
) {
199 // TODO Auto-generated catch block
201 } catch (TermNotFoundException e
) {
202 // TODO Auto-generated catch block
209 private ITaxonService taxonService
;
211 public ITaxonService
getTaxonService() {
212 if (taxonService
== null) {
213 taxonService
= getCdmApp().getTaxonService();
218 /* ***************************************************************************************
220 ************************************************************************************** */
222 * The dataset of taxa for this session
224 private WritableList observableTaxonTreeList
= null;
226 * Keeps track of which taxa have been opened for editing
228 private WritableList observableRecentNamesList
= null;
229 public WritableSet observableSynonymSet
= null;
230 private WritableList observableFavoritesList
= null;
231 public WritableList
getObservableTaxonTreeList() {
232 if (observableTaxonTreeList
== null) {
233 observableTaxonTreeList
= new WritableList();
234 ReferenceBase sec
= getCdmApp().getReferenceService().getReferenceByUuid(UUID
.fromString("f3593c18-a8d2-4e51-bdad-0befbf8fb2d1"));
235 observableTaxonTreeList
.addAll(getCdmApp().getTaxonService().getRootTaxa(sec
));
237 return observableTaxonTreeList
;
240 public WritableList
getObservableRecentNamesList() {
241 if (observableRecentNamesList
== null) {
242 observableRecentNamesList
= new WritableList();
244 return observableRecentNamesList
;
248 public WritableList
getObservableFavoritesList() {
249 if (observableFavoritesList
== null) {
250 observableFavoritesList
= new WritableList();
252 return observableFavoritesList
;
255 public WritableSet
getObservableSynonymSet() {
256 if (observableSynonymSet
== null) {
257 observableSynonymSet
= new WritableSet();
259 return observableSynonymSet
;
262 /* ***************************************************************************************
264 ************************************************************************************** */
265 public ImageDescriptor
getImageDescriptor(String key
) {
266 return getImageRegistry().getDescriptor(key
);
269 public Image
getImage(String key
) {
270 return getImageRegistry().get(key
);
273 private ResourceBundle resourceBundle
;
274 private FormColors formColors
;
276 protected void initializeImageRegistry(ImageRegistry registry
) {
277 registerImage(registry
, ITaxEditorConstants
.EDIT_ICON
, "edit_16x16.ico"); //$NON-NLS-1$
278 registerImage(registry
, ITaxEditorConstants
.WARNING_ICON
, "warn_tsk.gif"); //$NON-NLS-1$
279 registerImage(registry
, ITaxEditorConstants
.ACCEPTED_TAXON_ICON
, "accepted_small.gif"); //$NON-NLS-1$
280 registerImage(registry
, ITaxEditorConstants
.HOMOTYPIC_SYN_ICON
, "homosyn_no_bg.gif"); //$NON-NLS-1$
281 registerImage(registry
, ITaxEditorConstants
.HOMOTYPIC_SYN_ORIGINAL_ICON
, "homosyn_original_no_bg.gif"); //$NON-NLS-1$
282 registerImage(registry
, ITaxEditorConstants
.HETEROTYPIC_SYN_ICON
, "heterosyn_no_bg.gif"); //$NON-NLS-1$
283 registerImage(registry
, ITaxEditorConstants
.HETEROTYPIC_SYN_ORIGINAL_ICON
, "heterosyn_original_no_bg.gif"); //$NON-NLS-1$
284 registerImage(registry
, ITaxEditorConstants
.MISAPPLIED_NAME_ICON
, "misapplied_no_bg.gif"); //$NON-NLS-1$
285 registerImage(registry
, ITaxEditorConstants
.AUTONYM_ICON
, "autonym_no_bg.gif"); //$NON-NLS-1$
286 registerImage(registry
, ITaxEditorConstants
.BASIONYM_ICON
, "basionym_no_bg.gif"); //$NON-NLS-1$
287 registerImage(registry
, ITaxEditorConstants
.DB_ICON
, "db.gif"); //$NON-NLS-1$
288 registerImage(registry
, ITaxEditorConstants
.MOVE_ICON
, "move_no_bg.gif"); //$NON-NLS-1$
290 private void registerImage(ImageRegistry registry
, String key
,
293 IPath path
= new Path("icons/" + fileName
); //$NON-NLS-1$
294 URL url
= FileLocator
.find(getBundle(), path
, null);
296 ImageDescriptor desc
= ImageDescriptor
.createFromURL(url
);
297 registry
.put(key
, desc
);
299 } catch (Exception e
) {
303 /* ***************************************************************************************
305 ************************************************************************************** */
306 private FontRegistry fontRegistry
;
308 private FontRegistry
getFontRegistry() {
309 if (fontRegistry
== null) {
310 fontRegistry
= new FontRegistry(Display
.getCurrent());
312 fontRegistry
.put(ITaxEditorConstants
.MENU_ITEM_ITALICS
, new FontData
[]{new FontData("Arial", 9, SWT
.ITALIC
)});
313 fontRegistry
.put(ITaxEditorConstants
.ACCEPTED_TAXON_FONT
, new FontData
[]{new FontData("Georgia", 12, SWT
.NONE
)});
314 fontRegistry
.put(ITaxEditorConstants
.SYNONYM_FONT
, new FontData
[]{new FontData("Georgia", 10, SWT
.NONE
)});
315 fontRegistry
.put(ITaxEditorConstants
.MISAPPLIEDNAME_FONT
, new FontData
[]{new FontData("Georgia", 10, SWT
.NONE
)});
320 public Font
getFont(String key
) {
321 return getFontRegistry().get(key
);
324 /* ***************************************************************************************
326 ************************************************************************************** */
327 protected void initializeDefaultPreferences(IPreferenceStore store
) {
328 store
.setDefault(ITaxEditorConstants
.CODE_PREFERENCE
, ITaxEditorConstants
.DEFAULT_CODE_PREFERENCE
);
331 /* ***************************************************************************************
333 ************************************************************************************** */
335 public ReferenceBase
getSec() {
336 return getCdmApp().getReferenceService().getReferenceByUuid(UUID
.fromString("f3593c18-a8d2-4e51-bdad-0befbf8fb2d1"));
339 private List
<Taxon
> rootTaxa
;
341 public List
<Taxon
> getSessionRootTaxa() {
342 if (rootTaxa
== null) {
343 rootTaxa
= new ArrayList
<Taxon
>();
344 rootTaxa
.addAll(getCdmApp().getTaxonService().getRootTaxa(getSec()));
350 * This map of taxa to their taxonomic children is used by
351 * NameTreeContentProvider's getChildren method.
353 * key = taxon, value = key's child taxa
354 * Note that a map can have a key == null, i.e. no parent taxon
356 private HashMap
<Taxon
, Set
<Taxon
>> taxonomicChildrenMap
;
357 private IObservableSet observableTaxonSet
;
359 private Map
<Taxon
, Set
<Taxon
>> getTaxonomicChildrenMap() {
360 if (taxonomicChildrenMap
== null) {
361 taxonomicChildrenMap
= new HashMap
<Taxon
, Set
<Taxon
>>();
362 for (Taxon rootTaxon
: getSessionRootTaxa()) {
363 taxonomicChildrenMap
.put(rootTaxon
, rootTaxon
.getTaxonomicChildren());
366 return taxonomicChildrenMap
;
370 * Returns any child taxa for this taxon that have already been requested during
376 public Set
<Taxon
> getSessionTaxonomicChildren(Taxon parentTaxon
) {
377 return TaxEditorPlugin
.getDefault().getTaxonomicChildrenMap().get(parentTaxon
);
380 private void addSessionTaxonomicChildren(Taxon parentTaxon
,
381 Set
<Taxon
> childTaxa
) {
382 Set
<Taxon
> sessionChildTaxa
= getSessionTaxonomicChildren(parentTaxon
);
383 if (sessionChildTaxa
== null) {
384 getTaxonomicChildrenMap().put(parentTaxon
, childTaxa
);
386 sessionChildTaxa
.addAll(childTaxa
);
390 private void addSessionTaxonomicChild(Taxon parentTaxon
,
392 Set
<Taxon
> childTaxa
= new HashSet
<Taxon
>();
393 childTaxa
.add(childTaxon
);
394 addSessionTaxonomicChildren(parentTaxon
, childTaxa
);
397 public IObservableSet
getObservableSessionTaxa() {
398 if (observableTaxonSet
== null) {
399 Realm realm
= SWTObservables
.getRealm(Display
.getDefault());
400 observableTaxonSet
= new WritableSet(realm
);
402 return observableTaxonSet
;
405 public void removeSessionTaxon(Taxon taxon
) {
406 getObservableSessionTaxa().remove(taxon
);
407 Taxon parentTaxon
= taxon
.getTaxonomicParent();
408 Set
<Taxon
> children
= getSessionTaxonomicChildren(parentTaxon
);
409 if (children
!= null) {
410 children
.remove(taxon
);
414 public void addSessionTaxa(Collection
<Taxon
> taxa
) {
415 getObservableSessionTaxa().addAll(taxa
);
416 for (Taxon taxon
: taxa
) {
417 addSessionTaxonomicChild(taxon
.getTaxonomicParent(), taxon
);
421 public void addSessionTaxon(Taxon taxon
) {
422 getObservableSessionTaxa().add(taxon
);
423 addSessionTaxonomicChild(taxon
.getTaxonomicParent(), taxon
);
426 /* ***************************************************************************************
428 ************************************************************************************** */
429 OrderedTermVocabulary
<Rank
> rankVocabulary
= null;
431 public OrderedTermVocabulary
<Rank
> getRankVocabulary() {
432 if (rankVocabulary
== null) {
433 rankVocabulary
= getCdmApp().getNameService().getRankVocabulary();
435 return rankVocabulary
;
438 /* ***************************************************************************************
440 ************************************************************************************** */
441 TermVocabulary
<NomenclaturalStatusType
> nomStatusVocabulary
= null;
443 public TermVocabulary
<NomenclaturalStatusType
> getNomStatusVocabulary() {
444 if (nomStatusVocabulary
== null) {
445 nomStatusVocabulary
= getCdmApp().getNameService().getStatusTypeVocabulary();
447 return nomStatusVocabulary
;
450 /* ***************************************************************************************
452 ************************************************************************************** */
453 TermVocabulary
<NameRelationshipType
> nameRelationshipTypeVocabulary
= null;
455 public TermVocabulary
<NameRelationshipType
> getNameRelationshipTypeVocabulary() {
456 if (nameRelationshipTypeVocabulary
== null) {
457 nameRelationshipTypeVocabulary
= getCdmApp().getNameService().getNameRelationshipTypeVocabulary();
459 return nameRelationshipTypeVocabulary
;
463 /* ***************************************************************************************
465 ************************************************************************************** */
466 private Taxon
getSorayasGenusTaxon() {
468 String
[] children
= new String
[] {"Heterospathe annectens H.E.Moore",
469 "Heterospathe arfakiana (Becc.) H.E.Moore",
470 "Heterospathe brevicaulis Fernando",
471 "Heterospathe cagayanensis Becc.",
472 "Heterospathe califrons Fernando, Palms 45: 118 (2001).",
473 "Heterospathe clemensiae (Burret) H.E.Moore",
474 "Heterospathe delicatula H.E.Moore",
475 "Heterospathe dransfieldii Fernando",
476 "Heterospathe elata Scheff.",
477 "Heterospathe elata var. elata.",
478 "Heterospathe elata var. guamensis Becc.",
479 "Heterospathe elata var. palauensis (Becc.) Becc.",
480 "Heterospathe elegans (Becc.) Becc.",
481 "Heterospathe elmeri Becc.",
482 "Heterospathe glabra (Burret) H.E.Moore",
483 "Heterospathe glauca (Scheff.) H.E.Moore",
484 "Heterospathe humilis Becc.",
485 "Heterospathe intermedia (Becc.) Fernando",
486 "Heterospathe kajewskii Burret",
487 "Heterospathe ledermanniana Becc.",
488 "Heterospathe lepidota H.E.Moore",
489 "Heterospathe longipes (H.E.Moore) Norup",
490 "Heterospathe macgregorii (Becc.) H.E.Moore",
491 "Heterospathe micrantha (Becc.) H.E.Moore",
492 "Heterospathe minor Burret",
493 "Heterospathe muelleriana (Becc.) Becc.",
494 "Heterospathe negrosensis Becc.",
495 "Heterospathe obriensis (Becc.) H.E.Moore",
496 "Heterospathe palauensis Becc.",
497 "Heterospathe parviflora Essig",
498 "Heterospathe philippinensis (Becc.) Becc.",
499 // "Heterospathe phillipsii D.Fuller & Dowe", // <--------------
500 "Heterospathe pilosa (Burret) Burret",
501 "Heterospathe pisifera (Gaertn.) Burret",
502 "Heterospathe pulchra H.E.Moore",
503 "Heterospathe ramulosa Burret",
504 "Heterospathe salomonensis Becc.",
505 "Heterospathe scitula Fernando",
506 "Heterospathe sensisi Becc.",
507 "Heterospathe sibuyanensis Becc.",
508 "Heterospathe sphaerocarpa Burret",
509 "Heterospathe trispatha Fernando",
510 "Heterospathe uniformis Dowe",
511 "Heterospathe versteegiana Becc.",
512 "Heterospathe woodfordiana Becc."};
514 BotanicalName genusName
= BotanicalName
.PARSED_NAME("Heterospathe Scheff.");
516 Taxon genusTaxon
= Taxon
.NewInstance(genusName
, CdmUtil
.getSessionDefaultSec());
518 for (String child
: children
) {
519 BotanicalName speciesName
= BotanicalName
.PARSED_NAME(child
);
521 Taxon childTaxon
= Taxon
.NewInstance(speciesName
, CdmUtil
.getSessionDefaultSec());
522 childTaxon
.setTaxonomicParent(genusTaxon
, null, null);
524 if (child
.equals("Heterospathe elegans (Becc.) Becc.")) {
525 BotanicalName basionym
= BotanicalName
.PARSED_NAME("Barkerwebbia elegans Becc.");
526 speciesName
.addRelationshipFromName(basionym
, NameRelationshipType
.BASIONYM(), null);
527 childTaxon
.addHomotypicSynonymName(basionym
, null, null);
530 if (child
.equals("Heterospathe humilis Becc.")) {
531 BotanicalName synonymName
= BotanicalName
.PARSED_NAME("Barkerwebbia humilis (Becc.) Becc. ex Martelli");
532 childTaxon
.addHomotypicSynonymName(synonymName
, null, null);
539 public List
<TaxonNameBase
> getNameByName(String searchText
) {
540 // TODO make sure last character is %
541 return getCdmApp().getNameService().getNamesByName(searchText
);