deprecation removed
[fedora-idea.git] / platform / lang-impl / src / com / intellij / psi / impl / meta / MetaRegistry.java
blob4aa8843c6c4aa279efb7e92c98239e8dffc9359b
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.
17 package com.intellij.psi.impl.meta;
19 import com.intellij.openapi.Disposable;
20 import com.intellij.openapi.extensions.Extensions;
21 import com.intellij.openapi.progress.ProgressManager;
22 import com.intellij.openapi.util.Disposer;
23 import com.intellij.openapi.util.Key;
24 import com.intellij.openapi.util.UserDataCache;
25 import com.intellij.patterns.ElementPattern;
26 import com.intellij.psi.PsiElement;
27 import com.intellij.psi.filters.ElementFilter;
28 import com.intellij.psi.filters.position.PatternFilter;
29 import com.intellij.psi.meta.MetaDataContributor;
30 import com.intellij.psi.meta.MetaDataRegistrar;
31 import com.intellij.psi.meta.PsiMetaData;
32 import com.intellij.psi.util.CachedValue;
33 import com.intellij.psi.util.CachedValueProvider;
34 import com.intellij.psi.util.CachedValuesManager;
35 import com.intellij.util.containers.ContainerUtil;
36 import org.jetbrains.annotations.NotNull;
37 import org.jetbrains.annotations.Nullable;
39 import java.util.List;
41 /**
42 * Created by IntelliJ IDEA.
43 * User: ik
44 * Date: 07.05.2003
45 * Time: 3:31:09
46 * To change this template use Options | File Templates.
48 public class MetaRegistry extends MetaDataRegistrar {
49 private static final List<MyBinding> ourBindings = ContainerUtil.createEmptyCOWList();
50 private static volatile boolean ourContributorsLoaded = false;
52 private static final Key<CachedValue<PsiMetaData>> META_DATA_KEY = Key.create("META DATA KEY");
54 public static void bindDataToElement(final PsiElement element, final PsiMetaData data) {
55 CachedValue<PsiMetaData> value = CachedValuesManager.getManager(element.getProject()).createCachedValue(new CachedValueProvider<PsiMetaData>() {
56 public Result<PsiMetaData> compute() {
57 data.init(element);
58 return new Result<PsiMetaData>(data, data.getDependences());
60 });
61 element.putUserData(META_DATA_KEY, value);
64 public static PsiMetaData getMeta(final PsiElement element) {
65 final PsiMetaData base = getMetaBase(element);
66 return base != null ? base : null;
69 private static final UserDataCache<CachedValue<PsiMetaData>, PsiElement, Object> ourCachedMetaCache =
70 new UserDataCache<CachedValue<PsiMetaData>, PsiElement, Object>() {
71 protected CachedValue<PsiMetaData> compute(final PsiElement element, Object p) {
72 return CachedValuesManager.getManager(element.getProject()).createCachedValue(new CachedValueProvider<PsiMetaData>() {
73 public Result<PsiMetaData> compute() {
74 try {
75 ensureContributorsLoaded();
76 for (final MyBinding binding : ourBindings) {
77 if (binding.myFilter.isClassAcceptable(element.getClass()) && binding.myFilter.isAcceptable(element, element.getParent())) {
78 final PsiMetaData data = binding.myDataClass.newInstance();
79 data.init(element);
80 return new Result<PsiMetaData>(data, data.getDependences());
84 catch (IllegalAccessException iae) {
85 throw new RuntimeException(iae);
87 catch (InstantiationException ie) {
88 throw new RuntimeException(ie);
91 return new Result<PsiMetaData>(null, element);
93 }, false);
97 private static void ensureContributorsLoaded() {
98 if (!ourContributorsLoaded) {
99 synchronized (ourBindings) {
100 if (!ourContributorsLoaded) {
101 for(MetaDataContributor contributor: Extensions.getExtensions(MetaDataContributor.EP_NAME)) {
102 contributor.contributeMetaData(MetaDataRegistrar.getInstance());
104 ourContributorsLoaded = true;
110 @Nullable
111 public static PsiMetaData getMetaBase(final PsiElement element) {
112 ProgressManager.checkCanceled();
113 return ourCachedMetaCache.get(META_DATA_KEY, element, null).getValue();
116 public static <T extends PsiMetaData> void addMetadataBinding(ElementFilter filter, Class<T> aMetadataClass, Disposable parentDisposable) {
117 final MyBinding binding = new MyBinding(filter, aMetadataClass);
118 addBinding(binding);
119 Disposer.register(parentDisposable, new Disposable() {
120 public void dispose() {
121 ourBindings.remove(binding);
126 public static <T extends PsiMetaData> void addMetadataBinding(ElementFilter filter, Class<T> aMetadataClass) {
127 addBinding(new MyBinding(filter, aMetadataClass));
130 private static void addBinding(final MyBinding binding) {
131 ourBindings.add(0, binding);
134 public <T extends PsiMetaData> void registerMetaData(ElementFilter filter, Class<T> metadataDescriptorClass) {
135 addMetadataBinding(filter, metadataDescriptorClass);
138 @Override
139 public <T extends PsiMetaData> void registerMetaData(ElementPattern<?> pattern, Class<T> metadataDescriptorClass) {
140 addMetadataBinding(new PatternFilter(pattern), metadataDescriptorClass);
143 private static class MyBinding {
144 private final ElementFilter myFilter;
145 private final Class<? extends PsiMetaData> myDataClass;
147 public MyBinding(@NotNull ElementFilter filter, @NotNull Class<? extends PsiMetaData> dataClass) {
148 myFilter = filter;
149 myDataClass = dataClass;