/*
 * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.yangtools.yang.data.impl.schema.tree;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.util.concurrent.ExecutionException;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;

/**
 * Base strategy for applying changes to a ContainerNode, irrespective of its
 * actual type.
 *
 * @param <T> Type of the container node
 */
abstract class AbstractDataNodeContainerModificationStrategy<T extends DataNodeContainer> extends AbstractNodeContainerModificationStrategy {

    private final LoadingCache<PathArgument, ModificationApplyOperation> childCache = CacheBuilder.newBuilder()
            .build(CacheLoader.from(new Function<PathArgument, ModificationApplyOperation>() {

                @Override
                public ModificationApplyOperation apply(final PathArgument identifier) {
                    if (identifier instanceof AugmentationIdentifier && schema instanceof AugmentationTarget) {
                        return SchemaAwareApplyOperation.from(schema, (AugmentationTarget) schema, (AugmentationIdentifier) identifier);
                    }

                    DataSchemaNode child = schema.getDataChildByName(identifier.getNodeType());
                    if (child == null) {
                        return null;
                    }
                    return SchemaAwareApplyOperation.from(child);
                }
            }));
    private final T schema;

    protected AbstractDataNodeContainerModificationStrategy(final T schema, final Class<? extends NormalizedNode<?, ?>> nodeClass) {
        super(nodeClass);
        this.schema = Preconditions.checkNotNull(schema);
    }

    protected final T getSchema() {
        return schema;
    }

    @Override
    public final Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
        try {
            return Optional.<ModificationApplyOperation> fromNullable(childCache.get(identifier));
        } catch (ExecutionException e) {
            return Optional.absent();
        }
    }

    @Override
    @SuppressWarnings("rawtypes")
    protected abstract DataContainerNodeBuilder createBuilder(NormalizedNode<?, ?> original);

    @Override
    public String toString() {
        return getClass().getSimpleName() + " [" + schema + "]";
    }
}
@@ -369,48 +369,8 @@
 e;%0A%0A
-import com.google.common.base.Function;%0A
 impo
@@ -1178,16 +1178,73 @@
 emaNode;
+%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0A%0A/**%0A *
@@ -1525,16 +1525,131 @@
 ategy %7B%0A
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractDataNodeContainerModificationStrategy.class);
 %0A    pri
@@ -1772,16 +1772,20 @@
  .build(
+new 
 CacheLoa
@@ -1791,26 +1791,8 @@
 ader
-.from(new Function
 %3CPat
@@ -1834,17 +1834,16 @@
 on%3E() %7B%0A
-%0A
         
@@ -1910,21 +1910,20 @@
 eration 
-apply
+load
 (final P
@@ -1930,35 +1930,45 @@
 athArgument 
-identifier)
+key) throws Exception
  %7B%0A         
@@ -1982,26 +1982,19 @@
     if (
-identifier
+key
  instanc
@@ -2187,26 +2187,19 @@
 tifier) 
-identifier
+key
 );%0A     
@@ -2236,16 +2236,22 @@
         
+final 
 DataSche
@@ -2291,26 +2291,19 @@
 dByName(
-identifier
+key
 .getNode
@@ -2331,20 +2331,23 @@
         
-if (
+return 
 child ==
@@ -2355,97 +2355,17 @@
 null
-) %7B%0A                        return null;%0A                    %7D%0A                    return
+ ? null :
  Sch
@@ -2432,17 +2432,16 @@
       %7D)
-)
 ;%0A    pr
@@ -3013,24 +3013,112 @@
 eption e) %7B%0A
+            LOG.trace(%22Child %7B%7D not present in container schema %7B%7D%22, identifier, this);%0A
             

Optimize AbstractDataNodeContainerModificationStrategy loader