aba3aea6f9de3d5cc6e324327964d205c3d760e4
[idea/community.git] / python / src / com / jetbrains / python / run / PythonRunConfiguration.java
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.jetbrains.python.run;
17
18 import com.intellij.execution.ExecutionException;
19 import com.intellij.execution.Executor;
20 import com.intellij.execution.configurations.*;
21 import com.intellij.execution.runners.ExecutionEnvironment;
22 import com.intellij.openapi.options.SettingsEditor;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.openapi.util.Comparing;
25 import com.intellij.openapi.util.JDOMExternalizerUtil;
26 import com.intellij.openapi.util.WriteExternalException;
27 import com.intellij.openapi.util.io.FileUtil;
28 import com.intellij.openapi.util.text.StringUtil;
29 import com.intellij.openapi.vfs.VirtualFile;
30 import com.intellij.psi.PsiElement;
31 import com.intellij.psi.PsiFile;
32 import com.intellij.refactoring.listeners.RefactoringElementAdapter;
33 import com.intellij.refactoring.listeners.RefactoringElementListener;
34 import com.jetbrains.python.PyBundle;
35 import org.jdom.Element;
36 import org.jetbrains.annotations.NotNull;
37
38 import java.io.File;
39
40 /**
41  * @author yole
42  */
43 public class PythonRunConfiguration extends AbstractPythonRunConfiguration
44   implements AbstractPythonRunConfigurationParams, PythonRunConfigurationParams, RefactoringListenerProvider {
45   public static final String SCRIPT_NAME = "SCRIPT_NAME";
46   public static final String PARAMETERS = "PARAMETERS";
47   public static final String MULTIPROCESS = "MULTIPROCESS";
48   public static final String SHOW_COMMAND_LINE = "SHOW_COMMAND_LINE";
49   private String myScriptName;
50   private String myScriptParameters;
51   private boolean myShowCommandLineAfterwards = false;
52
53   protected PythonRunConfiguration(Project project, ConfigurationFactory configurationFactory) {
54     super(project, configurationFactory);
55     setUnbufferedEnv();
56   }
57
58   @Override
59   protected SettingsEditor<? extends RunConfiguration> createConfigurationEditor() {
60     return new PythonRunConfigurationEditor(this);
61   }
62
63   public RunProfileState getState(@NotNull final Executor executor, @NotNull final ExecutionEnvironment env) throws ExecutionException {
64     return new PythonScriptCommandLineState(this, env);
65   }
66
67   public void checkConfiguration() throws RuntimeConfigurationException {
68     super.checkConfiguration();
69
70     if (StringUtil.isEmptyOrSpaces(myScriptName)) {
71       throw new RuntimeConfigurationException(PyBundle.message("runcfg.unittest.no_script_name"));
72     }
73   }
74
75   public String suggestedName() {
76     final String scriptName = getScriptName();
77     if (scriptName == null) return null;
78     String name = new File(scriptName).getName();
79     if (name.endsWith(".py")) {
80       return name.substring(0, name.length() - 3);
81     }
82     return name;
83   }
84
85   public String getScriptName() {
86     return myScriptName;
87   }
88
89   public void setScriptName(String scriptName) {
90     myScriptName = scriptName;
91   }
92
93   public String getScriptParameters() {
94     return myScriptParameters;
95   }
96
97   public void setScriptParameters(String scriptParameters) {
98     myScriptParameters = scriptParameters;
99   }
100
101   public boolean showCommandLineAfterwards() {
102     return myShowCommandLineAfterwards;
103   }
104
105   public void setShowCommandLineAfterwards(boolean showCommandLineAfterwards) {
106     myShowCommandLineAfterwards = showCommandLineAfterwards;
107   }
108
109   public void readExternal(Element element) {
110     super.readExternal(element);
111     myScriptName = JDOMExternalizerUtil.readField(element, SCRIPT_NAME);
112     myScriptParameters = JDOMExternalizerUtil.readField(element, PARAMETERS);
113     myShowCommandLineAfterwards = Boolean.parseBoolean(JDOMExternalizerUtil.readField(element, SHOW_COMMAND_LINE, "false"));
114   }
115
116   public void writeExternal(Element element) throws WriteExternalException {
117     super.writeExternal(element);
118     JDOMExternalizerUtil.writeField(element, SCRIPT_NAME, myScriptName);
119     JDOMExternalizerUtil.writeField(element, PARAMETERS, myScriptParameters);
120     JDOMExternalizerUtil.writeField(element, SHOW_COMMAND_LINE, Boolean.toString(myShowCommandLineAfterwards));
121   }
122
123   public AbstractPythonRunConfigurationParams getBaseParams() {
124     return this;
125   }
126
127   public static void copyParams(PythonRunConfigurationParams source, PythonRunConfigurationParams target) {
128     AbstractPythonRunConfiguration.copyParams(source.getBaseParams(), target.getBaseParams());
129     target.setScriptName(source.getScriptName());
130     target.setScriptParameters(source.getScriptParameters());
131     target.setShowCommandLineAfterwards(source.showCommandLineAfterwards());
132   }
133
134   @Override
135   public RefactoringElementListener getRefactoringElementListener(PsiElement element) {
136     if (element instanceof PsiFile) {
137       VirtualFile virtualFile = ((PsiFile)element).getVirtualFile();
138       if (virtualFile != null && Comparing.equal(new File(virtualFile.getPath()).getAbsolutePath(),
139                                                  new File(myScriptName).getAbsolutePath())) {
140         return new RefactoringElementAdapter() {
141           @Override
142           public void elementRenamedOrMoved(@NotNull PsiElement newElement) {
143             VirtualFile virtualFile = ((PsiFile)newElement).getVirtualFile();
144             if (virtualFile != null) {
145               updateScriptName(virtualFile.getPath());
146             }
147           }
148
149           @Override
150           public void undoElementMovedOrRenamed(@NotNull PsiElement newElement, @NotNull String oldQualifiedName) {
151             updateScriptName(oldQualifiedName);
152           }
153
154           private void updateScriptName(String path) {
155             myScriptName = FileUtil.toSystemDependentName(path);
156           }
157         };
158       }
159     }
160     return null;
161   }
162 }