Lines 77-82
Link Here
|
77 |
import java.util.concurrent.Future; |
77 |
import java.util.concurrent.Future; |
78 |
import java.util.concurrent.TimeUnit; |
78 |
import java.util.concurrent.TimeUnit; |
79 |
import java.util.concurrent.TimeoutException; |
79 |
import java.util.concurrent.TimeoutException; |
|
|
80 |
import java.util.concurrent.atomic.AtomicBoolean; |
81 |
import java.util.concurrent.atomic.AtomicInteger; |
80 |
import java.util.concurrent.locks.Condition; |
82 |
import java.util.concurrent.locks.Condition; |
81 |
import java.util.concurrent.locks.Lock; |
83 |
import java.util.concurrent.locks.Lock; |
82 |
import java.util.concurrent.locks.ReentrantLock; |
84 |
import java.util.concurrent.locks.ReentrantLock; |
Lines 223-238
Link Here
|
223 |
// Implementation of the class --------------------------------------------- |
225 |
// Implementation of the class --------------------------------------------- |
224 |
|
226 |
|
225 |
public static OpenProjectList getDefault() { |
227 |
public static OpenProjectList getDefault() { |
226 |
synchronized ( OpenProjectList.class ) { |
228 |
return ProjectManager.mutex().writeAccess(new Mutex.Action<OpenProjectList>() { |
227 |
if ( INSTANCE == null ) { |
229 |
public @Override OpenProjectList run() { |
228 |
INSTANCE = new OpenProjectList(); |
230 |
if (INSTANCE == null) { |
229 |
INSTANCE.openProjects = loadProjectList(); |
231 |
INSTANCE = new OpenProjectList(); |
230 |
// Load recent project list |
232 |
INSTANCE.openProjects = loadProjectList(); |
231 |
INSTANCE.recentProjects.load(); |
233 |
// Load recent project list |
232 |
WindowManager.getDefault().invokeWhenUIReady(INSTANCE.LOAD); |
234 |
INSTANCE.recentProjects.load(); |
|
|
235 |
WindowManager.getDefault().invokeWhenUIReady(INSTANCE.LOAD); |
236 |
} |
237 |
return INSTANCE; |
233 |
} |
238 |
} |
234 |
} |
239 |
}); |
235 |
return INSTANCE; |
|
|
236 |
} |
240 |
} |
237 |
|
241 |
|
238 |
static void waitProjectsFullyOpen() { |
242 |
static void waitProjectsFullyOpen() { |
Lines 264-274
Link Here
|
264 |
} |
268 |
} |
265 |
|
269 |
|
266 |
/** Modifications to the recentTemplates variables shall be done only |
270 |
/** Modifications to the recentTemplates variables shall be done only |
267 |
* when hodling a lock. |
271 |
* when holding a lock. |
268 |
* @return the list |
272 |
* @return the list |
269 |
*/ |
273 |
*/ |
270 |
private List<String> getRecentTemplates() { |
274 |
private List<String> getRecentTemplates() { |
271 |
assert Thread.holdsLock(this); |
275 |
assert ProjectManager.mutex().isReadAccess() || ProjectManager.mutex().isWriteAccess(); |
272 |
return recentTemplates; |
276 |
return recentTemplates; |
273 |
} |
277 |
} |
274 |
|
278 |
|
Lines 341-348
Link Here
|
341 |
} |
345 |
} |
342 |
} |
346 |
} |
343 |
|
347 |
|
344 |
final void preferredProject(Project lazyP) { |
348 |
final void preferredProject(final Project lazyP) { |
345 |
synchronized (toOpenProjects) { |
349 |
ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
|
|
350 |
public @Override Void run() { |
346 |
for (Project p : toOpenProjects) { |
351 |
for (Project p : toOpenProjects) { |
347 |
FileObject dir = p.getProjectDirectory(); |
352 |
FileObject dir = p.getProjectDirectory(); |
348 |
assert dir != null : "Project has real directory " + p; |
353 |
assert dir != null : "Project has real directory " + p; |
Lines 352-366
Link Here
|
352 |
if (dir.equals(lazyP.getProjectDirectory())) { |
357 |
if (dir.equals(lazyP.getProjectDirectory())) { |
353 |
toOpenProjects.remove(p); |
358 |
toOpenProjects.remove(p); |
354 |
toOpenProjects.addFirst(p); |
359 |
toOpenProjects.addFirst(p); |
355 |
return; |
360 |
return null; |
356 |
} |
361 |
} |
357 |
} |
362 |
} |
358 |
} |
363 |
return null; |
|
|
364 |
} |
365 |
}); |
359 |
} |
366 |
} |
360 |
|
367 |
|
361 |
private void updateGlobalState() { |
368 |
private void updateGlobalState() { |
362 |
log(Level.FINER, "updateGlobalState"); // NOI18N |
369 |
log(Level.FINER, "updateGlobalState"); // NOI18N |
363 |
synchronized (INSTANCE) { |
370 |
ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
|
|
371 |
public @Override Void run() { |
364 |
INSTANCE.openProjects = lazilyOpenedProjects; |
372 |
INSTANCE.openProjects = lazilyOpenedProjects; |
365 |
log(Level.FINER, "openProjects changed: {0}", lazilyOpenedProjects); // NOI18N |
373 |
log(Level.FINER, "openProjects changed: {0}", lazilyOpenedProjects); // NOI18N |
366 |
if (lazyMainProject != null) { |
374 |
if (lazyMainProject != null) { |
Lines 369-375
Link Here
|
369 |
INSTANCE.mainProject = unwrapProject(INSTANCE.mainProject); |
377 |
INSTANCE.mainProject = unwrapProject(INSTANCE.mainProject); |
370 |
INSTANCE.getRecentTemplates().addAll(recentTemplates); |
378 |
INSTANCE.getRecentTemplates().addAll(recentTemplates); |
371 |
log(Level.FINER, "updateGlobalState, applied"); // NOI18N |
379 |
log(Level.FINER, "updateGlobalState, applied"); // NOI18N |
|
|
380 |
return null; |
372 |
} |
381 |
} |
|
|
382 |
}); |
373 |
|
383 |
|
374 |
INSTANCE.pchSupport.firePropertyChange(PROPERTY_OPEN_PROJECTS, new Project[0], lazilyOpenedProjects.toArray(new Project[0])); |
384 |
INSTANCE.pchSupport.firePropertyChange(PROPERTY_OPEN_PROJECTS, new Project[0], lazilyOpenedProjects.toArray(new Project[0])); |
375 |
INSTANCE.pchSupport.firePropertyChange(PROPERTY_MAIN_PROJECT, null, INSTANCE.mainProject); |
385 |
INSTANCE.pchSupport.firePropertyChange(PROPERTY_MAIN_PROJECT, null, INSTANCE.mainProject); |
Lines 377-412
Link Here
|
377 |
log(Level.FINER, "updateGlobalState, done, notified"); // NOI18N |
387 |
log(Level.FINER, "updateGlobalState, done, notified"); // NOI18N |
378 |
} |
388 |
} |
379 |
|
389 |
|
380 |
boolean closeBeforeOpen(Project[] arr) { |
390 |
boolean closeBeforeOpen(final Project[] arr) { |
381 |
NEXT: for (int i = 0; i < arr.length; i++) { |
391 |
return ProjectManager.mutex().writeAccess(new Mutex.Action<Boolean>() { |
382 |
FileObject dir = arr[i].getProjectDirectory(); |
392 |
public @Override Boolean run() { |
383 |
synchronized (toOpenProjects) { |
393 |
NEXT: for (Project p : arr) { |
384 |
for (Iterator<Project> it = toOpenProjects.iterator(); it.hasNext();) { |
394 |
FileObject dir = p.getProjectDirectory(); |
385 |
if (dir.equals(it.next().getProjectDirectory())) { |
395 |
for (Iterator<Project> it = toOpenProjects.iterator(); it.hasNext();) { |
386 |
it.remove(); |
396 |
if (dir.equals(it.next().getProjectDirectory())) { |
387 |
continue NEXT; |
397 |
it.remove(); |
|
|
398 |
continue NEXT; |
399 |
} |
388 |
} |
400 |
} |
|
|
401 |
return false; |
389 |
} |
402 |
} |
390 |
return false; |
403 |
return true; |
391 |
} |
404 |
} |
392 |
} |
405 |
}); |
393 |
return true; |
|
|
394 |
} |
406 |
} |
395 |
|
407 |
|
396 |
private void loadOnBackground() { |
408 |
private void loadOnBackground() { |
397 |
lazilyOpenedProjects = new ArrayList<Project>(); |
409 |
lazilyOpenedProjects = new ArrayList<Project>(); |
398 |
List<URL> URLs = OpenProjectListSettings.getInstance().getOpenProjectsURLs(); |
410 |
List<URL> URLs = OpenProjectListSettings.getInstance().getOpenProjectsURLs(); |
399 |
Project[] inital; |
411 |
final List<Project> initial = new ArrayList<Project>(); |
400 |
final LinkedList<Project> projects = URLs2Projects(URLs); |
412 |
final LinkedList<Project> projects = URLs2Projects(URLs); |
401 |
synchronized (toOpenProjects) { |
413 |
ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
402 |
toOpenProjects.addAll(projects); |
414 |
public @Override Void run() { |
403 |
log(Level.FINER, "loadOnBackground {0}", toOpenProjects); // NOI18N |
415 |
toOpenProjects.addAll(projects); |
404 |
inital = toOpenProjects.toArray(new Project[0]); |
416 |
log(Level.FINER, "loadOnBackground {0}", toOpenProjects); // NOI18N |
|
|
417 |
initial.addAll(toOpenProjects); |
418 |
return null; |
405 |
} |
419 |
} |
|
|
420 |
}); |
406 |
recentTemplates = new ArrayList<String>( OpenProjectListSettings.getInstance().getRecentTemplates() ); |
421 |
recentTemplates = new ArrayList<String>( OpenProjectListSettings.getInstance().getRecentTemplates() ); |
407 |
URL mainProjectURL = OpenProjectListSettings.getInstance().getMainProjectURL(); |
422 |
final URL mainProjectURL = OpenProjectListSettings.getInstance().getMainProjectURL(); |
408 |
int max; |
423 |
int max = ProjectManager.mutex().writeAccess(new Mutex.Action<Integer>() { |
409 |
synchronized (toOpenProjects) { |
424 |
public @Override Integer run() { |
410 |
for (Project p : toOpenProjects) { |
425 |
for (Project p : toOpenProjects) { |
411 |
INSTANCE.addModuleInfo(p); |
426 |
INSTANCE.addModuleInfo(p); |
412 |
// Set main project |
427 |
// Set main project |
Lines 420-438
Link Here
|
420 |
// Not a main project |
435 |
// Not a main project |
421 |
} |
436 |
} |
422 |
} |
437 |
} |
423 |
max = toOpenProjects.size(); |
438 |
return toOpenProjects.size(); |
424 |
} |
439 |
} |
|
|
440 |
}); |
425 |
progress.switchToDeterminate(max); |
441 |
progress.switchToDeterminate(max); |
426 |
for (;;) { |
442 |
for (;;) { |
427 |
Project p; |
443 |
final AtomicInteger openPrjSize = new AtomicInteger(); |
428 |
int openPrjSize; |
444 |
Project p = ProjectManager.mutex().writeAccess(new Mutex.Action<Project>() { |
429 |
synchronized (toOpenProjects) { |
445 |
public @Override Project run() { |
430 |
if (toOpenProjects.isEmpty()) { |
446 |
if (toOpenProjects.isEmpty()) { |
431 |
break; |
447 |
return null; |
|
|
448 |
} |
449 |
Project p = toOpenProjects.remove(); |
450 |
log(Level.FINER, "after remove {0}", toOpenProjects); // NOI18N |
451 |
openPrjSize.set(toOpenProjects.size()); |
452 |
return p; |
432 |
} |
453 |
} |
433 |
p = toOpenProjects.remove(); |
454 |
}); |
434 |
log(Level.FINER, "after remove {0}", toOpenProjects); // NOI18N |
455 |
if (p == null) { |
435 |
openPrjSize = toOpenProjects.size(); |
456 |
break; |
436 |
} |
457 |
} |
437 |
log(Level.FINE, "about to open a project {0}", p); // NOI18N |
458 |
log(Level.FINE, "about to open a project {0}", p); // NOI18N |
438 |
if (notifyOpened(p)) { |
459 |
if (notifyOpened(p)) { |
Lines 451-462
Link Here
|
451 |
lazyMainProject = null; |
472 |
lazyMainProject = null; |
452 |
} |
473 |
} |
453 |
} |
474 |
} |
454 |
progress.progress(max - openPrjSize); |
475 |
progress.progress(max - openPrjSize.get()); |
455 |
} |
476 |
} |
456 |
|
477 |
|
457 |
if (inital != null) { |
478 |
if (initial != null) { |
458 |
log(createRecord("UI_INIT_PROJECTS", inital),"org.netbeans.ui.projects"); |
479 |
Project[] initialA = initial.toArray(new Project[initial.size()]); |
459 |
log(createRecordMetrics("USG_PROJECT_OPEN", inital),"org.netbeans.ui.metrics.projects"); |
480 |
log(createRecord("UI_INIT_PROJECTS", initialA),"org.netbeans.ui.projects"); |
|
|
481 |
log(createRecordMetrics("USG_PROJECT_OPEN", initialA),"org.netbeans.ui.metrics.projects"); |
460 |
} |
482 |
} |
461 |
|
483 |
|
462 |
} |
484 |
} |
Lines 687-695
Link Here
|
687 |
|
709 |
|
688 |
final List<Project> oldprjs = new ArrayList<Project>(); |
710 |
final List<Project> oldprjs = new ArrayList<Project>(); |
689 |
final List<Project> newprjs = new ArrayList<Project>(); |
711 |
final List<Project> newprjs = new ArrayList<Project>(); |
690 |
synchronized (this) { |
712 |
ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
691 |
oldprjs.addAll(openProjects); |
713 |
public @Override Void run() { |
692 |
} |
714 |
oldprjs.addAll(openProjects); |
|
|
715 |
return null; |
716 |
} |
717 |
}); |
693 |
|
718 |
|
694 |
for (Project p: projectsToOpen) { |
719 |
for (Project p: projectsToOpen) { |
695 |
|
720 |
|
Lines 707-720
Link Here
|
707 |
handle.progress((int) currentWork); |
732 |
handle.progress((int) currentWork); |
708 |
} |
733 |
} |
709 |
} |
734 |
} |
710 |
|
735 |
|
711 |
synchronized ( this ) { |
736 |
final boolean _recentProjectsChanged = recentProjectsChanged; |
712 |
newprjs.addAll(openProjects); |
737 |
ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
713 |
saveProjectList( openProjects ); |
738 |
public @Override Void run() { |
714 |
if ( recentProjectsChanged ) { |
739 |
newprjs.addAll(openProjects); |
715 |
recentProjects.save(); |
740 |
saveProjectList(openProjects); |
|
|
741 |
if (_recentProjectsChanged) { |
742 |
recentProjects.save(); |
743 |
} |
744 |
return null; |
716 |
} |
745 |
} |
717 |
} |
746 |
}); |
718 |
|
747 |
|
719 |
if (handle != null) { |
748 |
if (handle != null) { |
720 |
handle.finish(); |
749 |
handle.finish(); |
Lines 750-756
Link Here
|
750 |
LOAD.waitFinished(); |
779 |
LOAD.waitFinished(); |
751 |
} |
780 |
} |
752 |
|
781 |
|
753 |
Project[] projects = new Project[someProjects.length]; |
782 |
final Project[] projects = new Project[someProjects.length]; |
754 |
for (int i = 0; i < someProjects.length; i++) { |
783 |
for (int i = 0; i < someProjects.length; i++) { |
755 |
projects[i] = unwrapProject(someProjects[i]); |
784 |
projects[i] = unwrapProject(someProjects[i]); |
756 |
} |
785 |
} |
Lines 764-781
Link Here
|
764 |
LOAD.enter(); |
793 |
LOAD.enter(); |
765 |
ProjectUtilities.WaitCursor.show(); |
794 |
ProjectUtilities.WaitCursor.show(); |
766 |
logProjects("close(): closing project: ", projects); |
795 |
logProjects("close(): closing project: ", projects); |
767 |
boolean mainClosed = false; |
796 |
final AtomicBoolean mainClosed = new AtomicBoolean(); |
768 |
boolean someClosed = false; |
797 |
final AtomicBoolean someClosed = new AtomicBoolean(); |
769 |
List<Project> oldprjs = new ArrayList<Project>(); |
798 |
final List<Project> oldprjs = new ArrayList<Project>(); |
770 |
List<Project> newprjs = new ArrayList<Project>(); |
799 |
final List<Project> newprjs = new ArrayList<Project>(); |
771 |
final List<Project> notifyList = new ArrayList<Project>(); |
800 |
final List<Project> notifyList = new ArrayList<Project>(); |
772 |
synchronized ( this ) { |
801 |
ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
|
|
802 |
public @Override Void run() { |
773 |
oldprjs.addAll(openProjects); |
803 |
oldprjs.addAll(openProjects); |
774 |
for( int i = 0; i < projects.length; i++ ) { |
804 |
for (Project p : projects) { |
775 |
Iterator<Project> it = openProjects.iterator(); |
805 |
Iterator<Project> it = openProjects.iterator(); |
776 |
boolean found = false; |
806 |
boolean found = false; |
777 |
while (it.hasNext()) { |
807 |
while (it.hasNext()) { |
778 |
if (it.next().equals(projects[i])) { |
808 |
if (it.next().equals(p)) { |
779 |
found = true; |
809 |
found = true; |
780 |
break; |
810 |
break; |
781 |
} |
811 |
} |
Lines 783-810
Link Here
|
783 |
if (!found) { |
813 |
if (!found) { |
784 |
continue; // Nothing to remove |
814 |
continue; // Nothing to remove |
785 |
} |
815 |
} |
786 |
if ( !mainClosed ) { |
816 |
if (!mainClosed.get()) { |
787 |
mainClosed = isMainProject( projects[i] ); |
817 |
mainClosed.set(isMainProject(p)); |
788 |
} |
818 |
} |
789 |
// remove the project from openProjects |
819 |
// remove the project from openProjects |
790 |
it.remove(); |
820 |
it.remove(); |
791 |
removeModuleInfo(projects[i]); |
821 |
removeModuleInfo(p); |
792 |
|
822 |
|
793 |
projects[i].getProjectDirectory().removeFileChangeListener(deleteListener); |
823 |
p.getProjectDirectory().removeFileChangeListener(deleteListener); |
794 |
|
824 |
|
795 |
notifyList.add(projects[i]); |
825 |
notifyList.add(p); |
796 |
|
826 |
|
797 |
someClosed = true; |
827 |
someClosed.set(true); |
798 |
} |
828 |
} |
799 |
if ( someClosed ) { |
829 |
if (someClosed.get()) { |
800 |
newprjs.addAll(openProjects); |
830 |
newprjs.addAll(openProjects); |
801 |
saveProjectList(openProjects); |
831 |
saveProjectList(openProjects); |
802 |
} |
832 |
} |
803 |
if ( mainClosed ) { |
833 |
if (mainClosed.get()) { |
804 |
this.mainProject = null; |
834 |
mainProject = null; |
805 |
saveMainProject( mainProject ); |
835 |
saveMainProject( mainProject ); |
806 |
} |
836 |
} |
|
|
837 |
return null; |
807 |
} |
838 |
} |
|
|
839 |
}); |
808 |
if (!notifyList.isEmpty()) { |
840 |
if (!notifyList.isEmpty()) { |
809 |
for (Project p : notifyList) { |
841 |
for (Project p : notifyList) { |
810 |
recentProjects.add(p); // #183681: call outside of lock |
842 |
recentProjects.add(p); // #183681: call outside of lock |
Lines 820-833
Link Here
|
820 |
} |
852 |
} |
821 |
}); |
853 |
}); |
822 |
logProjects("close(): openProjects == ", openProjects.toArray(new Project[0])); // NOI18N |
854 |
logProjects("close(): openProjects == ", openProjects.toArray(new Project[0])); // NOI18N |
823 |
if ( someClosed ) { |
855 |
if (someClosed.get()) { |
824 |
pchSupport.firePropertyChange( PROPERTY_OPEN_PROJECTS, |
856 |
pchSupport.firePropertyChange( PROPERTY_OPEN_PROJECTS, |
825 |
oldprjs.toArray(new Project[oldprjs.size()]), newprjs.toArray(new Project[newprjs.size()]) ); |
857 |
oldprjs.toArray(new Project[oldprjs.size()]), newprjs.toArray(new Project[newprjs.size()]) ); |
826 |
} |
858 |
} |
827 |
if ( mainClosed ) { |
859 |
if (mainClosed.get()) { |
828 |
pchSupport.firePropertyChange( PROPERTY_MAIN_PROJECT, null, null ); |
860 |
pchSupport.firePropertyChange( PROPERTY_MAIN_PROJECT, null, null ); |
829 |
} |
861 |
} |
830 |
if ( someClosed ) { |
862 |
if (someClosed.get()) { |
831 |
pchSupport.firePropertyChange( PROPERTY_RECENT_PROJECTS, null, null ); |
863 |
pchSupport.firePropertyChange( PROPERTY_RECENT_PROJECTS, null, null ); |
832 |
} |
864 |
} |
833 |
if (doSave) { |
865 |
if (doSave) { |
Lines 854-912
Link Here
|
854 |
} |
886 |
} |
855 |
} |
887 |
} |
856 |
|
888 |
|
857 |
public synchronized Project[] getOpenProjects() { |
889 |
public Project[] getOpenProjects() { |
858 |
Project projects[] = new Project[ openProjects.size() ]; |
890 |
return ProjectManager.mutex().readAccess(new Mutex.Action<Project[]>() { |
859 |
openProjects.toArray( projects ); |
891 |
public @Override Project[] run() { |
860 |
return projects; |
892 |
return openProjects.toArray(new Project[openProjects.size()]); |
|
|
893 |
} |
894 |
}); |
861 |
} |
895 |
} |
862 |
|
896 |
|
863 |
public synchronized boolean isOpen( Project p ) { |
897 |
public boolean isOpen(final Project p) { |
864 |
// XXX shouldn't this just use openProjects.contains(p)? |
898 |
// XXX shouldn't this just use openProjects.contains(p)? |
865 |
for(Project cp : openProjects) { |
899 |
return ProjectManager.mutex().readAccess(new Mutex.Action<Boolean>() { |
866 |
if ( p.getProjectDirectory().equals( cp.getProjectDirectory() ) ) { |
900 |
public @Override Boolean run() { |
867 |
return true; |
901 |
for (Project cp : openProjects) { |
|
|
902 |
if (p.getProjectDirectory().equals(cp.getProjectDirectory())) { |
903 |
return true; |
904 |
} |
905 |
} |
906 |
return false; |
868 |
} |
907 |
} |
869 |
} |
908 |
}); |
870 |
return false; |
|
|
871 |
} |
909 |
} |
872 |
|
910 |
|
873 |
public synchronized boolean isMainProject( Project p ) { |
911 |
public boolean isMainProject(final Project p) { |
874 |
|
912 |
return ProjectManager.mutex().readAccess(new Mutex.Action<Boolean>() { |
875 |
if ( mainProject != null && p != null && |
913 |
public @Override Boolean run() { |
876 |
mainProject.getProjectDirectory().equals( p.getProjectDirectory() ) ) { |
914 |
if (mainProject != null && p != null && mainProject.getProjectDirectory().equals(p.getProjectDirectory())) { |
877 |
return true; |
915 |
return true; |
878 |
} |
916 |
} else { |
879 |
else { |
917 |
return false; |
880 |
return false; |
918 |
} |
881 |
} |
919 |
} |
882 |
|
920 |
}); |
883 |
} |
921 |
} |
884 |
|
922 |
|
885 |
public synchronized Project getMainProject() { |
923 |
public Project getMainProject() { |
886 |
return mainProject; |
924 |
return ProjectManager.mutex().readAccess(new Mutex.Action<Project>() { |
|
|
925 |
public @Override Project run() { |
926 |
return mainProject; |
927 |
} |
928 |
}); |
887 |
} |
929 |
} |
888 |
|
930 |
|
889 |
public void setMainProject( Project mainProject ) { |
931 |
public void setMainProject( final Project mainProject ) { |
890 |
LOGGER.finer("Setting main project: " + mainProject); // NOI18N |
932 |
LOGGER.finer("Setting main project: " + mainProject); // NOI18N |
891 |
logProjects("setMainProject(): openProjects == ", openProjects.toArray(new Project[0])); // NOI18N |
933 |
logProjects("setMainProject(): openProjects == ", openProjects.toArray(new Project[0])); // NOI18N |
892 |
synchronized ( this ) { |
934 |
ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
893 |
if (mainProject != null && !openProjects.contains(mainProject)) { |
935 |
public @Override Void run() { |
|
|
936 |
Project main = mainProject; |
937 |
if (main != null && !openProjects.contains(main)) { |
894 |
//#139965 the project passed in here can be different from the current one. |
938 |
//#139965 the project passed in here can be different from the current one. |
895 |
// eg when the ManProjectAction shows a list of opened projects, it lists the "non-loaded skeletons" |
939 |
// eg when the ManProjectAction shows a list of opened projects, it lists the "non-loaded skeletons" |
896 |
// but when the user eventually selects one, the openProjects list already might hold the |
940 |
// but when the user eventually selects one, the openProjects list already might hold the |
897 |
// correct loaded list. |
941 |
// correct loaded list. |
898 |
try { |
942 |
try { |
899 |
mainProject = ProjectManager.getDefault().findProject(mainProject.getProjectDirectory()); |
943 |
main = ProjectManager.getDefault().findProject(main.getProjectDirectory()); |
900 |
if (mainProject != null) { |
944 |
if (main != null) { |
901 |
boolean fail = true; |
945 |
boolean fail = true; |
902 |
for (Project p : openProjects) { |
946 |
for (Project p : openProjects) { |
903 |
if (p.equals(mainProject)) { |
947 |
if (p.equals(main)) { |
904 |
fail = false; |
948 |
fail = false; |
905 |
break; |
949 |
break; |
906 |
} |
950 |
} |
907 |
if (p instanceof LazyProject) { |
951 |
if (p instanceof LazyProject) { |
908 |
if (p.getProjectDirectory().equals(mainProject.getProjectDirectory())) { |
952 |
if (p.getProjectDirectory().equals(main.getProjectDirectory())) { |
909 |
mainProject = p; |
953 |
main = p; |
910 |
fail = false; |
954 |
fail = false; |
911 |
break; |
955 |
break; |
912 |
} |
956 |
} |
Lines 922-939
Link Here
|
922 |
} |
966 |
} |
923 |
} |
967 |
} |
924 |
|
968 |
|
925 |
this.mainProject = mainProject; |
969 |
OpenProjectList.this.mainProject = main; |
926 |
saveMainProject( mainProject ); |
970 |
saveMainProject(main); |
|
|
971 |
return null; |
927 |
} |
972 |
} |
|
|
973 |
}); |
928 |
pchSupport.firePropertyChange( PROPERTY_MAIN_PROJECT, null, null ); |
974 |
pchSupport.firePropertyChange( PROPERTY_MAIN_PROJECT, null, null ); |
929 |
} |
975 |
} |
930 |
|
976 |
|
931 |
public List<Project> getRecentProjects() { |
977 |
public List<Project> getRecentProjects() { |
932 |
return ProjectManager.mutex().readAccess(new Mutex.Action<List<Project>>() { |
978 |
return ProjectManager.mutex().readAccess(new Mutex.Action<List<Project>>() { |
933 |
public List<Project> run() { |
979 |
public List<Project> run() { |
934 |
synchronized (OpenProjectList.class) { |
980 |
return recentProjects.getProjects(); |
935 |
return recentProjects.getProjects(); |
|
|
936 |
} |
937 |
} |
981 |
} |
938 |
}); |
982 |
}); |
939 |
} |
983 |
} |
Lines 941-949
Link Here
|
941 |
public boolean isRecentProjectsEmpty() { |
985 |
public boolean isRecentProjectsEmpty() { |
942 |
return ProjectManager.mutex().readAccess(new Mutex.Action<Boolean>() { |
986 |
return ProjectManager.mutex().readAccess(new Mutex.Action<Boolean>() { |
943 |
public Boolean run() { |
987 |
public Boolean run() { |
944 |
synchronized (OpenProjectList.class) { |
988 |
return recentProjects.isEmpty(); |
945 |
return recentProjects.isEmpty(); |
|
|
946 |
} |
947 |
} |
989 |
} |
948 |
}); |
990 |
}); |
949 |
} |
991 |
} |
Lines 951-959
Link Here
|
951 |
public List<UnloadedProjectInformation> getRecentProjectsInformation() { |
993 |
public List<UnloadedProjectInformation> getRecentProjectsInformation() { |
952 |
return ProjectManager.mutex().readAccess(new Mutex.Action<List<UnloadedProjectInformation>>() { |
994 |
return ProjectManager.mutex().readAccess(new Mutex.Action<List<UnloadedProjectInformation>>() { |
953 |
public List<UnloadedProjectInformation> run() { |
995 |
public List<UnloadedProjectInformation> run() { |
954 |
synchronized (OpenProjectList.class) { |
996 |
return recentProjects.getRecentProjectsInfo(); |
955 |
return recentProjects.getRecentProjectsInfo(); |
|
|
956 |
} |
957 |
} |
997 |
} |
958 |
}); |
998 |
}); |
959 |
} |
999 |
} |
Lines 997-1003
Link Here
|
997 |
|
1037 |
|
998 |
|
1038 |
|
999 |
// Used from NewFile action |
1039 |
// Used from NewFile action |
1000 |
public synchronized void updateTemplatesLRU( FileObject template ) { |
1040 |
public void updateTemplatesLRU(final FileObject template) { |
|
|
1041 |
ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
1042 |
public @Override Void run() { |
1001 |
|
1043 |
|
1002 |
String templateName = template.getPath(); |
1044 |
String templateName = template.getPath(); |
1003 |
|
1045 |
|
Lines 1011-1016
Link Here
|
1011 |
} |
1053 |
} |
1012 |
|
1054 |
|
1013 |
OpenProjectListSettings.getInstance().setRecentTemplates( new ArrayList<String>( getRecentTemplates() ) ); |
1055 |
OpenProjectListSettings.getInstance().setRecentTemplates( new ArrayList<String>( getRecentTemplates() ) ); |
|
|
1056 |
return null; |
1057 |
} |
1058 |
}); |
1014 |
} |
1059 |
} |
1015 |
|
1060 |
|
1016 |
|
1061 |
|
Lines 1159-1167
Link Here
|
1159 |
} |
1204 |
} |
1160 |
|
1205 |
|
1161 |
private boolean doOpenProject(final Project p) { |
1206 |
private boolean doOpenProject(final Project p) { |
1162 |
boolean recentProjectsChanged; |
|
|
1163 |
LOGGER.finer("doOpenProject(): opening project " + p.toString()); |
1207 |
LOGGER.finer("doOpenProject(): opening project " + p.toString()); |
1164 |
synchronized (this) { |
1208 |
boolean recentProjectsChanged = ProjectManager.mutex().writeAccess(new Mutex.Action<Boolean>() { |
|
|
1209 |
public @Override Boolean run() { |
1165 |
log(Level.FINER, "already opened: {0} ", openProjects); |
1210 |
log(Level.FINER, "already opened: {0} ", openProjects); |
1166 |
for (Project existing : openProjects) { |
1211 |
for (Project existing : openProjects) { |
1167 |
if (p.equals(existing) || existing.equals(p)) { |
1212 |
if (p.equals(existing) || existing.equals(p)) { |
Lines 1174-1181
Link Here
|
1174 |
p.getProjectDirectory().addFileChangeListener(deleteListener); |
1219 |
p.getProjectDirectory().addFileChangeListener(deleteListener); |
1175 |
p.getProjectDirectory().addFileChangeListener(nbprojectDeleteListener); |
1220 |
p.getProjectDirectory().addFileChangeListener(nbprojectDeleteListener); |
1176 |
|
1221 |
|
1177 |
recentProjectsChanged = recentProjects.remove(p); |
1222 |
return recentProjects.remove(p); |
1178 |
} |
1223 |
} |
|
|
1224 |
}); |
1179 |
logProjects("doOpenProject(): openProjects == ", openProjects.toArray(new Project[0])); // NOI18N |
1225 |
logProjects("doOpenProject(): openProjects == ", openProjects.toArray(new Project[0])); // NOI18N |
1180 |
// Notify projects opened |
1226 |
// Notify projects opened |
1181 |
notifyOpened(p); |
1227 |
notifyOpened(p); |
Lines 1238-1261
Link Here
|
1238 |
} |
1284 |
} |
1239 |
} |
1285 |
} |
1240 |
|
1286 |
|
1241 |
private ArrayList<FileObject> getTemplateNamesLRU( Project project, PrivilegedTemplates priv ) { |
1287 |
private ArrayList<FileObject> getTemplateNamesLRU( final Project project, PrivilegedTemplates priv ) { |
1242 |
// First take recently used templates and try to find those which |
1288 |
// First take recently used templates and try to find those which |
1243 |
// are supported by the project. |
1289 |
// are supported by the project. |
1244 |
|
1290 |
|
1245 |
ArrayList<FileObject> result = new ArrayList<FileObject>(NUM_TEMPLATES); |
1291 |
final ArrayList<FileObject> result = new ArrayList<FileObject>(NUM_TEMPLATES); |
1246 |
|
1292 |
|
1247 |
RecommendedTemplates rt = project.getLookup().lookup( RecommendedTemplates.class ); |
1293 |
RecommendedTemplates rt = project.getLookup().lookup( RecommendedTemplates.class ); |
1248 |
String rtNames[] = rt == null ? new String[0] : rt.getRecommendedTypes(); |
1294 |
String rtNames[] = rt == null ? new String[0] : rt.getRecommendedTypes(); |
1249 |
PrivilegedTemplates pt = priv != null ? priv : project.getLookup().lookup( PrivilegedTemplates.class ); |
1295 |
PrivilegedTemplates pt = priv != null ? priv : project.getLookup().lookup( PrivilegedTemplates.class ); |
1250 |
String ptNames[] = pt == null ? null : pt.getPrivilegedTemplates(); |
1296 |
String ptNames[] = pt == null ? null : pt.getPrivilegedTemplates(); |
1251 |
ArrayList<String> privilegedTemplates = new ArrayList<String>( Arrays.asList( pt == null ? new String[0]: ptNames ) ); |
1297 |
final ArrayList<String> privilegedTemplates = new ArrayList<String>( Arrays.asList( pt == null ? new String[0]: ptNames ) ); |
1252 |
|
1298 |
|
1253 |
if (priv == null) { |
1299 |
if (priv == null) { |
1254 |
// when the privileged templates are part of the active lookup, |
1300 |
// when the privileged templates are part of the active lookup, |
1255 |
// do not mix them with the recent templates, but use only the privileged ones. |
1301 |
// do not mix them with the recent templates, but use only the privileged ones. |
1256 |
// eg. on Webservices node, one is not interested in a recent "jsp" file template.. |
1302 |
// eg. on Webservices node, one is not interested in a recent "jsp" file template.. |
1257 |
|
1303 |
|
1258 |
synchronized (this) { |
1304 |
ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
|
|
1305 |
public @Override Void run() { |
1259 |
Iterator<String> it = getRecentTemplates().iterator(); |
1306 |
Iterator<String> it = getRecentTemplates().iterator(); |
1260 |
for( int i = 0; i < NUM_TEMPLATES && it.hasNext(); i++ ) { |
1307 |
for( int i = 0; i < NUM_TEMPLATES && it.hasNext(); i++ ) { |
1261 |
String templateName = it.next(); |
1308 |
String templateName = it.next(); |
Lines 1271-1277
Link Here
|
1271 |
continue; |
1318 |
continue; |
1272 |
} |
1319 |
} |
1273 |
} |
1320 |
} |
|
|
1321 |
return null; |
1274 |
} |
1322 |
} |
|
|
1323 |
}); |
1275 |
} |
1324 |
} |
1276 |
|
1325 |
|
1277 |
// If necessary fill the list with the rest of privileged templates |
1326 |
// If necessary fill the list with the rest of privileged templates |
Lines 1352-1359
Link Here
|
1352 |
} |
1401 |
} |
1353 |
} |
1402 |
} |
1354 |
|
1403 |
|
1355 |
public void add(Project p) { |
1404 |
public void add(final Project p) { |
1356 |
UnloadedProjectInformation projectInfo; |
1405 |
final UnloadedProjectInformation projectInfo; |
1357 |
try { // #183681: call outside of lock |
1406 |
try { // #183681: call outside of lock |
1358 |
projectInfo = ProjectInfoAccessor.DEFAULT.getProjectInfo( |
1407 |
projectInfo = ProjectInfoAccessor.DEFAULT.getProjectInfo( |
1359 |
ProjectUtils.getInformation(p).getDisplayName(), |
1408 |
ProjectUtils.getInformation(p).getDisplayName(), |
Lines 1363-1369
Link Here
|
1363 |
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); |
1412 |
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); |
1364 |
return; |
1413 |
return; |
1365 |
} |
1414 |
} |
1366 |
synchronized (this) { |
1415 |
ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
|
|
1416 |
public @Override Void run() { |
1367 |
int index = getIndex(p); |
1417 |
int index = getIndex(p); |
1368 |
if (index == -1) { |
1418 |
if (index == -1) { |
1369 |
// Project not in list |
1419 |
// Project not in list |
Lines 1383-1392
Link Here
|
1383 |
} |
1433 |
} |
1384 |
recentProjects.add(0, new ProjectReference(p)); |
1434 |
recentProjects.add(0, new ProjectReference(p)); |
1385 |
recentProjectsInfos.add(0, projectInfo); |
1435 |
recentProjectsInfos.add(0, projectInfo); |
|
|
1436 |
return null; |
1386 |
} |
1437 |
} |
|
|
1438 |
}); |
1387 |
} |
1439 |
} |
1388 |
|
1440 |
|
1389 |
public synchronized boolean remove( Project p ) { |
1441 |
public boolean remove(final Project p) { |
|
|
1442 |
return ProjectManager.mutex().writeAccess(new Mutex.Action<Boolean>() { |
1443 |
public @Override Boolean run() { |
1390 |
int index = getIndex( p ); |
1444 |
int index = getIndex( p ); |
1391 |
if ( index != -1 ) { |
1445 |
if ( index != -1 ) { |
1392 |
LOGGER.log(Level.FINE, "remove recent project: {0} @{1}", new Object[] {p, index}); |
1446 |
LOGGER.log(Level.FINE, "remove recent project: {0} @{1}", new Object[] {p, index}); |
Lines 1395-1406
Link Here
|
1395 |
return true; |
1449 |
return true; |
1396 |
} |
1450 |
} |
1397 |
return false; |
1451 |
return false; |
|
|
1452 |
} |
1453 |
}); |
1398 |
} |
1454 |
} |
1399 |
|
1455 |
|
1400 |
public void refresh() { |
1456 |
public void refresh() { |
1401 |
ProjectManager.mutex().readAccess(new Runnable() { |
1457 |
ProjectManager.mutex().writeAccess(new Runnable() { |
1402 |
public void run () { |
1458 |
public void run () { |
1403 |
synchronized (RecentProjectList.this) { |
|
|
1404 |
assert recentProjects.size() == recentProjectsInfos.size(); |
1459 |
assert recentProjects.size() == recentProjectsInfos.size(); |
1405 |
boolean refresh = false; |
1460 |
boolean refresh = false; |
1406 |
Iterator<ProjectReference> recentProjectsIter = recentProjects.iterator(); |
1461 |
Iterator<ProjectReference> recentProjectsIter = recentProjects.iterator(); |
Lines 1438-1444
Link Here
|
1438 |
pchSupport.firePropertyChange(PROPERTY_RECENT_PROJECTS, null, null); |
1493 |
pchSupport.firePropertyChange(PROPERTY_RECENT_PROJECTS, null, null); |
1439 |
save(); |
1494 |
save(); |
1440 |
} |
1495 |
} |
1441 |
} |
|
|
1442 |
} |
1496 |
} |
1443 |
}); |
1497 |
}); |
1444 |
} |
1498 |
} |
Lines 1473-1479
Link Here
|
1473 |
return empty; |
1527 |
return empty; |
1474 |
} |
1528 |
} |
1475 |
|
1529 |
|
1476 |
public synchronized void load() { |
1530 |
public void load() { |
|
|
1531 |
ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
1532 |
public @Override Void run() { |
1477 |
List<URL> URLs = OpenProjectListSettings.getInstance().getRecentProjectsURLs(); |
1533 |
List<URL> URLs = OpenProjectListSettings.getInstance().getRecentProjectsURLs(); |
1478 |
List<String> names = OpenProjectListSettings.getInstance().getRecentProjectsDisplayNames(); |
1534 |
List<String> names = OpenProjectListSettings.getInstance().getRecentProjectsDisplayNames(); |
1479 |
List<ExtIcon> icons = OpenProjectListSettings.getInstance().getRecentProjectsIcons(); |
1535 |
List<ExtIcon> icons = OpenProjectListSettings.getInstance().getRecentProjectsIcons(); |
Lines 1507-1512
Link Here
|
1507 |
assert p.getProjectDirectory() != null : "Project " + p + " has null project directory"; |
1563 |
assert p.getProjectDirectory() != null : "Project " + p + " has null project directory"; |
1508 |
p.getProjectDirectory().addFileChangeListener(nbprojectDeleteListener); |
1564 |
p.getProjectDirectory().addFileChangeListener(nbprojectDeleteListener); |
1509 |
} |
1565 |
} |
|
|
1566 |
return null; |
1567 |
} |
1568 |
}); |
1510 |
} |
1569 |
} |
1511 |
|
1570 |
|
1512 |
public void save() { |
1571 |
public void save() { |
Lines 1561-1570
Link Here
|
1561 |
return -1; |
1620 |
return -1; |
1562 |
} |
1621 |
} |
1563 |
|
1622 |
|
1564 |
private synchronized List<UnloadedProjectInformation> getRecentProjectsInfo() { |
1623 |
private List<UnloadedProjectInformation> getRecentProjectsInfo() { |
1565 |
// #166408: refreshing is too time expensive and we want to be fast, not correct |
1624 |
// #166408: refreshing is too time expensive and we want to be fast, not correct |
1566 |
//refresh(); |
1625 |
//refresh(); |
1567 |
return new ArrayList<UnloadedProjectInformation>(recentProjectsInfos); |
1626 |
return ProjectManager.mutex().readAccess(new Mutex.Action<List<UnloadedProjectInformation>>() { |
|
|
1627 |
public @Override List<UnloadedProjectInformation> run() { |
1628 |
return new ArrayList<UnloadedProjectInformation>(recentProjectsInfos); |
1629 |
} |
1630 |
}); |
1568 |
} |
1631 |
} |
1569 |
|
1632 |
|
1570 |
private class ProjectReference { |
1633 |
private class ProjectReference { |
Lines 1701-1714
Link Here
|
1701 |
} |
1764 |
} |
1702 |
|
1765 |
|
1703 |
/** |
1766 |
/** |
1704 |
* Closesdeleted projects. |
1767 |
* Closes deleted projects. |
1705 |
*/ |
1768 |
*/ |
1706 |
private final class ProjectDeletionListener extends FileChangeAdapter { |
1769 |
private final class ProjectDeletionListener extends FileChangeAdapter { |
1707 |
|
1770 |
|
1708 |
public ProjectDeletionListener() {} |
1771 |
public ProjectDeletionListener() {} |
1709 |
|
1772 |
|
1710 |
public @Override void fileDeleted(FileEvent fe) { |
1773 |
public @Override void fileDeleted(final FileEvent fe) { |
1711 |
synchronized (OpenProjectList.this) { |
1774 |
ProjectManager.mutex().readAccess(new Mutex.Action<Void>() { |
|
|
1775 |
public @Override Void run() { |
1712 |
Project toRemove = null; |
1776 |
Project toRemove = null; |
1713 |
for (Project prj : openProjects) { |
1777 |
for (Project prj : openProjects) { |
1714 |
if (fe.getFile().equals(prj.getProjectDirectory())) { |
1778 |
if (fe.getFile().equals(prj.getProjectDirectory())) { |
Lines 1726-1732
Link Here
|
1726 |
} |
1790 |
} |
1727 |
}); |
1791 |
}); |
1728 |
} |
1792 |
} |
1729 |
} |
1793 |
return null; |
|
|
1794 |
} |
1795 |
}); |
1730 |
} |
1796 |
} |
1731 |
|
1797 |
|
1732 |
} |
1798 |
} |
Lines 1747-1763
Link Here
|
1747 |
return info; |
1813 |
return info; |
1748 |
} |
1814 |
} |
1749 |
|
1815 |
|
1750 |
private void addModuleInfo(Project prj) { |
1816 |
private void addModuleInfo(final Project prj) { |
1751 |
ModuleInfo info = findModuleForProject(prj); |
1817 |
final ModuleInfo info = findModuleForProject(prj); |
1752 |
if (info != null) { |
1818 |
if (info != null) { |
1753 |
// is null in tests.. |
1819 |
// is null in tests.. |
1754 |
synchronized (openProjectsModuleInfos) { |
1820 |
ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
|
|
1821 |
public @Override Void run() { |
1755 |
if (!openProjectsModuleInfos.containsKey(info)) { |
1822 |
if (!openProjectsModuleInfos.containsKey(info)) { |
1756 |
openProjectsModuleInfos.put(info, new ArrayList<Project>()); |
1823 |
openProjectsModuleInfos.put(info, new ArrayList<Project>()); |
1757 |
info.addPropertyChangeListener(infoListener); |
1824 |
info.addPropertyChangeListener(infoListener); |
1758 |
} |
1825 |
} |
1759 |
openProjectsModuleInfos.get(info).add(prj); |
1826 |
openProjectsModuleInfos.get(info).add(prj); |
|
|
1827 |
return null; |
1760 |
} |
1828 |
} |
|
|
1829 |
}); |
1761 |
} |
1830 |
} |
1762 |
} |
1831 |
} |
1763 |
|
1832 |
|
Lines 1766-1784
Link Here
|
1766 |
removeModuleInfo(prj, info); |
1835 |
removeModuleInfo(prj, info); |
1767 |
} |
1836 |
} |
1768 |
|
1837 |
|
1769 |
private void removeModuleInfo(Project prj, ModuleInfo info) { |
1838 |
private void removeModuleInfo(final Project prj, final ModuleInfo info) { |
1770 |
// info can be null in case we are closing a project from disabled module |
1839 |
// info can be null in case we are closing a project from disabled module |
1771 |
if (info != null) { |
1840 |
if (info != null) { |
1772 |
synchronized (openProjectsModuleInfos) { |
1841 |
ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
|
|
1842 |
public @Override Void run() { |
1773 |
List<Project> prjlist = openProjectsModuleInfos.get(info); |
1843 |
List<Project> prjlist = openProjectsModuleInfos.get(info); |
1774 |
if (prjlist != null) { |
1844 |
if (prjlist != null) { |
1775 |
prjlist.remove(prj); |
1845 |
prjlist.remove(prj); |
1776 |
if (prjlist.size() == 0) { |
1846 |
if (prjlist.isEmpty()) { |
1777 |
info.removePropertyChangeListener(infoListener); |
1847 |
info.removePropertyChangeListener(infoListener); |
1778 |
openProjectsModuleInfos.remove(info); |
1848 |
openProjectsModuleInfos.remove(info); |
1779 |
} |
1849 |
} |
1780 |
} |
1850 |
} |
|
|
1851 |
return null; |
1781 |
} |
1852 |
} |
|
|
1853 |
}); |
1782 |
} |
1854 |
} |
1783 |
} |
1855 |
} |
1784 |
|
1856 |
|