Bump to odlparent 3.1.0 and yangtools 2.0.3
[packetcable.git] / packetcable-policy-server / src / main / java / org / opendaylight / controller / packetcable / provider / AbstractDataTreeChangeListener.java
1 /*
2  * Copyright (c) 2015 CableLabs 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
9 package org.opendaylight.controller.packetcable.provider;
10
11 import static com.google.common.base.Preconditions.checkNotNull;
12
13 import com.google.common.collect.Maps;
14 import java.util.Collection;
15 import java.util.Map;
16 import java.util.NoSuchElementException;
17 import javax.annotation.Nonnull;
18 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
19 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
20 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
21 import org.opendaylight.controller.packetcable.provider.validation.DataValidator;
22 import org.opendaylight.controller.packetcable.provider.validation.ValidationException;
23 import org.opendaylight.controller.packetcable.provider.validation.Validator;
24 import org.opendaylight.yangtools.yang.binding.DataObject;
25 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * @author rvail
31  * @author mmakati
32  */
33 public abstract class AbstractDataTreeChangeListener<T extends DataObject> implements DataTreeChangeListener<T> {
34
35     protected final Logger logger = LoggerFactory.getLogger(getClass());
36
37     private final Class<T> tClass;
38
39     private final DataValidator dataValidator;
40
41     public AbstractDataTreeChangeListener(Class<T> tClass,DataValidator dataValidator) {
42         this.tClass = checkNotNull(tClass);
43         this.dataValidator = checkNotNull(dataValidator);
44     }
45
46     private ValidationException validateData(final DataTreeModification<T> change){
47         InstanceIdentifier iid = change.getRootPath().getRootIdentifier();
48
49         try {
50             // getDataAfter should only remove null if the data was removed, but we don't validate on remove.
51             dataValidator.validate(iid, change.getRootNode().getDataAfter(), Validator.Extent.NODE_AND_SUBTREE);
52         }
53         catch (ValidationException e) {
54             logger.debug("invalid data: {}", change.getRootNode().getDataAfter(), e);
55             return e;
56         }
57         return null;
58     }
59
60     @Override
61     public void onDataTreeChanged(@Nonnull Collection<DataTreeModification<T>> changes)
62     {
63         Map<DataTreeModification<T>, ValidationException> exceptionMap = Maps.newHashMap();
64         for (final DataTreeModification<T> change : changes) {
65             final DataObjectModification<T> root = change.getRootNode();
66             switch (root.getModificationType()) {
67                 case SUBTREE_MODIFIED:
68                     try{
69                         ValidationException validationException = validateData(change);
70                         if(validationException != null){
71                             handleInvalidData(change,validationException);
72                         }
73                         else {
74                             handleUpdatedData(change);
75                         }
76                     }catch (NoSuchElementException e) {
77                         logger.error("Unable to find validator for data: {}", change.getRootNode().getDataAfter(), e);
78                     }
79                     break;
80                 case WRITE:
81                     try{
82                         ValidationException validationException = validateData(change);
83                         if(validationException != null){
84                             handleInvalidData(change,validationException);
85                         }
86                         else {
87                             // Treat an overwrite as an update
88                             boolean update = change.getRootNode().getDataBefore() != null;
89                             if (update) {
90                                 handleUpdatedData(change);
91                             } else {
92                                 handleCreatedData(change);
93                             }
94                         }
95                     }catch (NoSuchElementException e) {
96                         logger.error("Unable to find validator for data: {}", change.getRootNode().getDataAfter(), e);
97                     }
98                     break;
99                 case DELETE:
100                     handleRemovedData(change);
101                     break;
102                 default:
103                     break;
104             }
105         }
106     }
107     protected abstract void handleCreatedData(final DataTreeModification<T> change);
108
109     protected abstract void handleUpdatedData(final DataTreeModification<T> change);
110
111     protected abstract void handleRemovedData(final DataTreeModification<T> change);
112
113     protected abstract void handleInvalidData(final DataTreeModification<T> change, ValidationException validationException);
114
115
116 }