| /* |
| * Copyright 2000-2013 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.intellij.facet.impl.pointers; |
| |
| import com.intellij.ProjectTopics; |
| import com.intellij.facet.Facet; |
| import com.intellij.facet.FacetManager; |
| import com.intellij.facet.FacetManagerAdapter; |
| import com.intellij.facet.impl.FacetUtil; |
| import com.intellij.facet.pointers.FacetPointer; |
| import com.intellij.facet.pointers.FacetPointerListener; |
| import com.intellij.facet.pointers.FacetPointersManager; |
| import com.intellij.openapi.Disposable; |
| import com.intellij.openapi.components.ProjectComponent; |
| import com.intellij.openapi.module.Module; |
| import com.intellij.openapi.module.ModuleManager; |
| import com.intellij.openapi.project.ModuleAdapter; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.util.Disposer; |
| import com.intellij.openapi.util.Pair; |
| import com.intellij.util.EventDispatcher; |
| import com.intellij.util.Function; |
| import com.intellij.util.messages.MessageBusConnection; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * @author nik |
| */ |
| public class FacetPointersManagerImpl extends FacetPointersManager implements ProjectComponent { |
| private final Map<String, FacetPointerImpl> myPointers = new HashMap<String, FacetPointerImpl>(); |
| private final Map<Class<? extends Facet>, EventDispatcher<FacetPointerListener>> myDispatchers = |
| new HashMap<Class<? extends Facet>, EventDispatcher<FacetPointerListener>>(); |
| |
| public FacetPointersManagerImpl(final Project project) { |
| super(project); |
| } |
| |
| @Override |
| public <F extends Facet> FacetPointer<F> create(final F facet) { |
| String id = constructId(facet); |
| //noinspection unchecked |
| FacetPointerImpl<F> pointer = myPointers.get(id); |
| if (pointer == null) { |
| if (!FacetUtil.isRegistered(facet)) { |
| return create(id); |
| } |
| pointer = new FacetPointerImpl<F>(this, facet); |
| myPointers.put(id, pointer); |
| } |
| return pointer; |
| } |
| |
| @Override |
| public <F extends Facet> FacetPointer<F> create(final String id) { |
| //noinspection unchecked |
| FacetPointerImpl<F> pointer = myPointers.get(id); |
| if (pointer == null) { |
| pointer = new FacetPointerImpl<F>(this, id); |
| myPointers.put(id, pointer); |
| } |
| return pointer; |
| } |
| |
| <F extends Facet> void dispose(final FacetPointer<F> pointer) { |
| myPointers.remove(pointer.getId()); |
| } |
| |
| @Override |
| @NonNls |
| @NotNull |
| public String getComponentName() { |
| return "FacetPointersManager"; |
| } |
| |
| @Override |
| public void initComponent() { |
| MessageBusConnection connection = myProject.getMessageBus().connect(); |
| connection.subscribe(ProjectTopics.MODULES, new ModuleAdapter() { |
| @Override |
| public void moduleAdded(Project project, Module module) { |
| refreshPointers(module); |
| } |
| |
| @Override |
| public void modulesRenamed(Project project, List<Module> modules, Function<Module, String> oldNameProvider) { |
| for (Module module : modules) { |
| refreshPointers(module); |
| } |
| } |
| }); |
| connection.subscribe(FacetManager.FACETS_TOPIC, new FacetManagerAdapter() { |
| @Override |
| public void facetAdded(@NotNull Facet facet) { |
| refreshPointers(facet.getModule()); |
| } |
| |
| @Override |
| public void beforeFacetRenamed(@NotNull Facet facet) { |
| final FacetPointerImpl pointer = myPointers.get(constructId(facet)); |
| if (pointer != null) { |
| pointer.refresh(); |
| } |
| } |
| |
| @Override |
| public void facetRenamed(@NotNull final Facet facet, @NotNull final String oldName) { |
| refreshPointers(facet.getModule()); |
| } |
| }); |
| for (Module module : ModuleManager.getInstance(myProject).getModules()) { |
| refreshPointers(module); |
| } |
| } |
| |
| private void refreshPointers(@NotNull final Module module) { |
| //todo[nik] refresh only pointers related to renamed module/facet? |
| List<Pair<FacetPointerImpl, String>> changed = new ArrayList<Pair<FacetPointerImpl, String>>(); |
| |
| for (FacetPointerImpl pointer : myPointers.values()) { |
| final String oldId = pointer.getId(); |
| pointer.refresh(); |
| if (!oldId.equals(pointer.getId())) { |
| changed.add(Pair.create(pointer, oldId)); |
| } |
| } |
| |
| for (Pair<FacetPointerImpl, String> pair : changed) { |
| FacetPointerImpl pointer = pair.getFirst(); |
| final Facet facet = pointer.getFacet(); |
| Class facetClass = facet != null ? facet.getClass() : Facet.class; |
| while (facetClass != Object.class) { |
| final EventDispatcher<FacetPointerListener> dispatcher = myDispatchers.get(facetClass); |
| if (dispatcher != null) { |
| //noinspection unchecked |
| dispatcher.getMulticaster().pointerIdChanged(pointer, pair.getSecond()); |
| } |
| facetClass = facetClass.getSuperclass(); |
| } |
| } |
| } |
| |
| public boolean isRegistered(FacetPointer<?> pointer) { |
| return myPointers.containsKey(pointer.getId()); |
| } |
| |
| @Override |
| public void addListener(final FacetPointerListener<Facet> listener) { |
| addListener(Facet.class, listener); |
| } |
| |
| @Override |
| public void removeListener(final FacetPointerListener<Facet> listener) { |
| removeListener(Facet.class, listener); |
| } |
| |
| @Override |
| public void addListener(final FacetPointerListener<Facet> listener, final Disposable parentDisposable) { |
| addListener(Facet.class, listener, parentDisposable); |
| } |
| |
| @Override |
| public <F extends Facet> void addListener(final Class<F> facetClass, final FacetPointerListener<F> listener, final Disposable parentDisposable) { |
| addListener(facetClass, listener); |
| Disposer.register(parentDisposable, new Disposable() { |
| @Override |
| public void dispose() { |
| removeListener(facetClass, listener); |
| } |
| }); |
| } |
| |
| @Override |
| public <F extends Facet> void addListener(final Class<F> facetClass, final FacetPointerListener<F> listener) { |
| EventDispatcher<FacetPointerListener> dispatcher = myDispatchers.get(facetClass); |
| if (dispatcher == null) { |
| dispatcher = EventDispatcher.create(FacetPointerListener.class); |
| myDispatchers.put(facetClass, dispatcher); |
| } |
| dispatcher.addListener(listener); |
| } |
| |
| @Override |
| public <F extends Facet> void removeListener(final Class<F> facetClass, final FacetPointerListener<F> listener) { |
| EventDispatcher<FacetPointerListener> dispatcher = myDispatchers.get(facetClass); |
| if (dispatcher != null) { |
| dispatcher.removeListener(listener); |
| } |
| } |
| |
| public Project getProject() { |
| return myProject; |
| } |
| } |