From 136b86fefb2a79a89fa37ee4fd8eeb47e41c34ba Mon Sep 17 00:00:00 2001 From: Tom Pantelis Date: Tue, 12 Sep 2017 12:03:00 -0400 Subject: [PATCH] Add local MultivaluedHashMap implementation 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 --- .../common/util/MultivaluedHashMap.java | 188 ++++++++++++++++++ .../restconf/common/util/SimpleUriInfo.java | 130 ++++++++++++ .../impl/JSONRestconfServiceImpl.java | 119 +---------- .../impl/JSONRestconfServiceRfc8040Impl.java | 117 +---------- 4 files changed, 322 insertions(+), 232 deletions(-) create mode 100644 restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/util/MultivaluedHashMap.java create mode 100644 restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/util/SimpleUriInfo.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 index 0000000000..1036757f49 --- /dev/null +++ b/restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/util/MultivaluedHashMap.java @@ -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 implements MultivaluedMap { + private final Map> store = new HashMap<>(); + + @Override + public final void putSingle(K key, V value) { + List values = getValues(key); + + values.clear(); + if (value != null) { + values.add(value); + } + } + + @Override + public void add(K key, V value) { + List 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 values = getValues(key); + for (V value : newValues) { + if (value != null) { + values.add(value); + } + } + } + + @Override + public void addAll(K key, List valueList) { + Objects.requireNonNull(valueList, "Supplied list of values must not be null."); + + if (valueList.isEmpty()) { + return; + } + + List values = getValues(key); + for (V value : valueList) { + if (value != null) { + values.add(value); + } + } + } + + @Override + public void addFirst(K key, V value) { + List values = getValues(key); + + if (value != null) { + values.add(0, value); + } + } + + @Override + public V getFirst(K key) { + List values = store.get(key); + if (values != null && values.size() > 0) { + return values.get(0); + } else { + return null; + } + } + + @Override + public boolean equalsIgnoreValueOrder(MultivaluedMap omap) { + if (this == omap) { + return true; + } + if (!keySet().equals(omap.keySet())) { + return false; + } + for (Entry> e : entrySet()) { + List 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> values() { + return store.values(); + } + + @Override + public int size() { + return store.size(); + } + + @Override + public List remove(Object key) { + return store.remove(key); + } + + @Override + public void putAll(Map> map) { + store.putAll(map); + } + + @Override + public List put(K key, List value) { + return store.put(key, value); + } + + @Override + public Set keySet() { + return store.keySet(); + } + + @Override + public boolean isEmpty() { + return store.isEmpty(); + } + + @Override + public List get(Object key) { + return store.get(key); + } + + @Override + public Set>> 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 getValues(K key) { + List 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 index 0000000000..88da262573 --- /dev/null +++ b/restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/util/SimpleUriInfo.java @@ -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 queryParams; + + public SimpleUriInfo(String path) { + this(path, new MultivaluedHashMap<>()); + } + + public SimpleUriInfo(String path, MultivaluedMap queryParams) { + this.path = path; + this.queryParams = queryParams; + } + + @Override + public String getPath() { + return path; + } + + @Override + public String getPath(boolean decode) { + return path; + } + + @Override + public List getPathSegments() { + throw new UnsupportedOperationException(); + } + + @Override + public List 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 getPathParameters() { + return new MultivaluedHashMap<>(); + } + + @Override + public MultivaluedMap getPathParameters(boolean decode) { + return getPathParameters(); + } + + @Override + public MultivaluedMap getQueryParameters() { + return queryParams; + } + + @Override + public MultivaluedMap getQueryParameters(boolean decode) { + return getQueryParameters(); + } + + @Override + public List getMatchedURIs() { + return Collections.emptyList(); + } + + @Override + public List getMatchedURIs(boolean decode) { + return getMatchedURIs(); + } + + @Override + public List getMatchedResources() { + return Collections.emptyList(); + } + + @Override + public URI resolve(URI uri) { + return uri; + } + + @Override + public URI relativize(URI uri) { + return uri; + } +} diff --git a/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/JSONRestconfServiceImpl.java b/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/JSONRestconfServiceImpl.java index 178166a6cd..3b5ef86b37 100644 --- a/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/JSONRestconfServiceImpl.java +++ b/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/JSONRestconfServiceImpl.java @@ -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 queryParams; - - SimpleUriInfo(final String path) { - this(path, new MultivaluedHashMap<>()); - } - - SimpleUriInfo(final String path, final MultivaluedMap 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 getPathSegments() { - throw new UnsupportedOperationException(); - } - - @Override - public List 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 getPathParameters() { - return new MultivaluedHashMap<>(); - } - - @Override - public MultivaluedMap getPathParameters(final boolean decode) { - return getPathParameters(); - } - - @Override - public MultivaluedMap getQueryParameters() { - return queryParams; - } - - @Override - public MultivaluedMap getQueryParameters(final boolean decode) { - return getQueryParameters(); - } - - @Override - public List getMatchedURIs() { - return Collections.emptyList(); - } - - @Override - public List getMatchedURIs(final boolean decode) { - return getMatchedURIs(); - } - - @Override - public List getMatchedResources() { - return Collections.emptyList(); - } - - @Override - public URI resolve(final URI uri) { - return uri; - } - - @Override - public URI relativize(final URI uri) { - return uri; - } - } } diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040Impl.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040Impl.java index 5ba852a5c4..baad47fcbe 100644 --- a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040Impl.java +++ b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040Impl.java @@ -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 queryParams; - - SimpleUriInfo(final String path) { - this(path, new MultivaluedHashMap<>()); - } - - SimpleUriInfo(final String path, final MultivaluedMap 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 getPathSegments() { - throw new UnsupportedOperationException(); - } - - @Override - public List 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 getPathParameters() { - return new MultivaluedHashMap<>(); - } - - @Override - public MultivaluedMap getPathParameters(final boolean decode) { - return getPathParameters(); - } - - @Override - public MultivaluedMap getQueryParameters() { - return queryParams; - } - - @Override - public MultivaluedMap getQueryParameters(final boolean decode) { - return getQueryParameters(); - } - - @Override - public List getMatchedURIs() { - return Collections.emptyList(); - } - - @Override - public List getMatchedURIs(final boolean decode) { - return getMatchedURIs(); - } - - @Override - public List getMatchedResources() { - return Collections.emptyList(); - } - - @Override - public URI resolve(final URI uri) { - return uri; - } - - @Override - public URI relativize(final URI uri) { - return uri; - } - } } -- 2.36.6