Fix potential NPE
[taxeditor.git] / eu.etaxonomy.taxeditor.navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / NavigationUtil.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.navigation;
11
12 import java.util.Set;
13 import java.util.UUID;
14
15 import org.eclipse.core.commands.operations.IUndoContext;
16 import org.eclipse.core.commands.operations.UndoContext;
17 import org.eclipse.jface.viewers.StructuredSelection;
18 import org.eclipse.jface.wizard.WizardDialog;
19 import org.eclipse.swt.widgets.Display;
20 import org.eclipse.swt.widgets.Shell;
21 import org.eclipse.ui.IEditorPart;
22 import org.eclipse.ui.IEditorReference;
23 import org.eclipse.ui.IWorkbenchWindow;
24 import org.eclipse.ui.PartInitException;
25 import org.eclipse.ui.PlatformUI;
26 import org.eclipse.ui.navigator.CommonViewer;
27
28 import eu.etaxonomy.cdm.api.service.IClassificationService;
29 import eu.etaxonomy.cdm.api.service.INameService;
30 import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
31 import eu.etaxonomy.cdm.api.service.ITaxonService;
32 import eu.etaxonomy.cdm.model.common.ICdmBase;
33 import eu.etaxonomy.cdm.model.description.PolytomousKey;
34 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
35 import eu.etaxonomy.cdm.model.taxon.Classification;
36 import eu.etaxonomy.cdm.model.taxon.Synonym;
37 import eu.etaxonomy.cdm.model.taxon.Taxon;
38 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
39 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
40 import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
41 import eu.etaxonomy.taxeditor.editor.EditorUtil;
42 import eu.etaxonomy.taxeditor.editor.TaxonEditorInput;
43 import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin;
44 import eu.etaxonomy.taxeditor.model.AbstractUtility;
45 import eu.etaxonomy.taxeditor.model.MessagingUtils;
46 import eu.etaxonomy.taxeditor.navigation.internal.TaxeditorNavigationPlugin;
47 import eu.etaxonomy.taxeditor.navigation.navigator.TaxonNavigator;
48 import eu.etaxonomy.taxeditor.newWizard.NewClassificationWizard;
49 import eu.etaxonomy.taxeditor.store.CdmStore;
50 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
51
52 /**
53 * <p>NavigationUtil class.</p>
54 *
55 * @author n.hoffmann
56 * @created 24.03.2009
57 * @version 1.0
58 */
59 public class NavigationUtil extends AbstractUtility{
60 private static IUndoContext defaultUndoContext;
61
62 /**
63 * <p>openEditor</p>
64 *
65 * @param selectedObject a {@link eu.etaxonomy.cdm.model.common.CdmBase} object.
66 */
67 public static void openEditor(UuidAndTitleCache uuidAndTitleCache){
68 Class type = uuidAndTitleCache.getType();
69 ICdmBase cdmBase = null;
70 if(type.equals(Classification.class)){
71 cdmBase = CdmStore.getService(IClassificationService.class).load(uuidAndTitleCache.getUuid());
72 }
73 else if(type.equals(TaxonNode.class)){
74 cdmBase = CdmStore.getService(ITaxonNodeService.class).load(uuidAndTitleCache.getUuid());
75 }
76 else if(TaxonBase.class.isAssignableFrom(type)){
77 cdmBase = CdmStore.getService(ITaxonService.class).load(uuidAndTitleCache.getUuid());
78 }
79 else if(type.equals(TaxonNameBase.class)){
80 cdmBase = CdmStore.getService(INameService.class).load(uuidAndTitleCache.getUuid());
81 }
82 else{
83 MessagingUtils.warningDialog("Unknown type", NavigationUtil.class, "There is no editor available to open this object.");
84 }
85 if(cdmBase!=null){
86 openEditor(cdmBase);
87 }
88 else{
89 MessagingUtils.warningDialog("Cdm entity not found", NavigationUtil.class, "CDM entity could not be found in the database.");
90 }
91 }
92
93 public static void openEditor(ICdmBase selectedObject){
94 UUID entityUuid = selectedObject.getUuid();
95 try {
96 if(selectedObject instanceof Classification){
97 NewClassificationWizard classificationWizard = new NewClassificationWizard();
98 classificationWizard.init(null, null);
99 classificationWizard.setEntity((Classification) selectedObject);
100 WizardDialog dialog = new WizardDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), classificationWizard);
101 dialog.open();
102 }
103 else if(selectedObject instanceof TaxonNode){
104 EditorUtil.openTaxonNode(entityUuid);
105 }else if(selectedObject instanceof TaxonBase){
106 EditorUtil.openTaxonBase(entityUuid);
107 }else if(selectedObject instanceof TaxonNameBase){
108 // TODO open bulk editor
109 MessagingUtils.warningDialog("Not implemented yet", NavigationUtil.class, "You tried to open a name. This is not handled by the software yet. For open a pure name you can use the bulk editor");
110 }else if(selectedObject instanceof PolytomousKey){
111 EditorUtil.openPolytomousKey(entityUuid);
112 }else{
113 MessagingUtils.warningDialog("Unsupported Type", NavigationUtil.class, "No editor exists for the current selection: " + selectedObject);
114 }
115 } catch (PartInitException e) {
116 MessagingUtils.error(NavigationUtil.class, "Error opening the editor", e);
117 } catch (Exception e) {
118 MessagingUtils.errorDialog("Could not create Taxon",
119 NavigationUtil.class,
120 e.getMessage(), TaxeditorStorePlugin.PLUGIN_ID,
121 e,
122 true);
123
124 }
125 }
126
127 /**
128 * <p>openEmpty</p>
129 *
130 * @param parentNodeUuid a {@link java.util.UUID} object.
131 */
132 public static void openEmpty(UUID parentNodeUuid) {
133 try {
134 EditorUtil.openEmpty(parentNodeUuid);
135 } catch (PartInitException e) {
136 MessagingUtils.error(NavigationUtil.class, "Error opening the editor", e);
137 }
138 }
139
140 /**
141 * <p>getShell</p>
142 *
143 * @return a {@link org.eclipse.swt.widgets.Shell} object.
144 */
145 public static Shell getShell() {
146 return getActiveWindow().getShell();
147 }
148
149 /**
150 * <p>getActiveWindow</p>
151 *
152 * @return a {@link org.eclipse.ui.IWorkbenchWindow} object.
153 */
154 public static IWorkbenchWindow getActiveWindow() {
155 return TaxeditorNavigationPlugin.getDefault().getWorkbench().
156 getActiveWorkbenchWindow();
157 }
158
159 /**
160 * <p>getWorkbenchUndoContext</p>
161 *
162 * @return a {@link org.eclipse.core.commands.operations.IUndoContext} object.
163 */
164 public static IUndoContext getWorkbenchUndoContext() {
165 return TaxeditorEditorPlugin.getDefault().getWorkbench().
166 getOperationSupport().getUndoContext();
167 }
168
169 /**
170 * <p>getUndoContext</p>
171 *
172 * @return a {@link org.eclipse.core.commands.operations.IUndoContext} object.
173 */
174 public static IUndoContext getUndoContext() {
175 // FIXME this has to be more specific. Every widget has to have its own undo context
176 // return IOperationHistory.GLOBAL_UNDO_CONTEXT;
177
178 // Plug-ins that wish their operations to be undoable from workbench views
179 // such as the Navigator or Package Explorer should assign the workbench
180 // undo context to their operations.
181 if (defaultUndoContext == null) {
182 defaultUndoContext = new UndoContext();
183 }
184 return defaultUndoContext;
185 }
186
187 /**
188 * Whether a taxonNode has unsaved changes.
189 *
190 * @param taxonNode a {@link eu.etaxonomy.cdm.model.taxon.TaxonNode} object.
191 * @return a boolean.
192 */
193 public static boolean isDirty(TaxonNode taxonNode){
194
195 for (IEditorReference reference : getActivePage().getEditorReferences()) {
196
197 try {
198 if (reference.getEditorInput() instanceof TaxonEditorInput) {
199 TaxonEditorInput editorInput = (TaxonEditorInput) reference.getEditorInput();
200 if(editorInput.getTaxonNode().equals(taxonNode) && reference.isDirty()){
201 return true;
202 }
203 }
204 } catch (PartInitException e) {
205 MessagingUtils.error(NavigationUtil.class, e.getMessage(), e);
206 throw new RuntimeException(e);
207 }
208
209 }
210 return false;
211 }
212
213 /**
214 * <p>selectInNavigator</p>
215 *
216 * @param element a {@link java.lang.Object} object.
217 * @param parentElement a {@link java.lang.Object} object.
218 */
219 public static void selectInNavigator(final Object element, final Object parentElement) {
220 Display.getDefault().asyncExec(new Runnable(){
221
222 @Override
223 public void run() {
224 TaxonNavigator navigator = showNavigator();
225
226 if (navigator != null) {
227 CommonViewer viewer = navigator.getCommonViewer();
228 if (viewer != null) {
229 if (parentElement != null) {
230 viewer.setExpandedState(parentElement, true);
231 }
232 viewer.setSelection(new StructuredSelection(element));
233 }
234 }
235 }
236
237 });
238 }
239
240 /**
241 * <p>openSearch</p>
242 *
243 * @param selection a {@link java.lang.Object} object.
244 */
245 public static void openSearch(Object selection) {
246 if(selection instanceof Taxon){
247 Taxon taxon = (Taxon) selection;
248
249 handleOpeningOfMultipleTaxonNodes(taxon.getTaxonNodes());
250
251 }else if(selection instanceof Synonym){
252 Synonym synonym = (Synonym) selection;
253
254 handleOpeningOfMultipleTaxa(synonym.getAcceptedTaxa());
255
256 }else{
257 MessagingUtils.warningDialog("Not implemented yet", NavigationUtil.class, "You chose to open a name that has no connection to a taxon. The Editor does not support editing of such a content type at the moment.");
258 }
259
260 }
261
262 private static void handleOpeningOfMultipleTaxa(Set<Taxon> acceptedTaxa) {
263 if(acceptedTaxa.size() == 1){
264 openEditor(acceptedTaxa.iterator().next());
265 }else if(acceptedTaxa.size() > 1){
266 // FIXME implement a dialog that shows all possible taxa and let the user choose which he wants to open.
267 MessagingUtils.warningDialog("Not implemented yet", NavigationUtil.class, "The accepted taxon is in multiple taxonomic trees. We currently do not know which one you want to open." +
268 " This case is not handled yet by the software.");
269 }else if(acceptedTaxa.size() == 0){
270 // this is an undesired state
271 MessagingUtils.warningDialog("Not implemented yet", NavigationUtil.class, "This taxon is not connected to a classification. Currently editing of such taxa is not supported yet.");
272 }
273 }
274
275 /**
276 * @param taxonNodes
277 */
278 private static void handleOpeningOfMultipleTaxonNodes(
279 Set<TaxonNode> taxonNodes) {
280
281 if(taxonNodes.size() == 1){
282 openEditor(taxonNodes.iterator().next());
283 }else if(taxonNodes.size() > 1){
284 // FIXME implement a dialog that shows all possible taxa and let the user choose which he wants to open.
285 MessagingUtils.warningDialog("Not implemented yet", NavigationUtil.class, "The accepted taxon is in multiple taxonomic trees. We currently do not know which one you want to open." +
286 " This case is not handled yet by the software.");
287 }else if(taxonNodes.size() == 0){
288 // this is an undesired state
289 MessagingUtils.warningDialog("Incorrect state", NavigationUtil.class, "The accepted taxon is not in a taxonomic view. This should not have happened.");
290 }
291 }
292
293 /**
294 * <p>showNavigator</p>
295 *
296 * @return the TaxonNavigator instance if present
297 */
298 public static TaxonNavigator showNavigator() {
299 return (TaxonNavigator) showView(TaxonNavigator.ID);
300 }
301
302 /**
303 * <p>getNavigator</p>
304 *
305 * @param restore a boolean.
306 * @return a {@link eu.etaxonomy.taxeditor.navigation.navigator.TaxonNavigator} object.
307 */
308 public static TaxonNavigator getNavigator(boolean restore) {
309 return (TaxonNavigator) getView(TaxonNavigator.ID, restore);
310 }
311
312 /**
313 * <p>getOpenEditors</p>
314 *
315 * @return a {@link java.util.Set} object.
316 */
317 public static Set<IEditorPart> getOpenEditors() {
318 return EditorUtil.getOpenEditors();
319 }
320
321 /**
322 * <p>getPluginId</p>
323 *
324 * @return a {@link java.lang.String} object.
325 */
326 public static String getPluginId(){
327 return TaxeditorNavigationPlugin.PLUGIN_ID;
328 }
329
330 }