Skip to content

Commit

Permalink
GH-82 TransportContext: merge and key iterator (#85)
Browse files Browse the repository at this point in the history
* GH-82 TransportContext: merge and key iterator
  • Loading branch information
szysas authored Aug 13, 2024
1 parent ef8b0e2 commit f4adb67
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 22 deletions.
5 changes: 5 additions & 0 deletions coap-core/src/main/java/com/mbed/coap/packet/CoapRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,11 @@ public <T> Builder addContext(TransportContext.Key<T> key, T value) {
return this;
}

public <T> Builder addContext(TransportContext context) {
transContext = transContext.with(context);
return this;
}

public Builder address(InetSocketAddress address) {
this.peerAddress = address;
return this;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 java-coap contributors (https://github.com/open-coap/java-coap)
* Copyright (C) 2022-2024 java-coap contributors (https://github.com/open-coap/java-coap)
* SPDX-License-Identifier: Apache-2.0
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,7 +17,9 @@

import static java.util.Objects.requireNonNull;
import java.time.Duration;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

public final class TransportContext {

Expand Down Expand Up @@ -66,6 +68,17 @@ public <T> TransportContext with(Key<T> key, T value) {
return new TransportContext(requireNonNull(key), requireNonNull(value), this);
}

public TransportContext with(TransportContext otherCtx) {
if (otherCtx.equals(EMPTY)) {
return this;
}
TransportContext mergedContext = this.with(otherCtx.key, otherCtx.value);
if (otherCtx.next == null) {
return mergedContext;
}
return mergedContext.with(otherCtx.next);
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand All @@ -83,28 +96,24 @@ public int hashCode() {
return Objects.hash(key, value, next);
}

public Set<Key<?>> keys() {
Set<Key<?>> keys = new HashSet<>();
addKey(keys);
return keys;
}

private void addKey(Set<Key<?>> keys) {
keys.add(key);
if (next != null) {
next.addKey(keys);
}
}

public static final class Key<T> {
private final T defaultValue;

public Key(T defaultValue) {
this.defaultValue = defaultValue;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Key<?> key = (Key<?>) o;
return Objects.equals(defaultValue, key.defaultValue);
}

@Override
public int hashCode() {
return Objects.hash(defaultValue);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import static com.mbed.coap.packet.MediaTypes.CT_APPLICATION_JSON;
import static com.mbed.coap.packet.Opaque.EMPTY;
import static com.mbed.coap.packet.Opaque.decodeHex;
import static com.mbed.coap.transport.TransportContext.NON_CONFIRMABLE;
import static com.mbed.coap.transport.TransportContext.RESPONSE_TIMEOUT;
import static java.time.Duration.ofSeconds;
import static org.junit.jupiter.api.Assertions.assertEquals;
Expand Down Expand Up @@ -96,11 +97,13 @@ void shouldModifyTransportContext() {

// when
CoapRequest request2 = request.modify()
.addContext(DUMMY_KEY, "test")
.addContext(NON_CONFIRMABLE, true)
.addContext(TransportContext.of(DUMMY_KEY, "test"))
.build();

// then
assertEquals("test", request2.getTransContext(DUMMY_KEY));
assertEquals(true, request2.getTransContext(NON_CONFIRMABLE));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 java-coap contributors (https://github.com/open-coap/java-coap)
* Copyright (C) 2022-2024 java-coap contributors (https://github.com/open-coap/java-coap)
* SPDX-License-Identifier: Apache-2.0
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,7 +15,10 @@
*/
package com.mbed.coap.transport;

import static com.mbed.coap.transport.TransportContext.EMPTY;
import static org.assertj.core.util.Sets.set;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import nl.jqno.equalsverifier.EqualsVerifier;
import nl.jqno.equalsverifier.Warning;
Expand All @@ -26,6 +29,7 @@ public class TransportContextTest {

private TransportContext.Key<String> DUMMY_KEY = new TransportContext.Key<>(null);
private TransportContext.Key<String> DUMMY_KEY2 = new TransportContext.Key<>("na");
private TransportContext.Key<String> DUMMY_KEY3 = new TransportContext.Key<>(null);

@Test
void test() {
Expand All @@ -38,21 +42,68 @@ void test() {
assertEquals("afds", trans.get(DUMMY_KEY2));
}

@Test
void merge() {
TransportContext ctx1 = TransportContext.of(DUMMY_KEY, "111");
TransportContext ctx2 = TransportContext.of(DUMMY_KEY2, "222");

TransportContext ctx3 = ctx1.with(ctx2);

assertEquals("111", ctx3.get(DUMMY_KEY));
assertEquals("222", ctx3.get(DUMMY_KEY2));
assertEquals(set(DUMMY_KEY, DUMMY_KEY2), ctx3.keys());
}

@Test
void mergeWithEmpty() {
TransportContext ctx1 = TransportContext.of(DUMMY_KEY, "111");

assertEquals(ctx1, ctx1.with(EMPTY));
assertEquals(ctx1, EMPTY.with(ctx1));
assertEquals(set(DUMMY_KEY), ctx1.keys());
}

@Test
void mergeAndOverWrite() {
TransportContext ctx1 = TransportContext.of(DUMMY_KEY, "111").with(DUMMY_KEY2, "222");
TransportContext ctx2 = TransportContext.of(DUMMY_KEY, "aaa").with(DUMMY_KEY3, "333");

TransportContext ctx3 = ctx1.with(ctx2);

assertEquals("aaa", ctx3.get(DUMMY_KEY));
assertEquals("222", ctx3.get(DUMMY_KEY2));
assertEquals("333", ctx3.get(DUMMY_KEY3));

assertEquals(set(DUMMY_KEY, DUMMY_KEY2, DUMMY_KEY3), ctx3.keys());
}

@Test
void empty() {
TransportContext trans = TransportContext.EMPTY;
TransportContext trans = EMPTY;
assertNull(trans.get(DUMMY_KEY));
assertEquals("default-val", trans.getOrDefault(DUMMY_KEY2, "default-val"));
assertEquals("na", trans.get(DUMMY_KEY2));

assertEquals(EMPTY, EMPTY.with(EMPTY));
}

@Test
public void equalsAndHashTest() throws Exception {
EqualsVerifier.forClass(TransportContext.class)
.suppress(Warning.NONFINAL_FIELDS)
.usingGetClass()
.withPrefabValues(TransportContext.class, TransportContext.EMPTY, TransportContext.of(TransportContext.NON_CONFIRMABLE, true))
.withPrefabValues(TransportContext.class, EMPTY, TransportContext.of(TransportContext.NON_CONFIRMABLE, true))
.verify();
}

@Test
public void equalsAndHashKeys() {
assertEquals(DUMMY_KEY, DUMMY_KEY);

assertNotEquals(DUMMY_KEY, DUMMY_KEY2);
assertNotEquals(DUMMY_KEY, DUMMY_KEY3);

assertNotEquals(new TransportContext.Key<String>(null), new TransportContext.Key<String>(null));
}

}

0 comments on commit f4adb67

Please sign in to comment.