distinguish annotation interfaces in Ctrl-hover popup (IDEADEV-40633)
[fedora-idea.git] / java / idea-ui / src / com / intellij / jar / JarCompiler.java
blob24204833a2adadf47f7f28f20ad26485f6b8436d
1 package com.intellij.jar;
3 import com.intellij.openapi.application.ApplicationManager;
4 import com.intellij.openapi.compiler.CompileContext;
5 import com.intellij.openapi.compiler.CompileScope;
6 import com.intellij.openapi.compiler.PackagingCompiler;
7 import com.intellij.openapi.compiler.ValidityState;
8 import com.intellij.openapi.compiler.make.BuildInstructionVisitor;
9 import com.intellij.openapi.compiler.make.BuildRecipe;
10 import com.intellij.openapi.compiler.make.FileCopyInstruction;
11 import com.intellij.openapi.deployment.ModuleLink;
12 import com.intellij.openapi.deployment.PackagingConfiguration;
13 import com.intellij.openapi.diagnostic.Logger;
14 import com.intellij.openapi.module.Module;
15 import com.intellij.openapi.module.ModuleManager;
16 import com.intellij.openapi.project.Project;
17 import com.intellij.openapi.util.Comparing;
18 import com.intellij.openapi.util.Computable;
19 import com.intellij.openapi.util.io.FileUtil;
20 import com.intellij.openapi.vfs.LocalFileSystem;
21 import com.intellij.openapi.vfs.VfsUtil;
22 import com.intellij.openapi.vfs.VirtualFile;
23 import com.intellij.util.ArrayUtil;
24 import com.intellij.util.io.IOUtil;
25 import gnu.trove.THashSet;
26 import gnu.trove.TObjectLongHashMap;
27 import gnu.trove.TObjectLongProcedure;
28 import org.jetbrains.annotations.NotNull;
30 import java.io.DataInput;
31 import java.io.DataOutput;
32 import java.io.File;
33 import java.io.IOException;
34 import java.util.Collection;
36 public class JarCompiler implements PackagingCompiler {
37 private static final Logger LOG = Logger.getInstance("#com.intellij.jar.JarCompiler");
38 private static final JarCompiler INSTANCE = new JarCompiler();
40 public static JarCompiler getInstance() {
41 return INSTANCE;
44 public void processOutdatedItem(final CompileContext context, String url, final ValidityState state) {
45 if (state != null) {
46 ApplicationManager.getApplication().runReadAction(new Runnable() {
47 public void run() {
48 MyValState valState = (MyValState)state;
49 String jarPath = valState.getOutputJarUrl();
50 if (jarPath != null) {
51 FileUtil.delete(new File(VfsUtil.urlToPath(jarPath)));
54 });
58 public ValidityState createValidityState(DataInput in) throws IOException {
59 return new MyValState(in);
62 static class MyValState implements ValidityState {
63 private final String myModuleName;
64 private final String[] sourceUrls;
65 private final long[] timestamps;
66 private final String outputJarUrl;
67 private final long outputJarTimestamp;
69 public MyValState(final Module module) {
70 myModuleName = module.getName();
71 final BuildJarSettings jarSettings = BuildJarSettings.getInstance(module);
72 outputJarUrl = jarSettings.getJarUrl();
73 outputJarTimestamp = new File(VfsUtil.urlToPath(outputJarUrl)).lastModified();
74 final TObjectLongHashMap<String> url2Timestamps = new TObjectLongHashMap<String>();
75 ApplicationManager.getApplication().runReadAction(new Runnable(){
76 public void run() {
77 BuildRecipe buildRecipe = BuildJarProjectSettings.getBuildRecipe(module, jarSettings);
78 buildRecipe.visitInstructions(new BuildInstructionVisitor() {
79 public boolean visitFileCopyInstruction(FileCopyInstruction instruction) throws Exception {
80 File source = instruction.getFile();
81 VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(source.getPath()));
82 if (virtualFile != null) {
83 addFilesToMap(virtualFile, url2Timestamps);
85 return true;
87 }, false);
89 });
90 sourceUrls = ArrayUtil.newStringArray(url2Timestamps.size());
91 timestamps = new long[url2Timestamps.size()];
92 TObjectLongProcedure<String> iterator = new TObjectLongProcedure<String>() {
93 int i = 0;
94 public boolean execute(final String url, final long timestamp) {
95 sourceUrls[i] = url;
96 timestamps[i] = timestamp;
97 i++;
98 return true;
101 url2Timestamps.forEachEntry(iterator);
104 private static void addFilesToMap(final VirtualFile virtualFile, final TObjectLongHashMap<String> url2Timestamps) {
105 if (virtualFile.isDirectory()) {
106 VirtualFile[] children = virtualFile.getChildren();
107 for (VirtualFile child : children) {
108 addFilesToMap(child, url2Timestamps);
111 else {
112 long timestamp = virtualFile.getModificationStamp();
113 url2Timestamps.put(virtualFile.getUrl(), timestamp);
117 public MyValState(final DataInput is) throws IOException {
118 myModuleName = IOUtil.readString(is);
119 int size = is.readInt();
120 sourceUrls = ArrayUtil.newStringArray(size);
121 timestamps = new long[size];
122 for (int i=0;i<size;i++) {
123 String url = IOUtil.readString(is);
124 long timestamp = is.readLong();
125 sourceUrls[i] = url;
126 timestamps[i] = timestamp;
128 outputJarUrl = IOUtil.readString(is);
129 outputJarTimestamp = is.readLong();
132 public void save(DataOutput out) throws IOException {
133 IOUtil.writeString(myModuleName, out);
134 int size = sourceUrls.length;
135 out.writeInt(size);
136 for (int i=0;i<size;i++) {
137 String url = sourceUrls[i];
138 long timestamp = timestamps[i];
139 IOUtil.writeString(url, out);
140 out.writeLong(timestamp);
142 IOUtil.writeString(outputJarUrl, out);
143 out.writeLong(outputJarTimestamp);
146 public String getOutputJarUrl() {
147 return outputJarUrl;
150 public boolean equalsTo(ValidityState otherState) {
151 if (!(otherState instanceof MyValState)) return false;
152 final MyValState other = (MyValState)otherState;
153 if (!myModuleName.equals(other.myModuleName)) return false;
154 if (sourceUrls.length != other.sourceUrls.length) return false;
155 for (int i = 0; i < sourceUrls.length; i++) {
156 String url = sourceUrls[i];
157 long timestamp = timestamps[i];
158 if (!url.equals(other.sourceUrls[i]) || timestamp != other.timestamps[i]) return false;
160 if (!Comparing.strEqual(outputJarUrl,other.outputJarUrl)) return false;
161 if (outputJarTimestamp != other.outputJarTimestamp) return false;
162 return true;
166 static class MyProcItem implements ProcessingItem {
167 private final Module myModule;
169 public MyProcItem(Module module) {
170 myModule = module;
173 @NotNull
174 public VirtualFile getFile() {
175 // return (semifake) file url to store compiler cache entry under
176 return myModule.getModuleFile();
179 @NotNull
180 public MyValState getValidityState() {
181 return new MyValState(myModule);
184 public Module getModule() {
185 return myModule;
189 @NotNull
190 public ProcessingItem[] getProcessingItems(final CompileContext context) {
191 return ApplicationManager.getApplication().runReadAction(new Computable<ProcessingItem[]>(){
192 public ProcessingItem[] compute() {
193 final CompileScope compileScope = context.getCompileScope();
194 final Module[] affectedModules = compileScope.getAffectedModules();
195 if (affectedModules.length == 0) return ProcessingItem.EMPTY_ARRAY;
196 Project project = affectedModules[0].getProject();
197 Module[] modules = ModuleManager.getInstance(project).getModules();
198 Collection<Module> modulesToRebuild = new THashSet<Module>();
199 for (Module module : modules) {
200 BuildJarSettings jarSettings = BuildJarSettings.getInstance(module);
201 if (jarSettings == null || !jarSettings.isBuildJar()) continue;
202 PackagingConfiguration packagingConfiguration = jarSettings.getPackagingConfiguration();
203 ModuleLink[] containingModules = packagingConfiguration.getContainingModules();
204 for (ModuleLink moduleLink : containingModules) {
205 Module containingModule = moduleLink.getModule();
206 if (ArrayUtil.find(affectedModules, containingModule) != -1) {
207 modulesToRebuild.add(module);
212 ProcessingItem[] result = new ProcessingItem[modulesToRebuild.size()];
213 int i=0;
214 for (Module moduleToBuild : modulesToRebuild) {
215 if (moduleToBuild.getModuleFile() == null) continue;
216 result[i++] = new MyProcItem(moduleToBuild);
218 return result;
223 public ProcessingItem[] process(final CompileContext context, final ProcessingItem[] items) {
224 try {
225 for (ProcessingItem item : items) {
226 MyProcItem procItem = (MyProcItem)item;
227 Module module = procItem.getModule();
228 BuildJarSettings jarSettings = BuildJarSettings.getInstance(module);
229 BuildJarProjectSettings.buildJar(module, jarSettings, context.getProgressIndicator(), context);
232 catch (IOException e) {
233 LOG.error(e);
235 return items;
238 @NotNull
239 public String getDescription() {
240 return "jar compile";
243 public boolean validateConfiguration(CompileScope scope) {
244 return true;