| /* |
| * 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 org.jetbrains.jps.model.ex; |
| |
| import gnu.trove.THashMap; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| import org.jetbrains.jps.model.*; |
| |
| import java.util.Map; |
| |
| /** |
| * @author nik |
| */ |
| public class JpsElementContainerImpl extends JpsElementContainerEx implements JpsElementContainer { |
| private final Map<JpsElementChildRole<?>, JpsElement> myElements = new THashMap<JpsElementChildRole<?>, JpsElement>(1); |
| private final @NotNull JpsCompositeElementBase<?> myParent; |
| |
| public JpsElementContainerImpl(@NotNull JpsCompositeElementBase<?> parent) { |
| myParent = parent; |
| } |
| |
| public JpsElementContainerImpl(@NotNull JpsElementContainerEx original, @NotNull JpsCompositeElementBase<?> parent) { |
| myParent = parent; |
| for (Map.Entry<JpsElementChildRole<?>, JpsElement> entry : original.getElementsMap().entrySet()) { |
| final JpsElementChildRole role = entry.getKey(); |
| final JpsElement copy = entry.getValue().getBulkModificationSupport().createCopy(); |
| JpsElementBase.setParent(copy, myParent); |
| myElements.put(role, copy); |
| } |
| } |
| |
| @Override |
| public <T extends JpsElement> T getChild(@NotNull JpsElementChildRole<T> role) { |
| //noinspection unchecked |
| return (T)myElements.get(role); |
| } |
| |
| @NotNull |
| @Override |
| public <T extends JpsElement, P, K extends JpsElementChildRole<T> & JpsElementParameterizedCreator<T, P>> T setChild(@NotNull K role, |
| @NotNull P param) { |
| final T child = role.create(param); |
| return setChild(role, child); |
| } |
| |
| @NotNull |
| @Override |
| public <T extends JpsElement, K extends JpsElementChildRole<T> & JpsElementCreator<T>> T setChild(@NotNull K role) { |
| final T child = role.create(); |
| return setChild(role, child); |
| } |
| |
| @NotNull |
| @Override |
| public <T extends JpsElement, K extends JpsElementChildRole<T> & JpsElementCreator<T>> T getOrSetChild(@NotNull K role) { |
| final T child = getChild(role); |
| if (child == null) { |
| return setChild(role); |
| } |
| return child; |
| } |
| |
| @Override |
| public <T extends JpsElement> T setChild(JpsElementChildRole<T> role, T child) { |
| myElements.put(role, child); |
| JpsElementBase.setParent(child, myParent); |
| final JpsEventDispatcher eventDispatcher = getEventDispatcher(); |
| if (eventDispatcher != null) { |
| eventDispatcher.fireElementAdded(child, role); |
| } |
| return child; |
| } |
| |
| @Override |
| public <T extends JpsElement> void removeChild(@NotNull JpsElementChildRole<T> role) { |
| //noinspection unchecked |
| final T removed = (T)myElements.remove(role); |
| if (removed == null) return; |
| final JpsEventDispatcher eventDispatcher = getEventDispatcher(); |
| if (eventDispatcher != null) { |
| eventDispatcher.fireElementRemoved(removed, role); |
| } |
| JpsElementBase.setParent(removed, null); |
| } |
| |
| @Override |
| protected Map<JpsElementChildRole<?>, JpsElement> getElementsMap() { |
| return myElements; |
| } |
| |
| public void applyChanges(@NotNull JpsElementContainerEx modified) { |
| for (JpsElementChildRole<?> role : myElements.keySet()) { |
| applyChanges(role, modified); |
| } |
| for (JpsElementChildRole<?> role : modified.getElementsMap().keySet()) { |
| if (!myElements.containsKey(role)) { |
| applyChanges(role, modified); |
| } |
| } |
| } |
| |
| private <T extends JpsElement> void applyChanges(JpsElementChildRole<T> role, JpsElementContainerEx modified) { |
| final T child = getChild(role); |
| final T modifiedChild = modified.getChild(role); |
| if (child != null && modifiedChild != null) { |
| final JpsElement.BulkModificationSupport modificationSupport = child.getBulkModificationSupport(); |
| //noinspection unchecked |
| modificationSupport.applyChanges(modifiedChild); |
| } |
| else if (modifiedChild == null) { |
| removeChild(role); |
| } |
| else { |
| //noinspection unchecked |
| setChild(role, (T)modifiedChild.getBulkModificationSupport().createCopy()); |
| } |
| } |
| |
| @Nullable |
| private JpsEventDispatcher getEventDispatcher() { |
| return myParent.getEventDispatcher(); |
| } |
| } |