*/
package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerNode;
-import com.google.common.collect.Maps;
-
-abstract class AbstractImmutableDataContainerNodeBuilder<I extends InstanceIdentifier.PathArgument, R extends DataContainerNode<I>>
+abstract class AbstractImmutableDataContainerNodeBuilder<I extends YangInstanceIdentifier.PathArgument, R extends DataContainerNode<I>>
implements DataContainerNodeBuilder<I, R> {
- protected Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> value;
- protected I nodeIdentifier;
+ private Map<YangInstanceIdentifier.PathArgument, DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> value;
+ private I nodeIdentifier;
+
+ /*
+ * Tracks whether the builder is dirty, e.g. whether the value map has been used
+ * to construct a child. If it has, we detect this condition before any further
+ * modification and create a new value map with same contents. This way we do not
+ * force a map copy if the builder is not reused.
+ */
+ private boolean dirty;
protected AbstractImmutableDataContainerNodeBuilder() {
- this.value = Maps.newLinkedHashMap();
+ this.value = new HashMap<>();
+ this.dirty = false;
+ }
+
+ protected AbstractImmutableDataContainerNodeBuilder(final AbstractImmutableDataContainerNode<I> node) {
+ this.nodeIdentifier = node.getIdentifier();
+ this.value = node.getChildren();
+ this.dirty = true;
+ }
+
+ protected final I getNodeIdentifier() {
+ return nodeIdentifier;
+ }
+
+ protected final DataContainerChild<? extends PathArgument, ?> getChild(final PathArgument child) {
+ return value.get(child);
+ }
+
+ protected final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> buildValue() {
+ dirty = true;
+ return value;
+ }
+
+ private void checkDirty() {
+ if (dirty) {
+ value = new HashMap<>(value);
+ dirty = false;
+ }
}
@Override
- public DataContainerNodeBuilder<I, R> withValue(List<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> value) {
+ public DataContainerNodeBuilder<I, R> withValue(final List<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> value) {
// TODO Replace or putAll ?
- for (DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> dataContainerChild : value) {
+ for (final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild : value) {
withChild(dataContainerChild);
}
return this;
}
@Override
- public DataContainerNodeBuilder<I, R> withChild(DataContainerChild<?, ?> child) {
+ public DataContainerNodeBuilder<I, R> withChild(final DataContainerChild<?, ?> child) {
+ checkDirty();
this.value.put(child.getIdentifier(), child);
return this;
}
+ @Override
+ public DataContainerNodeBuilder<I, R> withoutChild(final PathArgument key) {
+ checkDirty();
+ this.value.remove(key);
+ return this;
+ }
@Override
- public DataContainerNodeBuilder<I, R> withNodeIdentifier(I nodeIdentifier) {
+ public DataContainerNodeBuilder<I, R> withNodeIdentifier(final I nodeIdentifier) {
this.nodeIdentifier = nodeIdentifier;
return this;
}
+
+ @Override
+ public DataContainerNodeBuilder<I, R> addChild(
+ final DataContainerChild<? extends PathArgument, ?> child) {
+ return withChild(child);
+ }
+
+ @Override
+ public NormalizedNodeContainerBuilder<I, PathArgument, DataContainerChild<? extends PathArgument, ?>, R> removeChild(final PathArgument key) {
+ return withoutChild(key);
+ }
}