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, State> NewCompilerCache<Key, State> getNewCompilerCache(NewCompiler<Key, State> compiler) throws IOException {
94 NewCompilerCache<?, ?> cache = myNewCachesMap.get(compiler);
96 final NewCompilerCache<?, ?> newCache = new NewCompilerCache<Key, State>(compiler, NewCompilerRunner.getNewCompilerCacheDir(myProject, compiler));
97 myNewCachesMap.put(compiler, newCache);
98 myCacheDisposables.add(new Disposable() {
100 public void dispose() {
106 //noinspection unchecked
107 return (NewCompilerCache<Key, State>)cache;
110 public synchronized FileProcessingCompilerStateCache getFileProcessingCompilerCache(FileProcessingCompiler compiler) throws IOException {
111 Object cache = myCompilerToCacheMap.get(compiler);
113 final FileProcessingCompilerStateCache stateCache = new FileProcessingCompilerStateCache(getCompilerRootDir(compiler),
116 myCompilerToCacheMap.put(compiler, stateCache);
117 myCacheDisposables.add(new Disposable() {
118 public void dispose() {
125 LOG.assertTrue(cache instanceof FileProcessingCompilerStateCache);
127 return (FileProcessingCompilerStateCache)cache;
130 public synchronized StateCache<ValidityState> getGeneratingCompilerCache(final GeneratingCompiler compiler) throws IOException {
131 Object cache = myCompilerToCacheMap.get(compiler);
133 final File cacheDir = getCompilerRootDir(compiler);
134 final StateCache<ValidityState> stateCache = new StateCache<ValidityState>(new File(cacheDir, "timestamps")) {
135 public ValidityState read(DataInput stream) throws IOException {
136 return compiler.createValidityState(stream);
139 public void write(ValidityState validityState, DataOutput out) throws IOException {
140 validityState.save(out);
143 myCompilerToCacheMap.put(compiler, stateCache);
144 myCacheDisposables.add(new Disposable() {
145 public void dispose() {
149 catch (IOException e) {
156 return (StateCache<ValidityState>)cache;
159 public static String getCompilerIdString(Compiler compiler) {
160 @NonNls String description = compiler.getDescription();
161 return description.replaceAll("\\s+", "_").replaceAll("[\\.\\?]", "_").toLowerCase();
164 public synchronized void flushCaches() {
165 for (Disposable disposable : myCacheDisposables) {
167 disposable.dispose();
169 catch (Throwable e) {
173 myCacheDisposables.clear();
174 myNewCachesMap.clear();
175 myCompilerToCacheMap.clear();
178 public void clearCaches(final CompileContext context) {
180 final File[] children = myCachesRoot.listFiles();
181 if (children != null) {
182 for (final File child : children) {
183 final boolean deleteOk = FileUtil.delete(child);
185 context.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("compiler.error.failed.to.delete", child.getPath()), null, -1, -1);