Add local MultivaluedHashMap implementation 53/63053/3
authorTom Pantelis <tompantelis@gmail.com>
Tue, 12 Sep 2017 16:03:00 +0000 (12:03 -0400)
committerTom Pantelis <tompantelis@gmail.com>
Wed, 27 Sep 2017 04:19:49 +0000 (00:19 -0400)
The JSONRestconfService implementation contains a local UriInfo
implementation, SimpleUriInfo, that uses a MultivaluedHashMap
implementation from javax.ws.rs.core. This class is provided by
the dependency used at compile time however, the runtime bundle
that provides the javax.ws.rs.core interfaces doesn't provide
MultivaluedHashMap. Therefore I added our own local MultivaluedHashMap
class based on the external class. I also refactored SimpleUriInfo into
it's own class as it's used by both JSONRestconfService implementations.

Change-Id: I1af0771327d46c72e55facf14c41038fd583e0ed
Signed-off-by: Tom Pantelis <tompantelis@gmail.com>
restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/util/MultivaluedHashMap.java [new file with mode: 0644]
restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/util/SimpleUriInfo.java [new file with mode: 0644]
restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/JSONRestconfServiceImpl.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040Impl.java

diff --git a/restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/util/MultivaluedHashMap.java b/restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/util/MultivaluedHashMap.java
new file mode 100644 (file)
index 0000000..1036757
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2017 Inocybe Technologies 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.restconf.common.util;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import javax.ws.rs.core.MultivaluedMap;
+
+/**
+ * A hash table based implementation of {@link MultivaluedMap} interface.
+ *
+ * @author Thomas Pantelis
+ */
+public class MultivaluedHashMap<K, V> implements MultivaluedMap<K, V> {
+    private final Map<K, List<V>> store = new HashMap<>();
+
+    @Override
+    public final void putSingle(K key, V value) {
+        List<V> values = getValues(key);
+
+        values.clear();
+        if (value != null) {
+            values.add(value);
+        }
+    }
+
+    @Override
+    public void add(K key, V value) {
+        List<V> values = getValues(key);
+
+        if (value != null) {
+            values.add(value);
+        }
+    }
+
+    @Override
+    public void addAll(K key, V... newValues) {
+        Objects.requireNonNull(newValues, "Supplied array of values must not be null.");
+
+        if (newValues.length == 0) {
+            return;
+        }
+
+        List<V> values = getValues(key);
+        for (V value : newValues) {
+            if (value != null) {
+                values.add(value);
+            }
+        }
+    }
+
+    @Override
+    public void addAll(K key, List<V> valueList) {
+        Objects.requireNonNull(valueList, "Supplied list of values must not be null.");
+
+        if (valueList.isEmpty()) {
+            return;
+        }
+
+        List<V> values = getValues(key);
+        for (V value : valueList) {
+            if (value != null) {
+                values.add(value);
+            }
+        }
+    }
+
+    @Override
+    public void addFirst(K key, V value) {
+        List<V> values = getValues(key);
+
+        if (value != null) {
+            values.add(0, value);
+        }
+    }
+
+    @Override
+    public V getFirst(K key) {
+        List<V> values = store.get(key);
+        if (values != null && values.size() > 0) {
+            return values.get(0);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean equalsIgnoreValueOrder(MultivaluedMap<K, V> omap) {
+        if (this == omap) {
+            return true;
+        }
+        if (!keySet().equals(omap.keySet())) {
+            return false;
+        }
+        for (Entry<K, List<V>> e : entrySet()) {
+            List<V> olist = omap.get(e.getKey());
+            if (e.getValue().size() != olist.size()) {
+                return false;
+            }
+            for (V v : e.getValue()) {
+                if (!olist.contains(v)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Collection<List<V>> values() {
+        return store.values();
+    }
+
+    @Override
+    public int size() {
+        return store.size();
+    }
+
+    @Override
+    public List<V> remove(Object key) {
+        return store.remove(key);
+    }
+
+    @Override
+    public void putAll(Map<? extends K, ? extends List<V>> map) {
+        store.putAll(map);
+    }
+
+    @Override
+    public List<V> put(K key, List<V> value) {
+        return store.put(key, value);
+    }
+
+    @Override
+    public Set<K> keySet() {
+        return store.keySet();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return store.isEmpty();
+    }
+
+    @Override
+    public List<V> get(Object key) {
+        return store.get(key);
+    }
+
+    @Override
+    public Set<Entry<K, List<V>>> entrySet() {
+        return store.entrySet();
+    }
+
+    @Override
+    public boolean containsValue(Object value) {
+        return store.containsValue(value);
+    }
+
+    @Override
+    public boolean containsKey(Object key) {
+        return store.containsKey(key);
+    }
+
+    @Override
+    public void clear() {
+        store.clear();
+    }
+
+    private List<V> getValues(K key) {
+        List<V> list = store.get(key);
+        if (list == null) {
+            list = new LinkedList<>();
+            store.put(key, list);
+        }
+
+        return list;
+    }
+}
diff --git a/restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/util/SimpleUriInfo.java b/restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/util/SimpleUriInfo.java
new file mode 100644 (file)
index 0000000..88da262
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2017 Inocybe Technologies 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.restconf.common.util;
+
+import java.net.URI;
+import java.util.Collections;
+import java.util.List;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.PathSegment;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+
+/**
+ * Simple implementation of the {@link UriInfo} interface.
+ *
+ * @author Thomas Pantelis
+ */
+public class SimpleUriInfo implements UriInfo {
+    private final String path;
+    private final MultivaluedMap<String, String> queryParams;
+
+    public SimpleUriInfo(String path) {
+        this(path, new MultivaluedHashMap<>());
+    }
+
+    public SimpleUriInfo(String path, MultivaluedMap<String, String> queryParams) {
+        this.path = path;
+        this.queryParams = queryParams;
+    }
+
+    @Override
+    public String getPath() {
+        return path;
+    }
+
+    @Override
+    public String getPath(boolean decode) {
+        return path;
+    }
+
+    @Override
+    public List<PathSegment> getPathSegments() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<PathSegment> getPathSegments(boolean decode) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public URI getRequestUri() {
+        return URI.create(path);
+    }
+
+    @Override
+    public UriBuilder getRequestUriBuilder() {
+        return UriBuilder.fromUri(getRequestUri());
+    }
+
+    @Override
+    public URI getAbsolutePath() {
+        return getRequestUri();
+    }
+
+    @Override
+    public UriBuilder getAbsolutePathBuilder() {
+        return UriBuilder.fromUri(getAbsolutePath());
+    }
+
+    @Override
+    public URI getBaseUri() {
+        return URI.create("");
+    }
+
+    @Override
+    public UriBuilder getBaseUriBuilder() {
+        return UriBuilder.fromUri(getBaseUri());
+    }
+
+    @Override
+    public MultivaluedMap<String, String> getPathParameters() {
+        return new MultivaluedHashMap<>();
+    }
+
+    @Override
+    public MultivaluedMap<String, String> getPathParameters(boolean decode) {
+        return getPathParameters();
+    }
+
+    @Override
+    public MultivaluedMap<String, String> getQueryParameters() {
+        return queryParams;
+    }
+
+    @Override
+    public MultivaluedMap<String, String> getQueryParameters(boolean decode) {
+        return getQueryParameters();
+    }
+
+    @Override
+    public List<String> getMatchedURIs() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public List<String> getMatchedURIs(boolean decode) {
+        return getMatchedURIs();
+    }
+
+    @Override
+    public List<Object> getMatchedResources() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public URI resolve(URI uri) {
+        return uri;
+    }
+
+    @Override
+    public URI relativize(URI uri) {
+        return uri;
+    }
+}
index 178166a6cda778ee6fa2c8fa425ef5789207790c..3b5ef86b374dfe12efc6a135ac62ca303e5c83f5 100644 (file)
@@ -14,16 +14,9 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
-import java.net.URI;
 import java.nio.charset.StandardCharsets;
-import java.util.Collections;
 import java.util.List;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.PathSegment;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.core.UriInfo;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
 import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
@@ -32,6 +25,7 @@ import org.opendaylight.restconf.common.context.NormalizedNodeContext;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfError;
 import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
+import org.opendaylight.restconf.common.util.SimpleUriInfo;
 import org.opendaylight.yangtools.yang.common.OperationFailedException;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
@@ -43,7 +37,7 @@ import org.slf4j.LoggerFactory;
  * Implementation of the JSONRestconfService interface using the restconf Draft02 implementation.
  *
  * @author Thomas Pantelis
- * @deprecated Replaced by {JSONRestconfServiceDraft18 from restconf-nb-rfc8040
+ * @deprecated Replaced by {JSONRestconfServiceRfc8040Impl from restconf-nb-rfc8040
  */
 @Deprecated
 public class JSONRestconfServiceImpl implements JSONRestconfService, AutoCloseable {
@@ -237,113 +231,4 @@ public class JSONRestconfServiceImpl implements JSONRestconfService, AutoCloseab
             }
         }
     }
-
-    private static class SimpleUriInfo implements UriInfo {
-        private final String path;
-        private final MultivaluedMap<String, String> queryParams;
-
-        SimpleUriInfo(final String path) {
-            this(path, new MultivaluedHashMap<>());
-        }
-
-        SimpleUriInfo(final String path, final MultivaluedMap<String, String> queryParams) {
-            this.path = path;
-            this.queryParams = queryParams;
-        }
-
-        @Override
-        public String getPath() {
-            return path;
-        }
-
-        @Override
-        public String getPath(final boolean decode) {
-            return path;
-        }
-
-        @Override
-        public List<PathSegment> getPathSegments() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public List<PathSegment> getPathSegments(final boolean decode) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public URI getRequestUri() {
-            return URI.create(path);
-        }
-
-        @Override
-        public UriBuilder getRequestUriBuilder() {
-            return UriBuilder.fromUri(getRequestUri());
-        }
-
-        @Override
-        public URI getAbsolutePath() {
-            return getRequestUri();
-        }
-
-        @Override
-        public UriBuilder getAbsolutePathBuilder() {
-            return UriBuilder.fromUri(getAbsolutePath());
-        }
-
-        @Override
-        public URI getBaseUri() {
-            return URI.create("");
-        }
-
-        @Override
-        public UriBuilder getBaseUriBuilder() {
-            return UriBuilder.fromUri(getBaseUri());
-        }
-
-        @Override
-        public MultivaluedMap<String, String> getPathParameters() {
-            return new MultivaluedHashMap<>();
-        }
-
-        @Override
-        public MultivaluedMap<String, String> getPathParameters(final boolean decode) {
-            return getPathParameters();
-        }
-
-        @Override
-        public MultivaluedMap<String, String> getQueryParameters() {
-            return queryParams;
-        }
-
-        @Override
-        public MultivaluedMap<String, String> getQueryParameters(final boolean decode) {
-            return getQueryParameters();
-        }
-
-        @Override
-        public List<String> getMatchedURIs() {
-            return Collections.emptyList();
-        }
-
-        @Override
-        public List<String> getMatchedURIs(final boolean decode) {
-            return getMatchedURIs();
-        }
-
-        @Override
-        public List<Object> getMatchedResources() {
-            return Collections.emptyList();
-        }
-
-        @Override
-        public URI resolve(final URI uri) {
-            return uri;
-        }
-
-        @Override
-        public URI relativize(final URI uri) {
-            return uri;
-        }
-    }
 }
index 5ba852a5c47ece8f61c5c9a88221cbb52fc1971d..baad47fcbe41251690ee005286c649c140e6c6e4 100644 (file)
@@ -14,24 +14,20 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
-import java.net.URI;
 import java.nio.charset.StandardCharsets;
-import java.util.Collections;
 import java.util.List;
 import javax.annotation.Nullable;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedHashMap;
 import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.PathSegment;
 import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.core.UriInfo;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
 import org.opendaylight.restconf.common.context.NormalizedNodeContext;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfError;
 import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
+import org.opendaylight.restconf.common.util.MultivaluedHashMap;
+import org.opendaylight.restconf.common.util.SimpleUriInfo;
 import org.opendaylight.restconf.nb.rfc8040.handlers.DOMMountPointServiceHandler;
 import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
 import org.opendaylight.restconf.nb.rfc8040.jersey.providers.JsonNormalizedNodeBodyReader;
@@ -254,113 +250,4 @@ public class JSONRestconfServiceRfc8040Impl implements JSONRestconfService, Auto
                 return ErrorType.APPLICATION;
         }
     }
-
-    private static class SimpleUriInfo implements UriInfo {
-        private final String path;
-        private final MultivaluedMap<String, String> queryParams;
-
-        SimpleUriInfo(final String path) {
-            this(path, new MultivaluedHashMap<>());
-        }
-
-        SimpleUriInfo(final String path, final MultivaluedMap<String, String> queryParams) {
-            this.path = path;
-            this.queryParams = queryParams;
-        }
-
-        @Override
-        public String getPath() {
-            return path;
-        }
-
-        @Override
-        public String getPath(final boolean decode) {
-            return path;
-        }
-
-        @Override
-        public List<PathSegment> getPathSegments() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public List<PathSegment> getPathSegments(final boolean decode) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public URI getRequestUri() {
-            return URI.create(path);
-        }
-
-        @Override
-        public UriBuilder getRequestUriBuilder() {
-            return UriBuilder.fromUri(getRequestUri());
-        }
-
-        @Override
-        public URI getAbsolutePath() {
-            return getRequestUri();
-        }
-
-        @Override
-        public UriBuilder getAbsolutePathBuilder() {
-            return UriBuilder.fromUri(getAbsolutePath());
-        }
-
-        @Override
-        public URI getBaseUri() {
-            return URI.create("");
-        }
-
-        @Override
-        public UriBuilder getBaseUriBuilder() {
-            return UriBuilder.fromUri(getBaseUri());
-        }
-
-        @Override
-        public MultivaluedMap<String, String> getPathParameters() {
-            return new MultivaluedHashMap<>();
-        }
-
-        @Override
-        public MultivaluedMap<String, String> getPathParameters(final boolean decode) {
-            return getPathParameters();
-        }
-
-        @Override
-        public MultivaluedMap<String, String> getQueryParameters() {
-            return queryParams;
-        }
-
-        @Override
-        public MultivaluedMap<String, String> getQueryParameters(final boolean decode) {
-            return getQueryParameters();
-        }
-
-        @Override
-        public List<String> getMatchedURIs() {
-            return Collections.emptyList();
-        }
-
-        @Override
-        public List<String> getMatchedURIs(final boolean decode) {
-            return getMatchedURIs();
-        }
-
-        @Override
-        public List<Object> getMatchedResources() {
-            return Collections.emptyList();
-        }
-
-        @Override
-        public URI resolve(final URI uri) {
-            return uri;
-        }
-
-        @Override
-        public URI relativize(final URI uri) {
-            return uri;
-        }
-    }
 }