e6235bb6b8c7321ca95644ea8f8ab63e23714a9e
[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 com.google.common.base.Optional;
11 import com.google.common.collect.Iterables;
12 import com.google.common.collect.Lists;
13 import java.util.List;
14 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
15 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
16 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
17 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
18 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
19
20 final class LeafSetNodeModification implements Modification<LeafListSchemaNode, LeafSetNode<?>> {
21
22     @Override
23     public Optional<LeafSetNode<?>> modify(LeafListSchemaNode schema, Optional<LeafSetNode<?>> actual,
24             Optional<LeafSetNode<?>> modification, OperationStack operationStack) throws DataModificationException {
25
26         List<LeafSetEntryNode<?>> resultNodes = Lists.newArrayList();
27         if(actual.isPresent()) {
28             Iterables.addAll(resultNodes, actual.get().getValue());
29         }
30
31         // TODO implement ordering for modification nodes
32
33         for (LeafSetEntryNode<?> leafListModification : modification.get().getValue()) {
34             operationStack.enteringNode(leafListModification);
35
36             switch (operationStack.getCurrentOperation()) {
37                 case MERGE:
38                 case CREATE: {
39                     DataModificationException.DataExistsException.check(schema.getQName(), actual, leafListModification);
40                 }
41                 case REPLACE: {
42                     if (!contains(actual, leafListModification)) {
43                         resultNodes.add(leafListModification);
44                     }
45                     break;
46                 }
47                 case DELETE: {
48                     DataModificationException.DataMissingException.check(schema.getQName(), actual, leafListModification);
49                 }
50                 case REMOVE: {
51                     if (resultNodes.contains(leafListModification)) {
52                         resultNodes.remove(leafListModification);
53                     }
54                     break;
55                 }
56                 case NONE: {
57                     break;
58                 }
59                 default:
60                     throw new UnsupportedOperationException(String.format("Unable to perform operation: %s on: %s, unknown", operationStack.getCurrentOperation(), schema));
61             }
62
63             operationStack.exitingNode(leafListModification);
64         }
65         return build(schema, resultNodes);
66     }
67
68     private Optional<LeafSetNode<?>> build(LeafListSchemaNode schemaNode, List<LeafSetEntryNode<?>> resultNodes) {
69         if(resultNodes.isEmpty()) {
70             return Optional.absent();
71         }
72
73         ListNodeBuilder<Object, LeafSetEntryNode<Object>> b = Builders.leafSetBuilder(schemaNode);
74         for (LeafSetEntryNode<?> resultNode : resultNodes) {
75             // FIXME: can we do something about this SuppressWarnings?
76             @SuppressWarnings("unchecked")
77             final LeafSetEntryNode<Object> child = (LeafSetEntryNode<Object>) resultNode;
78             b.withChild(child);
79         }
80
81         return Optional.<LeafSetNode<?>>of(b.build());
82     }
83
84     private static boolean contains(Optional<LeafSetNode<?>> actual, LeafSetEntryNode<?> leafListModification) {
85         boolean contains = actual.isPresent();
86         contains &= actual.get().getChild(leafListModification.getIdentifier()).isPresent();
87
88         return contains;
89     }
90 }