de5a5b0e24847430574a1f664dad791db1932ac4
[yangtools.git] / yang / yang-data-operations / src / main / java / org / opendaylight / yangtools / yang / data / operations / LeafSetNodeModification.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.data.operations;
9
10 import java.util.List;
11
12 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
13 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
14 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
15 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
16 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
17
18 import com.google.common.base.Optional;
19 import com.google.common.collect.Iterables;
20 import com.google.common.collect.Lists;
21
22 final class LeafSetNodeModification implements Modification<LeafListSchemaNode, LeafSetNode<?>> {
23
24     @Override
25     public Optional<LeafSetNode<?>> modify(LeafListSchemaNode schema, Optional<LeafSetNode<?>> actual,
26             Optional<LeafSetNode<?>> modification, OperationStack operationStack) throws DataModificationException {
27
28         List<LeafSetEntryNode<?>> resultNodes = Lists.newArrayList();
29         if(actual.isPresent()) {
30             Iterables.addAll(resultNodes, actual.get().getValue());
31         }
32
33         // TODO implement ordering for modification nodes
34
35         for (LeafSetEntryNode<?> leafListModification : modification.get().getValue()) {
36             operationStack.enteringNode(leafListModification);
37
38             switch (operationStack.getCurrentOperation()) {
39                 case MERGE:
40                 case CREATE: {
41                     DataModificationException.DataExistsException.check(schema.getQName(), actual, leafListModification);
42                 }
43                 case REPLACE: {
44                     if (contains(actual, leafListModification) == false) {
45                         resultNodes.add(leafListModification);
46                     }
47                     break;
48                 }
49                 case DELETE: {
50                     DataModificationException.DataMissingException.check(schema.getQName(), actual, leafListModification);
51                 }
52                 case REMOVE: {
53                     if (resultNodes.contains(leafListModification)) {
54                         resultNodes.remove(leafListModification);
55                     }
56                     break;
57                 }
58                 case NONE: {
59                     break;
60                 }
61                 default:
62                     throw new UnsupportedOperationException(String.format("Unable to perform operation: %s on: %s, unknown", operationStack.getCurrentOperation(), schema));
63             }
64
65             operationStack.exitingNode(leafListModification);
66         }
67         return build(schema, resultNodes);
68     }
69
70     private Optional<LeafSetNode<?>> build(LeafListSchemaNode schemaNode, List<LeafSetEntryNode<?>> resultNodes) {
71         if(resultNodes.isEmpty())
72             return Optional.absent();
73
74         ListNodeBuilder<Object, LeafSetEntryNode<Object>> b = Builders.leafSetBuilder(schemaNode);
75         for (LeafSetEntryNode<?> resultNode : resultNodes) {
76             // FIXME: can we do something about this SuppressWarnings?
77             @SuppressWarnings("unchecked")
78             final LeafSetEntryNode<Object> child = (LeafSetEntryNode<Object>) resultNode;
79             b.withChild(child);
80         }
81
82         return Optional.<LeafSetNode<?>>of(b.build());
83     }
84
85     private static boolean contains(Optional<LeafSetNode<?>> actual, LeafSetEntryNode<?> leafListModification) {
86         boolean contains = actual.isPresent();
87         contains &= actual.get().getChild(leafListModification.getIdentifier()).isPresent();
88
89         return contains;
90     }
91 }