+
+ private class NormalizedDataModification extends AbstractDataModification<InstanceIdentifier, CompositeNode> {
+
+ private final String CONFIGURATIONAL_DATA_STORE_MARKER = "configurational";
+ private final String OPERATIONAL_DATA_STORE_MARKER = "operational";
+ private final Object identifier;
+ private TransactionStatus status;
+
+ public NormalizedDataModification(DataModification<InstanceIdentifier, CompositeNode> original) {
+ super(getDelegate());
+ identifier = original;
+ status = TransactionStatus.NEW;
+ }
+
+ /**
+ *
+ * Ensures all subpaths are removed - this currently does slow lookup in
+ * all keys.
+ *
+ * @param entry
+ */
+ public void deepRemoveOperationalData(InstanceIdentifier entry) {
+ Iterable<InstanceIdentifier> paths = getOperationalSubpaths(entry);
+ removeOperationalData(entry);
+ for (InstanceIdentifier potential : paths) {
+ removeOperationalData(potential);
+ }
+ }
+
+ public void deepRemoveConfigurationData(InstanceIdentifier entry) {
+ Iterable<InstanceIdentifier> paths = getConfigurationSubpaths(entry);
+ removeConfigurationData(entry);
+ for (InstanceIdentifier potential : paths) {
+ removeConfigurationData(potential);
+ }
+ }
+
+ public void putDeepConfigurationData(InstanceIdentifier entryKey, CompositeNode entryData) {
+ this.putCompositeNodeData(entryKey, entryData, CONFIGURATIONAL_DATA_STORE_MARKER);
+ }
+
+ public void putDeepOperationalData(InstanceIdentifier entryKey, CompositeNode entryData) {
+ this.putCompositeNodeData(entryKey, entryData, OPERATIONAL_DATA_STORE_MARKER);
+ }
+
+ @Override
+ public Object getIdentifier() {
+ return this.identifier;
+ }
+
+ @Override
+ public TransactionStatus getStatus() {
+ return status;
+ }
+
+ @Override
+ public Future<RpcResult<TransactionStatus>> commit() {
+ throw new UnsupportedOperationException("Commit should not be invoked on this");
+ }
+
+ @Override
+ protected CompositeNode mergeConfigurationData(InstanceIdentifier path, CompositeNode stored,
+ CompositeNode modified) {
+ return mergeData(path, stored, modified, true);
+ }
+
+ @Override
+ protected CompositeNode mergeOperationalData(InstanceIdentifier path, CompositeNode stored,
+ CompositeNode modified) {
+ return mergeData(path, stored, modified, false);
+ }
+
+ private void putData(InstanceIdentifier entryKey, CompositeNode entryData, String dataStoreIdentifier) {
+ if (dataStoreIdentifier != null && entryKey != null && entryData != null) {
+ switch (dataStoreIdentifier) {
+ case (CONFIGURATIONAL_DATA_STORE_MARKER):
+ this.putConfigurationData(entryKey, entryData);
+ break;
+ case (OPERATIONAL_DATA_STORE_MARKER):
+ this.putOperationalData(entryKey, entryData);
+ break;
+
+ default:
+ LOG.error(dataStoreIdentifier + " is NOT valid DataStore switch marker");
+ throw new RuntimeException(dataStoreIdentifier + " is NOT valid DataStore switch marker");
+ }
+ }
+ }
+
+ private void putCompositeNodeData(InstanceIdentifier entryKey, CompositeNode entryData,
+ String dataStoreIdentifier) {
+ this.putData(entryKey, entryData, dataStoreIdentifier);
+
+ for (Node<?> child : entryData.getChildren()) {
+ InstanceIdentifier subEntryId = InstanceIdentifier.builder(entryKey).node(child.getNodeType())
+ .toInstance();
+ if (child instanceof CompositeNode) {
+ DataSchemaNode subSchema = schemaNodeFor(subEntryId);
+ CompositeNode compNode = (CompositeNode) child;
+ InstanceIdentifier instanceId = null;
+
+ if (subSchema instanceof ListSchemaNode) {
+ ListSchemaNode listSubSchema = (ListSchemaNode) subSchema;
+ Map<QName, Object> mapOfSubValues = this.getValuesFromListSchema(listSubSchema,
+ (CompositeNode) child);
+ if (mapOfSubValues != null) {
+ instanceId = InstanceIdentifier.builder(entryKey)
+ .nodeWithKey(listSubSchema.getQName(), mapOfSubValues).toInstance();
+ }
+ } else if (subSchema instanceof ContainerSchemaNode) {
+ ContainerSchemaNode containerSchema = (ContainerSchemaNode) subSchema;
+ instanceId = InstanceIdentifier.builder(entryKey).node(subSchema.getQName()).toInstance();
+ }
+ if (instanceId != null) {
+ this.putCompositeNodeData(instanceId, compNode, dataStoreIdentifier);
+ }
+ }
+ }
+ }
+
+ private Map<QName, Object> getValuesFromListSchema(ListSchemaNode listSchema, CompositeNode entryData) {
+ List<QName> keyDef = listSchema.getKeyDefinition();
+ if (keyDef != null && !keyDef.isEmpty()) {
+ Map<QName, Object> map = new HashMap<QName, Object>();
+ for (QName key : keyDef) {
+ List<Node<?>> data = entryData.get(key);
+ if (data != null && !data.isEmpty()) {
+ for (Node<?> nodeData : data) {
+ if (nodeData instanceof SimpleNode<?>) {
+ map.put(key, data.get(0).getValue());
+ }
+ }
+ }
+ }
+ return map;
+ }
+ return null;
+ }
+ }