Merge "BUG-1718 Fix hasAttributes method in XmlStreamUtils"
authorRobert Varga <rovarga@cisco.com>
Mon, 8 Sep 2014 15:45:13 +0000 (15:45 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 8 Sep 2014 15:45:13 +0000 (15:45 +0000)
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlDocumentUtils.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTree.java
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/repo/util/InMemorySchemaSourceCache.java

index d944842bf983ca534804929c2cd3b28143b2f577..d49d7e599d65f4f162360e37f647d4204d7a6717 100644 (file)
@@ -228,38 +228,30 @@ public class XmlDocumentUtils {
 
     protected static Node<?> toSimpleNodeWithType(final Element xmlElement, final LeafSchemaNode schema,
             final XmlCodecProvider codecProvider,final SchemaContext schemaCtx) {
-        final TypeDefinition<?> baseType = XmlUtils.resolveBaseTypeFrom(schema.getType());
-        final String text = xmlElement.getTextContent();
-        final Object value;
-
-        if (baseType instanceof InstanceIdentifierType) {
-            value = InstanceIdentifierForXmlCodec.deserialize(xmlElement, schemaCtx);
-        } else if (baseType instanceof IdentityrefTypeDefinition) {
-            value = InstanceIdentifierForXmlCodec.toIdentity(text, xmlElement, schemaCtx);
-        } else {
-            final TypeDefinitionAwareCodec<?, ?> codec = codecProvider.codecFor(schema.getType());
-            if (codec == null) {
-                LOG.info("No codec for schema {}, falling back to text", schema);
-                value = text;
-            } else {
-                value = codec.deserialize(text);
-            }
-        }
-
+        final Object value = resolveValueFromSchemaType(xmlElement, schema, schema.getType(), codecProvider, schemaCtx);
         Optional<ModifyAction> modifyAction = getModifyOperationFromAttributes(xmlElement);
         return new SimpleNodeTOImpl<>(schema.getQName(), null, value, modifyAction.orNull());
     }
 
     private static Node<?> toSimpleNodeWithType(final Element xmlElement, final LeafListSchemaNode schema,
             final XmlCodecProvider codecProvider,final SchemaContext schemaCtx) {
+        final Object value = resolveValueFromSchemaType(xmlElement, schema, schema.getType(), codecProvider, schemaCtx);
+        Optional<ModifyAction> modifyAction = getModifyOperationFromAttributes(xmlElement);
+        return new SimpleNodeTOImpl<>(schema.getQName(), null, value, modifyAction.orNull());
+    }
+
+    private static Object resolveValueFromSchemaType(final Element xmlElement, final DataSchemaNode schema, final TypeDefinition<?> type,
+        final XmlCodecProvider codecProvider,final SchemaContext schemaCtx) {
+        final TypeDefinition<?> baseType = XmlUtils.resolveBaseTypeFrom(type);
+        final String text = xmlElement.getTextContent();
         final Object value;
 
-        if (schema.getType() instanceof InstanceIdentifierType) {
+        if (baseType instanceof InstanceIdentifierType) {
             value = InstanceIdentifierForXmlCodec.deserialize(xmlElement, schemaCtx);
+        } else if (baseType instanceof IdentityrefTypeDefinition) {
+            value = InstanceIdentifierForXmlCodec.toIdentity(text, xmlElement, schemaCtx);
         } else {
-            final TypeDefinitionAwareCodec<?, ?> codec = codecProvider.codecFor(schema.getType());
-            final String text = xmlElement.getTextContent();
-
+            final TypeDefinitionAwareCodec<?, ?> codec = codecProvider.codecFor(type);
             if (codec == null) {
                 LOG.info("No codec for schema {}, falling back to text", schema);
                 value = text;
@@ -267,9 +259,7 @@ public class XmlDocumentUtils {
                 value = codec.deserialize(text);
             }
         }
-
-        Optional<ModifyAction> modifyAction = getModifyOperationFromAttributes(xmlElement);
-        return new SimpleNodeTOImpl<>(schema.getQName(), null, value, modifyAction.orNull());
+        return value;
     }
 
     private static Node<?> toCompositeNodeWithSchema(final Element xmlElement, final QName qName, final DataNodeContainer schema,
index 0f0b4a12da7e96f594a5d7a8f78c1a0dc79bf8c4..b8344d896387f9cbc7c35ebf785f6a5d681bfaf8 100644 (file)
@@ -7,9 +7,10 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
-
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
@@ -22,9 +23,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-
 /**
  * Read-only snapshot of the data tree.
  */
@@ -130,7 +128,7 @@ final class InMemoryDataTree implements DataTree {
         rwLock.writeLock().lock();
         try {
             Preconditions.checkState(c.getBeforeRoot() == rootNode,
-                    String.format("Store tree %s and candidate base %s differ.", rootNode, c.getBeforeRoot()));
+                    "Store tree %s and candidate base %s differ.", rootNode, c.getBeforeRoot());
             this.rootNode = c.getAfterRoot();
         } finally {
             rwLock.writeLock().unlock();
index ad594e422116463671bb760fd75945ff647f0660..e63d7a8abcadf2615fdf04601d3c5f035f973d67 100644 (file)
@@ -7,14 +7,15 @@
 package org.opendaylight.yangtools.yang.model.repo.util;
 
 import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
+import com.google.common.base.FinalizablePhantomReference;
+import com.google.common.base.FinalizableReferenceQueue;
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.RemovalListener;
-import com.google.common.cache.RemovalNotification;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
-
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
@@ -24,29 +25,14 @@ import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
 
 @Beta
-public class InMemorySchemaSourceCache<T extends SchemaSourceRepresentation> extends AbstractSchemaSourceCache<T> {
-    private static final class CacheEntry<T extends SchemaSourceRepresentation> {
-        private final SchemaSourceRegistration<T> reg;
-        private final T source;
-
-        public CacheEntry(final T source, final SchemaSourceRegistration<T> reg) {
-            this.source = Preconditions.checkNotNull(source);
-            this.reg = Preconditions.checkNotNull(reg);
-        }
-    }
-
-    private static final RemovalListener<SourceIdentifier, CacheEntry<?>> LISTENER = new RemovalListener<SourceIdentifier, CacheEntry<?>>() {
-        @Override
-        public void onRemoval(final RemovalNotification<SourceIdentifier, CacheEntry<?>> notification) {
-            notification.getValue().reg.close();
-        }
-    };
-
-    private final Cache<SourceIdentifier, CacheEntry<T>> cache;
+public class InMemorySchemaSourceCache<T extends SchemaSourceRepresentation> extends AbstractSchemaSourceCache<T> implements AutoCloseable {
+    private final List<FinalizablePhantomReference<T>> regs = Collections.synchronizedList(new ArrayList<FinalizablePhantomReference<T>>());
+    private final FinalizableReferenceQueue queue = new FinalizableReferenceQueue();
+    private final Cache<SourceIdentifier, T> cache;
 
     protected InMemorySchemaSourceCache(final SchemaSourceRegistry consumer, final Class<T> representation, final CacheBuilder<Object, Object> builder) {
         super(consumer, representation, Costs.IMMEDIATE);
-        cache = builder.removalListener(LISTENER).build();
+        cache = builder.build();
     }
 
     public static <R extends SchemaSourceRepresentation> InMemorySchemaSourceCache<R> createSoftCache(final SchemaSourceRegistry consumer, final Class<R> representation) {
@@ -55,9 +41,9 @@ public class InMemorySchemaSourceCache<T extends SchemaSourceRepresentation> ext
 
     @Override
     public CheckedFuture<? extends T, SchemaSourceException> getSource(final SourceIdentifier sourceIdentifier) {
-        final CacheEntry<T> present = cache.getIfPresent(sourceIdentifier);
+        final T present = cache.getIfPresent(sourceIdentifier);
         if (present != null) {
-            return Futures.immediateCheckedFuture(present.source);
+            return Futures.immediateCheckedFuture(present);
         }
 
         return Futures.<T, SchemaSourceException>immediateFailedCheckedFuture(new MissingSchemaSourceException("Source not found", sourceIdentifier));
@@ -65,10 +51,31 @@ public class InMemorySchemaSourceCache<T extends SchemaSourceRepresentation> ext
 
     @Override
     protected void offer(final T source) {
-        final CacheEntry<T> present = cache.getIfPresent(source.getIdentifier());
+        final T present = cache.getIfPresent(source.getIdentifier());
         if (present == null) {
+            cache.put(source.getIdentifier(), source);
+
             final SchemaSourceRegistration<T> reg = register(source.getIdentifier());
-            cache.put(source.getIdentifier(), new CacheEntry<T>(source, reg));
+            final FinalizablePhantomReference<T> ref = new FinalizablePhantomReference<T>(source, queue) {
+                @Override
+                public void finalizeReferent() {
+                    reg.close();
+                    regs.remove(this);
+                }
+            };
+
+            regs.add(ref);
         }
     }
+
+    @Override
+    public void close() {
+        while (!regs.isEmpty()) {
+            final FinalizablePhantomReference<?> ref = regs.get(0);
+            ref.finalizeReferent();
+        }
+
+        cache.invalidateAll();
+        queue.close();
+    }
 }