blob: 5f460d9ad56c6942e0ae9d2e1421dd81c9c4a75a [file] [log] [blame]
/*
* Copyright 2000-2012 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;
import com.intellij.ProjectTopics;
import com.intellij.facet.*;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.ModuleAdapter;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.EventDispatcher;
import com.intellij.util.containers.WeakHashMap;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
/**
* @author nik
*/
public class ProjectWideFacetListenersRegistryImpl extends ProjectWideFacetListenersRegistry {
private final Map<FacetTypeId, EventDispatcher<ProjectWideFacetListener>> myDispatchers = new HashMap<FacetTypeId, EventDispatcher<ProjectWideFacetListener>>();
private final Map<FacetTypeId, WeakHashMap<Facet, Boolean>> myFacetsByType = new HashMap<FacetTypeId, WeakHashMap<Facet, Boolean>>();
private final Map<Module, MessageBusConnection> myModule2Connection = new HashMap<Module, MessageBusConnection>();
private final FacetManagerAdapter myFacetListener;
private final EventDispatcher<ProjectWideFacetListener> myAllFacetsListener = EventDispatcher.create(ProjectWideFacetListener.class);
public ProjectWideFacetListenersRegistryImpl(MessageBus messageBus) {
myFacetListener = new MyFacetManagerAdapter();
messageBus.connect().subscribe(ProjectTopics.MODULES, new ModuleAdapter() {
@Override
public void moduleAdded(Project project, Module module) {
onModuleAdded(module);
}
@Override
public void beforeModuleRemoved(final Project project, final Module module) {
Facet[] allFacets = FacetManager.getInstance(module).getAllFacets();
for (Facet facet : allFacets) {
onFacetRemoved(facet, true);
}
}
@Override
public void moduleRemoved(Project project, Module module) {
onModuleRemoved(module);
}
});
}
private void onModuleRemoved(final Module module) {
final MessageBusConnection connection = myModule2Connection.remove(module);
if (connection != null) {
connection.disconnect();
}
final FacetManager facetManager = FacetManager.getInstance(module);
final Facet[] facets = facetManager.getAllFacets();
for (Facet facet : facets) {
onFacetRemoved(facet, false);
}
}
private void onModuleAdded(final Module module) {
final FacetManager facetManager = FacetManager.getInstance(module);
final Facet[] facets = facetManager.getAllFacets();
for (Facet facet : facets) {
onFacetAdded(facet);
}
final MessageBusConnection connection = module.getMessageBus().connect();
myModule2Connection.put(module, connection);
connection.subscribe(FacetManager.FACETS_TOPIC, myFacetListener);
}
private void onFacetRemoved(final Facet facet, final boolean before) {
final FacetTypeId typeId = facet.getTypeId();
WeakHashMap<Facet, Boolean> facets = myFacetsByType.get(typeId);
boolean lastFacet;
if (facets != null) {
facets.remove(facet);
lastFacet = facets.isEmpty();
if (lastFacet) {
myFacetsByType.remove(typeId);
}
}
else {
lastFacet = true;
}
final EventDispatcher<ProjectWideFacetListener> dispatcher = myDispatchers.get(typeId);
if (dispatcher != null) {
if (before) {
//noinspection unchecked
dispatcher.getMulticaster().beforeFacetRemoved(facet);
}
else {
//noinspection unchecked
dispatcher.getMulticaster().facetRemoved(facet);
if (lastFacet) {
dispatcher.getMulticaster().allFacetsRemoved();
}
}
}
if (before) {
getAllFacetsMulticaster().beforeFacetRemoved(facet);
}
else {
getAllFacetsMulticaster().facetRemoved(facet);
if (myFacetsByType.isEmpty()) {
getAllFacetsMulticaster().allFacetsRemoved();
}
}
}
private ProjectWideFacetListener<Facet> getAllFacetsMulticaster() {
//noinspection unchecked
return myAllFacetsListener.getMulticaster();
}
private void onFacetAdded(final Facet facet) {
boolean firstFacet = myFacetsByType.isEmpty();
final FacetTypeId typeId = facet.getTypeId();
WeakHashMap<Facet, Boolean> facets = myFacetsByType.get(typeId);
if (facets == null) {
facets = new WeakHashMap<Facet, Boolean>();
myFacetsByType.put(typeId, facets);
}
boolean firstFacetOfType = facets.isEmpty();
facets.put(facet, true);
if (firstFacet) {
getAllFacetsMulticaster().firstFacetAdded();
}
getAllFacetsMulticaster().facetAdded(facet);
final EventDispatcher<ProjectWideFacetListener> dispatcher = myDispatchers.get(typeId);
if (dispatcher != null) {
if (firstFacetOfType) {
dispatcher.getMulticaster().firstFacetAdded();
}
//noinspection unchecked
dispatcher.getMulticaster().facetAdded(facet);
}
}
private void onFacetChanged(final Facet facet) {
final EventDispatcher<ProjectWideFacetListener> dispatcher = myDispatchers.get(facet.getTypeId());
if (dispatcher != null) {
//noinspection unchecked
dispatcher.getMulticaster().facetConfigurationChanged(facet);
}
getAllFacetsMulticaster().facetConfigurationChanged(facet);
}
@Override
public <F extends Facet> void registerListener(@NotNull FacetTypeId<F> typeId, @NotNull ProjectWideFacetListener<? extends F> listener) {
EventDispatcher<ProjectWideFacetListener> dispatcher = myDispatchers.get(typeId);
if (dispatcher == null) {
dispatcher = EventDispatcher.create(ProjectWideFacetListener.class);
myDispatchers.put(typeId, dispatcher);
}
dispatcher.addListener(listener);
}
@Override
public <F extends Facet> void unregisterListener(@NotNull FacetTypeId<F> typeId, @NotNull ProjectWideFacetListener<? extends F> listener) {
final EventDispatcher<ProjectWideFacetListener> dispatcher = myDispatchers.get(typeId);
if (dispatcher != null) {
dispatcher.removeListener(listener);
}
}
@Override
public <F extends Facet> void registerListener(@NotNull final FacetTypeId<F> typeId, @NotNull final ProjectWideFacetListener<? extends F> listener,
@NotNull final Disposable parentDisposable) {
registerListener(typeId, listener);
Disposer.register(parentDisposable, new Disposable() {
@Override
public void dispose() {
unregisterListener(typeId, listener);
}
});
}
@Override
public void registerListener(@NotNull final ProjectWideFacetListener<Facet> listener) {
myAllFacetsListener.addListener(listener);
}
@Override
public void unregisterListener(@NotNull final ProjectWideFacetListener<Facet> listener) {
myAllFacetsListener.removeListener(listener);
}
@Override
public void registerListener(@NotNull final ProjectWideFacetListener<Facet> listener, @NotNull final Disposable parentDisposable) {
myAllFacetsListener.addListener(listener, parentDisposable);
}
private class MyFacetManagerAdapter extends FacetManagerAdapter {
@Override
public void facetAdded(@NotNull Facet facet) {
onFacetAdded(facet);
}
@Override
public void beforeFacetRemoved(@NotNull final Facet facet) {
onFacetRemoved(facet, true);
}
@Override
public void facetRemoved(@NotNull Facet facet) {
onFacetRemoved(facet, false);
}
@Override
public void facetConfigurationChanged(@NotNull final Facet facet) {
onFacetChanged(facet);
}
}
}