Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 281355
Collapse All | Expand All

(-)src/org/eclipse/rse/internal/efs/Activator.java (-13 / +45 lines)
Lines 1-5 Link Here
1
/********************************************************************************
1
/********************************************************************************
2
 * Copyright (c) 2006, 2007 IBM Corporation and others. All rights reserved.
2
 * Copyright (c) 2006, 2009 IBM Corporation and others. All rights reserved.
3
 * This program and the accompanying materials are made available under the terms
3
 * This program and the accompanying materials are made available under the terms
4
 * of the Eclipse Public License v1.0 which accompanies this distribution, and is 
4
 * of the Eclipse Public License v1.0 which accompanies this distribution, and is 
5
 * available at http://www.eclipse.org/legal/epl-v10.html
5
 * available at http://www.eclipse.org/legal/epl-v10.html
Lines 17-27 Link Here
17
 *    - Improve performance by RSEFileStore instance factory and caching IRemoteFile.
17
 *    - Improve performance by RSEFileStore instance factory and caching IRemoteFile.
18
 *    - Also remove unnecessary class RSEFileCache and obsolete branding files.
18
 *    - Also remove unnecessary class RSEFileCache and obsolete branding files.
19
 * Martin Oberhuber (Wind River) - [188360] renamed from plugin org.eclipse.rse.eclipse.filesystem
19
 * Martin Oberhuber (Wind River) - [188360] renamed from plugin org.eclipse.rse.eclipse.filesystem
20
 * David McKnight      (IBM) -[241315] [efs] Cannot restore editors for RSE/EFS-backed resources
20
 ********************************************************************************/
21
 ********************************************************************************/
21
22
22
package org.eclipse.rse.internal.efs;
23
package org.eclipse.rse.internal.efs;
23
24
25
import org.eclipse.core.resources.IResourceChangeEvent;
26
import org.eclipse.core.resources.ResourcesPlugin;
27
import org.eclipse.core.runtime.IProgressMonitor;
28
import org.eclipse.core.runtime.IStatus;
24
import org.eclipse.core.runtime.Plugin;
29
import org.eclipse.core.runtime.Plugin;
30
import org.eclipse.core.runtime.Status;
31
import org.eclipse.core.runtime.jobs.Job;
32
import org.eclipse.ui.IWorkbench;
33
import org.eclipse.ui.PlatformUI;
25
import org.osgi.framework.BundleContext;
34
import org.osgi.framework.BundleContext;
26
35
27
/**
36
/**
Lines 32-37 Link Here
32
	//The shared instance.
41
	//The shared instance.
33
	private static Activator plugin;
42
	private static Activator plugin;
34
	
43
	
44
	public static final String PLUGIN_ID = "org.eclipse.rse.efs"; //$NON-NLS-1$
45
46
	
35
	/**
47
	/**
36
	 * The constructor.
48
	 * The constructor.
37
	 */
49
	 */
Lines 39-63 Link Here
39
		plugin = this;
51
		plugin = this;
40
	}
52
	}
41
53
42
	/**
54
43
	 * This method is called upon plug-in activation
44
	 */
45
	public void start(BundleContext context) throws Exception {
55
	public void start(BundleContext context) throws Exception {
46
		super.start(context);
56
		super.start(context);
47
		////We must not activate RSE plugins prematurely, since we are being 
57
		final RemoteEditorManager mgr = RemoteEditorManager.getDefault();
48
		////activated VERY early while the Resources plugin is not yet fully up
58
		ResourcesPlugin.getWorkspace().addSaveParticipant(this, mgr);
49
		//RSECorePlugin.getDefault();
59
		ResourcesPlugin.getWorkspace().addResourceChangeListener(mgr, IResourceChangeEvent.POST_CHANGE);
50
		//RSEUIPlugin.getDefault();
60
		
61
		Job job = new Job("Add Listener"){					 //$NON-NLS-1$
62
			protected IStatus run(IProgressMonitor monitor) {
63
				
64
				while (!PlatformUI.isWorkbenchRunning()){
65
					try {
66
						//Checks in the loop are fast enough so we can poll often
67
						Thread.sleep(100);
68
					}
69
					catch (InterruptedException e){}
70
				}
71
				IWorkbench wb = PlatformUI.getWorkbench();				
72
				wb.addWorkbenchListener(mgr);	
73
				return Status.OK_STATUS;
74
			}			
75
		};
76
		job.schedule();
77
		
51
	}
78
	}
