IDEA-51354 (Not logged to SVN notification: allow to copy message to clipboard)
[fedora-idea.git] / platform / vcs-impl / src / com / intellij / openapi / vcs / impl / GenericNotifierImpl.java
blobb359ca0232ab456ea4825114c59f9ba0b17e7df9
1 /*
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;
30 import java.util.*;
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;
35 @NotNull
36 private final String myGroupId; //+- here
37 @NotNull
38 private final String myTitle;
39 @NotNull
40 private final NotificationType myType;
41 @NotNull
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) {
47 myGroupId = groupId;
48 myTitle = title;
49 myType = type;
50 myProject = project;
51 myState = new HashMap<Key, MyNotification<T>>();
52 myListener = new MyListener();
53 myLock = new Object();
56 protected abstract boolean ask(final T obj);
57 @NotNull
58 protected abstract Key getKey(final T obj);
59 @NotNull
60 protected abstract String getNotificationContent(final T obj);
62 @NotNull
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);
77 public void clear() {
78 final List<MyNotification<T>> notifications;
79 synchronized (myLock) {
80 notifications = new ArrayList<MyNotification<T>>(myState.values());
81 myState.clear();
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)) {
93 return;
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);
101 } else {
102 application.invokeLater(new Runnable() {
103 public void run() {
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) {
115 myState.remove(key);
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) {
129 myState.remove(key);
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);
143 if (state) {
144 synchronized (myLock) {
145 final Key key = getKey(obj);
146 myState.remove(key);
148 notification.expire();
154 @Nullable
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 {
163 private T myObj;
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);
170 myObj = obj;
171 myStringPresentation = stringPresentation;
174 public T getObj() {
175 return myObj;
178 @Override
179 public String toString() {
180 return myStringPresentation;
184 private static void log(final String s) {
185 LOG.debug(s);