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
.openapi
.vcs
.impl
;
18 import com
.intellij
.notification
.Notification
;
19 import com
.intellij
.notification
.NotificationListener
;
20 import com
.intellij
.notification
.NotificationType
;
21 import com
.intellij
.notification
.Notifications
;
22 import com
.intellij
.openapi
.application
.Application
;
23 import com
.intellij
.openapi
.application
.ApplicationManager
;
24 import com
.intellij
.openapi
.diagnostic
.Logger
;
25 import com
.intellij
.openapi
.project
.Project
;
26 import org
.jetbrains
.annotations
.NotNull
;
27 import org
.jetbrains
.annotations
.Nullable
;
29 import javax
.swing
.event
.HyperlinkEvent
;
32 public abstract class GenericNotifierImpl
<T
, Key
> {
33 private final static Logger LOG
= Logger
.getInstance("#com.intellij.openapi.vcs.impl.GenericNotifier");
34 private final Project myProject
;
36 private final String myGroupId
; //+- here
38 private final String myTitle
;
40 private final NotificationType myType
;
42 private final Map
<Key
, MyNotification
<T
>> myState
;
43 private final MyListener myListener
;
44 private final Object myLock
;
46 protected GenericNotifierImpl(final Project project
, @NotNull String groupId
, @NotNull String title
, final @NotNull NotificationType type
) {
51 myState
= new HashMap
<Key
, MyNotification
<T
>>();
52 myListener
= new MyListener();
53 myLock
= new Object();
56 protected abstract boolean ask(final T obj
);
58 protected abstract Key
getKey(final T obj
);
60 protected abstract String
getNotificationContent(final T obj
);
63 protected abstract String
getToString(final T obj
);
65 protected Collection
<Key
> getAllCurrentKeys() {
66 synchronized (myLock
) {
67 return new ArrayList
<Key
>(myState
.keySet());
71 protected boolean getStateFor(final Key key
) {
72 synchronized (myLock
) {
73 return myState
.containsKey(key
);
78 final List
<MyNotification
<T
>> notifications
;
79 synchronized (myLock
) {
80 notifications
= new ArrayList
<MyNotification
<T
>>(myState
.values());
83 for (MyNotification
<T
> notification
: notifications
) {
84 notification
.expire();
88 public void ensureNotify(final T obj
) {
89 final MyNotification
<T
> notification
;
90 synchronized (myLock
) {
91 final Key key
= getKey(obj
);
92 if (myState
.containsKey(key
)) {
95 notification
= new MyNotification
<T
>(myGroupId
, myTitle
, getNotificationContent(obj
), myType
, myListener
, obj
, getToString(obj
));
96 myState
.put(key
, notification
);
98 final Application application
= ApplicationManager
.getApplication();
99 if (application
.isDispatchThread()) {
100 Notifications
.Bus
.notify(notification
, myProject
);
102 application
.invokeLater(new Runnable() {
104 Notifications
.Bus
.notify(notification
, myProject
);
110 public void removeLazyNotificationByKey(final Key key
) {
111 final MyNotification
<T
> notification
;
112 synchronized (myLock
) {
113 notification
= myState
.get(key
);
114 if (notification
!= null) {
118 if (notification
!= null) {
119 notification
.expire();
123 public void removeLazyNotification(final T obj
) {
124 final MyNotification
<T
> notification
;
125 synchronized (myLock
) {
126 final Key key
= getKey(obj
);
127 notification
= myState
.get(key
);
128 if (notification
!= null) {
132 if (notification
!= null) {
133 notification
.expire();
137 private class MyListener
implements NotificationListener
{
138 public void hyperlinkUpdate(@NotNull Notification notification
, @NotNull HyperlinkEvent event
) {
139 if (notification
instanceof MyNotification
) {
140 final MyNotification
<T
> concreteNotification
= (MyNotification
<T
>) notification
;
141 final T obj
= concreteNotification
.getObj();
142 final boolean state
= ask(obj
);
144 synchronized (myLock
) {
145 final Key key
= getKey(obj
);
148 notification
.expire();
155 protected T
getObj(final Key key
) {
156 synchronized (myLock
) {
157 final MyNotification
<T
> notification
= myState
.get(key
);
158 return notification
== null ?
null : notification
.getObj();
162 protected static class MyNotification
<T
> extends Notification
{
164 private final String myStringPresentation
;
166 protected MyNotification(@NotNull String groupId
, @NotNull String title
, @NotNull String content
, @NotNull NotificationType type
, @Nullable NotificationListener listener
,
167 @NotNull final T obj
,
168 final String stringPresentation
) {
169 super(groupId
, title
, content
, type
, listener
);
171 myStringPresentation
= stringPresentation
;
179 public String
toString() {
180 return myStringPresentation
;
184 private static void log(final String s
) {