52
79
53
	/**
54
	 * This method is called when the plug-in is stopped
55
	 */
56
	public void stop(BundleContext context) throws Exception {
80
	public void stop(BundleContext context) throws Exception {
57
		super.stop(context);
81
		try {
82
			ResourcesPlugin.getWorkspace().removeSaveParticipant(this);
83
			ResourcesPlugin.getWorkspace().removeResourceChangeListener(RemoteEditorManager.getDefault());
84
		} finally {
85
			super.stop(context);
86
		}
58
		plugin = null;
87
		plugin = null;
59
	}
88
	}
60
61
	/**
89
	/**
62
	 * Returns the shared instance.
90
	 * Returns the shared instance.
63
	 *
91
	 *
Lines 66-70 Link Here
66
	public static Activator getDefault() {
94
	public static Activator getDefault() {
67
		return plugin;
95
		return plugin;
68
	}
96
	}
97
	
98
	public static IStatus errorStatus(Throwable e) {
99
		return new Status(IStatus.ERROR, PLUGIN_ID, e.getMessage(), e);
100
	}
69
101
70
}
102
}
(-)META-INF/MANIFEST.MF (-2 / +6 lines)
Lines 2-8 Link Here
2
Bundle-ManifestVersion: 2
2
Bundle-ManifestVersion: 2
3
Bundle-Name: %pluginName
3
Bundle-Name: %pluginName
4
Bundle-SymbolicName: org.eclipse.rse.efs;singleton:=true
4
Bundle-SymbolicName: org.eclipse.rse.efs;singleton:=true
5
Bundle-Version: 2.1.1.qualifier
5
Bundle-Version: 2.1.2.qualifier
6
Bundle-Activator: org.eclipse.rse.internal.efs.Activator
6
Bundle-Activator: org.eclipse.rse.internal.efs.Activator
7
Bundle-Localization: plugin
7
Bundle-Localization: plugin
8
Require-Bundle: org.eclipse.core.runtime,
8
Require-Bundle: org.eclipse.core.runtime,
Lines 10-16 Link Here
10
 org.eclipse.rse.core;bundle-version="[3.0.0,4.0.0)",
10
 org.eclipse.rse.core;bundle-version="[3.0.0,4.0.0)",
11
 org.eclipse.rse.subsystems.files.core;bundle-version="[3.0.1,4.0.0)",
11
 org.eclipse.rse.subsystems.files.core;bundle-version="[3.0.1,4.0.0)",
12
 org.eclipse.rse.services;bundle-version="[3.0.0,4.0.0)",
12
 org.eclipse.rse.services;bundle-version="[3.0.0,4.0.0)",
13
 org.eclipse.rse.ui;bundle-version="[3.0.0,4.0.0)"
13
 org.eclipse.rse.ui;bundle-version="[3.0.0,4.0.0)",
14
 org.eclipse.core.resources;bundle-version="3.4.0",
15
 org.eclipse.ui;bundle-version="3.4.0",
16
 org.eclipse.ui.ide;bundle-version="3.4.0",
17
 org.eclipse.ui.editors;bundle-version="3.4.0"
14
Bundle-ActivationPolicy: lazy
18
Bundle-ActivationPolicy: lazy
15
Eclipse-LazyStart: true
19
Eclipse-LazyStart: true
16
Bundle-Vendor: %providerName
20
Bundle-Vendor: %providerName
(-)src/org/eclipse/rse/internal/efs/RemoteEditorManager.java (+284 lines)
Added Link Here
1
/********************************************************************************
2
 * Copyright (c) 2009 IBM Corporation. All rights reserved.
3
 * This program and the accompanying materials are made available under the terms
4
 * of the Eclipse Public License v1.0 which accompanies this distribution, and is 
5
 * available at http://www.eclipse.org/legal/epl-v10.html
6
 * 
7
 * Initial Contributors:
8
 * The following IBM employees contributed to the Remote System Explorer
9
 * component that contains this file: David McKnight, Mike Kucera.
10
 * 
11
 * Contributors:
12
 * Mike Kucera         (IBM) -[241315] [efs] Cannot restore editors for RSE/EFS-backed resources
13
 * David McKnight      (IBM) -[241315] [efs] Cannot restore editors for RSE/EFS-backed resources
14
 ********************************************************************************/
