ref #8045: further implementation for default/explicit value selection preference...
[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.IContextListener;
30 import eu.etaxonomy.taxeditor.model.MementoHelper;
31 import eu.etaxonomy.taxeditor.model.MessagingUtils;
32 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
33
34 /**
35 * The context manager mediates context start/stop and workbench shutdowns to all registered listeners.
36 *
37 * @author n.hoffmann
38 * @created Sep 30, 2010
39 * @version 1.0
40 */
41 public class ContextManager implements IWorkbenchListener{
42
43 private final ListenerList 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 /**
57 * <p>addContextListener</p>
58 *
59 * @param listener a {@link eu.etaxonomy.taxeditor.model.IContextListener} object.
60 */
61 public void addContextListener(IContextListener listener){
62 contextListeners.add(listener);
63 }
64
65 /**
66 * <p>removeContextListener</p>
67 *
68 * @param listener a {@link eu.etaxonomy.taxeditor.model.IContextListener} object.
69 */
70 public void removeContextListener(IContextListener listener) {
71 contextListeners.remove(listener);
72 }
73
74 public void notifyContextStartWithoutDialog(IProgressMonitor monitor) {
75 MessagingUtils.info("Notifying context listeners, that the context has started.");
76
77 readMemento();
78
79 for(final Object listener : contextListeners.getListeners()){
80 ((IContextListener) listener).contextStart(memento, monitor);
81 }
82 }
83 /**
84 * <p>notifyContextStart</p>
85 * @throws Throwable
86 */
87 public void notifyContextStart() throws RemoteAccessException {
88 MessagingUtils.info("Notifying context listeners, that the context has started.");
89 ProgressMonitorDialog dialog = new ProgressMonitorDialog(StoreUtil.getShell());
90
91 try {
92 dialog.run(false, false, new IRunnableWithProgress() {
93 /* (non-Javadoc)
94 * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
95 */
96 @Override
97 public void run(IProgressMonitor monitor)
98 throws InvocationTargetException, InterruptedException {
99 monitor.beginTask("Starting context", contextListeners.size());
100
101
102 readMemento();
103
104 for(final Object listener : contextListeners.getListeners()){
105 ((IContextListener) listener).contextStart(memento, monitor);
106 monitor.worked(1);
107 }
108 monitor.done();
109 }
110 });
111 } catch (InvocationTargetException e) {
112 if (e.getTargetException().getClass().equals(RemoteAccessException.class)){
113 if (e.getTargetException().getMessage().contains("403")){
114 // new CdmAuthenticationException("Access Denied", e.getTargetException());
115 throw new CdmAuthenticationException("You are logged in now but you are not permitted to use the TaxEditor with the selected data source", e.getTargetException());
116 }else{
117 MessagingUtils.error(getClass(), e.getTargetException());
118 }
119 }else{
120 MessagingUtils.error(getClass(), e);
121 }
122 } catch (InterruptedException e) {
123 MessagingUtils.error(getClass(), e);
124 }
125 }
126
127
128 /**
129 *
130 */
131 public void notifyContextRefresh() {
132 MessagingUtils.info("Notifying context listeners, that the context needs to be refreshed.");
133 ProgressMonitorDialog dialog = new ProgressMonitorDialog(StoreUtil.getShell());
134
135 try {
136 dialog.run(false, false, new IRunnableWithProgress() {
137 /* (non-Javadoc)
138 * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
139 */
140 @Override
141 public void run(IProgressMonitor monitor)
142 throws InvocationTargetException, InterruptedException {
143 monitor.beginTask("Refreshing context", contextListeners.size());
144
145 for(final Object listener : contextListeners.getListeners()){
146 ((IContextListener) listener).contextRefresh(monitor);
147 monitor.worked(1);
148 }
149 monitor.done();
150 }
151 });
152 } catch (InvocationTargetException e) {
153 if (e.getTargetException().getClass().equals(RemoteAccessException.class)){
154 if (e.getTargetException().getMessage().contains("403")){
155 MessagingUtils.confirmDialog("Access denied", "Access denied");
156 }else{
157 MessagingUtils.error(getClass(), e.getTargetException());
158 }
159 }else{
160 MessagingUtils.error(getClass(), e);
161 }
162 } catch (InterruptedException e) {
163 MessagingUtils.error(getClass(), e);
164 }
165 }
166
167 /**
168 * <p>notifyContextAboutToStop</p>
169 *
170 * @param monitor a {@link org.eclipse.core.runtime.IProgressMonitor} object.
171 */
172 public void notifyContextAboutToStop(final IProgressMonitor monitor){
173
174 IProgressMonitor subMonitor = StoreUtil.getSubProgressMonitor(monitor, 1);
175
176 subMonitor.beginTask("Stoping context", contextListeners.size());
177 // we are creating the memento here; even if the context is not stopped
178 createMemento();
179
180 for(final Object listener : contextListeners.getListeners()){
181 ((IContextListener) listener).contextAboutToStop(memento, subMonitor);
182 subMonitor.worked(1);
183 }
184
185 subMonitor.done();
186 }
187
188 /**
189 * <p>notifyContextStop</p>
190 *
191 * @param monitor a {@link org.eclipse.core.runtime.IProgressMonitor} object.
192 */
193 public void notifyContextStop(IProgressMonitor monitor) {
194
195 IProgressMonitor subMonitor = StoreUtil.getSubProgressMonitor(monitor, 1);
196
197 subMonitor.beginTask("Stoping context", contextListeners.size());
198 MessagingUtils.info("Notifying context listeners, that the context has stopped.");
199
200 for(Object listener : contextListeners.getListeners()){
201 ((IContextListener) listener).contextStop(memento, subMonitor);
202 subMonitor.worked(1);
203 }
204
205 saveMemento();
206 subMonitor.done();
207 }
208
209 /* (non-Javadoc)
210 * @see org.eclipse.ui.IWorkbenchListener#preShutdown(org.eclipse.ui.IWorkbench, boolean)
211 */
212 /** {@inheritDoc} */
213 @Override
214 public boolean preShutdown(IWorkbench workbench, boolean forced) {
215
216 createMemento();
217
218 IProgressMonitor monitor = null;
219
220 for(Object listener : contextListeners.getListeners()){
221 ((IContextListener) listener).workbenchShutdown(memento, monitor);
222 }
223
224 saveMemento();
225
226 // return true in any case, otherwise the application will not stop
227 return true;
228 }
229
230 /* (non-Javadoc)
231 * @see org.eclipse.ui.IWorkbenchListener#postShutdown(org.eclipse.ui.IWorkbench)
232 */
233 /** {@inheritDoc} */
234 @Override
235 public void postShutdown(IWorkbench workbench) {
236
237
238 }
239
240
241 private void readMemento(){
242 try {
243 memento = MementoHelper.readMementoFromFile(getStateFileForCurrentDatabase());
244 } catch (FileNotFoundException e) {
245 // no memento -> no previous state
246 MessagingUtils.info("No state file for datasource");
247 }
248 }
249
250 private void createMemento(){
251
252 if (CdmStore.getActiveCdmSource() != null) {
253
254 try {
255 String name = CdmStore.getActiveCdmSource().getName();
256 name = name.trim();
257 name = name.replace(" ", "_");
258 memento = XMLMemento.createWriteRoot(name);
259
260 MessagingUtils.info("DataSource found. Memento created.");
261 } catch (Exception e) {
262 // The memento could not be created, but a not closable editor is avoided for this case.
263 MessagingUtils.error(this.getClass(), "The memento could not be created", e);
264 }
265 } else {
266 MessagingUtils.info("Not storing state data, because no DataSource present.");
267 }
268
269 }
270
271 private boolean saveMemento(){
272 return MementoHelper.saveMementoToFile(memento, getStateFileForCurrentDatabase()) != null;
273 }
274
275 /**
276 * <p>getStateFileForCurrentDatabase</p>
277 *
278 * @return a {@link java.io.File} object.
279 */
280 protected File getStateFileForCurrentDatabase() {
281 if(CdmStore.getActiveCdmSource() == null){
282 return null;
283 }
284
285 IPath path = TaxeditorStorePlugin.getDefault().getStateLocation();
286 if (path == null) {
287 return null;
288 }
289 path = path.append("editor_state_" + CdmStore.getActiveCdmSource().getName() + ".xml");
290 return path.toFile();
291 }
292
293 }