Lines 32-38
Link Here
|
32 |
import org.eclipse.swt.SWT; |
32 |
import org.eclipse.swt.SWT; |
33 |
import org.eclipse.swt.custom.BusyIndicator; |
33 |
import org.eclipse.swt.custom.BusyIndicator; |
34 |
import org.eclipse.swt.graphics.FontData; |
34 |
import org.eclipse.swt.graphics.FontData; |
|
|
35 |
import org.eclipse.swt.graphics.Image; |
35 |
import org.eclipse.swt.graphics.RGB; |
36 |
import org.eclipse.swt.graphics.RGB; |
|
|
37 |
import org.eclipse.swt.widgets.Decorations; |
36 |
|
38 |
|
37 |
import org.eclipse.jface.preference.IPreferenceNode; |
39 |
import org.eclipse.jface.preference.IPreferenceNode; |
38 |
import org.eclipse.jface.preference.IPreferenceStore; |
40 |
import org.eclipse.jface.preference.IPreferenceStore; |
Lines 620-682
Link Here
|
620 |
} |
622 |
} |
621 |
|
623 |
|
622 |
public void startup() throws CoreException { |
624 |
public void startup() throws CoreException { |
623 |
/* The plugin org.eclipse.ui has being separed in |
625 |
// Previously this impl. managed migration from 2.0 to 2.1, which is no longer |
624 |
several plugins. Copy the state files from |
626 |
// required. However, that previous impl. didn't call the parent method, so |
625 |
org.eclipse.ui to org.eclipse.ui.workbench */ |
627 |
// this empty impl. has been left to continue to prevent the parent behaviour |
626 |
|
628 |
// from being invoked. |
627 |
IPath locationPath = getStateLocation(); |
|
|
628 |
File newLocation = locationPath.toFile(); |
629 |
File oldLocation = new File(newLocation,"..//org.eclipse.ui"); //$NON-NLS-1$ |
630 |
try { |
631 |
oldLocation = oldLocation.getCanonicalFile(); |
632 |
} catch (IOException e) { |
633 |
// ignore |
634 |
} |
635 |
String markerFileName = ".copiedStateFiles_Marker"; //$NON-NLS-1$ |
636 |
File markerFile = new File(oldLocation,markerFileName); |
637 |
if(markerFile.exists()) |
638 |
return; |
639 |
|
640 |
try { |
641 |
String list[] = newLocation.list(); |
642 |
if(list != null && list.length != 0) |
643 |
return; |
644 |
|
645 |
String oldList[] = oldLocation.list(); |
646 |
if(oldList == null || oldList.length == 0) |
647 |
return; |
648 |
|
649 |
byte b[] = new byte[1024]; |
650 |
for (int i = 0; i < oldList.length; i++) { |
651 |
String string = oldList[i]; |
652 |
try { |
653 |
File oldFile = new File(oldLocation,string); |
654 |
FileInputStream in = new FileInputStream(oldFile); |
655 |
FileOutputStream out = new FileOutputStream(new File(newLocation,string)); |
656 |
int read = in.read(b); |
657 |
while(read >= 0) { |
658 |
out.write(b,0,read); |
659 |
read = in.read(b); |
660 |
} |
661 |
in.close(); |
662 |
out.close(); |
663 |
// Don't delete the old file since the public preferences and some |
664 |
// dialog settings are still read from org.eclipse.ui. |
665 |
// See bug 33334. |
666 |
// oldFile.delete(); |
667 |
} catch (IOException e) { |
668 |
new File(newLocation,string).delete(); |
669 |
} |
670 |
} |
671 |
} finally { |
672 |
try { |
673 |
new FileOutputStream(markerFile).close(); |
674 |
} catch (IOException e) { |
675 |
// ignore |
676 |
} |
677 |
} |
678 |
} |
629 |
} |
679 |
|
630 |
|
680 |
/** |
631 |
/** |
681 |
* Initializes product-specific information that comes from the |
632 |
* Initializes product-specific information that comes from the |
682 |
* about.ini file of the primary feature. |
633 |
* about.ini file of the primary feature. |
Lines 8-21
Link Here
|
8 |
* Contributors: |
8 |
* Contributors: |
9 |
* IBM Corporation - initial API and implementation |
9 |
* IBM Corporation - initial API and implementation |
10 |
*******************************************************************************/ |
10 |
*******************************************************************************/ |
11 |
|
|
|
12 |
package org.eclipse.ui.internal.ide; |
11 |
package org.eclipse.ui.internal.ide; |
13 |
|
12 |
|
|
|
13 |
import java.io.File; |
14 |
import java.io.FileInputStream; |
15 |
import java.io.FileOutputStream; |
16 |
import java.io.IOException; |
17 |
import java.io.OutputStream; |
18 |
import java.net.MalformedURLException; |
19 |
import java.net.URL; |
20 |
import java.util.Properties; |
21 |
|
14 |
import org.eclipse.core.boot.IPlatformRunnable; |
22 |
import org.eclipse.core.boot.IPlatformRunnable; |
15 |
import org.eclipse.core.runtime.CoreException; |
23 |
import org.eclipse.core.runtime.CoreException; |
16 |
import org.eclipse.core.runtime.IConfigurationElement; |
24 |
import org.eclipse.core.runtime.IConfigurationElement; |
17 |
import org.eclipse.core.runtime.IExecutableExtension; |
25 |
import org.eclipse.core.runtime.IExecutableExtension; |
|
|
26 |
import org.eclipse.core.runtime.IStatus; |
27 |
import org.eclipse.core.runtime.Platform; |
28 |
import org.eclipse.core.runtime.Status; |
29 |
import org.eclipse.jface.dialogs.MessageDialog; |
30 |
import org.eclipse.osgi.service.datalocation.Location; |
31 |
import org.eclipse.swt.SWT; |
18 |
import org.eclipse.swt.widgets.Display; |
32 |
import org.eclipse.swt.widgets.Display; |
|
|
33 |
import org.eclipse.swt.widgets.MessageBox; |
34 |
import org.eclipse.swt.widgets.Shell; |
19 |
import org.eclipse.ui.PlatformUI; |
35 |
import org.eclipse.ui.PlatformUI; |
20 |
|
36 |
|
21 |
/** |
37 |
/** |
Lines 25-61
Link Here
|
25 |
*/ |
41 |
*/ |
26 |
public final class IDEApplication implements IPlatformRunnable, IExecutableExtension { |
42 |
public final class IDEApplication implements IPlatformRunnable, IExecutableExtension { |
27 |
|
43 |
|
|
|
44 |
private static final String METADATA_FOLDER = ".metadata"; //$NON-NLS-1$ |
45 |
private static final String VERSION_FILENAME = "version.ini"; //$NON-NLS-1$ |
46 |
private static final String WORKSPACE_VERSION_KEY = "org.eclipse.core.runtime"; //$NON-NLS-1$ |
47 |
private static final String WORKSPACE_VERSION_VALUE = "1"; //$NON-NLS-1$ |
48 |
|
28 |
/** |
49 |
/** |
29 |
* Creates a new IDE application. |
50 |
* Creates a new IDE application. |
30 |
*/ |
51 |
*/ |
31 |
public IDEApplication() { |
52 |
public IDEApplication() { |
32 |
// There is nothing to do for IDEApplication |
53 |
// There is nothing to do for IDEApplication |
33 |
} |
54 |
} |
34 |
|
55 |
|
35 |
/* (non-Javadoc) |
56 |
/* (non-Javadoc) |
36 |
* @see org.eclipse.core.boot.IPlatformRunnable#run(java.lang.Object) |
57 |
* @see org.eclipse.core.boot.IPlatformRunnable#run(java.lang.Object) |
37 |
*/ |
58 |
*/ |
38 |
public Object run(Object args) throws Exception { |
59 |
public Object run(Object args) throws Exception { |
39 |
|
|
|
40 |
// create and startup the display for the workbench |
60 |
// create and startup the display for the workbench |
41 |
Display display = PlatformUI.createDisplay(); |
61 |
Display display = PlatformUI.createDisplay(); |
42 |
|
62 |
|
43 |
try { |
63 |
try { |
|
|
64 |
Shell shell = new Shell(display); |
65 |
try { |
66 |
if (!checkInstanceLocation(shell)) { |
67 |
Platform.endSplash(); |
68 |
return EXIT_OK; |
69 |
} |
70 |
} finally { |
71 |
if (shell != null) |
72 |
shell.dispose(); |
73 |
} |
74 |
|
44 |
// create the workbench with this advisor and run it until it exits |
75 |
// create the workbench with this advisor and run it until it exits |
45 |
// N.B. createWorkbench remembers the advisor, and also registers the |
76 |
// N.B. createWorkbench remembers the advisor, and also registers |
46 |
// workbench globally so that all UI plug-ins can find it using |
77 |
// the workbench globally so that all UI plug-ins can find it using |
47 |
// PlatformUI.getWorkbench() or AbstractUIPlugin.getWorkbench() |
78 |
// PlatformUI.getWorkbench() or AbstractUIPlugin.getWorkbench() |
48 |
int returnCode = PlatformUI.createAndRunWorkbench(display, new IDEWorkbenchAdvisor()); |
79 |
int returnCode = PlatformUI.createAndRunWorkbench(display, |
|
|
80 |
new IDEWorkbenchAdvisor()); |
49 |
|
81 |
|
50 |
// exit the application with an appropriate return code |
82 |
// exit the application with an appropriate return code |
51 |
if (returnCode == PlatformUI.RETURN_RESTART) { |
83 |
return returnCode == PlatformUI.RETURN_RESTART |
52 |
return IPlatformRunnable.EXIT_RESTART; |
84 |
? EXIT_RESTART |
53 |
} else { |
85 |
: EXIT_OK; |
54 |
return IPlatformRunnable.EXIT_OK; |
86 |
} finally { |
55 |
} |
87 |
if (display != null) |
56 |
} |
88 |
display.dispose(); |
57 |
finally { |
|
|
58 |
display.dispose(); |
59 |
} |
89 |
} |
60 |
} |
90 |
} |
61 |
|
91 |
|
Lines 64-68
Link Here
|
64 |
*/ |
94 |
*/ |
65 |
public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException { |
95 |
public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException { |
66 |
// There is nothing to do for IDEApplication |
96 |
// There is nothing to do for IDEApplication |
|
|
97 |
} |
98 |
|
99 |
/** |
100 |
* Return true if a valid workspace path has been set and false otherwise. |
101 |
* Prompt for and set the path if possible and required. |
102 |
* |
103 |
* @return true if a valid instance location has been set and false |
104 |
* otherwise |
105 |
*/ |
106 |
private boolean checkInstanceLocation(Shell shell) { |
107 |
// -data @none was specified but an ide requires workspace |
108 |
Location instanceLoc = Platform.getInstanceLocation(); |
109 |
if (instanceLoc == null) { |
110 |
MessageDialog |
111 |
.openError( |
112 |
shell, |
113 |
IDEWorkbenchMessages |
114 |
.getString("IDEApplication.workspaceMandatoryTitle"), //$NON-NLS-1$ |
115 |
IDEWorkbenchMessages |
116 |
.getString("IDEApplication.workspaceMandatoryMessage")); //$NON-NLS-1$ |
117 |
return false; |
118 |
} |
119 |
|
120 |
// -data "/valid/path", workspace already set |
121 |
if (instanceLoc.isSet()) |
122 |
return true; |
123 |
|
124 |
// -data @noDefault or -data not specified, prompt and set |
125 |
URL defaultUrl = instanceLoc.getDefault(); |
126 |
String initialDefault = defaultUrl == null ? null : defaultUrl |
127 |
.getFile(); |
128 |
ChooseWorkspaceData launchData = new ChooseWorkspaceData( |
129 |
initialDefault); |
130 |
|
131 |
while (true) { |
132 |
URL workspaceUrl = promptForWorkspace(shell, launchData); |
133 |
if (workspaceUrl == null) |
134 |
return false; |
135 |
|
136 |
try { |
137 |
// the operation will fail if the url is not a valid |
138 |
// instance data area, so other checking is unneeded |
139 |
if (instanceLoc.setURL(workspaceUrl, true)) { |
140 |
launchData.writePersistedData(); |
141 |
writeWorkspaceVersion(); |
142 |
return true; |
143 |
} |
144 |
} catch (IllegalStateException e) { |
145 |
MessageDialog |
146 |
.openError( |
147 |
shell, |
148 |
IDEWorkbenchMessages |
149 |
.getString("IDEApplication.workspaceCannotBeSetTitle"), //$NON-NLS-1$ |
150 |
IDEWorkbenchMessages |
151 |
.getString("IDEApplication.workspaceCannotBeSetMessage")); //$NON-NLS-1$ |
152 |
return false; |
153 |
} |
154 |
|
155 |
// by this point it has been determined that the workspace is already |
156 |
// in use -- force the user to choose again |
157 |
MessageDialog |
158 |
.openError( |
159 |
shell, |
160 |
IDEWorkbenchMessages |
161 |
.getString("IDEApplication.workspaceInUseTitle"), //$NON-NLS-1$ |
162 |
IDEWorkbenchMessages |
163 |
.getString("IDEApplication.workspaceInUseMessage")); //$NON-NLS-1$ |
164 |
} |
165 |
} |
166 |
|
167 |
/** |
168 |
* Open a workspace selection dialog on the argument shell, populating the |
169 |
* argument data with the user's selection. Perform first level validation |
170 |
* on the selection by comparing the version information. This method does |
171 |
* not examine the runtime state (e.g., is the workspace already locked?). |
172 |
* |
173 |
* @param shell |
174 |
* @param launchData |
175 |
* @return An URL storing the selected workspace or null if the user has |
176 |
* canceled the launch operation. |
177 |
*/ |
178 |
private URL promptForWorkspace(Shell shell, ChooseWorkspaceData launchData) { |
179 |
URL url = null; |
180 |
do { |
181 |
new ChooseWorkspaceDialog(shell, launchData).open(); |
182 |
String instancePath = launchData.getSelection(); |
183 |
if (instancePath == null) |
184 |
return null; |
185 |
|
186 |
try { |
187 |
url = new File(instancePath).toURL(); |
188 |
} catch (MalformedURLException e) { |
189 |
MessageDialog |
190 |
.openError( |
191 |
shell, |
192 |
IDEWorkbenchMessages |
193 |
.getString("IDEApplication.workspaceInvalidTitle"), //$NON-NLS-1$ |
194 |
IDEWorkbenchMessages |
195 |
.getString("IDEApplication.workspaceInvalidMessage")); //$NON-NLS-1$ |
196 |
continue; |
197 |
} |
198 |
} while (!isValidWorkspace(shell, url)); |
199 |
|
200 |
return url; |
201 |
} |
202 |
|
203 |
/** |
204 |
* Return true if the argument directory is ok to use as a workspace and |
205 |
* false otherwise. A version check will be performed, and a confirmation |
206 |
* box may be displayed on the argument shell if an older version is |
207 |
* detected. |
208 |
*/ |
209 |
private boolean isValidWorkspace(Shell shell, URL url) { |
210 |
String version = readWorkspaceVersion(url); |
211 |
|
212 |
// if the version could not be read, then there is not any existing |
213 |
// workspace data to trample, e.g., perhaps its a new directory that |
214 |
// is just starting to be used as a workspace |
215 |
if (version == null) |
216 |
return true; |
217 |
|
218 |
final int ide_version = Integer.parseInt(WORKSPACE_VERSION_VALUE); |
219 |
int workspace_version = Integer.parseInt(version); |
220 |
|
221 |
// equality test is required since any version difference (newer |
222 |
// or older) may result in data being trampled |
223 |
if (workspace_version == ide_version) |
224 |
return true; |
225 |
|
226 |
// At this point workspace has been detected to be from a version |
227 |
// other than the current ide version -- find out if the user wants |
228 |
// to use it anyhow. |
229 |
String title = IDEWorkbenchMessages |
230 |
.getString("IDEApplication.versionTitle"); //$NON-NLS-1$ |
231 |
String message = IDEWorkbenchMessages.format( |
232 |
"IDEApplication.versionMessage", //$NON-NLS-1$ |
233 |
new Object[]{url.getFile()}); |
234 |
|
235 |
MessageBox mbox = new MessageBox(shell, SWT.OK | SWT.CANCEL |
236 |
| SWT.ICON_WARNING | SWT.APPLICATION_MODAL); |
237 |
mbox.setText(title); |
238 |
mbox.setMessage(message); |
239 |
return mbox.open() == SWT.OK; |
240 |
} |
241 |
|
242 |
/** |
243 |
* Look at the argument URL for the workspace's version information. Return |
244 |
* that version if found and null otherwise. |
245 |
*/ |
246 |
private static String readWorkspaceVersion(URL workspace) { |
247 |
File versionFile = getVersionFile(workspace, false); |
248 |
if (versionFile == null || !versionFile.exists()) |
249 |
return null; |
250 |
|
251 |
try { |
252 |
// Although the version file is not spec'ed to be a Java properties |
253 |
// file, it happens to follow the same format currently, so using |
254 |
// Properties to read it is convenient. |
255 |
Properties props = new Properties(); |
256 |
FileInputStream is = new FileInputStream(versionFile); |
257 |
try { |
258 |
props.load(is); |
259 |
} finally { |
260 |
is.close(); |
261 |
} |
262 |
|
263 |
return props.getProperty(WORKSPACE_VERSION_KEY); |
264 |
} catch (IOException e) { |
265 |
IDEWorkbenchPlugin.log("Could not read version file", new Status( //$NON-NLS-1$ |
266 |
IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH, |
267 |
IStatus.ERROR, e.getMessage(), e)); |
268 |
return null; |
269 |
} |
270 |
} |
271 |
|
272 |
/** |
273 |
* Write the version of the metadata into a known file overwriting any |
274 |
* existing file contents. Writing the version file isn't really crucial, |
275 |
* so the function is silent about failure |
276 |
*/ |
277 |
private static void writeWorkspaceVersion() { |
278 |
Location instanceLoc = Platform.getInstanceLocation(); |
279 |
if (instanceLoc == null || instanceLoc.isReadOnly()) |
280 |
return; |
281 |
|
282 |
File versionFile = getVersionFile(instanceLoc.getURL(), true); |
283 |
if (versionFile == null) |
284 |
return; |
285 |
|
286 |
OutputStream output = null; |
287 |
try { |
288 |
String versionLine = WORKSPACE_VERSION_KEY + '=' + WORKSPACE_VERSION_VALUE; |
289 |
|
290 |
output = new FileOutputStream(versionFile); |
291 |
output.write(versionLine.getBytes("UTF-8")); //$NON-NLS-1$ |
292 |
} catch (IOException e) { |
293 |
IDEWorkbenchPlugin.log("Could not write version file", new Status( //$NON-NLS-1$ |
294 |
IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH, |
295 |
IStatus.ERROR, e.getMessage(), e)); |
296 |
} finally { |
297 |
try { |
298 |
if (output != null) |
299 |
output.close(); |
300 |
} catch (IOException e) { |
301 |
// do nothing |
302 |
} |
303 |
} |
304 |
} |
305 |
|
306 |
/** |
307 |
* The version file is stored in the metadata area of the workspace. This |
308 |
* method returns an URL to the file or null if the directory or file does |
309 |
* not exist (and the create parameter is false). |
310 |
* |
311 |
* @param create |
312 |
* If the directory and file does not exist this parameter |
313 |
* controls whether it will be created. |
314 |
* @return An url to the file or null if the version file does not exist or |
315 |
* could not be created. |
316 |
*/ |
317 |
private static File getVersionFile(URL workspaceUrl, boolean create) { |
318 |
if (workspaceUrl == null) |
319 |
return null; |
320 |
|
321 |
try { |
322 |
// make sure the directory exists |
323 |
URL metaUrl = new URL(workspaceUrl, METADATA_FOLDER); |
324 |
File metaDir = new File(metaUrl.getFile()); |
325 |
if (!metaDir.exists() && (!create || !metaDir.mkdir())) |
326 |
return null; |
327 |
|
328 |
// make sure the file exists |
329 |
URL versionUrl = new URL(metaDir.toURL(), VERSION_FILENAME); |
330 |
File versionFile = new File(versionUrl.getFile()); |
331 |
if (!versionFile.exists() |
332 |
&& (!create || !versionFile.createNewFile())) |
333 |
return null; |
334 |
|
335 |
return versionFile; |
336 |
} catch (IOException e) { |
337 |
// cannot log because instance area has not been set |
338 |
return null; |
339 |
} |
67 |
} |
340 |
} |
68 |
} |
341 |
} |