ffdabd43b6a0e8a67141b8cc85991968e0a1bd58
[idea/community.git] / platform / lang-impl / src / com / intellij / facet / impl / FacetModificationTrackingServiceImpl.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package com.intellij.facet.impl;
18
19 import com.intellij.facet.Facet;
20 import com.intellij.facet.FacetManager;
21 import com.intellij.facet.FacetManagerAdapter;
22 import com.intellij.facet.FacetModificationTrackingService;
23 import com.intellij.openapi.Disposable;
24 import com.intellij.openapi.module.Module;
25 import com.intellij.openapi.util.ModificationTracker;
26 import com.intellij.openapi.util.ModificationTrackerListener;
27 import com.intellij.openapi.util.Pair;
28 import com.intellij.openapi.util.SimpleModificationTracker;
29 import com.intellij.util.EventDispatcher;
30 import com.intellij.util.containers.ContainerUtil;
31 import org.jetbrains.annotations.NotNull;
32
33 import java.util.concurrent.ConcurrentMap;
34
35 public class FacetModificationTrackingServiceImpl extends FacetModificationTrackingService {
36   private final ConcurrentMap<Facet, Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>>> myModificationsTrackers =
37     ContainerUtil.newConcurrentMap();
38
39   public FacetModificationTrackingServiceImpl(final Module module) {
40     module.getMessageBus().connect().subscribe(FacetManager.FACETS_TOPIC, new FacetModificationTrackingListener());
41   }
42
43   @Override
44   @NotNull
45   public ModificationTracker getFacetModificationTracker(@NotNull final Facet facet) {
46     return getFacetInfo(facet).first;
47   }
48
49   private Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>> getFacetInfo(final Facet facet) {
50     Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>> pair = myModificationsTrackers.get(facet);
51     if (pair != null) return pair;
52
53     myModificationsTrackers.putIfAbsent(facet, Pair.create(new SimpleModificationTracker(), EventDispatcher.create(ModificationTrackerListener.class)));
54     return myModificationsTrackers.get(facet);
55   }
56
57   @Override
58   public void incFacetModificationTracker(@NotNull final Facet facet) {
59     final Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>> pair = getFacetInfo(facet);
60     pair.first.incModificationCount();
61     //noinspection unchecked
62     pair.second.getMulticaster().modificationCountChanged(facet);
63   }
64
65   @Override
66   public <T extends Facet> void addModificationTrackerListener(final T facet, final ModificationTrackerListener<? super T> listener, final Disposable parent) {
67     getFacetInfo(facet).second.addListener(listener, parent);
68   }
69
70   @Override
71   public void removeModificationTrackerListener(final Facet facet, final ModificationTrackerListener<?> listener) {
72     getFacetInfo(facet).second.removeListener(listener);
73   }
74
75   private class FacetModificationTrackingListener extends FacetManagerAdapter {
76     @Override
77     public void facetConfigurationChanged(@NotNull final Facet facet) {
78       incFacetModificationTracker(facet);
79     }
80
81     @Override
82     public void facetRemoved(@NotNull final Facet facet) {
83       myModificationsTrackers.remove(facet);
84     }
85   }
86 }