Java side of NativePlugins
Summary: Adds abstract classes NativePlugin and TableNativePlugin. Extend NativePlugin to implement a new NativePlugin type/template. TableNativePlugin is an example of that. Extend TableNativePlugin to add a particular instance of a table plugin. See the stacked diff for an example of that (newsfeed inspector). I think I'm going to change the NativePlugin implementation so it uses composition instead of inheriting from FlipperPlugin, so that the concrete subclasses don't get access to the FlipperPlugin primitive methods like onConnect etc. But I don't mind shipping this as is and changing it separately. Reviewed By: passy Differential Revision: D14505912 fbshipit-source-id: 0534147112aaf4c5a41d2d3e08de855767b2a010
This commit is contained in:
committed by
Facebook Github Bot
parent
f6f00611d5
commit
ff6988ddaf
@@ -0,0 +1,31 @@
|
||||
package com.facebook.flipper.nativeplugins;
|
||||
|
||||
import com.facebook.flipper.core.FlipperPlugin;
|
||||
|
||||
/**
|
||||
* Subclass of {@link FlipperPlugin} for mobile-defined plugins that conform to a template.
|
||||
* Implementations should call {@link #NativePlugin(String, String)} to specify which template will
|
||||
* be used. See {@link com.facebook.flipper.nativeplugins.table.TablePlugin} for an example
|
||||
* subclass.
|
||||
*/
|
||||
public abstract class NativePlugin implements FlipperPlugin {
|
||||
private final String pluginType;
|
||||
private final String id;
|
||||
|
||||
/**
|
||||
* Call super() inside subclass constructors to provide the template name and id of the concrete
|
||||
* plugin instance.
|
||||
*
|
||||
* @param pluginType This needs to correspond to a plugin template defined in Flipper.
|
||||
* @param id This will uniquely
|
||||
*/
|
||||
public NativePlugin(final String pluginType, final String id) {
|
||||
this.pluginType = pluginType;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getId() {
|
||||
return "_nativeplugin_" + pluginType + "_" + id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.facebook.flipper.nativeplugins.components;
|
||||
|
||||
import com.facebook.flipper.core.FlipperArray;
|
||||
|
||||
public class Sidebar {
|
||||
|
||||
private final FlipperArray.Builder sections = new FlipperArray.Builder();
|
||||
|
||||
public Sidebar addSection(SidebarSection section) {
|
||||
sections.put(section.serialize());
|
||||
return this;
|
||||
}
|
||||
|
||||
public FlipperArray serialize() {
|
||||
return sections.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.facebook.flipper.nativeplugins.components;
|
||||
|
||||
import com.facebook.flipper.core.FlipperObject;
|
||||
|
||||
interface SidebarSection {
|
||||
|
||||
FlipperObject serialize();
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.facebook.flipper.nativeplugins.table;
|
||||
|
||||
public class TableMetadata {
|
||||
|
||||
final TablePlugin.Column[] mColumns;
|
||||
|
||||
private TableMetadata(TablePlugin.Column[] columns) {
|
||||
if (columns == null) {
|
||||
throw new IllegalArgumentException("columns must not be null");
|
||||
}
|
||||
this.mColumns = columns;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private TablePlugin.Column[] columns;
|
||||
|
||||
public Builder columns(TablePlugin.Column... columns) {
|
||||
this.columns = columns;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TableMetadata build() {
|
||||
return new TableMetadata(columns);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2018-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the LICENSE
|
||||
* file in the root directory of this source tree.
|
||||
*
|
||||
*/
|
||||
package com.facebook.flipper.nativeplugins.table;
|
||||
|
||||
import com.facebook.flipper.core.FlipperArray;
|
||||
import com.facebook.flipper.core.FlipperConnection;
|
||||
import com.facebook.flipper.core.FlipperObject;
|
||||
import com.facebook.flipper.core.FlipperReceiver;
|
||||
import com.facebook.flipper.core.FlipperResponder;
|
||||
import com.facebook.flipper.nativeplugins.NativePlugin;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class TablePlugin extends NativePlugin {
|
||||
|
||||
public static class Column {
|
||||
public final String id;
|
||||
final String displayName;
|
||||
final String displayWidth;
|
||||
final boolean showByDefault;
|
||||
final boolean isFilterable;
|
||||
|
||||
Column(
|
||||
String id,
|
||||
String displayName,
|
||||
String displayWidth,
|
||||
boolean showByDefault,
|
||||
boolean isFilterable) {
|
||||
if (id == null) {
|
||||
throw new IllegalArgumentException("id must not be null");
|
||||
}
|
||||
if (displayName == null) {
|
||||
throw new IllegalArgumentException("displayName must not be null");
|
||||
}
|
||||
this.id = id;
|
||||
this.displayName = displayName;
|
||||
this.displayWidth = displayWidth;
|
||||
this.showByDefault = showByDefault;
|
||||
this.isFilterable = isFilterable;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final String id;
|
||||
private String displayName;
|
||||
private String displayWidth;
|
||||
private boolean showByDefault = true;
|
||||
private boolean isFilterable = false;
|
||||
|
||||
public Builder(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Builder displayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder displayWidthPx(int displayWidth) {
|
||||
this.displayWidth = Integer.toString(displayWidth);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder displayWidthPercent(int displayWidth) {
|
||||
this.displayWidth = Integer.toString(displayWidth) + "%";
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder showByDefault(boolean showByDefault) {
|
||||
this.showByDefault = showByDefault;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder isFilterable(boolean isFilterable) {
|
||||
this.isFilterable = isFilterable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Column build() {
|
||||
return new Column(id, displayName, displayWidth, showByDefault, isFilterable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FlipperConnection mConnection;
|
||||
|
||||
public TablePlugin(final String id) {
|
||||
super("Table", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onConnect(FlipperConnection connection) {
|
||||
this.mConnection = connection;
|
||||
connection.receive(
|
||||
"getMetadata",
|
||||
new FlipperReceiver() {
|
||||
@Override
|
||||
public void onReceive(FlipperObject params, FlipperResponder responder) throws Exception {
|
||||
final FlipperObject.Builder columns = new FlipperObject.Builder();
|
||||
final FlipperObject.Builder columnSizes = new FlipperObject.Builder();
|
||||
final FlipperArray.Builder columnOrder = new FlipperArray.Builder();
|
||||
final FlipperArray.Builder filterableColumns = new FlipperArray.Builder();
|
||||
for (Column c : getMetadata().mColumns) {
|
||||
columns.put(c.id, new FlipperObject.Builder().put("value", c.displayName).build());
|
||||
columnSizes.put(c.id, c.displayWidth);
|
||||
columnOrder.put(
|
||||
new FlipperObject.Builder().put("key", c.id).put("visible", c.showByDefault));
|
||||
if (c.isFilterable) {
|
||||
filterableColumns.put(c.id);
|
||||
}
|
||||
}
|
||||
|
||||
responder.success(
|
||||
new FlipperObject.Builder()
|
||||
.put("columns", columns.build())
|
||||
.put("columnSizes", columnSizes.build())
|
||||
.put("columnOrder", columnOrder.build())
|
||||
.put("filterableColumns", filterableColumns.build())
|
||||
.build());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract void onConnected();
|
||||
|
||||
protected abstract void onDisconnected();
|
||||
|
||||
protected final void updateRows(List<? extends TableRow> rows) {
|
||||
final FlipperArray.Builder array = new FlipperArray.Builder();
|
||||
for (TableRow r : rows) {
|
||||
array.put(r.serialize());
|
||||
}
|
||||
this.mConnection.send("updateRows", array.build());
|
||||
}
|
||||
|
||||
public abstract TableMetadata getMetadata();
|
||||
|
||||
public List<? extends TableRow> getRows() {
|
||||
throw new UnsupportedOperationException(
|
||||
"getRows not implemented in "
|
||||
+ getClass().getSimpleName()
|
||||
+ ". Perhaps this is a streaming plugin?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect() throws Exception {
|
||||
this.onDisconnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean runInBackground() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.facebook.flipper.nativeplugins.table;
|
||||
|
||||
import com.facebook.flipper.core.FlipperObject;
|
||||
import com.facebook.flipper.nativeplugins.components.Sidebar;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class TableRow {
|
||||
interface Value {
|
||||
FlipperObject serialize();
|
||||
}
|
||||
|
||||
public static class StringValue implements Value {
|
||||
private String val;
|
||||
|
||||
public StringValue(String s) {
|
||||
this.val = s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlipperObject serialize() {
|
||||
return new FlipperObject.Builder().put("type", "string").put("value", val).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class IntValue implements Value {
|
||||
private int val;
|
||||
|
||||
public IntValue(int i) {
|
||||
this.val = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlipperObject serialize() {
|
||||
return new FlipperObject.Builder().put("type", "int").put("value", val).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class TimeValue implements Value {
|
||||
private long millis;
|
||||
|
||||
public TimeValue(long millis) {
|
||||
this.millis = millis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlipperObject serialize() {
|
||||
return new FlipperObject.Builder().put("type", "time").put("value", millis).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class DurationValue implements Value {
|
||||
private long millis;
|
||||
|
||||
public DurationValue(long millis) {
|
||||
this.millis = millis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlipperObject serialize() {
|
||||
return new FlipperObject.Builder().put("type", "duration").put("value", millis).build();
|
||||
}
|
||||
}
|
||||
|
||||
final String id;
|
||||
final Map<TablePlugin.Column, ? extends Value> values;
|
||||
final Sidebar sidebar;
|
||||
|
||||
public TableRow(String id, Map<TablePlugin.Column, ? extends Value> values, Sidebar sidebar) {
|
||||
this.id = id;
|
||||
this.values = values;
|
||||
this.sidebar = sidebar;
|
||||
}
|
||||
|
||||
FlipperObject serialize() {
|
||||
FlipperObject.Builder columnsObject = new FlipperObject.Builder();
|
||||
for (Map.Entry<TablePlugin.Column, ? extends Value> e : values.entrySet()) {
|
||||
columnsObject.put(e.getKey().id, e.getValue().serialize());
|
||||
}
|
||||
columnsObject.put("id", id);
|
||||
return new FlipperObject.Builder()
|
||||
.put("columns", columnsObject.build())
|
||||
.put("sidebar", sidebar.serialize())
|
||||
.put("id", id)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user