2fe4bcd205c8ac9fa0b0ac7a25afa3f10903135a
[idea/community.git] / java / compiler / impl / src / com / intellij / compiler / actions / CompileAction.java
1 /*
2  * Copyright 2000-2012 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.compiler.actions;
17
18 import com.intellij.compiler.CompilerConfiguration;
19 import com.intellij.idea.ActionsBundle;
20 import com.intellij.openapi.actionSystem.*;
21 import com.intellij.openapi.compiler.CompilerBundle;
22 import com.intellij.openapi.compiler.CompilerManager;
23 import com.intellij.openapi.fileTypes.FileType;
24 import com.intellij.openapi.fileTypes.FileTypeManager;
25 import com.intellij.openapi.module.Module;
26 import com.intellij.openapi.project.Project;
27 import com.intellij.openapi.roots.ProjectFileIndex;
28 import com.intellij.openapi.roots.ProjectRootManager;
29 import com.intellij.openapi.util.text.StringUtil;
30 import com.intellij.openapi.vfs.VfsUtil;
31 import com.intellij.openapi.vfs.VirtualFile;
32 import com.intellij.packaging.artifacts.Artifact;
33 import com.intellij.packaging.impl.artifacts.ArtifactBySourceFileFinder;
34 import com.intellij.psi.*;
35
36 import java.util.ArrayList;
37 import java.util.Collection;
38 import java.util.List;
39
40 public class CompileAction extends CompileActionBase {
41   protected void doAction(DataContext dataContext, Project project) {
42     final Module module = LangDataKeys.MODULE_CONTEXT.getData(dataContext);
43     if (module != null) {
44       CompilerManager.getInstance(project).compile(module, null);
45     }
46     else {
47       VirtualFile[] files = getCompilableFiles(project, PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext));
48       if (files.length > 0) {
49         CompilerManager.getInstance(project).compile(files, null);
50       }
51     }
52
53   }
54
55   public void update(AnActionEvent event) {
56     super.update(event);
57     Presentation presentation = event.getPresentation();
58     if (!presentation.isEnabled()) {
59       return;
60     }
61     DataContext dataContext = event.getDataContext();
62
63     presentation.setText(ActionsBundle.actionText(IdeActions.ACTION_COMPILE));
64     presentation.setVisible(true);
65
66     Project project = PlatformDataKeys.PROJECT.getData(dataContext);
67     if (project == null) {
68       presentation.setEnabled(false);
69       return;
70     }
71
72     CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(project);
73     final Module module = LangDataKeys.MODULE_CONTEXT.getData(dataContext);
74
75     final VirtualFile[] files = getCompilableFiles(project, PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext));
76     if (module == null && files.length == 0) {
77       presentation.setEnabled(false);
78       presentation.setVisible(!ActionPlaces.isPopupPlace(event.getPlace()));
79       return;
80     }
81
82     String elementDescription = null;
83     if (module != null) {
84       elementDescription = CompilerBundle.message("action.compile.description.module", module.getName());
85     }
86     else {
87       PsiPackage aPackage = null;
88       if (files.length == 1) {
89         final PsiDirectory directory = PsiManager.getInstance(project).findDirectory(files[0]);
90         if (directory != null) {
91           aPackage = JavaDirectoryService.getInstance().getPackage(directory);
92         }
93       }
94       else {
95         PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext);
96         if (element instanceof PsiPackage) {
97           aPackage = (PsiPackage)element;
98         }
99       }
100
101       if (aPackage != null) {
102         String name = aPackage.getQualifiedName();
103         if (name.length() == 0) {
104           //noinspection HardCodedStringLiteral
105           name = "<default>";
106         }
107         elementDescription = "'" + name + "'";
108       }
109       else if (files.length == 1) {
110         final VirtualFile file = files[0];
111         FileType fileType = file.getFileType();
112         if (CompilerManager.getInstance(project).isCompilableFileType(fileType) || isCompilableResourceFile(project, compilerConfiguration, file)) {
113           elementDescription = "'" + file.getName() + "'";
114         }
115         else {
116           if (!ActionPlaces.MAIN_MENU.equals(event.getPlace())) {
117             // the action should be invisible in popups for non-java files
118             presentation.setEnabled(false);
119             presentation.setVisible(false);
120             return;
121           }
122         }
123       }
124       else {
125         elementDescription = CompilerBundle.message("action.compile.description.selected.files");
126       }
127     }
128
129     if (elementDescription == null) {
130       presentation.setEnabled(false);
131       return;
132     }
133
134     presentation.setText(createPresentationText(elementDescription), true);
135     presentation.setEnabled(true);
136   }
137
138   private static String createPresentationText(String elementDescription) {
139     StringBuffer buffer = new StringBuffer(40);
140     buffer.append(ActionsBundle.actionText(IdeActions.ACTION_COMPILE)).append(" ");
141     int length = elementDescription.length();
142     if (length > 23) {
143       if (StringUtil.startsWithChar(elementDescription, '\'')) {
144         buffer.append("'");
145       }
146       buffer.append("...");
147       buffer.append(elementDescription.substring(length - 20, length));
148     }
149     else {
150       buffer.append(elementDescription);
151     }
152     return buffer.toString();
153   }
154
155   private static VirtualFile[] getCompilableFiles(Project project, VirtualFile[] files) {
156     if (files == null || files.length == 0) {
157       return VirtualFile.EMPTY_ARRAY;
158     }
159     final PsiManager psiManager = PsiManager.getInstance(project);
160     final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(project);
161     final FileTypeManager typeManager = FileTypeManager.getInstance();
162     final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
163     final CompilerManager compilerManager = CompilerManager.getInstance(project);
164     final List<VirtualFile> filesToCompile = new ArrayList<VirtualFile>();
165     for (final VirtualFile file : files) {
166       if (!fileIndex.isInSourceContent(file)) {
167         continue;
168       }
169       if (!file.isInLocalFileSystem()) {
170         continue;
171       }
172       if (file.isDirectory()) {
173         final PsiDirectory directory = psiManager.findDirectory(file);
174         if (directory == null || JavaDirectoryService.getInstance().getPackage(directory) == null) {
175           continue;
176         }
177       }
178       else {
179         FileType fileType = file.getFileType();
180         if (!(compilerManager.isCompilableFileType(fileType) || isCompilableResourceFile(project, compilerConfiguration, file))) {
181           continue;
182         }
183       }
184       filesToCompile.add(file);
185     }
186     return VfsUtil.toVirtualFileArray(filesToCompile);
187   }
188
189   private static boolean isCompilableResourceFile(final Project project, final CompilerConfiguration compilerConfiguration, final VirtualFile file) {
190     if (!compilerConfiguration.isResourceFile(file)) {
191       return false;
192     }
193     final Collection<? extends Artifact> artifacts = ArtifactBySourceFileFinder.getInstance(project).findArtifacts(file);
194     return artifacts.isEmpty();
195   }
196 }