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.
17 package com
.intellij
.diagnostic
.logging
;
19 import com
.intellij
.execution
.configurations
.LogFileOptions
;
20 import com
.intellij
.execution
.configurations
.RunConfigurationBase
;
21 import com
.intellij
.execution
.process
.ProcessHandler
;
22 import com
.intellij
.openapi
.Disposable
;
23 import com
.intellij
.openapi
.project
.Project
;
24 import com
.intellij
.openapi
.util
.Condition
;
25 import com
.intellij
.openapi
.util
.Disposer
;
26 import com
.intellij
.util
.Alarm
;
27 import gnu
.trove
.THashSet
;
37 public class LogFilesManager
implements Disposable
{
38 private static final int UPDATE_INTERVAL
= 500;
40 private final Map
<LogFileOptions
, Set
<String
>> myLogFileManagerMap
= new LinkedHashMap
<LogFileOptions
, Set
<String
>>();
41 private final Map
<LogFileOptions
, RunConfigurationBase
> myLogFileToConfiguration
= new HashMap
<LogFileOptions
, RunConfigurationBase
>();
42 private final Runnable myUpdateRequest
;
43 private final LogConsoleManager myManager
;
44 private final Alarm myUpdateAlarm
= new Alarm(Alarm
.ThreadToUse
.OWN_THREAD
, this);
45 private boolean myDisposed
;
47 public LogFilesManager(final Project project
, LogConsoleManager manager
, Disposable parentDisposable
) {
49 Disposer
.register(parentDisposable
, this);
51 myUpdateRequest
= new Runnable() {
53 if (project
.isDisposed() || myDisposed
) return;
54 myUpdateAlarm
.cancelAllRequests();
55 for (final LogFileOptions logFile
: myLogFileManagerMap
.keySet()) {
56 final Set
<String
> oldFiles
= myLogFileManagerMap
.get(logFile
);
57 final Set
<String
> newFiles
= logFile
.getPaths(); // should not be called in UI thread
58 myLogFileManagerMap
.put(logFile
, newFiles
);
60 final Set
<String
> obsoleteFiles
= new THashSet
<String
>(oldFiles
);
61 obsoleteFiles
.removeAll(newFiles
);
63 SwingUtilities
.invokeLater(new Runnable() {
65 if (project
.isDisposed() || myDisposed
) return;
67 addConfigurationConsoles(logFile
, new Condition
<String
>() {
68 public boolean value(final String file
) {
69 return !oldFiles
.contains(file
);
72 for (String each
: obsoleteFiles
) {
73 myManager
.removeLogConsole(each
);
75 myUpdateAlarm
.addRequest(myUpdateRequest
, UPDATE_INTERVAL
);
83 public void registerFileMatcher(final RunConfigurationBase runConfiguration
) {
84 final ArrayList
<LogFileOptions
> logFiles
= runConfiguration
.getAllLogFiles();
85 for (LogFileOptions logFile
: logFiles
) {
86 if (logFile
.isEnabled()) {
87 myLogFileManagerMap
.put(logFile
, logFile
.getPaths());
88 myLogFileToConfiguration
.put(logFile
, runConfiguration
);
91 Alarm updateAlarm
= myUpdateAlarm
;
92 if (updateAlarm
!= null) {
93 updateAlarm
.addRequest(myUpdateRequest
, UPDATE_INTERVAL
);
97 public void dispose() {
99 if (myUpdateAlarm
!= null) {
100 myUpdateAlarm
.cancelAllRequests();
104 public void initLogConsoles(RunConfigurationBase base
, ProcessHandler startedProcess
) {
105 final ArrayList
<LogFileOptions
> logFiles
= base
.getAllLogFiles();
106 for (LogFileOptions logFile
: logFiles
) {
107 if (logFile
.isEnabled()) {
108 addConfigurationConsoles(logFile
, Condition
.TRUE
);
111 base
.createAdditionalTabComponents(myManager
, startedProcess
);
114 private void addConfigurationConsoles(final LogFileOptions logFile
, Condition
<String
> shouldInclude
) {
115 final Set
<String
> paths
= logFile
.getPaths();
116 if (!paths
.isEmpty()) {
117 final TreeMap
<String
, String
> title2Path
= new TreeMap
<String
, String
>();
118 if (paths
.size() == 1) {
119 final String path
= paths
.iterator().next();
120 if (shouldInclude
.value(path
)) {
121 title2Path
.put(logFile
.getName(), path
);
125 for (String path
: paths
) {
126 if (shouldInclude
.value(path
)) {
127 String title
= new File(path
).getName();
128 if (title2Path
.containsKey(title
)) {
131 title2Path
.put(title
, path
);
135 for (final String title
: title2Path
.keySet()) {
136 final String path
= title2Path
.get(title
);
137 myManager
.addLogConsole(title
, path
, logFile
.isSkipContent() ?
new File(path
).length() : 0);