/* * Copyright 2003-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 jetbrains.mps.smodel.language; import jetbrains.mps.smodel.structure.Extension; import jetbrains.mps.smodel.structure.ExtensionPoint; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; public class BaseExtensionRegistry { private Map<String, Collection<Extension>> myActiveExtensions = new HashMap<String, Collection<Extension>>(); private Map<String, Collection<Extension>> myInactiveExtensions = new HashMap<String, Collection<Extension>>(); private Map<String, ExtensionPoint> myExtensionPoints = new HashMap<String, ExtensionPoint>(); @SuppressWarnings("unchecked") public <T> ExtensionPoint<T> getExtensionPoint(String id) { return (ExtensionPoint<T>) myExtensionPoints.get(id); } public boolean hasExtensionPoint(String id) { return myExtensionPoints.containsKey(id); } public <T> Iterable<Extension<T>> getExtensions(ExtensionPoint<T> extensionPoint) { return optExtensionsBucket(extensionPoint.getId(), this.<T>activeExtensions()); } public <T> Iterable<T> getObjects(ExtensionPoint<T> extensionPoint) { Collection<Extension<T>> extensions = optExtensionsBucket(extensionPoint.getId(), this.<T>activeExtensions()); if (extensions.isEmpty()) return Collections.emptyList(); List<T> res = new ArrayList<T>(extensions.size()); for (Extension<T> extension : extensions) { res.add(extension.get()); } return res; } protected void clear() { // TODO check for eventual stuck extensions myActiveExtensions.clear(); myInactiveExtensions.clear(); myExtensionPoints.clear(); } @SuppressWarnings("unchecked") protected void unregisterExtensions(Iterable<? extends Extension> extensions) { for (Extension extension : extensions) { unregisterExtension(extension); } } @SuppressWarnings("unchecked") protected void unregisterExtensionPoints(Iterable<? extends ExtensionPoint> extensionPoints) { for (ExtensionPoint extensionPoint : extensionPoints) { unregisterExtensionPoint(extensionPoint); } } @SuppressWarnings("unchecked") protected void registerExtensions(Iterable<? extends Extension> extensions) { for (Extension extension : extensions) { registerExtension(extension); } } @SuppressWarnings("unchecked") protected void registerExtensionPoints(Iterable<? extends ExtensionPoint> extensionPoints) { for (ExtensionPoint extensionPoint : extensionPoints) { registerExtensionPoint(extensionPoint); } } private <T> void registerExtensionPoint(ExtensionPoint<T> extensionPoint) { myExtensionPoints.put(extensionPoint.getId(), extensionPoint); activateExtensionPoint(extensionPoint); } private <T> void registerExtension(Extension<T> extension) { if (hasExtensionPoint(extension.getExtensionPointId())) { registerActiveExtension(extension); } else { registerInactiveExtension(extension); } } private <T> void unregisterExtensionPoint(ExtensionPoint<T> extensionPoint) { deactivateExtensionPoint(extensionPoint); myExtensionPoints.remove(extensionPoint.getId()); } private <T> void unregisterExtension(Extension<T> extension) { if (hasExtensionPoint(extension.getExtensionPointId())) { unregisterActiveExtension(extension); } else { unregisterInactiveExtension(extension); } } private <T> void registerActiveExtension(Extension<T> extension) { if (activateExtension(extension)) { extensionsBucket(extension.getExtensionPointId(), this.<T>activeExtensions()).add(extension); } } private <T> void unregisterActiveExtension(Extension<T> extension) { if (optExtensionsBucket(extension.getExtensionPointId(), this.<T>activeExtensions()).remove(extension)) { deactivateExtension(extension); } } private <T> void registerInactiveExtension(Extension<T> extension) { extensionsBucket(extension.getExtensionPointId(), this.<T>inactiveExtensions()).add(extension); } private <T> void unregisterInactiveExtension(Extension<T> extension) { extensionsBucket(extension.getExtensionPointId(), this.<T>inactiveExtensions()).remove(extension); } private <T> void activateExtensionPoint(ExtensionPoint<T> extensionPoint) { for (Extension<T> extension : optExtensionsBucket(extensionPoint.getId(), this.<T>inactiveExtensions())) { activateExtension(extension); extensionsBucket(extensionPoint.getId(), this.<T>activeExtensions()).add(extension); } clearExtensionsBucket(extensionPoint.getId(), this.<T>inactiveExtensions()); } private <T> void deactivateExtensionPoint(ExtensionPoint<T> extensionPoint) { for (Extension<T> extension : optExtensionsBucket(extensionPoint.getId(), this.<T>activeExtensions())) { deactivateExtension(extension); extensionsBucket(extensionPoint.getId(), this.<T>inactiveExtensions()).add(extension); } clearExtensionsBucket(extensionPoint.getId(), this.<T>activeExtensions()); } private <T> Collection<Extension<T>> extensionsBucket(String id, Map<String, Collection<Extension<T>>> store) { Collection<Extension<T>> extensions = store.get(id); if (extensions == null) { extensions = new ArrayList<Extension<T>>(); store.put(id, extensions); } return extensions; } private <E> Collection<E> optExtensionsBucket(String id, Map<String, Collection<E>> store) { Collection<E> extensions = store.get(id); return extensions != null ? extensions : Collections.<E>emptyList(); } private <E> void clearExtensionsBucket(String id, Map<String, Collection<E>> store) { Collection<E> extensions = store.get(id); if (extensions != null) { extensions.clear(); store.remove(id); } } private boolean activateExtension(Extension extension) { extension.activate(); return true; } private boolean deactivateExtension(Extension extension) { extension.deactivate(); return true; } @SuppressWarnings("unchecked") private <T> Map<String, Collection<Extension<T>>> inactiveExtensions() { return (Map<String, Collection<Extension<T>>>) (Map) myInactiveExtensions; } @SuppressWarnings("unchecked") private <T> Map<String, Collection<Extension<T>>> activeExtensions() { return (Map<String, Collection<Extension<T>>>) (Map) myActiveExtensions; } }