1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package pl.edu.agh.cast.project;
19
20 import java.beans.PropertyChangeEvent;
21 import java.beans.PropertyChangeListener;
22 import java.io.ByteArrayInputStream;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.FileNotFoundException;
26
27 import org.apache.log4j.Logger;
28 import org.eclipse.core.resources.IFile;
29 import org.eclipse.core.resources.IProject;
30 import org.eclipse.core.resources.IProjectDescription;
31 import org.eclipse.core.resources.IWorkspace;
32 import org.eclipse.core.resources.ProjectScope;
33 import org.eclipse.core.resources.ResourcesPlugin;
34 import org.eclipse.core.runtime.CoreException;
35 import org.eclipse.core.runtime.IPath;
36 import org.eclipse.core.runtime.Path;
37 import org.eclipse.core.runtime.Platform;
38 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
39 import org.eclipse.osgi.util.NLS;
40 import org.eclipse.swt.SWT;
41 import org.eclipse.swt.widgets.Display;
42 import org.eclipse.ui.PlatformUI;
43 import org.osgi.service.prefs.BackingStoreException;
44
45 import pl.edu.agh.cast.Activator;
46 import pl.edu.agh.cast.CastApplication;
47 import pl.edu.agh.cast.CoreServiceLocator;
48 import pl.edu.agh.cast.data.persistence.IPersistenceProvider;
49 import pl.edu.agh.cast.data.persistence.PersistenceException;
50 import pl.edu.agh.cast.data.persistence.PersistenceProviderLocator;
51 import pl.edu.agh.cast.ui.dialogs.ProjectStartupDialog;
52 import pl.edu.agh.cast.ui.util.MsgBoxHelper;
53 import pl.edu.agh.cast.util.Configuration;
54 import pl.edu.agh.cast.util.Messages;
55
56
57
58
59
60
61 public final class ProjectUtil implements PropertyChangeListener {
62
63 private static final Logger LOG = Activator.getLogger();
64
65
66
67 public static final String PROJECT_VERSION = "0.5.x";
68
69
70
71
72 @SuppressWarnings("nls")
73 public static final String[] PROJECT_BAD_CHARS = new String[] { "\\", "/", ":", "*", "?", "<", ">", "|", ",", "." };
74
75
76
77
78 public static final String PROJECT_DISPLAY_NAME_PROPERTY = "project.displayName";
79
80
81
82
83 public static final String PROJECT_VERSION_PROPERTY = "project.version";
84
85
86
87
88 public static final String PROJECT_ID_PROPERTY = "project.id";
89
90
91
92
93 public static final String PERSISTENCE_PROVIDER_ID_PROPERTY = "persistence.id";
94
95
96
97
98 public static final String PERSISTENCE_PROVIDER_CONFIG_PROPERTY = "persistence.file";
99
100
101
102
103
104
105
106
107 public static enum ProjectOpenStatus {
108 OPENED, LOCKED, INVALID_VERSION;
109 }
110
111
112
113
114
115
116
117
118
119
120
121
122 public static String getProperty(IProject project, String propertyId) {
123 ProjectScope ps = new ProjectScope(project);
124 return ps.getNode(Activator.PLUGIN_ID).get(propertyId, null);
125 }
126
127
128
129
130
131
132
133
134
135
136
137 public static void setProperty(IProject project, String propertyId, String value) {
138 ProjectScope ps = new ProjectScope(project);
139 IEclipsePreferences node = ps.getNode(Activator.PLUGIN_ID);
140 node.put(propertyId, value);
141 try {
142 node.flush();
143 } catch (BackingStoreException e) {
144 Logger.getLogger(ProjectUtil.class).error("Failed to save property " + propertyId, e);
145 }
146 }
147
148
149
150
151
152
153
154
155
156
157 private static class ProjectUtilHolder {
158 private static final ProjectUtil INSTANCE = new ProjectUtil();
159 }
160
161
162
163
164 private ProjectUtil() {
165 if (CastApplication.getPropertyChangeProvider() != null) {
166 CastApplication.getPropertyChangeProvider().addPropertyChangeListener(this);
167 }
168 }
169
170
171
172
173
174
175 public static ProjectUtil getInstance() {
176 return ProjectUtilHolder.INSTANCE;
177 }
178
179
180
181
182
183
184
185
186
187
188
189
190 public String getDisplayName(IProject project) {
191 String displayName = getProperty(project, PROJECT_DISPLAY_NAME_PROPERTY);
192 return displayName != null && displayName.length() > 0 ? displayName : project.getName();
193 }
194
195
196
197
198
199
200
201
202
203 public void setDisplayName(final IProject project, final String name) {
204 UserPreferences.getInstance().changeMostRecentlyProjectName(project, name);
205 setProperty(project, PROJECT_DISPLAY_NAME_PROPERTY, name);
206 }
207
208
209
210
211
212
213
214
215 public String escapeName(String name) {
216 String r = name.replaceAll("[\\\\//?:]", "_"); //$NON-NLS-1$ //$NON-NLS-2$
217 String s = new File(r).toURI().getPath();
218 if (s.lastIndexOf('/') == s.length() - 1) {
219 s = s.substring(0, s.length() - 1);
220 }
221 s = s.substring(s.lastIndexOf('/') + 1);
222 return s;
223 }
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239 public IProject createProject(String projectName, IPath location) throws CoreException {
240
241 IWorkspace workspace = ResourcesPlugin.getWorkspace();
242 IProjectDescription pd = workspace.newProjectDescription(projectName);
243 if (Platform.getLocation() != null && location != null && !Platform.getLocation().isPrefixOf(location)) {
244 pd.setLocation(location);
245 } else {
246 pd.setLocation(null);
247 }
248
249 IProject project = workspace.getRoot().getProject(projectName);
250
251 if (!project.exists()) {
252 project.create(pd, null);
253 project.open(null);
254
255 if (getProperty(project, PROJECT_DISPLAY_NAME_PROPERTY) == null) {
256 setDisplayName(project, projectName);
257 }
258 if (getProperty(project, PROJECT_ID_PROPERTY) == null) {
259 setProperty(project, PROJECT_ID_PROPERTY, generateProjectId());
260 }
261
262 String dummyFileName = projectName + "." + Configuration.DUMMY_PROJECT_FILE_EXTENSION;
263 IFile dummyFile = project.getFile(dummyFileName);
264 dummyFile.create(new ByteArrayInputStream(new byte[0]), true, null);
265
266 init(project);
267 }
268 if (!project.isOpen()) {
269 project.open(null);
270 }
271
272 return project;
273 }
274
275
276
277
278
279
280
281
282 public void init(IProject project) throws CoreException {
283 String id = getProperty(project, ProjectUtil.PROJECT_ID_PROPERTY);
284 if (id == null) {
285 id = generateProjectId();
286 setProperty(project, ProjectUtil.PROJECT_ID_PROPERTY, id);
287 }
288
289 setProperty(project, PROJECT_VERSION_PROPERTY, PROJECT_VERSION);
290
291 String providerId = getProperty(project, PERSISTENCE_PROVIDER_ID_PROPERTY);
292 if (providerId == null) {
293 providerId = PersistenceProviderLocator.selectPersistenceProvider();
294 setProperty(project, PERSISTENCE_PROVIDER_ID_PROPERTY, providerId);
295 }
296
297 String providerFile = getProperty(project, PERSISTENCE_PROVIDER_CONFIG_PROPERTY);
298 if (providerFile == null) {
299 providerFile = PersistenceProviderLocator.getPersistenceFilePath(providerId);
300 setProperty(project, PERSISTENCE_PROVIDER_CONFIG_PROPERTY, providerFile);
301 }
302 IFile file = project.getFile(providerFile);
303 if (!file.exists()) {
304 file.create(new ByteArrayInputStream(new byte[0]), true, null);
305 }
306 }
307
308
309
310
311
312
313
314
315
316
317
318 public IProject createAndActivateProject(String projectName, IPath location) throws CoreException {
319 IProject project = createProject(projectName, location);
320
321 CastApplication.setActiveProject(project);
322 initializePersistenceProvider(project);
323 return project;
324 }
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345 public ProjectOpenStatus openProject(String location, boolean force) throws FileNotFoundException, CoreException {
346 ProjectOpenStatus res = ProjectOpenStatus.OPENED;
347 IWorkspace workspace = ResourcesPlugin.getWorkspace();
348
349 IProjectDescription projectDescription = workspace.loadProjectDescription(new FileInputStream(location
350 + File.separator + IProjectDescription.DESCRIPTION_FILE_NAME));
351
352 if (!Platform.getLocation().isPrefixOf(Path.fromOSString(location))) {
353 projectDescription.setLocation(Path.fromOSString(location));
354 }
355
356
357 IProject project = workspace.getRoot().getProject(projectDescription.getName());
358
359 if (project.exists()) {
360 if (!force) {
361
362 res = ProjectOpenStatus.LOCKED;
363 } else {
364
365 project.delete(false, false, null);
366 project.create(projectDescription, null);
367 res = ProjectOpenStatus.OPENED;
368 }
369 } else {
370 project.create(projectDescription, null);
371 res = ProjectOpenStatus.OPENED;
372 }
373
374 if (res == ProjectOpenStatus.OPENED) {
375 project.open(null);
376 if (!PROJECT_VERSION.equals(getProperty(project, PROJECT_VERSION_PROPERTY))) {
377 project.close(null);
378 project.delete(false, false, null);
379 return ProjectOpenStatus.INVALID_VERSION;
380 }
381 CastApplication.setActiveProject(project);
382 initializePersistenceProvider(project);
383 }
384
385 return res;
386
387 }
388
389
390
391
392
393
394
395
396
397 public IProject changeProjectLocation(String newLocation) {
398 IWorkspace workspace = ResourcesPlugin.getWorkspace();
399 try {
400
401 IProjectDescription projectDescription = workspace.loadProjectDescription(new FileInputStream(newLocation
402 + File.separator + IProjectDescription.DESCRIPTION_FILE_NAME));
403
404 IProject project = workspace.getRoot().getProject(projectDescription.getName());
405
406 if (!Platform.getLocation().isPrefixOf(Path.fromOSString(newLocation))) {
407 projectDescription.setLocation(Path.fromOSString(newLocation));
408 }
409 project.delete(false, false, null);
410 project.create(projectDescription, null);
411 LOG.info("Project " + projectDescription.getName() + " moved to "
412 + newLocation);
413 return project;
414 } catch (FileNotFoundException e) {
415 e.printStackTrace();
416 } catch (CoreException e) {
417 e.printStackTrace();
418 }
419 return null;
420 }
421
422
423
424
425
426
427 public String generateProjectId() {
428 return "CAST_project_" +
429 System.currentTimeMillis();
430 }
431
432
433
434
435
436
437
438
439
440 public boolean tryOpenRecentProject(MostRecentlyUsedProject mrup) {
441 ProjectOpenStatus res = ProjectOpenStatus.OPENED;
442 boolean foundSomewhere = false;
443
444 if (!ProjectUtil.getInstance().closeProject(CastApplication.getActiveProject())) {
445 return true;
446 }
447
448 for (IPath path : mrup.getLocations()) {
449 try {
450 res = ProjectUtil.getInstance().openProject(path.toOSString(), false);
451 switch (res) {
452 case LOCKED: {
453
454
455
456
457 foundSomewhere = true;
458 if (ProjectUtil.getInstance().handleExistingProjectAction(path.toOSString())) {
459 res = ProjectOpenStatus.OPENED;
460 break;
461 }
462 break;
463 }
464 }
465 } catch (FileNotFoundException e) {
466 LOG.warn("Failed to open project in location "
467 + path.toOSString(), e);
468 } catch (CoreException e) {
469 LOG.warn("Failed to open project " + path.toOSString(), e);
470 }
471 }
472 if (res != ProjectOpenStatus.OPENED) {
473 int rett = SWT.NO;
474 if (res == ProjectOpenStatus.LOCKED && !foundSomewhere) {
475 rett = MsgBoxHelper.showWarningQuestionBox(Display.getCurrent().getActiveShell(),
476 Messages.ProjectStartupDialog_9, NLS.bind(Messages.ProjectStartupDialog_10, mrup.getName()));
477 } else if (res == ProjectOpenStatus.INVALID_VERSION) {
478 rett = MsgBoxHelper.showWarningQuestionBox(Display.getCurrent().getActiveShell(),
479 Messages.ProjectUtil_WrongVersionTitle, NLS.bind(Messages.ProjectUtil_WrongVersionMRUMessage,
480 mrup.getName(), PROJECT_VERSION));
481 }
482 if (rett == SWT.YES) {
483 UserPreferences.getInstance().removeMRUProject(mrup.getName());
484 }
485 }
486
487 return res == ProjectOpenStatus.OPENED;
488 }
489
490
491
492
493
494
495
496
497 public boolean closeProject(IProject project) {
498 if (project != null) {
499
500 if (PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null) {
501 if (!PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().closeAllEditors(true)) {
502 return false;
503 }
504 }
505 try {
506 project.close(null);
507 project.delete(false, false, null);
508 destroyPersistenceProvider();
509 } catch (CoreException e) {
510 LOG.error("Failed to close project", e);
511 }
512 }
513 return true;
514 }
515
516 public void removeProject(String projectName, IPath location) throws CoreException {
517 IWorkspace workspace = ResourcesPlugin.getWorkspace();
518 IProjectDescription pd = workspace.newProjectDescription(projectName);
519 if (Platform.getLocation() != null && location != null && !Platform.getLocation().isPrefixOf(location)) {
520 pd.setLocation(location);
521 } else {
522 pd.setLocation(null);
523 }
524
525 IProject project = workspace.getRoot().getProject(projectName);
526
527 project.delete(true, null);
528 }
529
530
531
532
533
534
535
536
537
538
539
540
541 public boolean handleExistingProjectAction(String location) {
542 int res = MsgBoxHelper.showQuestionBox(CastApplication.getActiveShell(),
543 Messages.ApplicationWorkbenchAdvisor_7, NLS.bind(Messages.ApplicationWorkbenchAdvisor_8, location));
544 if (res == SWT.YES) {
545 IProject project = changeProjectLocation(location);
546 if (project != null) {
547 try {
548 project.open(null);
549 CastApplication.setActiveProject(project);
550 initializePersistenceProvider(project);
551 return true;
552 } catch (CoreException e) {
553 LOG.error("Failed to open locked project", e);
554 }
555
556 }
557 }
558 return false;
559 }
560
561
562
563
564
565 public void handleNoProjectAction() {
566 CastApplication.setActiveProject(null);
567 if (Boolean.toString(false).equals(
568 UserPreferences.getInstance().getPreference(UserPreferences.Pref.SHOW_PROJECT_STARTUP_DIALOG))) {
569
570 MostRecentlyUsedProject mruProject = UserPreferences.getInstance().getMostRecentlyUsedProjects().get(0);
571 tryOpenRecentProject(mruProject);
572 } else {
573
574 ProjectStartupDialog projectStartupDialog = new ProjectStartupDialog(CastApplication.getActiveShell(),
575 SWT.APPLICATION_MODAL);
576 projectStartupDialog.open();
577 }
578 }
579
580
581
582
583
584
585
586 public void handleWrongProjectLocationAction(String location) {
587 MsgBoxHelper.showWarningBox(CastApplication.getActiveShell(), Messages.ApplicationWorkbenchAdvisor_3, NLS.bind(
588 Messages.ApplicationWorkbenchAdvisor_4, location));
589 CastApplication.setActiveProject(null);
590
591 }
592
593
594
595
596 public void handleInvalidProjectAction() {
597 MsgBoxHelper.showWarningBox(CastApplication.getActiveShell(), Messages.ProjectUtil_WrongVersionTitle, NLS.bind(
598 Messages.ProjectUtil_WrongVersionMessage, PROJECT_VERSION));
599 CastApplication.setActiveProject(null);
600 }
601
602
603
604
605
606
607
608 public void handleMissingProjectFile(String location) {
609 MsgBoxHelper.showWarningBox(CastApplication.getActiveShell(), Messages.ApplicationWorkbenchAdvisor_3, NLS.bind(
610 Messages.ApplicationWorkbenchAdvisor_9, location));
611 CastApplication.setActiveProject(null);
612
613 }
614
615
616
617
618 public void handlePersistenceProviderInitializationError(IProject project) {
619 MsgBoxHelper.showWarningBox(CastApplication.getActiveShell(), Messages.ProjectUtil_InitializationErrorTitle,
620 NLS.bind(Messages.ProjectUtil_InitializationErrorMessage_Persistence, project.getName()));
621 CastApplication.setActiveProject(null);
622 }
623
624
625
626
627
628
629
630
631
632
633 public void propertyChange(PropertyChangeEvent evt) {
634 if (CastApplication.PROPERTY_ACTIVE_PROJECT.equals(evt.getPropertyName())) {
635 if (evt.getNewValue() != null) {
636 UserPreferences.getInstance().registerMostRecentlyUsedProject((IProject)evt.getNewValue());
637 }
638 }
639 }
640
641
642
643
644
645
646
647
648
649 @SuppressWarnings("nls")
650 public void initializePersistenceProvider(IProject project) {
651 String providerId = getProperty(project, PERSISTENCE_PROVIDER_ID_PROPERTY);
652 String providerConfig = getProperty(project, PERSISTENCE_PROVIDER_CONFIG_PROPERTY);
653 IFile configFile = project.getFile(providerConfig);
654 try {
655 IPersistenceProvider provider = PersistenceProviderLocator.createPersistenceProvider(providerId, configFile
656 .getLocation().toOSString());
657 CoreServiceLocator.getPersistenceProvider().setActualProvider(provider);
658 } catch (PersistenceException e) {
659 LOG.error(String.format("Failed to initialize persistence provider for project '{0}' ({1}). "
660 + "\r\nProviderId={2}\r\n persistence file:{3}", project.getName(), project.getLocation()
661 .toOSString(), providerId, providerConfig), e);
662 handlePersistenceProviderInitializationError(project);
663 }
664 }
665
666
667
668
669 public void destroyPersistenceProvider() {
670 CoreServiceLocator.getPersistenceProvider().setActualProvider(null);
671 }
672
673
674
675 }