2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.intellij.compiler.impl;
18 import com.intellij.compiler.impl.newApi.NewCompiler;
19 import com.intellij.compiler.impl.newApi.NewCompilerCache;
20 import com.intellij.openapi.Disposable;
21 import com.intellij.openapi.compiler.*;
22 import com.intellij.openapi.compiler.Compiler;
23 import com.intellij.openapi.components.ProjectComponent;
24 import com.intellij.openapi.diagnostic.Logger;
25 import com.intellij.openapi.project.Project;
26 import com.intellij.openapi.util.ShutDownTracker;
27 import com.intellij.openapi.util.io.FileUtil;
28 import org.jetbrains.annotations.NonNls;
29 import org.jetbrains.annotations.NotNull;
31 import java.io.DataInput;
32 import java.io.DataOutput;
34 import java.io.IOException;
35 import java.util.ArrayList;
36 import java.util.HashMap;
37 import java.util.List;
41 * @author Eugene Zhuravlev
44 public class CompilerCacheManager implements ProjectComponent {
45 private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompilerCacheManager");
46 private final Map<Compiler, Object> myCompilerToCacheMap = new HashMap<Compiler, Object>();
47 private final Map<NewCompiler<?,?,?>, NewCompilerCache<?,?,?>> myNewCachesMap = new HashMap<NewCompiler<?,?,?>, NewCompilerCache<?,?,?>>();
48 private final List<Disposable> myCacheDisposables = new ArrayList<Disposable>();
49 private final File myCachesRoot;
50 private final Runnable myShutdownTask = new Runnable() {
55 private final Project myProject;
57 public CompilerCacheManager(Project project) {
59 myCachesRoot = CompilerPaths.getCacheStoreDirectory(project);
62 public static CompilerCacheManager getInstance(Project project) {
63 return project.getComponent(CompilerCacheManager.class);
66 public void projectOpened() {
67 ShutDownTracker.getInstance().registerShutdownTask(myShutdownTask);
70 public void projectClosed() {
71 ShutDownTracker.getInstance().unregisterShutdownTask(myShutdownTask);
76 public String getComponentName() {
77 return "CompilerCacheManager";
80 public void initComponent() {
83 public void disposeComponent() {
87 private File getCompilerRootDir(final Compiler compiler) {
88 final File dir = new File(myCachesRoot, getCompilerIdString(compiler));
93 public synchronized <Key, SourceState, OutputState> NewCompilerCache<Key, SourceState, OutputState>
94 getNewCompilerCache(NewCompiler<Key, SourceState, OutputState> compiler) throws IOException {
95 NewCompilerCache<?,?,?> cache = myNewCachesMap.get(compiler);
97 final NewCompilerCache<?,?,?> newCache = new NewCompilerCache<Key, SourceState, OutputState>(compiler, NewCompilerRunner.getNewCompilerCacheDir(myProject, compiler));
98 myNewCachesMap.put(compiler, newCache);
99 myCacheDisposables.add(new Disposable() {
101 public void dispose() {
107 //noinspection unchecked
108 return (NewCompilerCache<Key, SourceState, OutputState>)cache;
111 public synchronized FileProcessingCompilerStateCache getFileProcessingCompilerCache(FileProcessingCompiler compiler) throws IOException {
112 Object cache = myCompilerToCacheMap.get(compiler);
114 final FileProcessingCompilerStateCache stateCache = new FileProcessingCompilerStateCache(getCompilerRootDir(compiler),
117 myCompilerToCacheMap.put(compiler, stateCache);
118 myCacheDisposables.add(new Disposable() {
119 public void dispose() {
126 LOG.assertTrue(cache instanceof FileProcessingCompilerStateCache);
128 return (FileProcessingCompilerStateCache)cache;
131 public synchronized StateCache<ValidityState> getGeneratingCompilerCache(final GeneratingCompiler compiler) throws IOException {
132 Object cache = myCompilerToCacheMap.get(compiler);
134 final File cacheDir = getCompilerRootDir(compiler);
135 final StateCache<ValidityState> stateCache = new StateCache<ValidityState>(new File(cacheDir, "timestamps")) {
136 public ValidityState read(DataInput stream) throws IOException {
137 return compiler.createValidityState(stream);
140 public void write(ValidityState validityState, DataOutput out) throws IOException {
141 validityState.save(out);
144 myCompilerToCacheMap.put(compiler, stateCache);
145 myCacheDisposables.add(new Disposable() {
146 public void dispose() {
150 catch (IOException e) {
157 return (StateCache<ValidityState>)cache;
160 public static String getCompilerIdString(Compiler compiler) {
161 @NonNls String description = compiler.getDescription();
162 return description.replaceAll("\\s+", "_").replaceAll("[\\.\\?]", "_").toLowerCase();
165 public synchronized void flushCaches() {
166 for (Disposable disposable : myCacheDisposables) {
168 disposable.dispose();
170 catch (Throwable e) {
174 myCacheDisposables.clear();
175 myNewCachesMap.clear();
176 myCompilerToCacheMap.clear();
179 public void clearCaches(final CompileContext context) {
181 final File[] children = myCachesRoot.listFiles();
182 if (children != null) {
183 for (final File child : children) {
184 final boolean deleteOk = FileUtil.delete(child);
186 context.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("compiler.error.failed.to.delete", child.getPath()), null, -1, -1);