cleanup
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / store / ContextManager.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.store;
11
12 import java.io.File;
13 import java.io.FileNotFoundException;
14 import java.lang.reflect.InvocationTargetException;
15
16 import org.eclipse.core.runtime.IPath;
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.core.runtime.ListenerList;
19 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
20 import org.eclipse.jface.operation.IRunnableWithProgress;
21 import org.eclipse.ui.IMemento;
22 import org.eclipse.ui.IWorkbench;
23 import org.eclipse.ui.IWorkbenchListener;
24 import org.eclipse.ui.PlatformUI;
25 import org.eclipse.ui.XMLMemento;
26 import org.eclipse.ui.internal.Workbench;
27 import org.springframework.remoting.RemoteAccessException;
28
29 import eu.etaxonomy.taxeditor.model.AbstractUtility;
30 import eu.etaxonomy.taxeditor.model.IContextListener;
31 import eu.etaxonomy.taxeditor.model.MementoHelper;
32 import eu.etaxonomy.taxeditor.model.MessagingUtils;
33 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
34
35 /**
36 * The context manager mediates context start/stop and workbench shutdowns to all registered listeners.
37 *
38 * @author n.hoffmann
39 * @created Sep 30, 2010
40 */
41 public class ContextManager implements IWorkbenchListener{
42
43 private final ListenerList<IContextListener> contextListeners = new ListenerList<>();
44
45 private IMemento memento;
46
47 /**
48 * <p>Constructor for ContextManager.</p>
49 */
50 protected ContextManager() {
51 if(Workbench.getInstance() != null) {
52 PlatformUI.getWorkbench().addWorkbenchListener(this);
53 }
54 }
55
56 public void addContextListener(IContextListener listener){
57 contextListeners.add(listener);
58 }
59
60 public void removeContextListener(IContextListener listener) {
61 contextListeners.remove(listener);
62 }
63
64 public void notifyContextStartWithoutDialog(IProgressMonitor monitor) {
65 MessagingUtils.info("Notifying context listeners, that the context has started.");
66
67 readMemento();
68
69 for(final Object listener : contextListeners.getListeners()){
70 ((IContextListener) listener).contextStart(memento, monitor);
71 }
72 }
73
74 public void notifyContextStart() throws RemoteAccessException {
75 MessagingUtils.info("Notifying context listeners, that the context has started.");
76 ProgressMonitorDialog dialog = new ProgressMonitorDialog(AbstractUtility.getShell());
77
78 try {
79 dialog.run(false, false, new IRunnableWithProgress() {
80
81 @Override
82 public void run(IProgressMonitor monitor)
83 throws InvocationTargetException, InterruptedException {
84 monitor.beginTask("Starting context", contextListeners.size());
85
86
87 readMemento();
88
89 for(final Object listener : contextListeners.getListeners()){
90 ((IContextListener) listener).contextStart(memento, monitor);
91 monitor.worked(1);
92 }
93 monitor.done();
94 }
95 });
96 } catch (InvocationTargetException e) {
97 if (e.getTargetException().getClass().equals(RemoteAccessException.class)){
98 if (e.getTargetException().getMessage().contains("403")){
99 // new CdmAuthenticationException("Access Denied", e.getTargetException());
100 throw new CdmAuthenticationException("You are logged in now but you are not permitted to use the TaxEditor with the selected data source", e.getTargetException());
101 }else{
102 MessagingUtils.error(getClass(), e.getTargetException());
103 }
104 }else{
105 MessagingUtils.error(getClass(), e);
106 }
107 } catch (InterruptedException e) {
108 MessagingUtils.error(getClass(), e);
109 }
110 }
111
112 public void notifyContextRefresh() {
113 MessagingUtils.info("Notifying context listeners, that the context needs to be refreshed.");
114 ProgressMonitorDialog dialog = new ProgressMonitorDialog(AbstractUtility.getShell());
115
116 try {
117 dialog.run(false, false, new IRunnableWithProgress() {
118
119 @Override
120 public void run(IProgressMonitor monitor)
121 throws InvocationTargetException, InterruptedException {
122 monitor.beginTask("Refreshing context", contextListeners.size());
123
124 for(final Object listener : contextListeners.getListeners()){
125 ((IContextListener) listener).contextRefresh(monitor);
126 monitor.worked(1);
127 }
128 monitor.done();
129 }
130 });
131 } catch (InvocationTargetException e) {
132 if (e.getTargetException().getClass().equals(RemoteAccessException.class)){
133 if (e.getTargetException().getMessage().contains("403")){
134 MessagingUtils.confirmDialog("Access denied", "Access denied");
135 }else{
136 MessagingUtils.error(getClass(), e.getTargetException());
137 }
138 }else{
139 MessagingUtils.error(getClass(), e);
140 }
141 } catch (InterruptedException e) {
142 MessagingUtils.error(getClass(), e);
143 }
144 }
145
146 public void notifyContextAboutToStop(final IProgressMonitor monitor){
147
148 IProgressMonitor subMonitor = AbstractUtility.getSubProgressMonitor(monitor, 1);
149
150 subMonitor.beginTask("Stoping context", contextListeners.size());
151 // we are creating the memento here; even if the context is not stopped
152 createMemento();
153
154 for(final Object listener : contextListeners.getListeners()){
155 ((IContextListener) listener).contextAboutToStop(memento, subMonitor);
156 subMonitor.worked(1);
157 }
158
159 subMonitor.done();
160 }
161
162 public void notifyContextStop(IProgressMonitor monitor) {
163
164 IProgressMonitor subMonitor = AbstractUtility.getSubProgressMonitor(monitor, 1);
165
166 subMonitor.beginTask("Stoping context", contextListeners.size());
167 MessagingUtils.info("Notifying context listeners, that the context has stopped.");
168
169 for(Object listener : contextListeners.getListeners()){
170 ((IContextListener) listener).contextStop(memento, subMonitor);
171 subMonitor.worked(1);
172 }
173
174 saveMemento();
175 subMonitor.done();
176 }
177
178 @Override
179 public boolean preShutdown(IWorkbench workbench, boolean forced) {
180
181 createMemento();
182
183 IProgressMonitor monitor = null;
184
185 for(Object listener : contextListeners.getListeners()){
186 ((IContextListener) listener).workbenchShutdown(memento, monitor);
187 }
188
189 saveMemento();
190
191 // return true in any case, otherwise the application will not stop
192 return true;
193 }
194
195 @Override
196 public void postShutdown(IWorkbench workbench) {
197 }
198
199 private void readMemento(){
200 try {
201 memento = MementoHelper.readMementoFromFile(getStateFileForCurrentDatabase());
202 } catch (FileNotFoundException e) {
203 // no memento -> no previous state
204 MessagingUtils.info("No state file for datasource");
205 }
206 }
207
208 private void createMemento(){
209
210 if (CdmStore.getActiveCdmSource() != null) {
211
212 try {
213 String name = CdmStore.getActiveCdmSource().getName();
214 name = name.trim();
215 name = name.replace(" ", "_");
216 memento = XMLMemento.createWriteRoot(name);
217
218 MessagingUtils.info("DataSource found. Memento created.");
219 } catch (Exception e) {
220 // The memento could not be created, but a not closable editor is avoided for this case.
221 MessagingUtils.error(this.getClass(), "The memento could not be created", e);
222 }
223 } else {
224 MessagingUtils.info("Not storing state data, because no DataSource present.");
225 }
226 }
227
228 private boolean saveMemento(){
229 return MementoHelper.saveMementoToFile(memento, getStateFileForCurrentDatabase()) != null;
230 }
231
232 protected File getStateFileForCurrentDatabase() {
233 if(CdmStore.getActiveCdmSource() == null){
234 return null;
235 }
236
237 IPath path = TaxeditorStorePlugin.getDefault().getStateLocation();
238 if (path == null) {
239 return null;
240 }
241 path = path.append("editor_state_" + CdmStore.getActiveCdmSource().getName() + ".xml");
242 return path.toFile();
243 }
244 }