15dec0d721c199f14b61f6de6e3eb58e94824721
[idea/community.git] / platform / lang-impl / src / com / intellij / execution / startup / ProjectStartupTaskManager.java
1 /*
2  * Copyright 2000-2017 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.execution.startup;
17
18 import com.intellij.execution.RunManager;
19 import com.intellij.execution.RunnerAndConfigurationSettings;
20 import com.intellij.execution.impl.RunManagerImpl;
21 import com.intellij.notification.NotificationGroup;
22 import com.intellij.openapi.Disposable;
23 import com.intellij.openapi.components.ServiceManager;
24 import com.intellij.openapi.project.Project;
25 import com.intellij.openapi.project.impl.ProjectLifecycleListener;
26 import com.intellij.openapi.ui.MessageType;
27 import com.intellij.openapi.util.Disposer;
28 import org.jetbrains.annotations.NonNls;
29 import org.jetbrains.annotations.NotNull;
30
31 import java.util.*;
32
33 /**
34  * @author Irina.Chernushina on 8/19/2015.
35  */
36 public class ProjectStartupTaskManager {
37   public static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.logOnlyGroup("Project Startup Tasks Messages");
38   @NonNls public static final String PREFIX = "Project Startup Tasks: ";
39   private final Project myProject;
40   private final ProjectStartupSharedConfiguration myShared;
41   private final ProjectStartupLocalConfiguration myLocal;
42
43   public static ProjectStartupTaskManager getInstance(@NotNull final Project project) {
44     return ServiceManager.getService(project, ProjectStartupTaskManager.class);
45   }
46
47   public ProjectStartupTaskManager(Project project, ProjectStartupSharedConfiguration shared, ProjectStartupLocalConfiguration local) {
48     myProject = project;
49     myShared = shared;
50     myLocal = local;
51     verifyState();
52   }
53
54   // This method is called from a post-startup activity so the 'post-startup activities done'
55   // event always happens after this method is done executing
56   public void waitForExecutionReady(Runnable runnable) {
57     Disposable readyDisposable = Disposer.newDisposable();
58     Disposer.register(myProject, readyDisposable);
59     myProject.getMessageBus().connect(readyDisposable).subscribe(ProjectLifecycleListener.TOPIC, new ProjectLifecycleListener() {
60       @Override
61       public void postStartupActivitiesPassed(@NotNull Project project) {
62         if (project == myProject) {
63           runnable.run();
64           Disposer.dispose(readyDisposable);
65         }
66       }
67     });
68   }
69
70   private void verifyState() {
71     if (! myShared.isEmpty()) {
72       final Collection<RunnerAndConfigurationSettings> sharedConfigurations = getSharedConfigurations();
73       final List<RunnerAndConfigurationSettings> canNotBeShared = new ArrayList<>();
74       final Iterator<RunnerAndConfigurationSettings> iterator = sharedConfigurations.iterator();
75       while (iterator.hasNext()) {
76         final RunnerAndConfigurationSettings configuration = iterator.next();
77         if (!configuration.isShared()) {
78           iterator.remove();
79           canNotBeShared.add(configuration);
80         }
81       }
82       if (! canNotBeShared.isEmpty()) {
83         canNotBeShared.addAll(getLocalConfigurations());
84         setStartupConfigurations(sharedConfigurations, canNotBeShared);
85       }
86     }
87   }
88
89   public Collection<RunnerAndConfigurationSettings> getSharedConfigurations() {
90     return getConfigurations(myShared);
91   }
92
93   public Collection<RunnerAndConfigurationSettings> getLocalConfigurations() {
94     return getConfigurations(myLocal);
95   }
96
97   private Collection<RunnerAndConfigurationSettings> getConfigurations(ProjectStartupConfigurationBase configuration) {
98     if (configuration.isEmpty()) return Collections.emptyList();
99
100     final List<RunnerAndConfigurationSettings> result = new ArrayList<>();
101     final List<ProjectStartupConfigurationBase.ConfigurationDescriptor> list = configuration.getList();
102     RunManagerImpl runManager = (RunManagerImpl)RunManager.getInstance(myProject);
103     for (ProjectStartupConfigurationBase.ConfigurationDescriptor descriptor : list) {
104       final RunnerAndConfigurationSettings settings = runManager.getConfigurationById(descriptor.getId());
105       if (settings != null && settings.getName().equals(descriptor.getName())) {
106         result.add(settings);
107       } else {
108         NOTIFICATION_GROUP.createNotification(PREFIX + " Run Configuration '" + descriptor.getName() + "' not found, removed from list.",
109                                               MessageType.WARNING).notify(myProject);
110       }
111     }
112     return result;
113   }
114
115   public void rename(final String oldId, RunnerAndConfigurationSettings settings) {
116     if (myShared.rename(oldId, settings)) return;
117     myLocal.rename(oldId, settings);
118   }
119
120   public void delete(final String id) {
121     if (myShared.deleteConfiguration(id)) return;
122     myLocal.deleteConfiguration(id);
123   }
124
125   public void setStartupConfigurations(final @NotNull Collection<? extends RunnerAndConfigurationSettings> shared,
126                                        final @NotNull Collection<? extends RunnerAndConfigurationSettings> local) {
127     myShared.setConfigurations(shared);
128     myLocal.setConfigurations(local);
129   }
130
131   public boolean isEmpty() {
132     return myShared.isEmpty() && myLocal.isEmpty();
133   }
134
135   public void checkOnChange(RunnerAndConfigurationSettings settings) {
136     if (!settings.isShared()) {
137       final Collection<RunnerAndConfigurationSettings> sharedConfigurations = getSharedConfigurations();
138       if (sharedConfigurations.remove(settings)) {
139         final List<RunnerAndConfigurationSettings> localConfigurations = new ArrayList<>(getLocalConfigurations());
140         localConfigurations.add(settings);
141         setStartupConfigurations(sharedConfigurations, localConfigurations);
142
143         NOTIFICATION_GROUP.createNotification(PREFIX + " configuration was made \"not shared\", since included Run Configuration '" +
144                                               settings.getName() + "' is not shared.", MessageType.WARNING).notify(myProject);
145       }
146     }
147   }
148 }