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
;
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() {
44 public void processOutdatedItem(final CompileContext context
, String url
, final ValidityState state
) {
46 ApplicationManager
.getApplication().runReadAction(new Runnable() {
48 MyValState valState
= (MyValState
)state
;
49 String jarPath
= valState
.getOutputJarUrl();
50 if (jarPath
!= null) {
51 FileUtil
.delete(new File(VfsUtil
.urlToPath(jarPath
)));
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(){
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
);
90 sourceUrls
= ArrayUtil
.newStringArray(url2Timestamps
.size());
91 timestamps
= new long[url2Timestamps
.size()];
92 TObjectLongProcedure
<String
> iterator
= new TObjectLongProcedure
<String
>() {
94 public boolean execute(final String url
, final long timestamp
) {
96 timestamps
[i
] = timestamp
;
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
);
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();
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
;
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() {
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;
166 static class MyProcItem
implements ProcessingItem
{
167 private final Module myModule
;
169 public MyProcItem(Module module
) {
174 public VirtualFile
getFile() {
175 // return (semifake) file url to store compiler cache entry under
176 return myModule
.getModuleFile();
180 public MyValState
getValidityState() {
181 return new MyValState(myModule
);
184 public Module
getModule() {
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()];
214 for (Module moduleToBuild
: modulesToRebuild
) {
215 if (moduleToBuild
.getModuleFile() == null) continue;
216 result
[i
++] = new MyProcItem(moduleToBuild
);
223 public ProcessingItem
[] process(final CompileContext context
, final ProcessingItem
[] items
) {
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
) {
239 public String
getDescription() {
240 return "jar compile";
243 public boolean validateConfiguration(CompileScope scope
) {