IDEA-104500 Gradle: Allow to reuse common logic for other external systems

1. 'external system' tool window is introduced;
2. It's possible to refresh all external projects from the corresponding tool window now;
3. New tasks infrastructure is defined;
This commit is contained in:
Denis.Zhdanov
2013-05-16 17:35:42 +04:00
parent fc35d1df82
commit 9d804d108c
71 changed files with 1549 additions and 833 deletions
@@ -18,7 +18,7 @@ package com.intellij.externalSystem;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.Key;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.project.AbstractProjectEntityData;
import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.pom.java.LanguageLevel;
@@ -32,7 +32,7 @@ import java.util.regex.Pattern;
* @author Denis Zhdanov
* @since 4/12/13 12:27 PM
*/
public class JavaProjectData extends AbstractProjectEntityData {
public class JavaProjectData extends AbstractExternalEntityData {
@NotNull public static final Key<JavaProjectData> KEY = Key.create(JavaProjectData.class);
@@ -15,16 +15,24 @@ settings.title.system.settings=Global {0} settings
# Progress.
progress.import.text=Building ''{0}'' {1} project info
progress.refresh.tasks.text=Building ''{0}'' {1} tasks list
progress.refresh.text=Refreshing ''{0}'' {1} project
progress.resolve.libraries=Resolving {0} libraries
progress.update.text={0}: {1}
# Errors.
error.project.undefined=No external project config file is defined
error.resolve.generic.without.reason=Can''t resolve target {0} project at ''{1}''.\nConsult IDE log for more details (Help | Show Log)
error.cannot.parse.project=Can not parse {0} project
error.resolve.with.reason={0}\n\nConsult IDE log for more details (Help | Show Log)
error.resolve.generic=Resolve error
# Tool window
tool.window.title.tasks=tasks
tool.window.title.tasks=tasks
# Action.
action.refresh.all.projects.text=Refresh all {0} projects
action.refresh.all.projects.description=Force refresh all linked {0} projects
# Notification
notification.project.refresh.fail.description={0} ''{1}'' project refresh failed:\n{2}
notification.action.show.settings=<a href="configure">{0} settings</a>
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
/**
* @author Denis Zhdanov
* @since 5/14/13 12:49 PM
*/
public interface ExternalSystemConfigurableAware {
@NotNull
Configurable getConfigurable(@NotNull Project project);
}
@@ -1,7 +1,7 @@
package com.intellij.openapi.externalSystem;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.externalSystem.build.ExternalSystemBuildManager;
import com.intellij.openapi.externalSystem.build.ExternalSystemTaskManager;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings;
import com.intellij.openapi.externalSystem.service.ParametersEnhancer;
@@ -78,5 +78,5 @@ public interface ExternalSystemManager<
* @return class of the build manager to use for the target external system
* @see #getProjectResolverClass()
*/
Class<? extends ExternalSystemBuildManager<ExecutionSettings>> getBuildManagerClass();
Class<? extends ExternalSystemTaskManager<ExecutionSettings>> getTaskManagerClass();
}
@@ -13,18 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.service.task;
package com.intellij.openapi.externalSystem;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* @author Denis Zhdanov
* @since 5/12/13 10:28 PM
* @since 5/15/13 12:37 PM
*/
public class ExternalSystemTasksTreeModel extends DefaultTreeModel {
public ExternalSystemTasksTreeModel() {
super(null);
}
public interface ExternalSystemUiAware {
@Nullable
Icon getProjectIcon();
}
@@ -16,15 +16,12 @@
package com.intellij.openapi.externalSystem.build;
import com.intellij.openapi.externalSystem.model.ExternalSystemException;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* Abstraction layer for executing gradle tasks.
@@ -32,22 +29,8 @@ import java.util.Map;
* @author Denis Zhdanov
* @since 3/14/13 5:04 PM
*/
public interface ExternalSystemBuildManager<S extends ExternalSystemExecutionSettings> {
public interface ExternalSystemTaskManager<S extends ExternalSystemExecutionSettings> {
/**
* Refreshes available tasks for the target external project.
*
* @param id request task id
* @param projectPath target external project path
* @param settings settings to use during the refresh
* @return mappings like 'module name -&gt; module tasks'
* @throws ExternalSystemException in case when unexpected exception occurs during project info construction
*/
Map<String, Collection<ExternalSystemTaskDescriptor>> listTasks(@NotNull ExternalSystemTaskId id,
@NotNull String projectPath,
@Nullable S settings)
throws ExternalSystemException;
void executeTasks(@NotNull ExternalSystemTaskId id, @NotNull List<String> taskNames, @NotNull String projectPath, @Nullable S settings)
throws ExternalSystemException;
}
@@ -16,6 +16,7 @@
package com.intellij.openapi.externalSystem.model;
import com.intellij.openapi.externalSystem.model.project.*;
import com.intellij.openapi.externalSystem.model.task.TaskData;
import org.jetbrains.annotations.NotNull;
/**
@@ -33,6 +34,8 @@ public class ProjectKeys {
@NotNull public static final Key<ModuleDependencyData> MODULE_DEPENDENCY = Key.create(ModuleDependencyData.class);
@NotNull public static final Key<LibraryDependencyData> LIBRARY_DEPENDENCY = Key.create(LibraryDependencyData.class);
@NotNull public static final Key<TaskData> TASK = Key.create(TaskData.class);
private ProjectKeys() {
}
}
@@ -1,5 +1,6 @@
package com.intellij.openapi.externalSystem.model;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import java.io.Serializable;
@@ -20,9 +21,15 @@ public class ProjectSystemId implements Serializable {
@NotNull public static final ProjectSystemId IDE = new ProjectSystemId("IDE");
@NotNull private final String myId;
@NotNull private final String myReadableName;
public ProjectSystemId(@NotNull String id) {
this(id, StringUtil.capitalize(id.toLowerCase()));
}
public ProjectSystemId(@NotNull String id, @NotNull String readableName) {
myId = id;
myReadableName = readableName;
}
@Override
@@ -40,6 +47,11 @@ public class ProjectSystemId implements Serializable {
return myId.equals(owner.myId);
}
@NotNull
public String getReadableName() {
return myReadableName;
}
@Override
public String toString() {
return myId;
@@ -3,8 +3,6 @@ package com.intellij.openapi.externalSystem.model.project;
import com.intellij.openapi.roots.DependencyScope;
import org.jetbrains.annotations.NotNull;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.ObjectInputStream;
@@ -12,7 +10,7 @@ import java.io.ObjectInputStream;
* @author Denis Zhdanov
* @since 8/10/11 6:41 PM
*/
public abstract class AbstractDependencyData<T extends AbstractProjectEntityData & Named> extends AbstractProjectEntityData
public abstract class AbstractDependencyData<T extends AbstractExternalEntityData & Named> extends AbstractExternalEntityData
implements DependencyData, Named
{
@@ -23,14 +21,12 @@ public abstract class AbstractDependencyData<T extends AbstractProjectEntityData
private DependencyScope myScope = DependencyScope.COMPILE;
private transient boolean mySkipNameChange;
private boolean myExported;
private boolean myExported;
protected AbstractDependencyData(@NotNull ModuleData ownerModule, @NotNull T dependency) {
super(ownerModule.getOwner());
myOwnerModule = ownerModule;
myTarget = dependency;
initListener();
}
@NotNull
@@ -70,39 +66,12 @@ public abstract class AbstractDependencyData<T extends AbstractProjectEntityData
@Override
public void setName(@NotNull String name) {
mySkipNameChange = true;
try {
String oldName = myTarget.getName();
myTarget.setName(name);
firePropertyChange(NAME_PROPERTY, oldName, name);
}
finally {
mySkipNameChange = false;
}
}
private void initListener() {
myTarget.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (mySkipNameChange || !NAME_PROPERTY.equals(evt.getPropertyName())) {
return;
}
mySkipNameChange = true;
try {
firePropertyChange(NAME_PROPERTY, evt.getOldValue(), evt.getNewValue());
}
finally {
mySkipNameChange = false;
}
}
});
myTarget.setName(name);
}
@SuppressWarnings("MethodOverridesPrivateMethodOfSuperclass")
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initListener();
}
@Override
@@ -0,0 +1,43 @@
package com.intellij.openapi.externalSystem.model.project;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import org.jetbrains.annotations.NotNull;
/**
* @author Denis Zhdanov
* @since 8/25/11 3:44 PM
*/
public abstract class AbstractExternalEntityData implements ExternalEntityData {
private static final long serialVersionUID = 1L;
@NotNull private ProjectSystemId myOwner;
public AbstractExternalEntityData(@NotNull ProjectSystemId owner) {
myOwner = owner;
}
@Override
@NotNull
public ProjectSystemId getOwner() {
return myOwner;
}
@Override
public int hashCode() {
return myOwner.hashCode();
}
@SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (getClass() != obj.getClass()) {
return false;
}
AbstractExternalEntityData that = (AbstractExternalEntityData)obj;
return myOwner.equals(that.myOwner);
}
}
@@ -7,7 +7,7 @@ import org.jetbrains.annotations.NotNull;
* @author Denis Zhdanov
* @since 8/25/11 5:38 PM
*/
public abstract class AbstractNamedData extends AbstractProjectEntityData implements Named {
public abstract class AbstractNamedData extends AbstractExternalEntityData implements Named {
private static final long serialVersionUID = 1L;
@@ -26,9 +26,7 @@ public abstract class AbstractNamedData extends AbstractProjectEntityData implem
@Override
public void setName(@NotNull String name) {
String oldName = myName;
myName = name;
firePropertyChange(NAME_PROPERTY, oldName, name);
}
@Override
@@ -1,65 +0,0 @@
package com.intellij.openapi.externalSystem.model.project;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import org.jetbrains.annotations.NotNull;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
import java.io.ObjectInputStream;
/**
* @author Denis Zhdanov
* @since 8/25/11 3:44 PM
*/
public abstract class AbstractProjectEntityData implements ProjectEntityData {
private static final long serialVersionUID = 1L;
@NotNull private ProjectSystemId myOwner;
private transient PropertyChangeSupport myPropertyChangeSupport;
public AbstractProjectEntityData(@NotNull ProjectSystemId owner) {
myOwner = owner;
myPropertyChangeSupport = new PropertyChangeSupport(this);
}
@Override
@NotNull
public ProjectSystemId getOwner() {
return myOwner;
}
@Override
public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) {
myPropertyChangeSupport.addPropertyChangeListener(listener);
}
protected void firePropertyChange(@NotNull String propertyName, @NotNull Object oldValue, @NotNull Object newValue) {
myPropertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
myPropertyChangeSupport = new PropertyChangeSupport(this);
myOwner = (ProjectSystemId)in.readObject();
}
@Override
public int hashCode() {
return myOwner.hashCode();
}
@SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (getClass() != obj.getClass()) {
return false;
}
AbstractProjectEntityData that = (AbstractProjectEntityData)obj;
return myOwner.equals(that.myOwner);
}
}
@@ -15,7 +15,7 @@ import java.util.Map;
* @author Denis Zhdanov
* @since 8/9/11 6:25 PM
*/
public class ContentRootData extends AbstractProjectEntityData {
public class ContentRootData extends AbstractExternalEntityData {
private static final long serialVersionUID = 1L;
@@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull;
* @author Denis Zhdanov
* @since 8/10/11 6:31 PM
*/
public interface DependencyData<T extends ProjectEntityData> extends ProjectEntityData {
public interface DependencyData<T extends ExternalEntityData> extends ExternalEntityData {
boolean isExported();
@@ -3,8 +3,6 @@ package com.intellij.openapi.externalSystem.model.project;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import org.jetbrains.annotations.NotNull;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
/**
@@ -18,15 +16,8 @@ import java.io.Serializable;
* @author Denis Zhdanov
* @since 8/12/11 12:50 PM
*/
public interface ProjectEntityData extends Serializable {
public interface ExternalEntityData extends Serializable {
@NotNull
ProjectSystemId getOwner();
/**
* Follows contract of {@link PropertyChangeSupport#addPropertyChangeListener(PropertyChangeListener)}
*
* @param listener target listener
*/
void addPropertyChangeListener(@NotNull PropertyChangeListener listener);
}
@@ -20,12 +20,19 @@ public class ModuleData extends AbstractNamedData implements Named {
@NotNull private final Map<ExternalSystemSourceType, String> myCompileOutputPaths = ContainerUtilRt.newHashMap();
@NotNull private final String myModuleTypeId;
@NotNull private final String myExternalConfigPath;
@NotNull private String myModuleFilePath;
private boolean myInheritProjectCompileOutputPath = true;
public ModuleData(@NotNull ProjectSystemId owner, @NotNull String typeId, @NotNull String name, @NotNull String moduleFileDirectoryPath) {
public ModuleData(@NotNull ProjectSystemId owner,
@NotNull String typeId,
@NotNull String name,
@NotNull String moduleFileDirectoryPath,
@NotNull String externalConfigPath)
{
super(owner, name);
myModuleTypeId = typeId;
myExternalConfigPath = externalConfigPath;
setModuleFileDirectoryPath(moduleFileDirectoryPath);
}
@@ -34,6 +41,11 @@ public class ModuleData extends AbstractNamedData implements Named {
return myModuleTypeId;
}
@NotNull
public String getExternalConfigPath() {
return myExternalConfigPath;
}
@NotNull
public String getModuleFilePath() {
return myModuleFilePath;
@@ -1,5 +1,6 @@
package com.intellij.openapi.externalSystem.model.task;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import java.io.Serializable;
@@ -13,26 +14,45 @@ import java.util.concurrent.atomic.AtomicLong;
*/
public class ExternalSystemTaskId implements Serializable {
private static final long serialVersionUID = 1L;
private static final AtomicLong COUNTER = new AtomicLong();
@NotNull private static final AtomicLong COUNTER = new AtomicLong();
private static final long serialVersionUID = 1L;
private final ExternalSystemTaskType myType;
private final long myId;
@NotNull private final ExternalSystemTaskType myType;
@NotNull private final String myProjectId;
private ExternalSystemTaskId(@NotNull ExternalSystemTaskType type, long id) {
private final long myId;
private ExternalSystemTaskId(@NotNull ExternalSystemTaskType type, @NotNull String projectId, long taskId) {
myType = type;
myId = id;
myProjectId = projectId;
myId = taskId;
}
@NotNull
public String getIdeProjectId() {
return myProjectId;
}
/**
* Allows to retrieve distinct task id object of the given type.
*
* @param type target task type
* @return distinct task id object of the given type
* @param type target task type
* @param project target ide project
* @return distinct task id object of the given type
*/
@NotNull
public static ExternalSystemTaskId create(@NotNull ExternalSystemTaskType type) {
return new ExternalSystemTaskId(type, COUNTER.getAndIncrement());
public static ExternalSystemTaskId create(@NotNull ExternalSystemTaskType type, @NotNull Project project) {
return create(type, getProjectId(project));
}
@NotNull
public static ExternalSystemTaskId create(@NotNull ExternalSystemTaskType type, @NotNull String ideProjectId) {
return new ExternalSystemTaskId(type, ideProjectId, COUNTER.getAndIncrement());
}
@NotNull
public static String getProjectId(@NotNull Project project) {
return project.getName() + ":" + project.getLocationHash();
}
@NotNull
@@ -0,0 +1,55 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model.task;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Container for external system task information.
*
* @author Denis Zhdanov
* @since 5/15/13 10:59 AM
*/
public class TaskData extends AbstractExternalEntityData {
@NotNull private final List<ExternalSystemTaskDescriptor> myTasks = ContainerUtilRt.newArrayList();
@NotNull private final String myLinkedProjectPath;
public TaskData(@NotNull ProjectSystemId owner, @NotNull String linkedProjectPath) {
super(owner);
myLinkedProjectPath = linkedProjectPath;
}
@NotNull
public String getLinkedProjectPath() {
return myLinkedProjectPath;
}
public void addTask(@NotNull ExternalSystemTaskDescriptor task) {
myTasks.add(task);
}
@NotNull
public List<ExternalSystemTaskDescriptor> getTasks() {
return myTasks;
}
}
@@ -64,6 +64,10 @@ public abstract class AbstractExternalSystemLocalSettings {
public Map<String, List<ExternalSystemTaskDescriptor>> getAvailableTasks() {
return myAvailableTasks.get();
}
public void setAvailableTasks(@NotNull Map<String, List<ExternalSystemTaskDescriptor>> tasks) {
myAvailableTasks.set(tasks);
}
@NotNull
public Map<String, List<ExternalSystemTaskDescriptor>> getRecentTasks() {
@@ -184,13 +184,13 @@ public class ExternalSystemApiUtil {
}
@NotNull
public static Map<Key<?>, Collection<DataNode<?>>> group(@NotNull Collection<DataNode<?>> nodes) {
public static Map<Key<?>, List<DataNode<?>>> group(@NotNull Collection<DataNode<?>> nodes) {
if (nodes.isEmpty()) {
return Collections.emptyMap();
}
Map<Key<?>, Collection<DataNode<?>>> result = ContainerUtilRt.newHashMap();
Map<Key<?>, List<DataNode<?>>> result = ContainerUtilRt.newHashMap();
for (DataNode<?> node : nodes) {
Collection<DataNode<?>> n = result.get(node.getKey());
List<DataNode<?>> n = result.get(node.getKey());
if (n == null) {
result.put(node.getKey(), n = ContainerUtilRt.newArrayList());
}
@@ -200,8 +200,8 @@ public class ExternalSystemApiUtil {
}
@NotNull
public static <K, V> Map<DataNode<K>, Collection<DataNode<V>>> groupBy(@NotNull Collection<DataNode<V>> nodes, @NotNull Key<K> key) {
Map<DataNode<K>, Collection<DataNode<V>>> result = ContainerUtilRt.newHashMap();
public static <K, V> Map<DataNode<K>, List<DataNode<V>>> groupBy(@NotNull Collection<DataNode<V>> nodes, @NotNull Key<K> key) {
Map<DataNode<K>, List<DataNode<V>>> result = ContainerUtilRt.newHashMap();
for (DataNode<V> data : nodes) {
DataNode<K> grouper = data.getDataNode(key);
if (grouper == null) {
@@ -211,7 +211,7 @@ public class ExternalSystemApiUtil {
));
continue;
}
Collection<DataNode<V>> grouped = result.get(grouper);
List<DataNode<V>> grouped = result.get(grouper);
if (grouped == null) {
result.put(grouper, grouped = ContainerUtilRt.newArrayList());
}
@@ -373,4 +373,15 @@ public class ExternalSystemApiUtil {
public static boolean isNewProjectConstruction() {
return ProjectManager.getInstance().getOpenProjects().length == 0;
}
/**
* Tries to guess external project name given it's path.
*
* @param projectPath target external project path
* @return external project name on the basis of the given external project path
*/
@NotNull
public static String guessProjectName(@NotNull String projectPath) {
return new File(projectPath).getParentFile().getName();
}
}
@@ -27,7 +27,12 @@ public class ExternalSystemConstants {
@NonNls @NotNull public static final String EXTERNAL_SYSTEM_ID_KEY = "external.system.id";
@NonNls @NotNull public static final String LINKED_PROJECT_PATH_KEY = "external.linked.project.path";
@NonNls @NotNull public static final String TOOL_WINDOW_TOOLBAR_ACTIONS_GROUP_ID = "ExternalSystem.ToolWindow.Toolbar";
@NonNls @NotNull public static final String TOOL_WINDOW_PLACE = "ExternalSystem.ToolWindow";
// Order.
public static final int BUILTIN_SERVICE_ORDER = 42;
public static final int UNORDERED = 1000;
public static final int BUILTIN_SERVICE_ORDER = 42;
public static final int BUILTIN_TOOL_WINDOW_SERVICE_ORDER = 62;
public static final int UNORDERED = 1000;
}
@@ -0,0 +1,65 @@
package com.intellij.openapi.externalSystem.action;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType;
import com.intellij.openapi.externalSystem.service.internal.ExternalSystemProcessingManager;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
/**
* Forces the ide to retrieve the most up-to-date info about the linked external projects and updates project state if necessary
* (e.g. imports missing libraries).
*
* @author Denis Zhdanov
* @since 1/23/12 3:48 PM
*/
public class RefreshAllExternalProjectsAction extends AnAction implements DumbAware, AnAction.TransparentUpdate {
@Override
public void update(AnActionEvent e) {
ProjectSystemId externalSystemId = ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.getData(e.getDataContext());
if (externalSystemId == null) {
e.getPresentation().setEnabled(false);
return;
}
String name = externalSystemId.getReadableName();
e.getPresentation().setText(ExternalSystemBundle.message("action.refresh.all.projects.text", name));
e.getPresentation().setDescription(ExternalSystemBundle.message("action.refresh.all.projects.description", name));
Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
if (project == null) {
e.getPresentation().setEnabled(false);
return;
}
ExternalSystemProcessingManager processingManager = ServiceManager.getService(ExternalSystemProcessingManager.class);
e.getPresentation().setEnabled(!processingManager.hasTaskOfTypeInProgress(ExternalSystemTaskType.RESOLVE_PROJECT, project));
}
@Override
public void actionPerformed(AnActionEvent e) {
ProjectSystemId externalSystemId = ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.getData(e.getDataContext());
if (externalSystemId == null) {
return;
}
Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
if (project == null) {
e.getPresentation().setEnabled(false);
return;
}
// We save all documents because there is a possible case that there is an external system config file changed inside the ide.
FileDocumentManager.getInstance().saveAllDocuments();
ExternalSystemUtil.refreshProjects(project, externalSystemId);
}
}
@@ -1,7 +1,24 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model;
import com.intellij.notification.NotificationGroup;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.externalSystem.service.task.ExternalSystemTasksTreeModel;
import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel;
import org.jetbrains.annotations.NotNull;
/**
* @author Denis Zhdanov
@@ -9,7 +26,9 @@ import com.intellij.openapi.externalSystem.service.task.ExternalSystemTasksTreeM
*/
public class ExternalSystemDataKeys {
public static final DataKey<ExternalSystemTasksTreeModel> ALL_TASKS_MODEL = DataKey.create("external.system.all.tasks.model");
@NotNull public static final DataKey<ProjectSystemId> EXTERNAL_SYSTEM_ID = DataKey.create("external.system.id");
@NotNull public static final DataKey<NotificationGroup> NOTIFICATION_GROUP = DataKey.create("external.system.notification");
@NotNull public static final DataKey<ExternalSystemTasksTreeModel> ALL_TASKS_MODEL = DataKey.create("external.system.all.tasks.model");
private ExternalSystemDataKeys() {
}
@@ -1,7 +1,6 @@
package com.intellij.openapi.externalSystem.model.settings;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.PropertyKey;
@@ -46,7 +45,7 @@ public enum LocationSettingType {
* @return human-readable description of the current setting type
*/
public String getDescription(@NotNull ProjectSystemId externalSystemId) {
return ExternalSystemBundle.message(myDescriptionKey, ExternalSystemApiUtil.toReadableName(externalSystemId));
return ExternalSystemBundle.message(myDescriptionKey, externalSystemId.getReadableName());
}
@NotNull
@@ -1,11 +1,11 @@
package com.intellij.openapi.externalSystem.service;
import com.intellij.execution.rmi.RemoteServer;
import com.intellij.openapi.externalSystem.build.ExternalSystemTaskManager;
import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationEvent;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType;
import com.intellij.openapi.externalSystem.build.ExternalSystemBuildManager;
import com.intellij.openapi.externalSystem.service.project.ExternalSystemProjectResolver;
import com.intellij.openapi.externalSystem.service.remote.*;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
@@ -47,14 +47,14 @@ public class ExternalSystemFacadeImpl<S extends ExternalSystemExecutionSettings>
= new AtomicReference<ExternalSystemTaskNotificationListener>();
@NotNull private final RemoteExternalSystemProjectResolverImpl<S> myProjectResolver;
@NotNull private final RemoteExternalSystemBuildManagerImpl<S> myBuildManager;
@NotNull private final RemoteExternalSystemTaskManagerImpl<S> myTaskManager;
public ExternalSystemFacadeImpl(@NotNull Class<ExternalSystemProjectResolver<S>> projectResolverClass,
@NotNull Class<ExternalSystemBuildManager<S>> buildManagerClass)
@NotNull Class<ExternalSystemTaskManager<S>> buildManagerClass)
throws IllegalAccessException, InstantiationException
{
myProjectResolver = new RemoteExternalSystemProjectResolverImpl<S>(projectResolverClass.newInstance());
myBuildManager = new RemoteExternalSystemBuildManagerImpl<S>(buildManagerClass.newInstance());
myTaskManager = new RemoteExternalSystemTaskManagerImpl<S>(buildManagerClass.newInstance());
updateAutoShutdownTime();
}
@@ -78,11 +78,11 @@ public class ExternalSystemFacadeImpl<S extends ExternalSystemExecutionSettings>
"Can't create external system facade. Reason: given arguments don't contain information about external system build manager to use"
);
}
final Class<ExternalSystemBuildManager<?>> buildManagerClass = (Class<ExternalSystemBuildManager<?>>)Class.forName(args[1]);
final Class<ExternalSystemTaskManager<?>> buildManagerClass = (Class<ExternalSystemTaskManager<?>>)Class.forName(args[1]);
if (!ExternalSystemProjectResolver.class.isAssignableFrom(resolverClass)) {
throw new IllegalArgumentException(String.format(
"Can't create external system facade. Reason: given external system build manager (%s) must be IS-A '%s'",
buildManagerClass, ExternalSystemBuildManager.class
buildManagerClass, ExternalSystemTaskManager.class
));
}
@@ -111,12 +111,12 @@ public class ExternalSystemFacadeImpl<S extends ExternalSystemExecutionSettings>
@SuppressWarnings("unchecked")
@NotNull
@Override
public RemoteExternalSystemBuildManager<S> getBuildManager() throws RemoteException {
public RemoteExternalSystemTaskManager<S> getTaskManager() throws RemoteException {
try {
return getRemote(RemoteExternalSystemBuildManager.class, myBuildManager);
return getRemote(RemoteExternalSystemTaskManager.class, myTaskManager);
}
catch (Exception e) {
throw new IllegalStateException(String.format("Can't create '%s' service", ExternalSystemBuildManager.class.getName()), e);
throw new IllegalStateException(String.format("Can't create '%s' service", ExternalSystemTaskManager.class.getName()), e);
}
}
@@ -237,7 +237,7 @@ public class ExternalSystemFacadeImpl<S extends ExternalSystemExecutionSettings>
ExternalSystemTaskNotificationListener listener = new SwallowingNotificationListener(progressManager);
myNotificationListener.set(listener);
myProjectResolver.setNotificationListener(listener);
myBuildManager.setNotificationListener(listener);
myTaskManager.setNotificationListener(listener);
}
/**
@@ -170,7 +170,7 @@ public class ExternalSystemFacadeManager {
params.getVMParametersList().addParametersString(
"-Dsun.rmi.transport.connectionTimeout=" + String.valueOf(TimeUnit.HOURS.toMillis(1))
);
//params.getVMParametersList().addParametersString("-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5009");
// params.getVMParametersList().addParametersString("-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5009");
ProjectSystemId externalSystemId = myTargetExternalSystemId.get();
if (externalSystemId != null) {
@@ -178,7 +178,7 @@ public class ExternalSystemFacadeManager {
if (manager != null) {
params.getClassPath().add(PathUtil.getJarPathForClass(manager.getProjectResolverClass().getClass()));
params.getProgramParametersList().add(manager.getProjectResolverClass().getName());
params.getProgramParametersList().add(manager.getBuildManagerClass().getName());
params.getProgramParametersList().add(manager.getTaskManagerClass().getName());
manager.enhanceParameters(params);
}
}
@@ -1,10 +1,10 @@
package com.intellij.openapi.externalSystem.service;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskAware;
import com.intellij.openapi.externalSystem.service.internal.ExternalSystemTaskAware;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType;
import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings;
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemBuildManager;
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemTaskManager;
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProgressNotificationManager;
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolver;
import org.jetbrains.annotations.NotNull;
@@ -39,8 +39,8 @@ public interface RemoteExternalSystemFacade<S extends ExternalSystemExecutionSet
@NotNull
@Override
public RemoteExternalSystemBuildManager<ExternalSystemExecutionSettings> getBuildManager() throws RemoteException {
return RemoteExternalSystemBuildManager.NULL_OBJECT;
public RemoteExternalSystemTaskManager<ExternalSystemExecutionSettings> getTaskManager() throws RemoteException {
return RemoteExternalSystemTaskManager.NULL_OBJECT;
}
@Override
@@ -80,7 +80,7 @@ public interface RemoteExternalSystemFacade<S extends ExternalSystemExecutionSet
* @throws RemoteException in case of inability to create the service
*/
@NotNull
RemoteExternalSystemBuildManager<S> getBuildManager() throws RemoteException;
RemoteExternalSystemTaskManager<S> getTaskManager() throws RemoteException;
/**
* Asks remote external system process to apply given settings.
@@ -1,6 +1,6 @@
package com.intellij.openapi.externalSystem.service;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskAware;
import com.intellij.openapi.externalSystem.service.internal.ExternalSystemTaskAware;
import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
import org.jetbrains.annotations.NotNull;
@@ -1,12 +1,12 @@
package com.intellij.openapi.externalSystem.model.task;
package com.intellij.openapi.externalSystem.service.internal;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.task.*;
import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager;
import com.intellij.openapi.externalSystem.service.RemoteExternalSystemFacade;
import com.intellij.openapi.externalSystem.service.notification.ExternalSystemProgressNotificationManager;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
@@ -44,7 +44,7 @@ public abstract class AbstractExternalSystemTask implements ExternalSystemTask {
{
myExternalSystemId = id;
myIdeProject = project;
myId = ExternalSystemTaskId.create(type);
myId = ExternalSystemTaskId.create(type, myIdeProject);
myExernalProjectPath = externalProjectPath;
}
@@ -159,6 +159,6 @@ public abstract class AbstractExternalSystemTask implements ExternalSystemTask {
@Override
public String toString() {
return String.format("%s task %s: %s", ExternalSystemApiUtil.toReadableName(myExternalSystemId), myId, myState);
return String.format("%s task %s: %s", myExternalSystemId.getReadableName(), myId, myState);
}
}
@@ -13,16 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.gradle.internal.task;
package com.intellij.openapi.externalSystem.service.internal;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.task.AbstractExternalSystemTask;
import com.intellij.openapi.externalSystem.service.internal.AbstractExternalSystemTask;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType;
import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -1,4 +1,4 @@
package com.intellij.openapi.externalSystem.service.task;
package com.intellij.openapi.externalSystem.service.internal;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
@@ -8,6 +8,7 @@ import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotifica
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType;
import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager;
import com.intellij.openapi.externalSystem.service.notification.ExternalSystemProgressNotificationManager;
import com.intellij.openapi.project.Project;
import com.intellij.util.Alarm;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
@@ -25,7 +26,7 @@ import java.util.concurrent.TimeUnit;
* @author Denis Zhdanov
* @since 2/8/12 1:52 PM
*/
public class ExternalSystemTaskManager implements ExternalSystemTaskNotificationListener, Disposable {
public class ExternalSystemProcessingManager implements ExternalSystemTaskNotificationListener, Disposable {
/**
* We receive information about the tasks being enqueued to the slave processes which work directly with external systems here.
@@ -40,7 +41,7 @@ public class ExternalSystemTaskManager implements ExternalSystemTaskNotification
* We need to distinguish between them, so, we perform 'task pings' if any task is executed too long. Current constant holds
* criteria of 'too long execution'.
*/
private static final long TOO_LONG_EXECUTION_MS = TimeUnit.SECONDS.toMillis(10);
private static final long TOO_LONG_EXECUTION_MS = TimeUnit.SECONDS.toMillis(10);
@NotNull private final ConcurrentMap<ExternalSystemTaskId, Long> myTasksInProgress = ContainerUtil.newConcurrentMap();
@NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
@@ -48,8 +49,8 @@ public class ExternalSystemTaskManager implements ExternalSystemTaskNotification
@NotNull private final ExternalSystemFacadeManager myFacadeManager;
@NotNull private final ExternalSystemProgressNotificationManager myProgressNotificationManager;
public ExternalSystemTaskManager(@NotNull ExternalSystemFacadeManager facadeManager,
@NotNull ExternalSystemProgressNotificationManager notificationManager)
public ExternalSystemProcessingManager(@NotNull ExternalSystemFacadeManager facadeManager,
@NotNull ExternalSystemProgressNotificationManager notificationManager)
{
myFacadeManager = facadeManager;
myProgressNotificationManager = notificationManager;
@@ -73,9 +74,10 @@ public class ExternalSystemTaskManager implements ExternalSystemTaskNotification
* @return <code>true</code> if any task of the given type is being executed at the moment;
* <code>false</code> otherwise
*/
public boolean hasTaskOfTypeInProgress(@NotNull ExternalSystemTaskType type) {
public boolean hasTaskOfTypeInProgress(@NotNull ExternalSystemTaskType type, @NotNull Project project) {
String projectId = ExternalSystemTaskId.getProjectId(project);
for (ExternalSystemTaskId id : myTasksInProgress.keySet()) {
if (type.equals(id.getType())) {
if (type.equals(id.getType()) && projectId.equals(id.getIdeProjectId())) {
return true;
}
}
@@ -1,14 +1,15 @@
package com.intellij.openapi.externalSystem.model.task;
package com.intellij.openapi.externalSystem.service.internal;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager;
import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskState;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType;
import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager;
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolver;
import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsManager;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
@@ -44,17 +45,21 @@ public class ExternalSystemResolveProjectTask extends AbstractExternalSystemTask
final ExternalSystemFacadeManager manager = ServiceManager.getService(ExternalSystemFacadeManager.class);
Project ideProject = getIdeProject();
RemoteExternalSystemProjectResolver resolver = manager.getFacade(ideProject, myProjectPath, getExternalSystemId()).getResolver();
setState(ExternalSystemTaskState.IN_PROGRESS);
ExternalSystemSettingsManager settingsManager = ServiceManager.getService(ExternalSystemSettingsManager.class);
ExternalSystemExecutionSettings settings = settingsManager.getExecutionSettings(ideProject, myProjectPath, getExternalSystemId());
DataNode<ProjectData> project = resolver.resolveProjectInfo(getId(), myProjectPath, myResolveLibraries, settings);
if (project == null) {
return;
setState(ExternalSystemTaskState.IN_PROGRESS);
try {
ExternalSystemSettingsManager settingsManager = ServiceManager.getService(ExternalSystemSettingsManager.class);
ExternalSystemExecutionSettings settings = settingsManager.getExecutionSettings(ideProject, myProjectPath, getExternalSystemId());
DataNode<ProjectData> project = resolver.resolveProjectInfo(getId(), myProjectPath, myResolveLibraries, settings);
if (project == null) {
return;
}
myExternalProject.set(project);
}
finally {
setState(ExternalSystemTaskState.FINISHED);
}
myExternalProject.set(project);
setState(ExternalSystemTaskState.FINISHED);
}
@Nullable
@@ -65,6 +70,6 @@ public class ExternalSystemResolveProjectTask extends AbstractExternalSystemTask
@Override
@NotNull
protected String wrapProgressText(@NotNull String text) {
return ExternalSystemBundle.message("progress.update.text", ExternalSystemApiUtil.toReadableName(getExternalSystemId()), text);
return ExternalSystemBundle.message("progress.update.text", getExternalSystemId().getReadableName(), text);
}
}
@@ -1,5 +1,7 @@
package com.intellij.openapi.externalSystem.model.task;
package com.intellij.openapi.externalSystem.service.internal;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType;
import org.jetbrains.annotations.NotNull;
import java.rmi.RemoteException;
@@ -0,0 +1,90 @@
package com.intellij.openapi.externalSystem.service.notification;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationGroup;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.externalSystem.ExternalSystemConfigurableAware;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.ui.EditorNotifications;
import org.jetbrains.annotations.NotNull;
import javax.swing.event.HyperlinkEvent;
import java.util.concurrent.atomic.AtomicReference;
/**
* This class is responsible for ide user by external system integration-specific events.
* <p/>
* One example use-case is a situation when an error occurs during external project refresh. We need to
* show corresponding message to the end-user.
* <p/>
* Thread-safe.
*
* @author Denis Zhdanov
* @since 3/21/12 4:04 PM
*/
public class ExternalSystemIdeNotificationManager {
@NotNull private final AtomicReference<Notification> myNotification = new AtomicReference<Notification>();
public void processExternalProjectRefreshError(@NotNull String message,
@NotNull final Project project,
@NotNull String externalProjectName,
@NotNull ProjectSystemId externalSystemId)
{
NotificationGroup group = ExternalSystemUtil.getToolWindowElement(NotificationGroup.class,
project,
ExternalSystemDataKeys.NOTIFICATION_GROUP,
externalSystemId);
if (group == null) {
return;
}
ExternalSystemManager<?,?,?,?,?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
if (!(manager instanceof ExternalSystemConfigurableAware)) {
return;
}
final Configurable configurable = ((ExternalSystemConfigurableAware)manager).getConfigurable(project);
EditorNotifications.getInstance(project).updateAllNotifications();
final Notification notification = group.createNotification(
ExternalSystemBundle.message("notification.project.refresh.fail.description",
externalSystemId.getReadableName(), externalProjectName, message),
ExternalSystemBundle.message("notification.action.show.settings", externalSystemId.getReadableName()),
NotificationType.WARNING,
new NotificationListener() {
@Override
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
if (event.getEventType() != HyperlinkEvent.EventType.ACTIVATED) {
return;
}
ShowSettingsUtil.getInstance().editConfigurable(project, configurable);
}
}
);
applyNotification(notification, project);
}
private void applyNotification(@NotNull Notification notification, @NotNull Project project) {
final Notification oldNotification = myNotification.get();
if (oldNotification != null && myNotification.compareAndSet(oldNotification, null)) {
oldNotification.expire();
}
if (!myNotification.compareAndSet(null, notification)) {
notification.expire();
return;
}
notification.notify(project);
}
}
@@ -22,6 +22,7 @@ import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
@@ -56,9 +57,8 @@ public class ContentRootDataService implements ProjectDataService<ContentRootDat
return;
}
Map<DataNode<ModuleData>, Collection<DataNode<ContentRootData>>> byModule
= ExternalSystemApiUtil.groupBy(toImport, ProjectKeys.MODULE);
for (Map.Entry<DataNode<ModuleData>, Collection<DataNode<ContentRootData>>> entry : byModule.entrySet()) {
Map<DataNode<ModuleData>, List<DataNode<ContentRootData>>> byModule = ExternalSystemApiUtil.groupBy(toImport, ProjectKeys.MODULE);
for (Map.Entry<DataNode<ModuleData>, List<DataNode<ContentRootData>>> entry : byModule.entrySet()) {
final Module module = myProjectStructureHelper.findIdeModule(entry.getKey().getData(), project);
if (module == null) {
LOG.warn(String.format(
@@ -15,7 +15,6 @@
*/
package com.intellij.openapi.externalSystem.service.project.manage;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.Key;
@@ -32,7 +31,6 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.externalSystem.util.Order;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ExportableOrderEntry;
import com.intellij.openapi.roots.LibraryOrderEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
@@ -86,8 +84,8 @@ public class LibraryDependencyDataService extends AbstractDependencyDataService<
return;
}
Map<DataNode<ModuleData>, Collection<DataNode<LibraryDependencyData>>> byModule = ExternalSystemApiUtil.groupBy(toImport, MODULE);
for (Map.Entry<DataNode<ModuleData>, Collection<DataNode<LibraryDependencyData>>> entry : byModule.entrySet()) {
Map<DataNode<ModuleData>, List<DataNode<LibraryDependencyData>>> byModule = ExternalSystemApiUtil.groupBy(toImport, MODULE);
for (Map.Entry<DataNode<ModuleData>, List<DataNode<LibraryDependencyData>>> entry : byModule.entrySet()) {
Module module = myProjectStructureHelper.findIdeModule(entry.getKey().getData(), project);
if (module == null) {
myModuleManager.importData(Collections.singleton(entry.getKey()), project, true);
@@ -37,6 +37,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static com.intellij.openapi.externalSystem.model.ProjectKeys.MODULE;
@@ -66,8 +67,8 @@ public class ModuleDependencyDataService extends AbstractDependencyDataService<M
@Override
public void importData(@NotNull Collection<DataNode<ModuleDependencyData>> toImport, @NotNull Project project, boolean synchronous) {
Map<DataNode<ModuleData>, Collection<DataNode<ModuleDependencyData>>> byModule= ExternalSystemApiUtil.groupBy(toImport, MODULE);
for (Map.Entry<DataNode<ModuleData>, Collection<DataNode<ModuleDependencyData>>> entry : byModule.entrySet()) {
Map<DataNode<ModuleData>, List<DataNode<ModuleDependencyData>>> byModule= ExternalSystemApiUtil.groupBy(toImport, MODULE);
for (Map.Entry<DataNode<ModuleData>, List<DataNode<ModuleDependencyData>>> entry : byModule.entrySet()) {
Module ideModule = myProjectStructureHelper.findIdeModule(entry.getKey().getData(), project);
if (ideModule == null) {
myModuleDataManager.importData(Collections.singleton(entry.getKey()), project, true);
@@ -64,8 +64,8 @@ public class ProjectDataManager {
@SuppressWarnings("unchecked")
public <T> void importData(@NotNull Collection<DataNode<?>> nodes, @NotNull Project project, boolean synchronous) {
Map<Key<?>, Collection<DataNode<?>>> grouped = ExternalSystemApiUtil.group(nodes);
for (Map.Entry<Key<?>, Collection<DataNode<?>>> entry : grouped.entrySet()) {
Map<Key<?>, List<DataNode<?>>> grouped = ExternalSystemApiUtil.group(nodes);
for (Map.Entry<Key<?>, List<DataNode<?>>> entry : grouped.entrySet()) {
// Simple class cast makes ide happy but compiler fails.
Collection<DataNode<T>> dummy = ContainerUtilRt.newArrayList();
for (DataNode<?> node : entry.getValue()) {
@@ -7,7 +7,7 @@ import com.intellij.openapi.externalSystem.model.ProjectKeys;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.project.LibraryData;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemResolveProjectTask;
import com.intellij.openapi.externalSystem.service.internal.ExternalSystemResolveProjectTask;
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
import com.intellij.openapi.externalSystem.service.settings.AbstractImportFromExternalSystemControl;
@@ -152,8 +152,7 @@ public abstract class AbstractExternalProjectImportBuilder<C extends AbstractImp
final Runnable resolveDependenciesTask = new Runnable() {
@Override
public void run() {
String progressText
= ExternalSystemBundle.message("progress.resolve.libraries", ExternalSystemApiUtil.toReadableName(myExternalSystemId));
String progressText = ExternalSystemBundle.message("progress.resolve.libraries", myExternalSystemId.getReadableName());
ProgressManager.getInstance().run(
new Task.Backgroundable(project, progressText, false) {
@Override
@@ -254,7 +253,7 @@ public abstract class AbstractExternalProjectImportBuilder<C extends AbstractImp
* @throws ConfigurationException if gradle project is not defined and can't be constructed
*/
public void ensureProjectIsDefined(@NotNull WizardContext wizardContext) throws ConfigurationException {
String externalSystemName = ExternalSystemApiUtil.toReadableName(myExternalSystemId);
String externalSystemName = myExternalSystemId.getReadableName();
File projectFile = getProjectFile();
if (projectFile == null) {
throw new ConfigurationException(ExternalSystemBundle.message("error.project.undefined"));
@@ -17,37 +17,28 @@ package com.intellij.openapi.externalSystem.service.remote;
import com.intellij.openapi.externalSystem.model.ExternalSystemException;
import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType;
import com.intellij.openapi.externalSystem.service.RemoteExternalSystemService;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.rmi.RemoteException;
import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Denis Zhdanov
* @since 4/9/13 7:02 PM
*/
public interface RemoteExternalSystemBuildManager<S extends ExternalSystemExecutionSettings> extends RemoteExternalSystemService<S> {
public interface RemoteExternalSystemTaskManager<S extends ExternalSystemExecutionSettings> extends RemoteExternalSystemService<S> {
/** <a href="http://en.wikipedia.org/wiki/Null_Object_pattern">Null object</a> for {@link RemoteExternalSystemProjectResolverImpl}. */
RemoteExternalSystemBuildManager<ExternalSystemExecutionSettings> NULL_OBJECT =
new RemoteExternalSystemBuildManager<ExternalSystemExecutionSettings>() {
@Nullable
@Override
public Map<String, Collection<ExternalSystemTaskDescriptor>> listTasks(@NotNull ExternalSystemTaskId id,
@NotNull String projectPath,
@Nullable ExternalSystemExecutionSettings settings)
throws RemoteException, ExternalSystemException
{
return ContainerUtilRt.newHashMap();
}
RemoteExternalSystemTaskManager<ExternalSystemExecutionSettings> NULL_OBJECT =
new RemoteExternalSystemTaskManager<ExternalSystemExecutionSettings>() {
@Override
public void executeTasks(@NotNull ExternalSystemTaskId id,
@@ -77,12 +68,6 @@ public interface RemoteExternalSystemBuildManager<S extends ExternalSystemExecut
}
};
@Nullable
Map<String, Collection<ExternalSystemTaskDescriptor>> listTasks(@NotNull ExternalSystemTaskId id,
@NotNull String projectPath,
@Nullable S settings)
throws RemoteException, ExternalSystemException;
void executeTasks(@NotNull ExternalSystemTaskId id, @NotNull List<String> taskNames, @NotNull String projectPath, @Nullable S settings)
throws RemoteException, ExternalSystemException;
}
@@ -15,50 +15,31 @@
*/
package com.intellij.openapi.externalSystem.service.remote;
import com.intellij.openapi.externalSystem.build.ExternalSystemBuildManager;
import com.intellij.openapi.externalSystem.build.ExternalSystemTaskManager;
import com.intellij.openapi.externalSystem.model.ExternalSystemException;
import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.util.Producer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.rmi.RemoteException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* @author Denis Zhdanov
* @since 4/9/13 7:49 PM
*/
public class RemoteExternalSystemBuildManagerImpl<S extends ExternalSystemExecutionSettings>
extends AbstractRemoteExternalSystemService<S> implements RemoteExternalSystemBuildManager<S>
public class RemoteExternalSystemTaskManagerImpl<S extends ExternalSystemExecutionSettings>
extends AbstractRemoteExternalSystemService<S> implements RemoteExternalSystemTaskManager<S>
{
@NotNull private final ExternalSystemBuildManager<S> myDelegate;
public RemoteExternalSystemBuildManagerImpl(@NotNull ExternalSystemBuildManager<S> delegate) {
@NotNull private final ExternalSystemTaskManager<S> myDelegate;
public RemoteExternalSystemTaskManagerImpl(@NotNull ExternalSystemTaskManager<S> delegate) {
myDelegate = delegate;
}
@Override
public Map<String, Collection<ExternalSystemTaskDescriptor>> listTasks(@NotNull final ExternalSystemTaskId id,
@NotNull final String projectPath,
@Nullable final S settings)
throws RemoteException, ExternalSystemException
{
return execute(id, new Producer<Map<String, Collection<ExternalSystemTaskDescriptor>>>() {
@Nullable
@Override
public Map<String, Collection<ExternalSystemTaskDescriptor>> produce() {
return myDelegate.listTasks(id, projectPath, settings);
}
});
}
@Override
public void executeTasks(@NotNull final ExternalSystemTaskId id,
@NotNull final List<String> taskNames,
@@ -69,7 +50,7 @@ public class RemoteExternalSystemBuildManagerImpl<S extends ExternalSystemExecut
@Nullable
@Override
public Object produce() {
myDelegate.executeTasks(id, taskNames, projectPath, settings);
myDelegate.executeTasks(id, taskNames, projectPath, settings);
return null;
}
});
@@ -4,7 +4,7 @@ import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType;
import com.intellij.openapi.externalSystem.service.RemoteExternalSystemFacade;
import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings;
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemBuildManager;
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemTaskManager;
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProgressNotificationManager;
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolver;
import org.jetbrains.annotations.NotNull;
@@ -43,8 +43,8 @@ public class ExternalSystemFacadeWrapper<S extends ExternalSystemExecutionSettin
@NotNull
@Override
public RemoteExternalSystemBuildManager<S> getBuildManager() throws RemoteException {
return new ExternalSystemBuildManagerWrapper<S>(myDelegate.getBuildManager(), myProgressManager);
public RemoteExternalSystemTaskManager<S> getTaskManager() throws RemoteException {
return new ExternalSystemTaskManagerWrapper<S>(myDelegate.getTaskManager(), myProgressManager);
}
@Override
@@ -16,53 +16,34 @@
package com.intellij.openapi.externalSystem.service.remote.wrapper;
import com.intellij.openapi.externalSystem.model.ExternalSystemException;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings;
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemBuildManager;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProgressNotificationManager;
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemTaskManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.rmi.RemoteException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* @author Denis Zhdanov
* @since 3/14/13 5:53 PM
*/
public class ExternalSystemBuildManagerWrapper<S extends ExternalSystemExecutionSettings>
extends AbstractRemoteExternalSystemServiceWrapper<S, RemoteExternalSystemBuildManager<S>>
implements RemoteExternalSystemBuildManager<S>
public class ExternalSystemTaskManagerWrapper<S extends ExternalSystemExecutionSettings>
extends AbstractRemoteExternalSystemServiceWrapper<S, RemoteExternalSystemTaskManager<S>>
implements RemoteExternalSystemTaskManager<S>
{
@NotNull private final RemoteExternalSystemProgressNotificationManager myProgressManager;
public ExternalSystemBuildManagerWrapper(@NotNull RemoteExternalSystemBuildManager<S> delegate,
@NotNull RemoteExternalSystemProgressNotificationManager progressManager)
public ExternalSystemTaskManagerWrapper(@NotNull RemoteExternalSystemTaskManager<S> delegate,
@NotNull RemoteExternalSystemProgressNotificationManager progressManager)
{
super(delegate);
myProgressManager = progressManager;
}
@Nullable
@Override
public Map<String, Collection<ExternalSystemTaskDescriptor>> listTasks(@NotNull ExternalSystemTaskId id,
@NotNull String projectPath,
@Nullable S settings)
throws RemoteException, ExternalSystemException
{
myProgressManager.onQueued(id);
try {
return getDelegate().listTasks(id, projectPath, settings);
}
finally {
myProgressManager.onEnd(id);
}
}
@Override
public void executeTasks(@NotNull ExternalSystemTaskId id,
@NotNull List<String> taskNames,
@@ -95,7 +95,7 @@ public abstract class AbstractExternalSystemConfigurable<
@Nls
@Override
public String getDisplayName() {
return ExternalSystemApiUtil.toReadableName(myExternalSystemId);
return myExternalSystemId.getReadableName();
}
@Nullable
@@ -126,8 +126,7 @@ public abstract class AbstractExternalSystemConfigurable<
myProjectsList = new JBList(myProjectsModel);
myProjectsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
String externalSystemName = ExternalSystemApiUtil.toReadableName(myExternalSystemId);
addTitle(ExternalSystemBundle.message("settings.title.linked.projects", externalSystemName));
addTitle(ExternalSystemBundle.message("settings.title.linked.projects", myExternalSystemId.getReadableName()));
myComponent.add(new JBScrollPane(myProjectsList), ExternalSystemUiUtil.getFillLineConstraints(1));
addTitle(ExternalSystemBundle.message("settings.title.project.settings"));
@@ -170,7 +169,7 @@ public abstract class AbstractExternalSystemConfigurable<
if (!myProjectsModel.isEmpty()) {
addTitle(ExternalSystemBundle.message("settings.title.system.settings", externalSystemName));
addTitle(ExternalSystemBundle.message("settings.title.system.settings", myExternalSystemId.getReadableName()));
myProjectsList.setSelectedIndex(0);
}
}
@@ -19,7 +19,6 @@ import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListener;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil;
import com.intellij.openapi.externalSystem.util.PaintAwarePanel;
@@ -66,13 +65,13 @@ public abstract class AbstractImportFromExternalSystemControl<
myProjectSettingsControl = createProjectSettingsControl(myProjectSettings);
mySystemSettingsControl = createSystemSettingsControl(mySystemSettings);
String name = ExternalSystemApiUtil.toReadableName(externalSystemId);
JLabel linkedProjectPathLabel = new JLabel(ExternalSystemBundle.message("settings.label.select.project", name));
JLabel linkedProjectPathLabel
= new JLabel(ExternalSystemBundle.message("settings.label.select.project", externalSystemId.getReadableName()));
FileChooserDescriptor fileChooserDescriptor = getLinkedProjectChooserDescriptor();
myLinkedProjectPathField.addBrowseFolderListener(
"",
ExternalSystemBundle.message("settings.label.select.project", ExternalSystemApiUtil.toReadableName(externalSystemId)),
ExternalSystemBundle.message("settings.label.select.project", externalSystemId.getReadableName()),
null,
fileChooserDescriptor,
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT,
@@ -0,0 +1,54 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.service.task;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
import com.intellij.openapi.externalSystem.model.project.ExternalEntityData;
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataService;
import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* @author Denis Zhdanov
* @since 5/15/13 1:32 PM
*/
public abstract class AbstractToolWindowService<T extends ExternalEntityData> implements ProjectDataService<T, Void> {
@Override
public void importData(@NotNull Collection<DataNode<T>> toImport, @NotNull Project project, boolean synchronous) {
if (toImport.isEmpty()) {
return;
}
ExternalSystemTasksTreeModel model = ExternalSystemUtil.getToolWindowElement(ExternalSystemTasksTreeModel.class,
project,
ExternalSystemDataKeys.ALL_TASKS_MODEL,
toImport.iterator().next().getData().getOwner());
if (model != null) {
processData(toImport, model);
}
}
protected abstract void processData(@NotNull Collection<DataNode<T>> nodes, @NotNull ExternalSystemTasksTreeModel model);
@Override
public void removeData(@NotNull Collection<? extends Void> toRemove, @NotNull Project project, boolean synchronous) {
}
}
@@ -1,53 +0,0 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.service.task;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.treeStructure.Tree;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
/**
* @author Denis Zhdanov
* @since 5/12/13 10:18 PM
*/
public class ExternalSystemTasksPanel extends JPanel implements DataProvider {
@NotNull ExternalSystemTasksTreeModel myAllTasksModel = new ExternalSystemTasksTreeModel();
@NotNull Tree myAllTasksTree = new Tree(myAllTasksModel);
public ExternalSystemTasksPanel() {
super(new GridBagLayout());
add(new JBScrollPane(myAllTasksTree), ExternalSystemUiUtil.getFillLineConstraints(0));
}
@Nullable
@Override
public Object getData(@NonNls String dataId) {
if (ExternalSystemDataKeys.ALL_TASKS_MODEL.is(dataId)) {
return myAllTasksModel;
}
return null;
}
}
@@ -0,0 +1,71 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.service.task;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.Key;
import com.intellij.openapi.externalSystem.model.ProjectKeys;
import com.intellij.openapi.externalSystem.model.project.ModuleData;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.externalSystem.util.Order;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* Ensures that all external system sub-projects are correctly represented at the external system tool window.
*
* @author Denis Zhdanov
* @since 5/15/13 1:02 PM
*/
@Order(ExternalSystemConstants.BUILTIN_TOOL_WINDOW_SERVICE_ORDER)
public class ToolWindowModuleService extends AbstractToolWindowService<ModuleData> {
@NotNull
public static final Function<DataNode<ModuleData>, ModuleData> MAPPER = new Function<DataNode<ModuleData>, ModuleData>() {
@Override
public ModuleData fun(DataNode<ModuleData> node) {
return node.getData();
}
};
@NotNull
@Override
public Key<ModuleData> getTargetDataKey() {
return ProjectKeys.MODULE;
}
@Override
protected void processData(@NotNull final Collection<DataNode<ModuleData>> nodes, @NotNull final ExternalSystemTasksTreeModel model) {
final Map<DataNode<ProjectData>, List<DataNode<ModuleData>>> grouped = ExternalSystemApiUtil.groupBy(nodes, ProjectKeys.PROJECT);
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
for (Map.Entry<DataNode<ProjectData>, List<DataNode<ModuleData>>> entry : grouped.entrySet()) {
model.ensureSubProjectsStructure(entry.getKey().getData(), ContainerUtilRt.map2List(entry.getValue(), MAPPER));
}
}
});
}
}
@@ -0,0 +1,55 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.service.task;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.Key;
import com.intellij.openapi.externalSystem.model.ProjectKeys;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.externalSystem.util.Order;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* @author Denis Zhdanov
* @since 5/15/13 11:46 AM
*/
@Order(ExternalSystemConstants.BUILTIN_TOOL_WINDOW_SERVICE_ORDER)
public class ToolWindowProjectService extends AbstractToolWindowService<ProjectData> {
@NotNull
@Override
public Key<ProjectData> getTargetDataKey() {
return ProjectKeys.PROJECT;
}
@Override
protected void processData(@NotNull final Collection<DataNode<ProjectData>> nodes, @NotNull final ExternalSystemTasksTreeModel model) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
for (DataNode<ProjectData> node : nodes) {
model.ensureProjectNodeExists(node.getData());
}
}
});
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.service.task;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.Key;
import com.intellij.openapi.externalSystem.model.ProjectKeys;
import com.intellij.openapi.externalSystem.model.task.TaskData;
import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.externalSystem.util.Order;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* @author Denis Zhdanov
* @since 5/15/13 7:21 PM
*/
@Order(ExternalSystemConstants.BUILTIN_TOOL_WINDOW_SERVICE_ORDER)
public class ToolWindowTaskService extends AbstractToolWindowService<TaskData> {
@NotNull
@Override
public Key<TaskData> getTargetDataKey() {
return ProjectKeys.TASK;
}
@Override
protected void processData(@NotNull Collection<DataNode<TaskData>> nodes, @NotNull ExternalSystemTasksTreeModel model) {
// TODO den implement
}
}
@@ -0,0 +1,63 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.service.task.ui;
import com.intellij.notification.NotificationGroup;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.ui.content.ContentManager;
import com.intellij.ui.content.impl.ContentImpl;
import org.jetbrains.annotations.NotNull;
/**
* @author Denis Zhdanov
* @since 5/13/13 4:15 PM
*/
public abstract class AbstractExternalSystemToolWindowFactory implements ToolWindowFactory, DumbAware {
@NotNull private final ProjectSystemId myExternalSystemId;
@NotNull private final NotificationGroup myNotificationGroup;
protected AbstractExternalSystemToolWindowFactory(@NotNull ProjectSystemId id) {
myExternalSystemId = id;
myNotificationGroup = NotificationGroup.toolWindowGroup("notification.group.id." + id.toString().toLowerCase(),
myExternalSystemId.getReadableName(),
true);
}
@Override
public void createToolWindowContent(final Project project, final ToolWindow toolWindow) {
toolWindow.setTitle(myExternalSystemId.getReadableName());
ContentManager contentManager = toolWindow.getContentManager();
String tasksTitle = ExternalSystemBundle.message("tool.window.title.tasks");
ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(myExternalSystemId);
assert manager != null;
AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
ExternalSystemTasksPanel panel = new ExternalSystemTasksPanel(settings.getAvailableTasks(),
project,
myExternalSystemId,
myNotificationGroup);
ContentImpl tasksContent = new ContentImpl(panel, tasksTitle, true);
contentManager.addContent(tasksContent);
}
}
@@ -0,0 +1,42 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.service.task.ui;
import org.jetbrains.annotations.NotNull;
import javax.swing.tree.DefaultMutableTreeNode;
/**
* @author Denis Zhdanov
* @since 5/14/13 2:42 PM
*/
@SuppressWarnings("unchecked")
public class ExternalSystemNode<T> extends DefaultMutableTreeNode {
public ExternalSystemNode(@NotNull ExternalSystemNodeDescriptor<T> descriptor) {
super(descriptor);
}
@NotNull
public ExternalSystemNodeDescriptor<T> getDescriptor() {
return (ExternalSystemNodeDescriptor<T>)getUserObject();
}
@Override
public ExternalSystemNode<?> getChildAt(int index) {
return (ExternalSystemNode<?>)super.getChildAt(index);
}
}
@@ -0,0 +1,51 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.service.task.ui;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.util.treeView.PresentableNodeDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* @author Denis Zhdanov
* @since 5/14/13 2:32 PM
*/
public class ExternalSystemNodeDescriptor<T> extends PresentableNodeDescriptor<T> {
@NotNull private final T myElement;
public ExternalSystemNodeDescriptor(@NotNull T element, @NotNull String text, @Nullable Icon icon) {
super(null, null);
myElement = element;
myName = text;
setIcon(icon);
}
@Override
protected void update(PresentationData presentation) {
presentation.setPresentableText(myName);
presentation.setIcon(getIcon());
}
@NotNull
@Override
public T getElement() {
return myElement;
}
}
@@ -0,0 +1,92 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.service.task.ui;
import com.intellij.notification.NotificationGroup;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionToolbar;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.ui.components.JBScrollPane;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
/**
* @author Denis Zhdanov
* @since 5/12/13 10:18 PM
*/
public class ExternalSystemTasksPanel extends SimpleToolWindowPanel implements DataProvider {
@NotNull private final ExternalSystemTasksTreeModel myAllTasksModel;
@NotNull private final ExternalSystemTasksTree myAllTasksTree;
@NotNull private final ProjectSystemId myExternalSystemId;
@NotNull private final NotificationGroup myNotificationGroup;
public ExternalSystemTasksPanel(@NotNull Map<String, List<ExternalSystemTaskDescriptor>> tasks,
@NotNull Project project,
@NotNull ProjectSystemId externalSystemId,
@NotNull NotificationGroup notificationGroup)
{
super(true);
myExternalSystemId = externalSystemId;
myNotificationGroup = notificationGroup;
myAllTasksModel = new ExternalSystemTasksTreeModel(externalSystemId);
ExternalSystemManager<?,?,?,?,?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
assert manager != null;
AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
myAllTasksTree = new ExternalSystemTasksTree(myAllTasksModel, settings.getExpandStates());
ActionManager actionManager = ActionManager.getInstance();
ActionGroup group = (ActionGroup)actionManager.getAction(ExternalSystemConstants.TOOL_WINDOW_TOOLBAR_ACTIONS_GROUP_ID);
ActionToolbar toolbar = actionManager.createActionToolbar(ExternalSystemConstants.TOOL_WINDOW_PLACE, group, true);
toolbar.setTargetComponent(this);
setToolbar(toolbar.getComponent());
setContent(new JBScrollPane(myAllTasksTree));
// TODO den implement
// myAllTasksModel.updateTasks(tasks);
}
@Nullable
@Override
public Object getData(@NonNls String dataId) {
if (ExternalSystemDataKeys.ALL_TASKS_MODEL.is(dataId)) {
return myAllTasksModel;
}
else if (ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.is(dataId)) {
return myExternalSystemId;
}
else if (ExternalSystemDataKeys.NOTIFICATION_GROUP.is(dataId)) {
return myNotificationGroup;
}
return null;
}
}
@@ -0,0 +1,139 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.service.task.ui;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.Alarm;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.ui.tree.TreeModelAdapter;
import org.jetbrains.annotations.NotNull;
import javax.swing.event.TreeModelEvent;
import javax.swing.tree.TreePath;
import java.util.*;
/**
* @author Denis Zhdanov
* @since 5/13/13 4:18 PM
*/
public class ExternalSystemTasksTree extends Tree {
private static final int COLLAPSE_STATE_PROCESSING_DELAY_MILLIS = 200;
@NotNull private static final Comparator<TreePath> PATH_COMPARATOR = new Comparator<TreePath>() {
@Override
public int compare(TreePath o1, TreePath o2) {
return o2.getPathCount() - o1.getPathCount();
}
};
@NotNull private final Alarm myCollapseStateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
/** Holds list of paths which 'expand/collapse' state should be restored. */
@NotNull private final Set<TreePath> myPathsToProcessCollapseState = ContainerUtilRt.newHashSet();
@NotNull private final Map<String/*tree path*/, Boolean/*expanded*/> myExpandedStateHolder;
private boolean mySuppressCollapseTracking;
public ExternalSystemTasksTree(@NotNull ExternalSystemTasksTreeModel model,
@NotNull Map<String/*tree path*/, Boolean/*expanded*/> expandedStateHolder)
{
super(model);
myExpandedStateHolder = expandedStateHolder;
setRootVisible(false);
model.addTreeModelListener(new TreeModelAdapter() {
@Override
public void treeStructureChanged(TreeModelEvent e) {
scheduleCollapseStateAppliance(e.getTreePath());
}
@Override
public void treeNodesInserted(TreeModelEvent e) {
scheduleCollapseStateAppliance(e.getTreePath());
}
});
}
/**
* Schedules 'collapse/expand' state restoring for the given path. We can't do that immediately from the tree model listener
* as there is a possible case that other listeners have not been notified about the model state change, hence, attempt to define
* 'collapse/expand' state may bring us to the inconsistent state.
*
* @param path target path
*/
private void scheduleCollapseStateAppliance(@NotNull TreePath path) {
myPathsToProcessCollapseState.add(path);
myCollapseStateAlarm.cancelAllRequests();
myCollapseStateAlarm.addRequest(new Runnable() {
@Override
public void run() {
// We assume that the paths collection is modified only from the EDT, so, ConcurrentModificationException doesn't have
// a chance.
// Another thing is that we sort the paths in order to process the longest first. That is related to the JTree specifics
// that it automatically expands parent paths on child path expansion.
List<TreePath> paths = new ArrayList<TreePath>(myPathsToProcessCollapseState);
myPathsToProcessCollapseState.clear();
Collections.sort(paths, PATH_COMPARATOR);
for (TreePath treePath : paths) {
applyCollapseState(treePath);
}
final TreePath rootPath = new TreePath(getModel().getRoot());
if (isCollapsed(rootPath)) {
expandPath(rootPath);
}
}
}, COLLAPSE_STATE_PROCESSING_DELAY_MILLIS);
}
/**
* Applies stored 'collapse/expand' state to the node located at the given path.
*
* @param path target path
*/
private void applyCollapseState(@NotNull TreePath path) {
final String key = getPath(path);
final Boolean expanded = myExpandedStateHolder.get(key);
if (expanded == null) {
return;
}
boolean s = mySuppressCollapseTracking;
mySuppressCollapseTracking = true;
try {
if (expanded) {
expandPath(path);
}
else {
collapsePath(path);
}
}
finally {
mySuppressCollapseTracking = s;
}
}
@NotNull
private static String getPath(@NotNull TreePath path) {
StringBuilder buffer = new StringBuilder();
for (TreePath current = path; current != null; current = current.getParentPath()) {
buffer.append(current.getLastPathComponent().toString()).append('/');
}
buffer.setLength(buffer.length() - 1);
return buffer.toString();
}
}
@@ -0,0 +1,177 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.service.task.ui;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.project.ModuleData;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor;
import com.intellij.openapi.externalSystem.service.ui.DefaultExternalSystemUiAware;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil;
import com.intellij.util.containers.ContainerUtilRt;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
/**
* @author Denis Zhdanov
* @since 5/12/13 10:28 PM
*/
public class ExternalSystemTasksTreeModel extends DefaultTreeModel {
@NotNull private final TreeNode[] myNodeHolder = new TreeNode[1];
@NotNull private final int[] myIndexHolder = new int[1];
@NotNull private final ExternalSystemUiAware myUiAware;
public ExternalSystemTasksTreeModel(@NotNull ProjectSystemId externalSystemId) {
super(new ExternalSystemNode<String>(new ExternalSystemNodeDescriptor<String>("", "", null)));
ExternalSystemManager<?,?,?,?,?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
if (manager instanceof ExternalSystemUiAware) {
myUiAware = (ExternalSystemUiAware)manager;
}
else {
myUiAware = DefaultExternalSystemUiAware.INSTANCE;
}
}
/**
* Ensures that current model has a top-level node which corresponds to the given external project info holder
*
* @param externalProject target external project info holder
*/
@SuppressWarnings("unchecked")
@NotNull
public ExternalSystemNode<ProjectNodeElement> ensureProjectNodeExists(@NotNull ProjectData externalProject) {
ExternalSystemNode<?> root = getRoot();
// Remove outdated projects.
for (int i = root.getChildCount() - 1; i >= 0; i--) {
ExternalSystemNode<?> child = root.getChildAt(i);
Object element = child.getDescriptor().getElement();
if (element instanceof ProjectNodeElement
&& ((ProjectNodeElement)element).path.equals(externalProject.getLinkedExternalProjectPath()))
{
return (ExternalSystemNode<ProjectNodeElement>)child;
}
}
ProjectNodeElement element = new ProjectNodeElement(externalProject.getName(), externalProject.getLinkedExternalProjectPath());
ExternalSystemNodeDescriptor<ProjectNodeElement> descriptor = descriptor(element, myUiAware.getProjectIcon());
myIndexHolder[0] = root.getChildCount();
ExternalSystemNode<ProjectNodeElement> result = new ExternalSystemNode<ProjectNodeElement>(descriptor);
root.add(result);
nodesWereInserted(root, myIndexHolder);
return result;
}
public void ensureSubProjectsStructure(@NotNull ProjectData topLevelProject, @NotNull List<ModuleData> subProjects) {
ExternalSystemNode<ProjectNodeElement> topLevelProjectNode = ensureProjectNodeExists(topLevelProject);
Map<String/*config path*/, ModuleData> toAdd = ContainerUtilRt.newHashMap();
final TObjectIntHashMap<String/* sub-project config path */> subProjectWeights = new TObjectIntHashMap<String>();
int w = 0;
for (ModuleData subProject : subProjects) {
toAdd.put(subProject.getExternalConfigPath(), subProject);
subProjectWeights.put(subProject.getExternalConfigPath(), w++);
}
final TObjectIntHashMap<Object> taskWeights = new TObjectIntHashMap<Object>();
for (int i = 0; i < topLevelProjectNode.getChildCount(); i++) {
ExternalSystemNode<?> child = topLevelProjectNode.getChildAt(i);
Object childElement = child.getDescriptor().getElement();
if (childElement instanceof ExternalSystemTaskDescriptor) {
taskWeights.put(childElement, subProjects.size() + i);
continue;
}
if (toAdd.remove(((ProjectNodeElement)childElement).path) == null) {
topLevelProjectNode.remove(child);
myIndexHolder[0] = i;
myNodeHolder[0] = child;
nodesWereRemoved(topLevelProjectNode, myIndexHolder, myNodeHolder);
//noinspection AssignmentToForLoopParameter
i--;
}
}
if (!toAdd.isEmpty()) {
for (Map.Entry<String, ModuleData> entry : toAdd.entrySet()) {
ProjectNodeElement element = new ProjectNodeElement(entry.getValue().getName(), entry.getValue().getExternalConfigPath());
topLevelProjectNode.add(new ExternalSystemNode<ProjectNodeElement>(descriptor(element, myUiAware.getProjectIcon())));
}
}
ExternalSystemUiUtil.sort(topLevelProjectNode, this, new Comparator<TreeNode>() {
@Override
public int compare(TreeNode o1, TreeNode o2) {
// A node might be one of the following:
// 1. Sub-project node;
// 2. Top-level project's task node;
// We want to put top-level project's tasks before sub-projects and preserve relative order between them.
return getWeight(o1) - getWeight(o2);
}
private int getWeight(@NotNull TreeNode node) {
if (!(node instanceof ExternalSystemNode<?>)) {
return 0;
}
Object element = ((ExternalSystemNode)node).getDescriptor().getElement();
if (element instanceof ProjectNodeElement) {
return subProjectWeights.get(((ProjectNodeElement)element).path);
}
else if (element instanceof ExternalSystemTaskDescriptor) {
return taskWeights.get(element);
}
else {
return 0;
}
}
});
}
@NotNull
private static <T> ExternalSystemNodeDescriptor<T> descriptor(@NotNull T element, @Nullable Icon icon) {
return new ExternalSystemNodeDescriptor<T>(element, element.toString(), icon);
}
@NotNull
public ExternalSystemNode<?> getRoot() {
return (ExternalSystemNode<?>)super.getRoot();
}
private static class ProjectNodeElement {
@NotNull public final String name;
@NotNull public final String path;
ProjectNodeElement(@NotNull String name, @NotNull String path) {
this.name = name;
this.path = path;
}
@Override
public String toString() {
return name;
}
}
}
@@ -0,0 +1,40 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.service.ui;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* This class is not singleton but offers single-point-of-usage field - {@link #INSTANCE}.
*
* @author Denis Zhdanov
* @since 5/15/13 12:45 PM
*/
public class DefaultExternalSystemUiAware implements ExternalSystemUiAware {
@NotNull public static final DefaultExternalSystemUiAware INSTANCE = new DefaultExternalSystemUiAware();
@Nullable
@Override
public Icon getProjectIcon() {
return AllIcons.Nodes.IdeaProject;
}
}
@@ -21,11 +21,20 @@ import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.BalloonBuilder;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.ui.GridBag;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
@@ -82,4 +91,30 @@ public class ExternalSystemUiUtil {
public static void fillBottom(@NotNull JComponent component) {
component.add(Box.createVerticalGlue(), new GridBag().weightx(1).weighty(1).fillCell().coverLine());
}
public static void sort(@NotNull DefaultMutableTreeNode parent,
@NotNull DefaultTreeModel model,
@NotNull Comparator<TreeNode> comparator)
{
List<MutableTreeNode> children = ContainerUtilRt.newArrayList();
THashMap<TreeNode, Integer> initialOrder = ContainerUtil.newIdentityTroveMap();
for (int i = 0; i < parent.getChildCount(); i++) {
MutableTreeNode child = (MutableTreeNode)parent.getChildAt(i);
children.add(child);
initialOrder.put(child, i);
}
Collections.sort(children, comparator);
parent.removeAllChildren();
for (MutableTreeNode child : children) {
parent.add(child);
}
for (int i = 0; i < children.size(); i++) {
MutableTreeNode child = children.get(i);
Integer initialIndex = initialOrder.get(child);
if (initialIndex != i) {
model.nodeChanged(child);
}
}
}
}
@@ -28,7 +28,8 @@ import com.intellij.openapi.externalSystem.model.ProjectKeys;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.project.ModuleData;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemResolveProjectTask;
import com.intellij.openapi.externalSystem.service.internal.ExternalSystemResolveProjectTask;
import com.intellij.openapi.externalSystem.service.notification.ExternalSystemIdeNotificationManager;
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
import com.intellij.openapi.externalSystem.service.project.PlatformFacade;
import com.intellij.openapi.externalSystem.service.project.manage.ModuleDataService;
@@ -109,7 +110,7 @@ public class ExternalSystemUtil {
if (toolWindowManager == null) {
return null;
}
final ToolWindow toolWindow = toolWindowManager.getToolWindow(ExternalSystemApiUtil.toReadableName(externalSystemId));
final ToolWindow toolWindow = toolWindowManager.getToolWindow(externalSystemId.getReadableName());
if (toolWindow == null) {
return null;
}
@@ -233,10 +234,9 @@ public class ExternalSystemUtil {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
final String externalSystem = ExternalSystemApiUtil.toReadableName(externalSystemId);
final JPanel content = new JPanel(new GridBagLayout());
content.add(new JLabel(ExternalSystemBundle.message("orphan.modules.text", externalSystem)),
content.add(new JLabel(ExternalSystemBundle.message("orphan.modules.text", externalSystemId.getReadableName())),
ExternalSystemUiUtil.getFillLineConstraints(0));
final CheckBoxList<Module> orphanModulesList = new CheckBoxList<Module>();
@@ -255,7 +255,7 @@ public class ExternalSystemUtil {
DialogWrapper dialog = new DialogWrapper(project) {
{
setTitle(ExternalSystemBundle.message("import.title", externalSystem));
setTitle(ExternalSystemBundle.message("import.title", externalSystemId.getReadableName()));
init();
}
@@ -314,6 +314,7 @@ public class ExternalSystemUtil {
final boolean resolveLibraries,
final boolean modal)
{
final String projectName = new File(externalProjectPath).getParentFile().getName();
final TaskUnderProgress refreshProjectStructureTask = new TaskUnderProgress() {
@SuppressWarnings({"ThrowableResultOfMethodCallIgnored", "IOResourceOpenedButNotSafelyClosed"})
@Override
@@ -331,26 +332,22 @@ public class ExternalSystemUtil {
if (StringUtil.isEmpty(message)) {
message = String.format(
"Can't resolve %s project at '%s'. Reason: %s",
ExternalSystemApiUtil.toReadableName(externalSystemId), externalProjectPath, message
externalSystemId.getReadableName(), externalProjectPath, message
);
}
callback.onFailure(message, extractDetails(error));
ExternalSystemIdeNotificationManager notificationManager = ServiceManager.getService(ExternalSystemIdeNotificationManager.class);
if (notificationManager != null) {
notificationManager.processExternalProjectRefreshError(message, project, projectName, externalSystemId);
}
}
};
// TODO den implement
//final TaskUnderProgress refreshTasksTask = new TaskUnderProgress() {
// @Override
// public void execute(@NotNull ProgressIndicator indicator) {
// final ExternalSystemRefreshTasksListTask task = new ExternalSystemRefreshTasksListTask(project, externalProjectPath);
// task.execute(indicator);
// }
//};
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
final String projectName = new File(externalProjectPath).getParentFile().getName();
if (modal) {
String title = ExternalSystemBundle.message("progress.import.text",
projectName,
@@ -359,9 +356,6 @@ public class ExternalSystemUtil {
@Override
public void run(@NotNull ProgressIndicator indicator) {
refreshProjectStructureTask.execute(indicator);
// TODO den uncomment
//setTitle(ExternalSystemBundle.message("gradle.task.progress.initial.text"));
//refreshTasksTask.execute(indicator);
}
});
}
@@ -372,9 +366,6 @@ public class ExternalSystemUtil {
@Override
public void run(@NotNull ProgressIndicator indicator) {
refreshProjectStructureTask.execute(indicator);
// TODO den uncomment
//setTitle(ExternalSystemBundle.message("gradle.task.progress.initial.text"));
//refreshTasksTask.execute(indicator);
}
});
}
@@ -14,6 +14,8 @@
serviceImplementation="com.intellij.openapi.externalSystem.service.project.ExternalLibraryPathTypeMapperImpl"/>
<applicationService serviceImplementation="com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsManager"/>
<applicationService serviceImplementation="com.intellij.openapi.externalSystem.service.project.ProjectStructureHelper"/>
<applicationService serviceImplementation="com.intellij.openapi.externalSystem.service.internal.ExternalSystemProcessingManager"/>
<applicationService serviceImplementation="com.intellij.openapi.externalSystem.service.notification.ExternalSystemIdeNotificationManager"/>
<!--Project structure management services-->
<applicationService serviceImplementation="com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager"/>
@@ -23,7 +25,13 @@
<externalProjectDataService implementation="com.intellij.openapi.externalSystem.service.project.manage.ContentRootDataService"/>
<externalProjectDataService implementation="com.intellij.openapi.externalSystem.service.project.manage.LibraryDependencyDataService"/>
<externalProjectDataService implementation="com.intellij.openapi.externalSystem.service.project.manage.ModuleDependencyDataService"/>
<!--Tool window services-->
<externalProjectDataService implementation="com.intellij.openapi.externalSystem.service.task.ToolWindowProjectService"/>
<externalProjectDataService implementation="com.intellij.openapi.externalSystem.service.task.ToolWindowModuleService"/>
<externalProjectDataService implementation="com.intellij.openapi.externalSystem.service.task.ToolWindowTaskService"/>
</extensions>
</idea-plugin>
@@ -0,0 +1,13 @@
<component>
<actions>
<!--Tool window actions-->
<action id="ExternalSystem.RefreshAllProjects"
class="com.intellij.openapi.externalSystem.action.RefreshAllExternalProjectsAction"
icon="AllIcons.Actions.Refresh"/>
<group id="ExternalSystem.ToolWindow.Toolbar">
<reference id="ExternalSystem.RefreshAllProjects"/>
</group>
</actions>
</component>
+1 -25
View File
@@ -45,30 +45,6 @@
<projectService serviceImplementation="org.jetbrains.plugins.gradle.settings.GradleSettings"/>
<projectService serviceImplementation="org.jetbrains.plugins.gradle.settings.GradleLocalSettings"/>
<!--<applicationService serviceInterface="com.intellij.openapi.externalSystem.service.notification.ExternalSystemProgressNotificationManager"-->
<!--serviceImplementation="com.intellij.openapi.externalSystem.service.remote.ExternalSystemProgressNotificationManagerImpl"/>-->
<!--<applicationService serviceInterface="com.intellij.openapi.externalSystem.service.project.PlatformFacade"-->
<!--serviceImplementation="com.intellij.openapi.externalSystem.service.project.PlatformFacadeImpl"/>-->
<!--<applicationService serviceInterface="com.intellij.openapi.externalSystem.service.project.ExternalLibraryPathTypeMapper"-->
<!--serviceImplementation="com.intellij.openapi.externalSystem.service.project.ExternalLibraryPathTypeMapperImpl"/>-->
<!--Conflict UI components-->
<!--<applicationService serviceImplementation="org.jetbrains.plugins.gradle.sync.conflict.GradleConflictControlFactory"/>-->
<!--<applicationService serviceImplementation="org.jetbrains.plugins.gradle.sync.conflict.GradleProjectConflictControlFactory"/>-->
<!--<applicationService serviceImplementation="org.jetbrains.plugins.gradle.sync.conflict.GradleCommonDependencyConflictControlFactory"/>-->
<!--<projectService serviceImplementation="com.intellij.openapi.externalSystem.service.project.change.ProjectStructureChangesModel"/>-->
<!--<projectService serviceImplementation="com.intellij.openapi.externalSystem.service.project.ProjectStructureHelper"/>-->
<!--<projectService serviceImplementation="com.intellij.openapi.externalSystem.service.project.manage.OutdatedLibraryManager"/>-->
<!--<projectService serviceImplementation="com.intellij.openapi.externalSystem.model.project.id.EntityIdMapper"/>-->
<!--<projectService serviceImplementation="com.intellij.openapi.externalSystem.service.project.ProjectStructureServices"/>-->
<!--<projectService serviceImplementation="com.intellij.openapi.externalSystem.service.project.manage.GradleLocalNodeManageHelper"/>-->
<!--<projectService serviceImplementation="com.intellij.openapi.externalSystem.service.project.manage.EntityManageHelper"/>-->
<!--<projectService serviceImplementation="com.intellij.openapi.externalSystem.service.project.ProjectStructureChangesDetector"/>-->
<!--<projectService serviceImplementation="com.intellij.openapi.externalSystem.service.project.change.user.UserProjectChangesCalculator"/>-->
<!--<projectService serviceImplementation="org.jetbrains.plugins.gradle.notification.GradleConfigNotificationManager"/>-->
<!--<projectService serviceImplementation="com.intellij.openapi.externalSystem.service.task.ExternalSystemTaskManager"/>-->
<toolWindow id="Gradle" anchor="right" icon="GradleIcons.ToolWindowGradle"
factoryClass="org.jetbrains.plugins.gradle.ui.GradleToolWindowFactory"
conditionClass="org.jetbrains.plugins.gradle.ui.GradleToolWindowFactoryCondition"/>
@@ -84,7 +60,7 @@
<actions>
<!-- Tool window toolbar actions -->
<action id="Gradle.RefreshProject" class="org.jetbrains.plugins.gradle.action.GradleRefreshProjectAction" icon="AllIcons.Actions.Refresh"/>
<action id="Gradle.RefreshProject" class="com.intellij.openapi.externalSystem.action.RefreshAllExternalProjectsAction" icon="AllIcons.Actions.Refresh"/>
<action id="Gradle.OpenScript" class="org.jetbrains.plugins.gradle.action.GradleOpenScriptAction" icon="GradleIcons.GradleNavigate"/>
<action id="Gradle.Help.ToolWindow" class="org.jetbrains.plugins.gradle.action.GradleToolWindowHelpAction" icon="AllIcons.Actions.Help"/>
<group id="Gradle.ChangeActionsToolbar">
@@ -20,8 +20,10 @@ import com.intellij.execution.configurations.SimpleJavaParameters;
import com.intellij.externalSystem.JavaProjectData;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.ExternalSystemConfigurableAware;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.build.ExternalSystemBuildManager;
import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
import com.intellij.openapi.externalSystem.build.ExternalSystemTaskManager;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.service.project.ExternalSystemProjectResolver;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
@@ -29,6 +31,7 @@ import com.intellij.openapi.module.EmptyModuleType;
import com.intellij.openapi.module.JavaModuleType;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.Pair;
@@ -38,17 +41,21 @@ import com.intellij.util.Function;
import com.intellij.util.PathUtil;
import com.intellij.util.PathsList;
import com.intellij.util.containers.ContainerUtilRt;
import icons.GradleIcons;
import org.gradle.tooling.ProjectConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.remote.GradleJavaHelper;
import org.jetbrains.plugins.gradle.remote.impl.GradleBuildManager;
import org.jetbrains.plugins.gradle.remote.impl.GradleTaskManager;
import org.jetbrains.plugins.gradle.service.GradleInstallationManager;
import org.jetbrains.plugins.gradle.service.project.GradleProjectResolver;
import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverExtension;
import org.jetbrains.plugins.gradle.service.settings.GradleConfigurable;
import org.jetbrains.plugins.gradle.settings.*;
import org.jetbrains.plugins.gradle.util.GradleBundle;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import javax.swing.*;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
@@ -59,7 +66,7 @@ import java.util.List;
* @author Denis Zhdanov
* @since 4/10/13 1:19 PM
*/
public class GradleManager implements ExternalSystemManager<
public class GradleManager implements ExternalSystemConfigurableAware, ExternalSystemUiAware, ExternalSystemManager<
GradleProjectSettings,
GradleSettingsListener,
GradleSettings,
@@ -207,7 +214,19 @@ public class GradleManager implements ExternalSystemManager<
}
@Override
public Class<? extends ExternalSystemBuildManager<GradleExecutionSettings>> getBuildManagerClass() {
return GradleBuildManager.class;
public Class<? extends ExternalSystemTaskManager<GradleExecutionSettings>> getTaskManagerClass() {
return GradleTaskManager.class;
}
@NotNull
@Override
public Configurable getConfigurable(@NotNull Project project) {
return new GradleConfigurable(project);
}
@Nullable
@Override
public Icon getProjectIcon() {
return GradleIcons.Gradle;
}
}
@@ -1,74 +0,0 @@
package org.jetbrains.plugins.gradle.action;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.settings.GradleSettings;
import com.intellij.openapi.externalSystem.service.task.ExternalSystemTaskManager;
import org.jetbrains.plugins.gradle.notification.GradleConfigNotificationManager;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import org.jetbrains.plugins.gradle.util.GradleUtil;
/**
* Forces the 'gradle' plugin to retrieve the most up-to-date info about the
* {@link GradleSettings#getLinkedExternalProjectPath() linked gradle project} and update all affected control if necessary
* (like project structure UI, tasks list etc).
*
* @author Denis Zhdanov
* @since 1/23/12 3:48 PM
*/
public class GradleRefreshProjectAction extends AbstractGradleLinkedProjectAction implements DumbAware, AnAction.TransparentUpdate {
private final Ref<String> myErrorMessage = new Ref<String>();
public GradleRefreshProjectAction() {
// TODO den uncomment
//getTemplatePresentation().setText(ExternalSystemBundle.message("gradle.action.refresh.project.text"));
//getTemplatePresentation().setDescription(ExternalSystemBundle.message("gradle.action.refresh.project.description"));
}
@Override
protected void doUpdate(@NotNull AnActionEvent event, @NotNull Project project, @NotNull String linkedProjectPath) {
String message = myErrorMessage.get();
if (message != null) {
// TODO den implement
// ExternalProjectStructureTreeModel model = GradleUtil.getProjectStructureTreeModel(event.getDataContext());
// if (model != null) {
// model.rebuild();
// }
GradleConfigNotificationManager notificationManager = ServiceManager.getService(project, GradleConfigNotificationManager.class);
notificationManager.processRefreshError(message);
myErrorMessage.set(null);
}
boolean enabled = false;
final ExternalSystemTaskManager taskManager = ServiceManager.getService(project, ExternalSystemTaskManager.class);
if (taskManager != null) {
enabled = !taskManager.hasTaskOfTypeInProgress(ExternalSystemTaskType.RESOLVE_PROJECT);
}
event.getPresentation().setEnabled(enabled);
}
@Override
protected void doActionPerformed(@NotNull AnActionEvent event, @NotNull final Project project, @NotNull final String linkedProjectPath) {
// We save all documents because there is more than one target 'build.gradle' file in case of multi-module gradle project.
FileDocumentManager.getInstance().saveAllDocuments();
GradleConfigNotificationManager notificationManager = ServiceManager.getService(project, GradleConfigNotificationManager.class);
// TODO den implement
//if (!GradleUtil.isGradleAvailable(project)) {
// notificationManager.processUnknownGradleHome();
// return;
//}
//myErrorMessage.set(null);
//ExternalSystemUtil.refreshProject(project, GradleConstants.SYSTEM_ID, myErrorMessage);
}
}
@@ -1,90 +0,0 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.gradle.internal.task;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.externalSystem.build.ExternalSystemBuildManager;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.task.AbstractExternalSystemTask;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskState;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType;
import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager;
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemBuildManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Denis Zhdanov
* @since 3/15/13 1:20 PM
*/
public class ExternalSystemRefreshTasksListTask extends AbstractExternalSystemTask {
@NotNull private final String myProjectPath;
public ExternalSystemRefreshTasksListTask(@NotNull ProjectSystemId externalSystemId,
@NotNull Project project,
@NotNull String projectPath)
{
super(externalSystemId, ExternalSystemTaskType.REFRESH_TASKS_LIST, project, projectPath);
myProjectPath = projectPath;
}
@Override
protected void doExecute() throws Exception {
final ExternalSystemFacadeManager manager = ServiceManager.getService(ExternalSystemFacadeManager.class);
Project project = getIdeProject();
RemoteExternalSystemBuildManager buildManager = manager.getFacade(project, myProjectPath, getExternalSystemId()).getBuildManager();
setState(ExternalSystemTaskState.IN_PROGRESS);
// TODO den implement
//buildManager.listTasks()
//try {
// final Collection<ExternalSystemTaskDescriptor> descriptors = buildManager.listTasks(getId(), myProjectPath);
// if (descriptors == null || descriptors.isEmpty()) {
// return;
// }
//
// if (project == null) {
// return;
// }
//
// GradleLocalSettings settings = GradleLocalSettings.getInstance(project);
// settings.setAvailableTasks(descriptors);
//
// final GradleTasksModel tasksModel = GradleUtil.getToolWindowElement(GradleTasksModel.class, project, ExternalSystemDataKeys.ALL_TASKS_MODEL);
// if (tasksModel == null) {
// return;
// }
// UIUtil.invokeLaterIfNeeded(new Runnable() {
// @Override
// public void run() {
// tasksModel.setTasks(descriptors);
// }
// });
//}
//finally {
// setState(GradleTaskState.FINISHED);
//}
}
@Override
@NotNull
protected String wrapProgressText(@NotNull String text) {
// TODO den implement
return "";
// return ExternalSystemBundle.message("gradle.tasks.progress.update.text", text);
}
}
@@ -1,117 +0,0 @@
package org.jetbrains.plugins.gradle.notification;
import com.intellij.notification.Notification;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.ui.EditorNotifications;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.settings.GradleSettingsListener;
import org.jetbrains.plugins.gradle.config.GradleSettingsListenerAdapter;
import org.jetbrains.plugins.gradle.service.GradleInstallationManager;
import org.jetbrains.plugins.gradle.util.GradleUtil;
import java.util.concurrent.atomic.AtomicReference;
/**
* This class is responsible for notifying about the gradle config changes.
* <p/>
* One example use-case is a situation when a user resets gradle home (e.g. project config dir has been (re)moved). We need to
* explain that we can't use the integration until gradle is properly configured then.
* <p/>
* Thread-safe.
*
* @author Denis Zhdanov
* @since 3/21/12 4:04 PM
*/
public class GradleConfigNotificationManager {
// TODO den implement
// @NotNull private static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup(
// ExternalSystemBundle.message("gradle.notification.group.display.warning"), GradleConstants.TOOL_WINDOW_ID, true
// );
@NotNull private final AtomicReference<Notification> myNotification = new AtomicReference<Notification>();
@NotNull private final GradleInstallationManager myLibraryManager;
@NotNull private final Project myProject;
public GradleConfigNotificationManager(@NotNull final Project project, @NotNull GradleInstallationManager manager) {
myProject = project;
myLibraryManager = manager;
final GradleSettingsListenerAdapter handler = new GradleSettingsListenerAdapter() {
public void onGradleHomeChange(@Nullable String oldPath, @Nullable String newPath) {
processGradleHomeChange();
}
};
project.getMessageBus().connect(project).subscribe(GradleSettingsListener.TOPIC, handler);
ProjectManager.getInstance().getDefaultProject().getMessageBus().connect(project).subscribe(GradleSettingsListener.TOPIC, handler);
}
private void processGradleHomeChange() {
EditorNotifications.getInstance(myProject).updateAllNotifications();
// TODO den implement
//if (!GradleUtil.isGradleAvailable(myProject)) {
// return;
//}
//
//final Notification notification = myNotification.get();
//if (notification != null && myNotification.compareAndSet(notification, null)) {
// notification.expire();
//}
}
public void processRefreshError(@NotNull String message) {
// TODO den implement
// final Notification notification = NOTIFICATION_GROUP.createNotification(
// ExternalSystemBundle.message("gradle.notification.refresh.fail.description", message),
// ExternalSystemBundle.message("gradle.notification.action.show.settings"),
// NotificationType.WARNING,
// new NotificationListener() {
// @Override
// public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
// if (event.getEventType() != HyperlinkEvent.EventType.ACTIVATED) {
// return;
// }
// ShowSettingsUtil.getInstance().editConfigurable(myProject, new GradleConfigurable(myProject, myLibraryManager));
// }
// }
// );
//
// applyNotification(notification);
}
public void processUnknownGradleHome() {
// TODO den implement
// final Notification notification = NOTIFICATION_GROUP.createNotification(
// ExternalSystemBundle.message("gradle.notification.gradle.home.undefined.description"),
// ExternalSystemBundle.message("gradle.notification.action.show.settings"),
// NotificationType.WARNING,
// new NotificationListener() {
// @Override
// public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
// if (event.getEventType() != HyperlinkEvent.EventType.ACTIVATED) {
// return;
// }
// ShowSettingsUtil.getInstance().editConfigurable(myProject, new GradleConfigurable(myProject, myLibraryManager));
// }
// }
// );
//
// applyNotification(notification);
}
private void applyNotification(@NotNull Notification notification) {
final Notification oldNotification = myNotification.get();
if (oldNotification != null && myNotification.compareAndSet(oldNotification, null)) {
oldNotification.expire();
}
if (!myNotification.compareAndSet(null, notification)) {
notification.expire();
return;
}
notification.notify(myProject);
}
}
@@ -1,103 +0,0 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.gradle.remote.impl;
import com.intellij.openapi.externalSystem.build.ExternalSystemBuildManager;
import com.intellij.openapi.externalSystem.model.ExternalSystemException;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import org.gradle.tooling.BuildLauncher;
import org.gradle.tooling.ModelBuilder;
import org.gradle.tooling.ProjectConnection;
import org.gradle.tooling.model.DomainObjectSet;
import org.gradle.tooling.model.GradleTask;
import org.gradle.tooling.model.idea.IdeaModule;
import org.gradle.tooling.model.idea.IdeaProject;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.service.project.GradleExecutionHelper;
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings;
import java.util.*;
/**
* @author Denis Zhdanov
* @since 3/14/13 5:09 PM
*/
public class GradleBuildManager implements ExternalSystemBuildManager<GradleExecutionSettings> {
private final GradleExecutionHelper myHelper = new GradleExecutionHelper();
@Override
public Map<String, Collection<ExternalSystemTaskDescriptor>> listTasks(@NotNull final ExternalSystemTaskId id,
@NotNull String projectPath,
@Nullable final GradleExecutionSettings settings)
throws ExternalSystemException
{
// TODO den implement
return Collections.emptyMap();
//Function<ProjectConnection, Collection<ExternalSystemTaskDescriptor>> f =
// new Function<ProjectConnection, Collection<ExternalSystemTaskDescriptor>>() {
// @Nullable
// @Override
// public Collection<ExternalSystemTaskDescriptor> fun(ProjectConnection connection) {
// ModelBuilder<? extends IdeaProject> modelBuilder = myHelper.getModelBuilder(id, settings, connection, false);
// IdeaProject project = modelBuilder.get();
// DomainObjectSet<? extends IdeaModule> modules = project.getModules();
// if (modules == null) {
// return Collections.emptyList();
// }
// Set<ExternalSystemTaskDescriptor> result = new HashSet<ExternalSystemTaskDescriptor>();
// for (IdeaModule module : modules) {
// for (GradleTask task : module.getGradleProject().getTasks()) {
// String name = task.getName();
// if (name == null || name.trim().isEmpty()) {
// continue;
// }
// String s = name.toLowerCase();
// if (s.contains("idea") || s.contains("eclipse")) {
// continue;
// }
// result.add(new ExternalSystemTaskDescriptor(name, task.getDescription()));
// }
// }
// return result;
// }
// };
//return myHelper.execute(projectPath, settings, f);
}
@Override
public void executeTasks(@NotNull final ExternalSystemTaskId id,
@NotNull final List<String> taskNames,
@NotNull String projectPath,
@Nullable final GradleExecutionSettings settings) throws ExternalSystemException
{
Function<ProjectConnection, Void> f = new Function<ProjectConnection, Void>() {
@Override
public Void fun(ProjectConnection connection) {
BuildLauncher launcher = myHelper.getBuildLauncher(id, connection, settings);
launcher.forTasks(ArrayUtil.toStringArray(taskNames));
launcher.run();
return null;
}
};
myHelper.execute(projectPath, settings, f);
}
}
@@ -0,0 +1,57 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.gradle.remote.impl;
import com.intellij.openapi.externalSystem.build.ExternalSystemTaskManager;
import com.intellij.openapi.externalSystem.model.ExternalSystemException;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import org.gradle.tooling.BuildLauncher;
import org.gradle.tooling.ProjectConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.service.project.GradleExecutionHelper;
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings;
import java.util.List;
/**
* @author Denis Zhdanov
* @since 3/14/13 5:09 PM
*/
public class GradleTaskManager implements ExternalSystemTaskManager<GradleExecutionSettings> {
private final GradleExecutionHelper myHelper = new GradleExecutionHelper();
@Override
public void executeTasks(@NotNull final ExternalSystemTaskId id,
@NotNull final List<String> taskNames,
@NotNull String projectPath,
@Nullable final GradleExecutionSettings settings) throws ExternalSystemException
{
Function<ProjectConnection, Void> f = new Function<ProjectConnection, Void>() {
@Override
public Void fun(ProjectConnection connection) {
BuildLauncher launcher = myHelper.getBuildLauncher(id, connection, settings);
launcher.forTasks(ArrayUtil.toStringArray(taskNames));
launcher.run();
return null;
}
};
myHelper.execute(projectPath, settings, f);
}
}
@@ -5,7 +5,9 @@ import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.ExternalSystemException;
import com.intellij.openapi.externalSystem.model.ProjectKeys;
import com.intellij.openapi.externalSystem.model.project.*;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskDescriptor;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.model.task.TaskData;
import com.intellij.openapi.externalSystem.service.project.ExternalSystemProjectResolver;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.module.StdModuleTypes;
@@ -19,6 +21,7 @@ import com.intellij.util.containers.ContainerUtilRt;
import org.gradle.tooling.ModelBuilder;
import org.gradle.tooling.ProjectConnection;
import org.gradle.tooling.model.DomainObjectSet;
import org.gradle.tooling.model.GradleTask;
import org.gradle.tooling.model.idea.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -27,10 +30,7 @@ import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
/**
* @author Denis Zhdanov
@@ -102,6 +102,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
populateModules(modules.values(), result);
Collection<DataNode<LibraryData>> libraries = ExternalSystemApiUtil.getChildren(result, ProjectKeys.LIBRARY);
myLibraryNamesMixer.mixNames(libraries);
parseTasks(result, project);
return result;
}
@@ -142,9 +143,11 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
throw new IllegalStateException("Module with undefined name detected: " + gradleModule);
}
ProjectData projectData = ideProject.getData();
ModuleData ideModule = new ModuleData(
GradleConstants.SYSTEM_ID, StdModuleTypes.JAVA.getId(), moduleName, projectData.getIdeProjectFileDirectoryPath()
);
ModuleData ideModule = new ModuleData(GradleConstants.SYSTEM_ID,
StdModuleTypes.JAVA.getId(),
moduleName,
projectData.getIdeProjectFileDirectoryPath(),
gradleModule.getGradleProject().getPath());
Pair<DataNode<ModuleData>, IdeaModule> previouslyParsedModule = result.get(moduleName);
if (previouslyParsedModule != null) {
throw new IllegalStateException(
@@ -381,4 +384,34 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
}
return null;
}
private static void parseTasks(@NotNull DataNode<?> parent, @NotNull IdeaProject project) {
Map<String/* module name */, TaskData> tasksByModule = ContainerUtilRt.newHashMap();
for (IdeaModule module : project.getModules()) {
TaskData taskData = new TaskData(GradleConstants.SYSTEM_ID, module.getGradleProject().getPath());
for (GradleTask task : module.getGradleProject().getTasks()) {
String name = task.getName();
if (name == null || name.trim().isEmpty()) {
continue;
}
String s = name.toLowerCase();
if (s.contains("idea") || s.contains("eclipse")) {
continue;
}
taskData.addTask(new ExternalSystemTaskDescriptor(name, task.getDescription()));
}
Collections.sort(taskData.getTasks());
tasksByModule.put(module.getName(), taskData);
}
Collection<DataNode<ModuleData>> moduleNodes = ExternalSystemApiUtil.findAll(parent, ProjectKeys.MODULE);
for (DataNode<ModuleData> moduleNode : moduleNodes) {
TaskData taskData = tasksByModule.get(moduleNode.getData().getName());
if (taskData != null && !taskData.getTasks().isEmpty()) {
moduleNode.createChild(ProjectKeys.TASK, taskData);
}
}
}
}
@@ -1,23 +1,10 @@
package org.jetbrains.plugins.gradle.ui;
import com.intellij.openapi.externalSystem.service.task.ExternalSystemTasksPanel;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.ui.content.ContentManager;
import com.intellij.ui.content.impl.ContentImpl;
import org.jetbrains.plugins.gradle.util.GradleBundle;
import com.intellij.openapi.externalSystem.service.task.ui.AbstractExternalSystemToolWindowFactory;
import org.jetbrains.plugins.gradle.util.GradleConstants;
public class GradleToolWindowFactory implements ToolWindowFactory, DumbAware {
@Override
public void createToolWindowContent(final Project project, final ToolWindow toolWindow) {
toolWindow.setTitle(GradleBundle.message("gradle.name"));
ContentManager contentManager = toolWindow.getContentManager();
String tasksTitle = ExternalSystemBundle.message("tool.window.title.tasks");
ContentImpl tasksContent = new ContentImpl(new ExternalSystemTasksPanel(), tasksTitle, true);
contentManager.addContent(tasksContent);
public class GradleToolWindowFactory extends AbstractExternalSystemToolWindowFactory {
public GradleToolWindowFactory() {
super(GradleConstants.SYSTEM_ID);
}
}
@@ -25,6 +25,7 @@
<xi:include href="/idea/PlatformActions.xml" xpointer="xpointer(/component/*)"/>
<xi:include href="/idea/VcsActions.xml" xpointer="xpointer(/component/*)"/>
<xi:include href="/idea/ExternalSystemActions.xml" xpointer="xpointer(/component/*)"/>
<xi:include href="/idea/LangActions.xml" xpointer="xpointer(/component/*)"/>
<actions>