Skip to content

Commit

Permalink
jarek/7110: output widget captures general display method (#7161)
Browse files Browse the repository at this point in the history
* #7110: output widget captures general display method

* document general display handling of Output Widget
  • Loading branch information
jaroslawmalekcodete authored and scottdraves committed Apr 12, 2018
1 parent 4b71e20 commit 9772c4d
Show file tree
Hide file tree
Showing 9 changed files with 349 additions and 56 deletions.
14 changes: 12 additions & 2 deletions doc/groovy/OutputWidget.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@
" Thread.sleep(1000)\n",
" println(\"tick \" + i)\n",
" if (i % 5 == 3) System.err.println(\"stderr!\")\n",
" if (i % 6 == 2) out.display(HTML('any <b>MIME</b> <em>type</em>'))\n",
" if (i % 7 == 4) out.display(new Plot(initHeight:150) << new Line(y: [0,5,2,3,11]))\n",
" if (i % 6 == 2) display(HTML('any <b>MIME</b> <em>type</em>'))\n",
" if (i % 7 == 4) out.display(new Plot(initHeight:150) << new Line(y: [0,5,2,3,11])) \n",
" }});\n",
"println(\"ready set go\")\n",
"t.start()"
Expand All @@ -72,6 +72,16 @@
"println(\"some other cell\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"display(HTML('any <b>MIME</b> <em>type</em>'))\n",
"display(new Plot(initHeight:150) << new Line(y: [0,11,2,8,1])) "
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down
44 changes: 20 additions & 24 deletions kernel/base/src/main/java/com/twosigma/beakerx/Display.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,41 @@
*/
package com.twosigma.beakerx;

import com.twosigma.beakerx.kernel.KernelManager;
import com.twosigma.beakerx.kernel.comm.Comm;
import com.twosigma.beakerx.message.Message;
import com.twosigma.beakerx.mimetype.MIMEContainer;
import com.twosigma.beakerx.widget.MIMEDisplayMethodManager;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

import static com.twosigma.beakerx.evaluator.InternalVariable.getParentHeader;
import static com.twosigma.beakerx.kernel.comm.Comm.DATA;
import static com.twosigma.beakerx.kernel.comm.Comm.METADATA;
import static com.twosigma.beakerx.kernel.msg.JupyterMessages.DISPLAY_DATA;
import static java.util.Collections.singletonList;

public class Display {

private static Display instance = new Display(MIMEDisplayMethodManager.getInstance());

private MIMEDisplayMethodManager mimeDisplayMethodManager;

private Display(MIMEDisplayMethodManager mimeDisplayMethodManager) {
this.mimeDisplayMethodManager = mimeDisplayMethodManager;
}

public static void display(Object value) {
List<MIMEContainer> result = getMIMEContainers(value);
if (!result.isEmpty()) {
displayMIMEContainers(result);
}
instance.displayObject(value);
}

private static void displayMIMEContainers(List<MIMEContainer> result) {
HashMap<String, Serializable> content = new HashMap<>();
HashMap<String, Object> data = new HashMap<>();
result.forEach(x -> data.put(x.getMime().asString(), x.getData()));
content.put(DATA, data);
content.put(METADATA,new HashMap<>());
Message message = Comm.messageMessage(DISPLAY_DATA, Comm.Buffer.EMPTY, content, getParentHeader());
KernelManager.get().publish(singletonList(message));
private void displayObject(Object value) {
List<MIMEContainer> result = getNotHiddenMIMEContainers(value);
if (!result.isEmpty()) {
mimeDisplayMethodManager.display(result);
}
}

private static List<MIMEContainer> getMIMEContainers(Object value) {
private List<MIMEContainer> getNotHiddenMIMEContainers(Object value) {
List<MIMEContainer> containers = MIMEContainerFactory.createMIMEContainers(value);
return containers.stream()
.filter(x -> !x.getMime().asString().equals(MIMEContainer.MIME.HIDDEN)).collect(Collectors.toList());
}

public interface MIMEContainerDisplayMethodStrategy {
void display(List<MIMEContainer> mimeContainers);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2018 TWO SIGMA OPEN SOURCE, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.twosigma.beakerx.widget;

import com.twosigma.beakerx.Display;
import com.twosigma.beakerx.kernel.KernelManager;
import com.twosigma.beakerx.kernel.comm.Comm;
import com.twosigma.beakerx.message.Message;
import com.twosigma.beakerx.mimetype.MIMEContainer;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;

import static com.twosigma.beakerx.evaluator.InternalVariable.getParentHeader;
import static com.twosigma.beakerx.kernel.comm.Comm.DATA;
import static com.twosigma.beakerx.kernel.comm.Comm.METADATA;
import static com.twosigma.beakerx.kernel.msg.JupyterMessages.DISPLAY_DATA;
import static java.util.Collections.singletonList;

public class MIMEDisplayMethodManager {

private static MIMEDisplayMethodManager instance = new MIMEDisplayMethodManager();

private Display.MIMEContainerDisplayMethodStrategy defaultDisplayMimeMethodStrategy = new DefaultMIMEContainerDisplayMethodStrategy();
private Display.MIMEContainerDisplayMethodStrategy displayMimeMethodStrategy = defaultDisplayMimeMethodStrategy;

private MIMEDisplayMethodManager() {
}

public static MIMEDisplayMethodManager getInstance() {
return instance;
}

public void display(List<MIMEContainer> mimeContainers) {
this.displayMimeMethodStrategy.display(mimeContainers);
}

public void setDefaultDisplayMethod() {
this.displayMimeMethodStrategy = defaultDisplayMimeMethodStrategy;
}

public void defineDisplayMethod(Display.MIMEContainerDisplayMethodStrategy mimeContainerDisplayMethodStrategy) {
this.displayMimeMethodStrategy = mimeContainerDisplayMethodStrategy;
}

public static class DefaultMIMEContainerDisplayMethodStrategy implements Display.MIMEContainerDisplayMethodStrategy {
@Override
public void display(List<MIMEContainer> mimeContainers) {
HashMap<String, Serializable> content = new HashMap<>();
HashMap<String, Object> data = new HashMap<>();
mimeContainers.forEach(x -> data.put(x.getMime().asString(), x.getData()));
content.put(DATA, data);
content.put(METADATA, new HashMap<>());
Message message = Comm.messageMessage(DISPLAY_DATA, Comm.Buffer.EMPTY, content, getParentHeader());
KernelManager.get().publish(singletonList(message));
}
}
}
10 changes: 10 additions & 0 deletions kernel/base/src/main/java/com/twosigma/beakerx/widget/Output.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ public void display(MIMEContainer mimeContainer) {
display(content);
}

public void display(List<MIMEContainer> mimeContainers) {
mimeContainers.forEach(this::display);
}

public void display(Widget widget) {
widget.beforeDisplay();
HashMap<String, Serializable> content = new HashMap<>();
Expand All @@ -151,4 +155,10 @@ private void display(HashMap<String, Serializable> content) {
getComm().publish(list);
}

@Override
public void display() {
beforeDisplay();
sendDisplay();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,42 +15,62 @@
*/
package com.twosigma.beakerx.widget;

public class OutputManager {
import com.twosigma.beakerx.Display;
import com.twosigma.beakerx.mimetype.MIMEContainer;

private static Output output;
private static Output stderr;
private static Output stdout;
import java.util.List;

public final class OutputManager {

private static OutputManager instance = new OutputManager(
WidgetDisplayMethodManager.getInstance(),
MIMEDisplayMethodManager.getInstance());

private WidgetDisplayMethodManager widgetDisplayMethodManager;
private MIMEDisplayMethodManager mimeDisplayMethodManager;
private Output output;
private Output stderr;
private Output stdout;
private Widget.WidgetDisplayMethodStrategy widgetDisplayMethodStrategy = new WidgetDisplayMethodStrategy();
private Display.MIMEContainerDisplayMethodStrategy mimeContainerDisplayMethodStrategy = new MIMEContainerDisplayMethodStrategy();

private OutputManager(WidgetDisplayMethodManager widgetDisplayMethodManager, MIMEDisplayMethodManager mimeDisplayMethodManager) {
this.widgetDisplayMethodManager = widgetDisplayMethodManager;
this.mimeDisplayMethodManager = mimeDisplayMethodManager;
}

public static Output setOutput(Output out) {
output = out;
return output;
instance.output = out;
defineWidgetDisplayMethod();
return instance.output;
}

public static Output setStandardError(Output out) {
stderr = out;
return stderr;
instance.stderr = out;
return instance.stderr;
}

public static Output setStandardOutput(Output out) {
stdout = out;
return stdout;
instance.stdout = out;
defineWidgetDisplayMethod();
return instance.stdout;
}

public static void clearStderr() {
if (stderr != null) {
stderr.clearOutput();
if (instance.stderr != null) {
instance.stderr.clearOutput();
}
}

public static void clearStdout() {
if (stdout != null) {
stdout.clearOutput();
if (instance.stdout != null) {
instance.stdout.clearOutput();
}
}

public static void clearOutput() {
if (output != null) {
output.clearOutput();
if (instance.output != null) {
instance.output.clearOutput();
}
}

Expand All @@ -61,28 +81,71 @@ public static void clear() {
}

public static boolean sendStdout(String s) {
if (output != null || stdout != null) {
if (output != null) {
output.sendStdout(s);
if (instance.output != null || instance.stdout != null) {
if (instance.output != null) {
instance.output.sendStdout(s);
}
if (stdout != null) {
stdout.sendStdout(s);
if (instance.stdout != null) {
instance.stdout.sendStdout(s);
}
return true;
}
return false;
}

public static boolean sendStderr(String s) {
if (output != null || stderr != null) {
if (output != null) {
output.sendStderr(s);
if (instance.output != null || instance.stderr != null) {
if (instance.output != null) {
instance.output.sendStderr(s);
}
if (stderr != null) {
stderr.sendStderr(s);
if (instance.stderr != null) {
instance.stderr.sendStderr(s);
}
return true;
}
return false;
}

private static void defineWidgetDisplayMethod() {
Output outputWidget = getOutput();
if (outputWidget == null) {
instance.widgetDisplayMethodManager.setDefaultDisplayMethod();
instance.mimeDisplayMethodManager.setDefaultDisplayMethod();
} else {
instance.widgetDisplayMethodManager.defineDisplayMethod(instance.widgetDisplayMethodStrategy);
instance.mimeDisplayMethodManager.defineDisplayMethod(instance.mimeContainerDisplayMethodStrategy);
}
}

private static Output getOutput() {
if (instance.output != null) {
return instance.output;
}
if (instance.stdout != null) {
return instance.stdout;
}
return null;
}

static void changeWidgetDisplayMethodStrategy(Widget.WidgetDisplayMethodStrategy displayMethodStrategy) {
instance.widgetDisplayMethodManager.defineDisplayMethod(displayMethodStrategy);
}

static void changeMIMEDisplayMethodStrategy(Display.MIMEContainerDisplayMethodStrategy displayMethodStrategy) {
instance.mimeDisplayMethodManager.defineDisplayMethod(displayMethodStrategy);
}

static class WidgetDisplayMethodStrategy implements Widget.WidgetDisplayMethodStrategy {
@Override
public void display(Widget widget) {
getOutput().display(widget);
}
}

static class MIMEContainerDisplayMethodStrategy implements Display.MIMEContainerDisplayMethodStrategy {
@Override
public void display(List<MIMEContainer> mimeContainers) {
getOutput().display(mimeContainers);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,18 @@ public abstract class Widget implements CommFunctionality, DisplayableWidget {
public static final String INDEX = "index";

private Comm comm;
private WidgetDisplayMethodManager displayMethodManager;

public Widget() {
comm = new Comm(TargetNamesEnum.JUPYTER_WIDGET);
displayMethodManager = WidgetDisplayMethodManager.getInstance();
}

protected void openComm() {
openComm(Comm.Buffer.EMPTY);
}

protected void openComm(Comm.Buffer buffer) {
private void openComm(Comm.Buffer buffer) {
comm.setData(createContent());
addValueChangeMsgCallback();
comm.open(buffer);
Expand All @@ -84,14 +86,13 @@ public void close() {

@Override
public void display() {
beforeDisplay();
sendDisplay();
displayMethodManager.display(this);
}

protected void beforeDisplay() {
}

private void sendDisplay() {
protected void sendDisplay() {
HashMap<String, Serializable> content = new HashMap<>();
HashMap<String, Serializable> data = new HashMap<>();
//These magic numbers needs to be clarified
Expand Down Expand Up @@ -170,4 +171,8 @@ public void activateWidgetInContainer() {
// should be removed when our widgets will be rewritten to ipywidget style
}

public interface WidgetDisplayMethodStrategy {
void display(Widget widget);
}

}
Loading

0 comments on commit 9772c4d

Please sign in to comment.