From 753c4dfc872183126dcb7a04356b85d34d4762c1 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Fri, 3 Nov 2017 12:53:34 +0100 Subject: [PATCH 1/3] Add Span#unwrap --- .../src/main/java/io/opentracing/Span.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/opentracing-api/src/main/java/io/opentracing/Span.java b/opentracing-api/src/main/java/io/opentracing/Span.java index 548ac4f8..50a78101 100644 --- a/opentracing-api/src/main/java/io/opentracing/Span.java +++ b/opentracing-api/src/main/java/io/opentracing/Span.java @@ -161,4 +161,21 @@ public interface Span { * @see Span#context() */ void finish(long finishMicros); + + /** + * Returns an object that is an instance of the given class to allow access to non-standard methods. + * + *

Using this method is highly preferred to type casts, especially because there might be a hierarchy of wrapper + * objects.

+ * + *

If the class implementing this interface is an instance of the provided class, the this + * reference is returned. Otherwise, if the receiver is a wrapper, return the the result of calling + * unwrap recursively on the wrapped object. If the receiver is not a wrapper and is not an instance of + * the provided class, then null is returned.

+ * + * @param clazz The Class that the result must be an instance of. + * @return an object that is an instance of the provided class, or null if there is no such class in + * the wrapper hierarchy. + */ + T unwrap(java.lang.Class clazz); } From 87a120ebde9a18b34629aeeeee48eeb909a9c320 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Fri, 3 Nov 2017 13:15:50 +0100 Subject: [PATCH 2/3] Add implementation and test --- .../src/main/java/io/opentracing/mock/MockSpan.java | 9 +++++++++ .../test/java/io/opentracing/mock/MockSpanTest.java | 8 ++++++++ .../src/main/java/io/opentracing/noop/NoopSpan.java | 13 +++++++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/opentracing-mock/src/main/java/io/opentracing/mock/MockSpan.java b/opentracing-mock/src/main/java/io/opentracing/mock/MockSpan.java index 859513aa..403bf705 100644 --- a/opentracing-mock/src/main/java/io/opentracing/mock/MockSpan.java +++ b/opentracing-mock/src/main/java/io/opentracing/mock/MockSpan.java @@ -115,6 +115,15 @@ public synchronized void finish(long finishMicros) { this.finished = true; } + @Override + public T unwrap(Class clazz) { + if (clazz.isInstance(this)) { + return clazz.cast(this); + } else { + return null; + } + } + @Override public MockSpan setTag(String key, String value) { return setObjectTag(key, value); diff --git a/opentracing-mock/src/test/java/io/opentracing/mock/MockSpanTest.java b/opentracing-mock/src/test/java/io/opentracing/mock/MockSpanTest.java index b488f657..f0f05118 100644 --- a/opentracing-mock/src/test/java/io/opentracing/mock/MockSpanTest.java +++ b/opentracing-mock/src/test/java/io/opentracing/mock/MockSpanTest.java @@ -17,6 +17,7 @@ import org.junit.Test; import io.opentracing.Span; +import io.opentracing.Tracer; /** * @author Pavol Loffay @@ -78,4 +79,11 @@ public void testAddBaggageAfterFinish() { } Assert.assertEquals(1, tracer.finishedSpans().get(0).generatedErrors().size()); } + + @Test + public void testUnwrap() throws Exception { + Tracer tracer = new MockTracer(); + Span span = tracer.buildSpan("foo").startManual(); + Assert.assertSame(span, span.unwrap(MockSpan.class)); + } } diff --git a/opentracing-noop/src/main/java/io/opentracing/noop/NoopSpan.java b/opentracing-noop/src/main/java/io/opentracing/noop/NoopSpan.java index 7d503066..e42e5713 100644 --- a/opentracing-noop/src/main/java/io/opentracing/noop/NoopSpan.java +++ b/opentracing-noop/src/main/java/io/opentracing/noop/NoopSpan.java @@ -13,11 +13,11 @@ */ package io.opentracing.noop; +import java.util.Map; + import io.opentracing.Span; import io.opentracing.SpanContext; -import java.util.Map; - public interface NoopSpan extends Span { static final NoopSpan INSTANCE = new NoopSpanImpl(); } @@ -33,6 +33,15 @@ public void finish() {} @Override public void finish(long finishMicros) {} + @Override + public T unwrap(Class clazz) { + if (clazz.isInstance(this)) { + return clazz.cast(this); + } else { + return null; + } + } + @Override public NoopSpan setTag(String key, String value) { return this; } From f259b891ca753c0a6689573860c5db89b872747c Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Fri, 3 Nov 2017 13:22:22 +0100 Subject: [PATCH 3/3] Improve generic signature and add another test --- opentracing-api/src/main/java/io/opentracing/Span.java | 2 +- .../src/main/java/io/opentracing/mock/MockSpan.java | 2 +- .../src/test/java/io/opentracing/mock/MockSpanTest.java | 8 ++++++++ .../src/main/java/io/opentracing/noop/NoopSpan.java | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/opentracing-api/src/main/java/io/opentracing/Span.java b/opentracing-api/src/main/java/io/opentracing/Span.java index 50a78101..f515a064 100644 --- a/opentracing-api/src/main/java/io/opentracing/Span.java +++ b/opentracing-api/src/main/java/io/opentracing/Span.java @@ -177,5 +177,5 @@ public interface Span { * @return an object that is an instance of the provided class, or null if there is no such class in * the wrapper hierarchy. */ - T unwrap(java.lang.Class clazz); + T unwrap(java.lang.Class clazz); } diff --git a/opentracing-mock/src/main/java/io/opentracing/mock/MockSpan.java b/opentracing-mock/src/main/java/io/opentracing/mock/MockSpan.java index 403bf705..ffd7f6e6 100644 --- a/opentracing-mock/src/main/java/io/opentracing/mock/MockSpan.java +++ b/opentracing-mock/src/main/java/io/opentracing/mock/MockSpan.java @@ -116,7 +116,7 @@ public synchronized void finish(long finishMicros) { } @Override - public T unwrap(Class clazz) { + public T unwrap(Class clazz) { if (clazz.isInstance(this)) { return clazz.cast(this); } else { diff --git a/opentracing-mock/src/test/java/io/opentracing/mock/MockSpanTest.java b/opentracing-mock/src/test/java/io/opentracing/mock/MockSpanTest.java index f0f05118..b258b8ac 100644 --- a/opentracing-mock/src/test/java/io/opentracing/mock/MockSpanTest.java +++ b/opentracing-mock/src/test/java/io/opentracing/mock/MockSpanTest.java @@ -18,6 +18,7 @@ import io.opentracing.Span; import io.opentracing.Tracer; +import io.opentracing.noop.NoopSpan; /** * @author Pavol Loffay @@ -86,4 +87,11 @@ public void testUnwrap() throws Exception { Span span = tracer.buildSpan("foo").startManual(); Assert.assertSame(span, span.unwrap(MockSpan.class)); } + + @Test + public void testUnwrapWrongInstance() throws Exception { + Tracer tracer = new MockTracer(); + Span span = tracer.buildSpan("foo").startManual(); + Assert.assertNull(span.unwrap(NoopSpan.class)); + } } diff --git a/opentracing-noop/src/main/java/io/opentracing/noop/NoopSpan.java b/opentracing-noop/src/main/java/io/opentracing/noop/NoopSpan.java index e42e5713..ec09dca7 100644 --- a/opentracing-noop/src/main/java/io/opentracing/noop/NoopSpan.java +++ b/opentracing-noop/src/main/java/io/opentracing/noop/NoopSpan.java @@ -34,7 +34,7 @@ public void finish() {} public void finish(long finishMicros) {} @Override - public T unwrap(Class clazz) { + public T unwrap(Class clazz) { if (clazz.isInstance(this)) { return clazz.cast(this); } else {