-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial support for mime rendering. See #2.
- Parse MIME types - Register render functions for MIME types - Displayable interface for owned classes - Render with parameters and request rendering as certain types
- Loading branch information
1 parent
aebf87e
commit ab43047
Showing
26 changed files
with
1,450 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
72 changes: 72 additions & 0 deletions
72
src/main/java/io/github/spencerpark/jupyter/kernel/display/DisplayDataRenderable.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package io.github.spencerpark.jupyter.kernel.display; | ||
|
||
import io.github.spencerpark.jupyter.kernel.display.mime.MIMEType; | ||
|
||
import java.util.Set; | ||
import java.util.function.BiConsumer; | ||
|
||
public interface DisplayDataRenderable { | ||
/** | ||
* Specifies a set of {@link MIMEType}s that this class may be rendered as. | ||
* <p> | ||
* NOTE: Specifying the supported render types does not prevent {@link #render(RenderContext)} | ||
* from being invoked with other types. Implementations should handle these cases gracefully | ||
* with a no-op. | ||
* <p> | ||
* When used in conjunction with {@link Renderer} this annotation provides information to the | ||
* routing algorithm. | ||
* <p> | ||
* In particular {@link Renderer#render(Object)} will request that the object | ||
* is rendered as the {@link #getPreferredRenderTypes()} types. | ||
*/ | ||
public Set<MIMEType> getSupportedRenderTypes(); | ||
|
||
/** | ||
* Species a subset of {@link #getSupportedRenderTypes()} in which this class | ||
* prefers to be rendered as. | ||
* <p> | ||
* For example a class may support rendering as {@code application/json} and | ||
* {@code application/xml} but when given a choice should only be rendered as | ||
* {@code application/json}. In this case {@code getPreferredRenderTypes()} should | ||
* be {@code "application/json"}. | ||
* | ||
* @return a set of {@link MIMEType}s that this class | ||
* prefers to be rendered as. | ||
*/ | ||
public default Set<MIMEType> getPreferredRenderTypes() { | ||
return this.getSupportedRenderTypes(); | ||
} | ||
|
||
/** | ||
* Render this object into the {@link RenderContext#getOutputContainer()} based on the requested types | ||
* from the {@code context}. Implementations may also use the {@code context} | ||
* to delegate rendering. | ||
* <p> | ||
* Implementations should test if the {@link RenderContext#wantsDataRenderedAs(MIMEType)} | ||
* for all of the supported types and if true store the rendered data in the container | ||
* <strong>at the resolved MIME type, not the supported one.</strong> Use the type returned | ||
* by {@link RenderContext#resolveRequestedType(MIMEType)}. | ||
* <p> | ||
* For convenience implementations may use {@link RenderContext#renderIfRequested(MIMEType, BiConsumer)} | ||
* which streamlines these operations: | ||
* <pre> | ||
* {@code private static MIMEType PNG = MIMEType.parse("image/png"); | ||
* private String renderAsPNG() {...} | ||
* public void render(RenderContext context) { | ||
* context.renderIfRequested(PNG, (type, out) -> { | ||
* out.putData(type, this.renderAsPNG()); | ||
* }); | ||
* // or to store the return value of renderAsPNG at the correct | ||
* // type use | ||
* context.renderIfRequested(PNG, this::renderAsPNG); | ||
* // or if you need the type to make a rendering decision and then store | ||
* // the return value at the correct type | ||
* context.renderIfRequested(PNG, type -> this.renderAsPNG()); | ||
* } | ||
* } | ||
* </pre> | ||
* | ||
* @param context the context that the render is taking place in. | ||
*/ | ||
public void render(RenderContext context); | ||
} |
18 changes: 18 additions & 0 deletions
18
src/main/java/io/github/spencerpark/jupyter/kernel/display/MIMESuffixAssociation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package io.github.spencerpark.jupyter.kernel.display; | ||
|
||
import io.github.spencerpark.jupyter.kernel.display.mime.MIMEType; | ||
|
||
@FunctionalInterface | ||
public interface MIMESuffixAssociation { | ||
static final MIMESuffixAssociation NONE = s -> null; | ||
|
||
/** | ||
* Returns the delegate MIME type associated with a suffix. For example the | ||
* suffix {@code json} is associated with the {@code application/json} type. | ||
* | ||
* @param suffix the suffix to resolve | ||
* | ||
* @return the delegate {@link MIMEType} | ||
*/ | ||
MIMEType resolveSuffix(String suffix); | ||
} |
116 changes: 116 additions & 0 deletions
116
src/main/java/io/github/spencerpark/jupyter/kernel/display/RenderContext.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package io.github.spencerpark.jupyter.kernel.display; | ||
|
||
import io.github.spencerpark.jupyter.kernel.display.mime.MIMEType; | ||
|
||
import java.util.Map; | ||
import java.util.function.BiConsumer; | ||
import java.util.function.Function; | ||
import java.util.function.Supplier; | ||
|
||
public class RenderContext { | ||
private final RenderRequestTypes requestedTypes; | ||
private final Renderer renderer; | ||
private final Map<String, Object> params; | ||
private final DisplayData out; | ||
|
||
public RenderContext(RenderRequestTypes requestedTypes, Renderer renderer, Map<String, Object> params, DisplayData out) { | ||
this.requestedTypes = requestedTypes; | ||
this.renderer = renderer; | ||
this.params = params; | ||
this.out = out; | ||
} | ||
|
||
public Renderer getRenderer() { | ||
return this.renderer; | ||
} | ||
|
||
public DisplayData getOutputContainer() { | ||
return this.out; | ||
} | ||
|
||
public Object getParameter(String key) { | ||
return this.params.get(key); | ||
} | ||
|
||
public Object getParameter(String key, Object defaultValue) { | ||
return this.params.getOrDefault(key, defaultValue); | ||
} | ||
|
||
public String getParameterAsString(String key) { | ||
Object value = this.getParameter(key); | ||
return value == null ? null : String.valueOf(value); | ||
} | ||
|
||
public String getParameterAsString(String key, String defaultValue) { | ||
String value = this.getParameterAsString(key); | ||
return value == null ? defaultValue : value; | ||
} | ||
|
||
public Integer getParameterAsInt(String key) { | ||
Object value = this.getParameter(key); | ||
return value == null | ||
? null | ||
: value instanceof Number | ||
? ((Number) value).intValue() | ||
: Integer.parseInt(String.valueOf(value)); | ||
} | ||
|
||
public Integer getParameterAsInt(String key, Integer defaultValue) { | ||
Integer value = this.getParameterAsInt(key); | ||
return value == null ? defaultValue : value; | ||
} | ||
|
||
public Double getParameterAsDouble(String key) { | ||
Object value = this.getParameter(key); | ||
return value == null | ||
? null | ||
: value instanceof Number | ||
? ((Number) value).doubleValue() | ||
: Double.parseDouble(String.valueOf(value)); | ||
} | ||
|
||
public Double getParameterAsDouble(String key, Double defaultValue) { | ||
Double value = this.getParameterAsDouble(key); | ||
return value == null ? defaultValue : value; | ||
} | ||
|
||
public Boolean getParameterAsBoolean(String key) { | ||
Object value = this.getParameter(key); | ||
return value == null | ||
? null | ||
: value instanceof Boolean | ||
? (Boolean) value | ||
: Boolean.parseBoolean(String.valueOf(value)); | ||
} | ||
|
||
public Boolean getParameterAsBoolean(String key, Boolean defaultValue) { | ||
Boolean value = this.getParameterAsBoolean(key); | ||
return value == null ? defaultValue : value; | ||
} | ||
|
||
public boolean wantsDataRenderedAs(MIMEType type) { | ||
return this.requestedTypes.resolveSupportedType(type) != null; | ||
} | ||
|
||
public MIMEType resolveRequestedType(MIMEType supported) { | ||
return this.requestedTypes.resolveSupportedType(supported); | ||
} | ||
|
||
public void renderIfRequested(MIMEType supportedType, BiConsumer<MIMEType, DisplayData> renderFunction) { | ||
MIMEType resolvedType = this.requestedTypes.resolveSupportedType(supportedType); | ||
if (resolvedType != null) | ||
renderFunction.accept(resolvedType, this.getOutputContainer()); | ||
} | ||
|
||
public void renderIfRequested(MIMEType supportedType, Function<MIMEType, Object> renderFunction) { | ||
MIMEType resolvedType = this.requestedTypes.resolveSupportedType(supportedType); | ||
if (resolvedType != null) | ||
this.getOutputContainer().putData(resolvedType, renderFunction.apply(resolvedType)); | ||
} | ||
|
||
public void renderIfRequested(MIMEType supportedType, Supplier<Object> render) { | ||
MIMEType resolvedType = this.requestedTypes.resolveSupportedType(supportedType); | ||
if (resolvedType != null) | ||
this.getOutputContainer().putData(resolvedType, render.get()); | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
src/main/java/io/github/spencerpark/jupyter/kernel/display/RenderFunction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package io.github.spencerpark.jupyter.kernel.display; | ||
|
||
@FunctionalInterface | ||
public interface RenderFunction<T> { | ||
void render(T data, RenderContext context); | ||
} |
58 changes: 58 additions & 0 deletions
58
src/main/java/io/github/spencerpark/jupyter/kernel/display/RenderParams.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package io.github.spencerpark.jupyter.kernel.display; | ||
|
||
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
|
||
/** | ||
* A utility class for inline map construction for use in the context of rendering. | ||
* | ||
* See: {@link Renderer#render(Object, Map)} and {@link Renderer#renderAs(Object, Map, String...)} | ||
* which take a parameter map. | ||
*/ | ||
public class RenderParams extends LinkedHashMap<String, Object> { | ||
//TODO use the path map from MellowD to support a getAll query or one with wildcard patterns | ||
public static class Param<T> { | ||
public final String key; | ||
public final T value; | ||
|
||
public Param(String key, T value) { | ||
this.key = key; | ||
this.value = value; | ||
} | ||
} | ||
|
||
public static <T> Param<T> param(String key, T value) { | ||
return new Param<>(key, value); | ||
} | ||
|
||
public static RenderParams paramsOf(Param... params) { | ||
RenderParams renderParams = new RenderParams(); | ||
for (Param p : params) | ||
renderParams.put(p.key, p.value); | ||
return renderParams; | ||
} | ||
|
||
public static RenderParams paramsOf(String key, Object value) { | ||
RenderParams renderParams = new RenderParams(); | ||
renderParams.put(key, value); | ||
return renderParams; | ||
} | ||
|
||
public RenderParams with(String key, Object value) { | ||
this.put(key, value); | ||
return this; | ||
} | ||
|
||
public RenderParams with(Param param) { | ||
this.put(param.key, param.value); | ||
return this; | ||
} | ||
|
||
public RenderParams and(String key, Object value) { | ||
return with(key, value); | ||
} | ||
|
||
public RenderParams and(Param param) { | ||
return with(param); | ||
} | ||
} |
Oops, something went wrong.