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
.extensions
;
18 import com
.intellij
.util
.NullableFunction
;
19 import com
.intellij
.util
.containers
.ContainerUtil
;
20 import org
.jetbrains
.annotations
.NotNull
;
21 import org
.jetbrains
.annotations
.Nullable
;
23 import java
.util
.ArrayList
;
24 import java
.util
.Collection
;
25 import java
.util
.List
;
30 public abstract class SmartExtensionPoint
<Extension
,V
> implements ExtensionPointAndAreaListener
<Extension
> {
31 private final Collection
<V
> myExplicitExtensions
;
32 private ExtensionPoint
<Extension
> myExtensionPoint
;
33 private List
<V
> myCache
;
35 protected SmartExtensionPoint(@NotNull final Collection
<V
> explicitExtensions
) {
36 myExplicitExtensions
= explicitExtensions
;
40 protected abstract ExtensionPoint
<Extension
> getExtensionPoint();
42 public final void addExplicitExtension(@NotNull V extension
) {
43 synchronized (myExplicitExtensions
) {
44 myExplicitExtensions
.add(extension
);
49 public final void removeExplicitExtension(@NotNull V extension
) {
50 synchronized (myExplicitExtensions
) {
51 myExplicitExtensions
.remove(extension
);
57 protected abstract V
getExtension(@NotNull final Extension extension
);
60 public final List
<V
> getExtensions() {
61 synchronized (myExplicitExtensions
) {
62 if (myCache
== null) {
63 myExtensionPoint
= getExtensionPoint();
64 myExtensionPoint
.addExtensionPointListener(this);
65 myCache
= new ArrayList
<V
>(myExplicitExtensions
);
66 myCache
.addAll(ContainerUtil
.mapNotNull(myExtensionPoint
.getExtensions(), new NullableFunction
<Extension
, V
>() {
68 public V
fun(final Extension extension
) {
69 return getExtension(extension
);
77 public final void extensionAdded(final Extension extension
, @Nullable final PluginDescriptor pluginDescriptor
) {
81 public final void dropCache() {
82 synchronized (myExplicitExtensions
) {
83 if (myCache
!= null) {
85 myExtensionPoint
.removeExtensionPointListener(this);
86 myExtensionPoint
= null;
91 public final void extensionRemoved(final Extension extension
, @Nullable final PluginDescriptor pluginDescriptor
) {
95 public void areaReplaced(final ExtensionsArea area
) {