Files
flipper/android/plugins/inspector/NodeDescriptor.java
Sara Valderrama 1c5ecce667 NodeInfo tree working (besides litho nodes)
Summary: The second tree has access to all AX NodeInfo properties (they are not in the sidebar yet). Infrastructure set up to customize displayed information bassed on what is most useful. Descriptors for views updated to include AX functionality and non-view descriptors AX functions defaulted to null/empty. Non-view nodes (like Fragments, Window, Appication) no longer included in AX tree. Corresponding nodes will be highlighted (although not expanded) on click in either tree.

Differential Revision: D8795800

fbshipit-source-id: cf2333f69bfecca3ff84aae62681c684dfa14bf3
2018-07-12 09:33:21 -07:00

166 lines
5.8 KiB
Java

/*
* 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.sonar.plugins.inspector;
import com.facebook.sonar.core.SonarArray;
import com.facebook.sonar.core.SonarConnection;
import com.facebook.sonar.core.SonarDynamic;
import com.facebook.sonar.core.SonarObject;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
/**
* A NodeDescriptor is an object which known how to expose an Object of type T to the ew Inspector.
* This class is the extension point for the Sonar inspector plugin and is how custom classes and
* data can be exposed to the inspector.
*/
public abstract class NodeDescriptor<T> {
private SonarConnection mConnection;
private DescriptorMapping mDescriptorMapping;
void setConnection(SonarConnection connection) {
mConnection = connection;
}
void setDescriptorMapping(DescriptorMapping descriptorMapping) {
mDescriptorMapping = descriptorMapping;
}
/**
* @return The descriptor for a given class. This is useful for when a descriptor wants to
* delegate parts of its implementation to another descriptor, say the super class of the
* object it describes. This is highly encouraged instead of subclassing another descriptor
* class.
*/
protected final NodeDescriptor<?> descriptorForClass(Class<?> clazz) {
return mDescriptorMapping.descriptorForClass(clazz);
}
/**
* Invalidate a node. This tells Sonar that this node is no longer valid and its properties and/or
* children have changed. This will trigger Sonar to re-query this node getting any new data.
*/
protected final void invalidate(final T node) {
if (mConnection != null) {
new ErrorReportingRunnable() {
@Override
protected void runOrThrow() throws Exception {
SonarArray array =
new SonarArray.Builder()
.put(new SonarObject.Builder().put("id", getId(node)).build())
.build();
SonarObject params = new SonarObject.Builder().put("nodes", array).build();
mConnection.send("invalidate", params);
}
}.run();
}
}
protected final boolean connected() {
return mConnection != null;
}
protected abstract class ErrorReportingRunnable
extends com.facebook.sonar.core.ErrorReportingRunnable {
public ErrorReportingRunnable() {
super(mConnection);
}
}
/**
* Initialize a node. This implementation usually consists of setting up listeners to know when to
* call {@link NodeDescriptor#invalidate(Object)}.
*/
public abstract void init(T node) throws Exception;
/**
* A globally unique ID used to identify a node in a hierarchy. If your node does not have a
* globally unique ID it is fine to rely on {@link System#identityHashCode(Object)}.
*/
public abstract String getId(T node) throws Exception;
/**
* The name used to identify this node in the inspector. Does not need to be unique. A good
* default is to use the class name of the node.
*/
public abstract String getName(T node) throws Exception;
/** Gets name for AX tree. */
public String getAXName(T node) throws Exception {
return "";
}
/** @return The number of children this node exposes in the inspector. */
public abstract int getChildCount(T node) throws Exception;
/** @return The child at index. */
public abstract Object getChildAt(T node, int index) throws Exception;
/** Gets child at index for AX tree. Ignores non-view children. */
public @Nullable Object getAXChildAt(T node, int index) throws Exception {
return null;
}
/**
* Get the data to show for this node in the sidebar of the inspector. The object will be showen
* in order and with a header matching the given name.
*/
public abstract List<Named<SonarObject>> getData(T node) throws Exception;
/** Gets data for AX tree */
public List<Named<SonarObject>> getAXData(T node) throws Exception {
return Collections.EMPTY_LIST;
}
/**
* Set a value on the provided node at the given path. The path will match a key path in the data
* provided by {@link this#getData(Object)} and the value will be of the same type as the value
* mathcing that path in the returned object.
*/
public abstract void setValue(T node, String[] path, SonarDynamic value) throws Exception;
/**
* Get the attributes for this node. This is a list of read-only string:string mapping which show
* up inline in the elements inspector. See {@link Named} for more information.
*/
public abstract List<Named<String>> getAttributes(T node) throws Exception;
/** Gets attributes for AX tree */
public List<Named<String>> getAXAttributes(T node) throws Exception {
return Collections.EMPTY_LIST;
}
/**
* Highlight this node. Use {@link HighlightedOverlay} if possible. This is used to highlight a
* node which is selected in the inspector. The plugin automatically takes care of de-selecting
* the previously highlighted node.
*/
public abstract void setHighlighted(T node, boolean selected) throws Exception;
/**
* Perform hit testing on the given node. Either continue the search in a child with {@link
* Touch#continueWithOffset(int, int, int)} or finish the hit testing on this node with {@link
* Touch#finish()}
*/
public abstract void hitTest(T node, Touch touch) throws Exception;
/**
* @return A string indicating how this element should be decorated. Check with the Sonar desktop
* app to see what values are supported.
*/
public abstract String getDecoration(T node) throws Exception;
/**
* Test this node against a given query to see if it matches. This is used for finding search
* results.
*/
public abstract boolean matches(String query, T node) throws Exception;
}