15
package org.eclipse.rse.internal.efs;
16
17
import java.net.URI;
18
import java.net.URISyntaxException;
19
import java.util.HashMap;
20
import java.util.Iterator;
21
import java.util.LinkedList;
22
import java.util.List;
23
import java.util.Map;
24
25
import org.eclipse.core.filesystem.EFS;
26
import org.eclipse.core.filesystem.IFileStore;
27
import org.eclipse.core.resources.IFile;
28
import org.eclipse.core.resources.IProject;
29
import org.eclipse.core.resources.IResourceChangeEvent;
30
import org.eclipse.core.resources.IResourceChangeListener;
31
import org.eclipse.core.resources.IResourceDelta;
32
import org.eclipse.core.resources.ISaveContext;
33
import org.eclipse.core.resources.ISaveParticipant;
34
import org.eclipse.core.runtime.CoreException;
35
import org.eclipse.core.runtime.IPath;
36
import org.eclipse.core.runtime.IProgressMonitor;
37
import org.eclipse.core.runtime.IStatus;
38
import org.eclipse.core.runtime.Status;
39
import org.eclipse.core.runtime.jobs.Job;
40
import org.eclipse.rse.ui.RSEUIPlugin;
41
import org.eclipse.ui.IEditorInput;
42
import org.eclipse.ui.IEditorPart;
43
import org.eclipse.ui.IEditorReference;
44
import org.eclipse.ui.IWorkbench;
45
import org.eclipse.ui.IWorkbenchListener;
46
import org.eclipse.ui.IWorkbenchPage;
47
import org.eclipse.ui.IWorkbenchWindow;
48
import org.eclipse.ui.PartInitException;
49
import org.eclipse.ui.PlatformUI;
50
import org.eclipse.ui.ide.IDE;
51
import org.eclipse.ui.part.FileEditorInput;
52
import org.eclipse.ui.progress.UIJob;
53
54
public class RemoteEditorManager implements ISaveParticipant, IResourceChangeListener, IWorkbenchListener {
55
	public static final String PREFERENCE_EDITOR_LIST = "org.eclipse.rse.internal.efs.EditorSaver.preferenceEditorList"; //$NON-NLS-1$
56
	
57
	private static RemoteEditorManager defaultInstance;
58
	
59
	private Map projectNameToUriMap = null;
60
	
61
	private RemoteEditorManager() {}
62
	
63
	public static synchronized RemoteEditorManager getDefault() {
64
		if(defaultInstance == null)
65
			defaultInstance = new RemoteEditorManager();
66
		return defaultInstance;
67
	}
68
69
	
70
	/**
71
	 * Restores remote editors when a remote project is opened.
72
	 */
73
	public void resourceChanged(IResourceChangeEvent event) {
74
		String pref = RSEUIPlugin.getDefault().getPreferenceStore().getString(PREFERENCE_EDITOR_LIST);
75
		Map projectNameToUriMap = getProjectNameToUriMap(pref);
76
		if(projectNameToUriMap.isEmpty())
77
			return;
78
		
79
		IResourceDelta[] children = event.getDelta().getAffectedChildren();
80
		for(int i = 0; i < children.length; i++) {
81
			IResourceDelta delta = children[i];
82
			
83
			// if a project has just been opened
84
			if((delta.getFlags() & IResourceDelta.OPEN) != 0) {
85
				IProject project = delta.getResource().getProject();
86
				if(project.isOpen()) {
87
88
					// restore remote editors for the project
89
					List uris = (List) projectNameToUriMap.remove(project.getName());
90
					if(uris != null) {
91
						for(Iterator iter = uris.iterator(); iter.hasNext();) {
92
							final String uriString = (String) iter.next();
93
							
94
							Job job = new UIJob("Restore Remote Editor") { //$NON-NLS-1$
95
								public IStatus runInUIThread(IProgressMonitor monitor) {
96
									if(monitor.isCanceled())
97
										return Status.OK_STATUS;
98
										
99
									try {
100
										// got this code from http://wiki.eclipse.org/FAQ_How_do_I_open_an_editor_programmatically%3F 
101
										IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
102
										IFileStore fileStore = EFS.getStore(new URI(uriString));
103
										IDE.openEditorOnFileStore(page, fileStore);
104
									} catch (URISyntaxException e) {
105
										return Activator.errorStatus(e);
106
									} catch (PartInitException e) {
107
										return Activator.errorStatus(e);
108
									} catch (CoreException e) {
109
										return Activator.errorStatus(e);
110
									}
111
									return Status.OK_STATUS;
112
								}
113
							};
114
							job.schedule();
115
							
116
						}
117
					}
118
				}
119
			}
120
		}
121
		
122
	}
123
	
124
	/**
125
	 * Saves the URIs of remote resources that are open in editors into the
126
	 * plugin's preference store.
127
	 */
128
	public synchronized void saveRemoteEditors() {
129
		IWorkbench wb = PlatformUI.getWorkbench();
130
		IWorkbenchWindow[] windows = wb.getWorkbenchWindows();
131
		if(windows.length > 0) {
132
			String list = generateEditorList();
133
			RSEUIPlugin.getDefault().getPreferenceStore().putValue(PREFERENCE_EDITOR_LIST, list);
134
		}
135
		projectNameToUriMap = null;
136
	}
137
	
138
	private Map getProjectNameToUriMap(String raw) {
139
		if(projectNameToUriMap == null) {
140
			projectNameToUriMap = new HashMap();
141
			
142
			if(raw == null || raw.length() == 0)
143
				return projectNameToUriMap;
144
145
			int index = 0;
146
			while(true) {
147
				int i = raw.indexOf(IPath.SEPARATOR, index);
148
				if(i < 0) break;
149
				String projectName = raw.substring(index, i);
150
				index = i + 1;
151
				i = raw.indexOf(' ', index);
152
				if(i < 0) break;
153
				String uriString = raw.substring(index, i);
154
				index = i + 1;
155
				
156
				List uris = (List) projectNameToUriMap.get(projectName);
157
				if(uris == null) {
158
					uris = new LinkedList();
159
					projectNameToUriMap.put(projectName, uris);
160
				}
161
				uris.add(uriString);
162
			}
163
		}
164
		return projectNameToUriMap;
165
	}
166
	
167
	
168
	private String generateEditorList() {
169
		final StringBuffer sb = new StringBuffer();
170
		
171
		forEachOpenRemoteEditor(new IEditorCallback() {
172
			public void apply(IWorkbenchPage page, IEditorPart editor, IFile file) {
173
				IProject project = file.getProject();
174
				URI uri = file.getLocationURI();
175
				sb.append(project.getName());
176
				sb.append(IPath.SEPARATOR); // not allowed in resource names
177
				sb.append(uri);
178
				sb.append(' '); // not allowed in URIs
179
			}
180
		});
181
		
182
		return sb.toString();
183
	}
184
	
185
	
186
	private static interface IEditorCallback {
187
		public void apply(IWorkbenchPage page, IEditorPart editor, IFile file);
188
	}
189
	
190
	private static void forEachOpenRemoteEditor(IEditorCallback callback) {
191
		IWorkbench wb = PlatformUI.getWorkbench();
192
		IWorkbenchWindow[] windows = wb.getWorkbenchWindows();
193
		for (int w = 0; w < windows.length; w++){
194
			IWorkbenchWindow win = windows[w];
195
			IWorkbenchPage[] pages = win.getPages();
196
			for (int p = 0; p < pages.length; p++){
197
				IWorkbenchPage page = pages[p];
198
				IEditorReference[] activeReferences = page.getEditorReferences();
199
				for (int er = 0; er < activeReferences.length; er++){
200
					IEditorReference editorReference = activeReferences[er];
201
					
202
					try {
203
						IEditorInput input = editorReference.getEditorInput();
204
						if (input instanceof FileEditorInput){
205
							IFile file = ((FileEditorInput)input).getFile();
206
							URI uri = file.getLocationURI();
207
							if ("rse".equals(uri.getScheme())) { //$NON-NLS-1$
208
								IEditorPart editor = editorReference.getEditor(false);
209
								callback.apply(page, editor, file);																
210
							}
211
						}
212
					} catch (PartInitException e){
213
						e.printStackTrace();
214
					}
215
				}
216
			}
217
		}
218
	}
219
	
220
	/**
221
	 * Close each editor that is open for any file that uses "rse" as it's uri scheme
222
	 * @return true if successful, false otherwise
223
	 */
224
	public boolean closeRemoteEditors() {
225
		boolean result = true;
226
		IWorkbench wb = PlatformUI.getWorkbench();
227
		IWorkbenchWindow[] windows = wb.getWorkbenchWindows();
228
		for (int w = 0; w < windows.length; w++){
229
			IWorkbenchWindow win = windows[w];
230
			IWorkbenchPage[] pages = win.getPages();
231
			for (int p = 0; p < pages.length && result; p++){
232
				IWorkbenchPage page = pages[p];
233
				IEditorReference[] activeReferences = page.getEditorReferences();
234
				for (int er = 0; er < activeReferences.length; er++){
235
					IEditorReference editorReference = activeReferences[er];
236
					
237
					try {
238
						IEditorInput input = editorReference.getEditorInput();
239
						if (input instanceof FileEditorInput){
240
							IFile file = ((FileEditorInput)input).getFile();
241
							URI uri = file.getLocationURI();
242
							if ("rse".equals(uri.getScheme())) { //$NON-NLS-1$
243
								IEditorPart editor = editorReference.getEditor(false);			
244
								
245
								// close the editor
246
								result = page.closeEditor(editor, true);															
247
							}
248
						}
249
					} catch (PartInitException e){
250
						e.printStackTrace();
251
					}
252
				}
253
			}
254
		}
255
		return result;
256
	}
257
258
	
259
	public void saving(ISaveContext context) throws CoreException {
260
		saveRemoteEditors();
261
	}
262
	
263
	
264
	public void doneSaving(ISaveContext context) {
265
	}
266
267
	public void prepareToSave(ISaveContext context) throws CoreException {
268
	}
269
270
	public void rollback(ISaveContext context) {
271
	}
272
	
273
	
274
	// for IWorkbenchListener
275
	public void postShutdown(IWorkbench workbench) {
276
	}
277
278
	// for IWorkbenchListener
279
	public boolean preShutdown(IWorkbench workbench, boolean forced) {	
280
		RemoteEditorManager.getDefault().saveRemoteEditors();
281
		return RemoteEditorManager.getDefault().closeRemoteEditors();
282
	}
283
	
284
}

Return to bug 281355