下面列出了java.util.concurrent.CompletableFuture#getNow ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public boolean isNamespaceBundleDisabled(NamespaceBundle bundle) throws Exception {
try {
// Does ZooKeeper says that the namespace is disabled?
CompletableFuture<Optional<NamespaceEphemeralData>> nsDataFuture = ownershipCache.getOwnerAsync(bundle);
if (nsDataFuture != null) {
Optional<NamespaceEphemeralData> nsData = nsDataFuture.getNow(null);
if (nsData != null && nsData.isPresent()) {
return nsData.get().isDisabled();
} else {
return false;
}
} else {
// if namespace is not owned, it is not considered disabled
return false;
}
} catch (Exception e) {
LOG.warn("Exception in getting ownership info for service unit {}: {}", bundle, e.getMessage(), e);
}
return false;
}
private void waitForLogAccordingTo(WaitFor waitFor) {
String expectedLog = waitFor.value();
if (!WaitFor.NOTHING.equals(expectedLog)) {
ExecutorService executor = Executors.newSingleThreadExecutor();
CompletableFuture<Boolean> logFound = supplyAsync(findFirstLogContaining(expectedLog), executor);
executor.shutdown();
try {
boolean termination = executor.awaitTermination(waitFor.timeoutInMillis(), TimeUnit.MILLISECONDS);
if (!termination) {
throw new AssertionError("Timeout while waiting for log : \"" + expectedLog + "\"");
}
if (!logFound.getNow(false)) {
throw new AssertionError("\"" + expectedLog + "\" not found in logs and container stopped");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
@Override
protected void handleRedeliverUnacknowledged(CommandRedeliverUnacknowledgedMessages redeliver) {
checkArgument(state == State.Connected);
if (log.isDebugEnabled()) {
log.debug("[{}] Received Resend Command from consumer {} ", remoteAddress, redeliver.getConsumerId());
}
CompletableFuture<Consumer> consumerFuture = consumers.get(redeliver.getConsumerId());
if (consumerFuture != null && consumerFuture.isDone() && !consumerFuture.isCompletedExceptionally()) {
Consumer consumer = consumerFuture.getNow(null);
if (redeliver.getMessageIdsCount() > 0 && Subscription.isIndividualAckMode(consumer.subType())) {
consumer.redeliverUnacknowledgedMessages(redeliver.getMessageIdsList());
} else {
consumer.redeliverUnacknowledgedMessages();
}
}
}
@Override
protected void handleGetLastMessageId(CommandGetLastMessageId getLastMessageId) {
checkArgument(state == State.Connected);
CompletableFuture<Consumer> consumerFuture = consumers.get(getLastMessageId.getConsumerId());
if (consumerFuture != null && consumerFuture.isDone() && !consumerFuture.isCompletedExceptionally()) {
Consumer consumer = consumerFuture.getNow(null);
long requestId = getLastMessageId.getRequestId();
Topic topic = consumer.getSubscription().getTopic();
Position position = topic.getLastPosition();
int partitionIndex = TopicName.getPartitionIndex(topic.getName());
getLargestBatchIndexWhenPossible(
topic,
(PositionImpl) position,
partitionIndex,
requestId,
consumer.getSubscription().getName());
} else {
ctx.writeAndFlush(Commands.newError(getLastMessageId.getRequestId(), ServerError.MetadataError, "Consumer not found"));
}
}
@Override
protected void handleConsumerStats(CommandConsumerStats commandConsumerStats) {
if (log.isDebugEnabled()) {
log.debug("Received CommandConsumerStats call from {}", remoteAddress);
}
final long requestId = commandConsumerStats.getRequestId();
final long consumerId = commandConsumerStats.getConsumerId();
CompletableFuture<Consumer> consumerFuture = consumers.get(consumerId);
Consumer consumer = consumerFuture.getNow(null);
ByteBuf msg = null;
if (consumer == null) {
log.error(
"Failed to get consumer-stats response - Consumer not found for CommandConsumerStats[remoteAddress = {}, requestId = {}, consumerId = {}]",
remoteAddress, requestId, consumerId);
msg = Commands.newConsumerStatsResponse(ServerError.ConsumerNotFound,
"Consumer " + consumerId + " not found", requestId);
} else {
if (log.isDebugEnabled()) {
log.debug("CommandConsumerStats[requestId = {}, consumer = {}]", requestId, consumer);
}
msg = Commands.newConsumerStatsResponse(createConsumerStatsResponse(consumer, requestId));
}
ctx.writeAndFlush(msg);
}
public Set<String> getChildrenIfPresent(String path) {
CompletableFuture<Set<String>> future = childrenCache.getIfPresent(path);
if (future != null && future.isDone() && !future.isCompletedExceptionally()) {
return future.getNow(null);
} else {
return null;
}
}
/**
* Calculates the preferred locations based on the location preference constraint.
*
* @param locationPreferenceConstraint constraint for the location preference
* @return Future containing the collection of preferred locations. This might not be completed if not all inputs
* have been a resource assigned.
*/
@VisibleForTesting
public CompletableFuture<Collection<TaskManagerLocation>> calculatePreferredLocations(LocationPreferenceConstraint locationPreferenceConstraint) {
final Collection<CompletableFuture<TaskManagerLocation>> preferredLocationFutures = getVertex().getPreferredLocations();
final CompletableFuture<Collection<TaskManagerLocation>> preferredLocationsFuture;
switch(locationPreferenceConstraint) {
case ALL:
preferredLocationsFuture = FutureUtils.combineAll(preferredLocationFutures);
break;
case ANY:
final ArrayList<TaskManagerLocation> completedTaskManagerLocations = new ArrayList<>(preferredLocationFutures.size());
for (CompletableFuture<TaskManagerLocation> preferredLocationFuture : preferredLocationFutures) {
if (preferredLocationFuture.isDone() && !preferredLocationFuture.isCompletedExceptionally()) {
final TaskManagerLocation taskManagerLocation = preferredLocationFuture.getNow(null);
if (taskManagerLocation == null) {
throw new FlinkRuntimeException("TaskManagerLocationFuture was completed with null. This indicates a programming bug.");
}
completedTaskManagerLocations.add(taskManagerLocation);
}
}
preferredLocationsFuture = CompletableFuture.completedFuture(completedTaskManagerLocations);
break;
default:
throw new RuntimeException("Unknown LocationPreferenceConstraint " + locationPreferenceConstraint + '.');
}
return preferredLocationsFuture;
}
/**
* Calculates the preferred locations based on the location preference constraint.
*
* @param locationPreferenceConstraint constraint for the location preference
* @return Future containing the collection of preferred locations. This might not be completed if not all inputs
* have been a resource assigned.
*/
@VisibleForTesting
public CompletableFuture<Collection<TaskManagerLocation>> calculatePreferredLocations(LocationPreferenceConstraint locationPreferenceConstraint) {
final Collection<CompletableFuture<TaskManagerLocation>> preferredLocationFutures = getVertex().getPreferredLocations();
final CompletableFuture<Collection<TaskManagerLocation>> preferredLocationsFuture;
switch(locationPreferenceConstraint) {
case ALL:
preferredLocationsFuture = FutureUtils.combineAll(preferredLocationFutures);
break;
case ANY:
final ArrayList<TaskManagerLocation> completedTaskManagerLocations = new ArrayList<>(preferredLocationFutures.size());
for (CompletableFuture<TaskManagerLocation> preferredLocationFuture : preferredLocationFutures) {
if (preferredLocationFuture.isDone() && !preferredLocationFuture.isCompletedExceptionally()) {
final TaskManagerLocation taskManagerLocation = preferredLocationFuture.getNow(null);
if (taskManagerLocation == null) {
throw new FlinkRuntimeException("TaskManagerLocationFuture was completed with null. This indicates a programming bug.");
}
completedTaskManagerLocations.add(taskManagerLocation);
}
}
preferredLocationsFuture = CompletableFuture.completedFuture(completedTaskManagerLocations);
break;
default:
throw new RuntimeException("Unknown LocationPreferenceConstraint " + locationPreferenceConstraint + '.');
}
return preferredLocationsFuture;
}
static void assertZero(CompletableFuture<?> f) {
try {
f.getNow(null);
throw new AssertionFailedError("should throw");
} catch (CompletionException success) {
assertTrue(success.getCause() instanceof ZeroException);
}
}
@Override
protected void customizeCellRenderer(JTable table, @Nullable Object value, boolean selected, boolean hasFocus, int row, int column) {
if (value == null) return;
final DiagnosticsNode node = (DiagnosticsNode)value;
// If we should not show a separator then we should show the property name
// as part of the property value instead of in its own column.
if (!node.getShowSeparator() || !node.getShowName()) {
return;
}
// Present user defined properties in BOLD.
final SimpleTextAttributes attributes =
node.hasCreationLocation() ? SimpleTextAttributes.REGULAR_ITALIC_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES;
append(node.getName(), attributes);
// Set property description in tooltip.
// TODO (pq):
// * consider tooltips for values
// * consider rich navigation hovers (w/ styling and navigable docs)
final CompletableFuture<String> propertyDoc = node.getPropertyDoc();
final String doc = propertyDoc.getNow(null);
if (doc != null) {
setToolTipText(doc);
}
else {
// Make sure we see nothing stale while we wait.
setToolTipText(null);
node.safeWhenComplete(propertyDoc, (String tooltip, Throwable th) -> {
// TODO(jacobr): make sure we still care about seeing this tooltip.
if (th != null) {
FlutterUtils.warn(LOG, th);
}
setToolTipText(tooltip);
});
}
}
boolean isDrained() {
CompletableFuture<Boolean> tracker = this.draining.get();
try {
if (tracker != null && tracker.getNow(false)) {
return true;
}
} catch (Exception e) {
// These indicate the tracker was cancelled/timed out
}
return false;
}
public static CompletedCheckpoint takeCheckpoint(DefaultScheduler scheduler) throws Exception {
final CheckpointCoordinator checkpointCoordinator = getCheckpointCoordinator(scheduler);
checkpointCoordinator.triggerCheckpoint(false);
assertEquals("test setup inconsistent", 1, checkpointCoordinator.getNumberOfPendingCheckpoints());
final PendingCheckpoint checkpoint = checkpointCoordinator.getPendingCheckpoints().values().iterator().next();
final CompletableFuture<CompletedCheckpoint> future = checkpoint.getCompletionFuture();
acknowledgePendingCheckpoint(scheduler, checkpoint.getCheckpointId());
CompletedCheckpoint completed = future.getNow(null);
assertNotNull("checkpoint not complete", completed);
return completed;
}
/**
* If the future has failed returns the exception that caused it. Otherwise returns null.
*
* @param <T> The Type of the future's result.
* @param future The future to inspect.
* @return null or the exception that caused the Future to fail.
*/
public static <T> Throwable getException(CompletableFuture<T> future) {
try {
future.getNow(null);
return null;
} catch (Exception e) {
return Exceptions.unwrap(e);
}
}
@Test
public void testHeartbeatTimeoutWithTaskManager() throws Exception {
final CompletableFuture<ResourceID> heartbeatResourceIdFuture = new CompletableFuture<>();
final CompletableFuture<JobID> disconnectedJobManagerFuture = new CompletableFuture<>();
final UnresolvedTaskManagerLocation unresolvedTaskManagerLocation = new LocalUnresolvedTaskManagerLocation();
final TestingTaskExecutorGateway taskExecutorGateway = new TestingTaskExecutorGatewayBuilder()
.setHeartbeatJobManagerConsumer((taskManagerId, ignored) -> heartbeatResourceIdFuture.complete(taskManagerId))
.setDisconnectJobManagerConsumer((jobId, throwable) -> disconnectedJobManagerFuture.complete(jobId))
.createTestingTaskExecutorGateway();
rpcService.registerGateway(taskExecutorGateway.getAddress(), taskExecutorGateway);
final JobManagerSharedServices jobManagerSharedServices = new TestingJobManagerSharedServicesBuilder().build();
final JobMaster jobMaster = createJobMaster(
configuration,
jobGraph,
haServices,
jobManagerSharedServices);
CompletableFuture<Acknowledge> startFuture = jobMaster.start(jobMasterId);
try {
// wait for the start to complete
startFuture.get(testingTimeout.toMilliseconds(), TimeUnit.MILLISECONDS);
final JobMasterGateway jobMasterGateway = jobMaster.getSelfGateway(JobMasterGateway.class);
// register task manager will trigger monitor heartbeat target, schedule heartbeat request at interval time
CompletableFuture<RegistrationResponse> registrationResponse = jobMasterGateway.registerTaskManager(
taskExecutorGateway.getAddress(),
unresolvedTaskManagerLocation,
testingTimeout);
// wait for the completion of the registration
registrationResponse.get();
final JobID disconnectedJobManager = disconnectedJobManagerFuture.get(testingTimeout.toMilliseconds(), TimeUnit.MILLISECONDS);
assertThat(disconnectedJobManager, Matchers.equalTo(jobGraph.getJobID()));
final ResourceID heartbeatResourceId = heartbeatResourceIdFuture.getNow(null);
assertThat(heartbeatResourceId, anyOf(nullValue(), equalTo(jmResourceId)));
} finally {
jobManagerSharedServices.shutdown();
RpcUtils.terminateRpcEndpoint(jobMaster, testingTimeout);
}
}
@Test
public void testHeartbeatTimeoutWithTaskManager() throws Exception {
final CompletableFuture<ResourceID> heartbeatResourceIdFuture = new CompletableFuture<>();
final CompletableFuture<JobID> disconnectedJobManagerFuture = new CompletableFuture<>();
final TaskManagerLocation taskManagerLocation = new LocalTaskManagerLocation();
final TestingTaskExecutorGateway taskExecutorGateway = new TestingTaskExecutorGatewayBuilder()
.setHeartbeatJobManagerConsumer((taskManagerId, ignored) -> heartbeatResourceIdFuture.complete(taskManagerId))
.setDisconnectJobManagerConsumer((jobId, throwable) -> disconnectedJobManagerFuture.complete(jobId))
.createTestingTaskExecutorGateway();
rpcService.registerGateway(taskExecutorGateway.getAddress(), taskExecutorGateway);
final JobManagerSharedServices jobManagerSharedServices = new TestingJobManagerSharedServicesBuilder().build();
final JobMaster jobMaster = createJobMaster(
configuration,
jobGraph,
haServices,
jobManagerSharedServices);
CompletableFuture<Acknowledge> startFuture = jobMaster.start(jobMasterId);
try {
// wait for the start to complete
startFuture.get(testingTimeout.toMilliseconds(), TimeUnit.MILLISECONDS);
final JobMasterGateway jobMasterGateway = jobMaster.getSelfGateway(JobMasterGateway.class);
// register task manager will trigger monitor heartbeat target, schedule heartbeat request at interval time
CompletableFuture<RegistrationResponse> registrationResponse = jobMasterGateway.registerTaskManager(
taskExecutorGateway.getAddress(),
taskManagerLocation,
testingTimeout);
// wait for the completion of the registration
registrationResponse.get();
final JobID disconnectedJobManager = disconnectedJobManagerFuture.get(testingTimeout.toMilliseconds(), TimeUnit.MILLISECONDS);
assertThat(disconnectedJobManager, Matchers.equalTo(jobGraph.getJobID()));
final ResourceID heartbeatResourceId = heartbeatResourceIdFuture.getNow(null);
assertThat(heartbeatResourceId, anyOf(nullValue(), equalTo(jmResourceId)));
} finally {
jobManagerSharedServices.shutdown();
RpcUtils.terminateRpcEndpoint(jobMaster, testingTimeout);
}
}
@Override
protected void handleCloseProducer(CommandCloseProducer closeProducer) {
checkArgument(state == State.Connected);
final long producerId = closeProducer.getProducerId();
final long requestId = closeProducer.getRequestId();
CompletableFuture<Producer> producerFuture = producers.get(producerId);
if (producerFuture == null) {
log.warn("[{}] Producer {} was not registered on the connection", remoteAddress, producerId);
ctx.writeAndFlush(Commands.newError(requestId, ServerError.UnknownError,
"Producer was not registered on the connection"));
return;
}
if (!producerFuture.isDone() && producerFuture
.completeExceptionally(new IllegalStateException("Closed producer before creation was complete"))) {
// We have received a request to close the producer before it was actually completed, we have marked the
// producer future as failed and we can tell the client the close operation was successful.
log.info("[{}] Closed producer {} before its creation was completed", remoteAddress, producerId);
ctx.writeAndFlush(Commands.newSuccess(requestId));
producers.remove(producerId, producerFuture);
return;
} else if (producerFuture.isCompletedExceptionally()) {
log.info("[{}] Closed producer {} that already failed to be created", remoteAddress, producerId);
ctx.writeAndFlush(Commands.newSuccess(requestId));
producers.remove(producerId, producerFuture);
return;
}
// Proceed with normal close, the producer
Producer producer = producerFuture.getNow(null);
log.info("[{}][{}] Closing producer on cnx {}", producer.getTopic(), producer.getProducerName(), remoteAddress);
producer.close(true).thenAccept(v -> {
log.info("[{}][{}] Closed producer on cnx {}", producer.getTopic(), producer.getProducerName(),
remoteAddress);
ctx.writeAndFlush(Commands.newSuccess(requestId));
producers.remove(producerId, producerFuture);
});
}
private void calculateTooltip(MouseEvent event) {
final Point p = event.getPoint();
final int row = tree.getClosestRowForLocation(p.x, p.y);
final TreeCellRenderer r = tree.getCellRenderer();
if (r == null) {
return;
}
if (row == -1) {
clearTooltip();
return;
}
final TreePath path = tree.getPathForRow(row);
final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
lastHover = node;
final Component rComponent = r.getTreeCellRendererComponent(tree, node, tree.isRowSelected(row), tree.isExpanded(row),
tree.getModel().isLeaf(node), row, true);
final Rectangle pathBounds = tree.getPathBounds(path);
if (pathBounds == null) {
// Something went wrong and the path isn't really visible.
return;
}
p.translate(-pathBounds.x, -pathBounds.y);
if (rComponent == null) {
clearTooltip();
return;
}
String tooltip = null;
final DiagnosticsTreeCellRenderer renderer = (DiagnosticsTreeCellRenderer)rComponent;
final DiagnosticsNode diagnostic = TreeUtils.maybeGetDiagnostic(node);
if (diagnostic != null) {
if (diagnostic.hasTooltip()) {
tooltip = diagnostic.getTooltip();
}
final Icon icon = renderer.getIconAt(p.x);
if (icon != null) {
if (icon == panel.defaultIcon) {
tooltip = "default value";
}
}
else {
if (diagnostic.getShowName()) {
final int fragmentIndex = renderer.findFragmentAt(p.x);
if (fragmentIndex == 0) {
// The name fragment is being hovered over.
// Set property description in tooltip.
// TODO (pq):
// * consider tooltips for values
// * consider rich navigation hovers (w/ styling and navigable docs)
final CompletableFuture<String> propertyDoc = diagnostic.getPropertyDoc();
final String doc = propertyDoc.getNow(null);
if (doc != null) {
tooltip = doc;
}
else {
tooltip = "Loading dart docs...";
diagnostic.safeWhenComplete(propertyDoc, (String tip, Throwable th) -> {
if (th != null) {
FlutterUtils.warn(LOG, th);
}
if (lastHover == node) {
// We are still hovering of the same node so show the user the tooltip.
renderer.setToolTipText(tip);
}
});
}
}
else {
if (diagnostic.isEnumProperty()) {
// We can display a better tooltip as we have access to introspection
// via the observatory service.
diagnostic.safeWhenComplete(diagnostic.getValueProperties(), (properties, th) -> {
if (properties == null || lastHover != node) {
return;
}
renderer.setToolTipText("Allowed values:\n" + Joiner.on('\n').join(properties.keySet()));
});
}
else {
renderer.setToolTipText(diagnostic.getTooltip());
}
}
}
}
}
renderer.setToolTipText(tooltip);
}
@Override
protected void handleCloseConsumer(CommandCloseConsumer closeConsumer) {
checkArgument(state == State.Connected);
log.info("[{}] Closing consumer: {}", remoteAddress, closeConsumer.getConsumerId());
long requestId = closeConsumer.getRequestId();
long consumerId = closeConsumer.getConsumerId();
CompletableFuture<Consumer> consumerFuture = consumers.get(consumerId);
if (consumerFuture == null) {
log.warn("[{}] Consumer was not registered on the connection: {}", consumerId, remoteAddress);
ctx.writeAndFlush(Commands.newError(requestId, ServerError.MetadataError, "Consumer not found"));
return;
}
if (!consumerFuture.isDone() && consumerFuture
.completeExceptionally(new IllegalStateException("Closed consumer before creation was complete"))) {
// We have received a request to close the consumer before it was actually completed, we have marked the
// consumer future as failed and we can tell the client the close operation was successful. When the actual
// create operation will complete, the new consumer will be discarded.
log.info("[{}] Closed consumer {} before its creation was completed", remoteAddress, consumerId);
ctx.writeAndFlush(Commands.newSuccess(requestId));
return;
}
if (consumerFuture.isCompletedExceptionally()) {
log.info("[{}] Closed consumer {} that already failed to be created", remoteAddress, consumerId);
ctx.writeAndFlush(Commands.newSuccess(requestId));
return;
}
// Proceed with normal consumer close
Consumer consumer = consumerFuture.getNow(null);
try {
consumer.close();
consumers.remove(consumerId, consumerFuture);
ctx.writeAndFlush(Commands.newSuccess(requestId));
log.info("[{}] Closed consumer {}", remoteAddress, consumer);
} catch (BrokerServiceException e) {
log.warn("[{]] Error closing consumer {} : {}", remoteAddress, consumer, e);
ctx.writeAndFlush(
Commands.newError(requestId, BrokerServiceException.getClientErrorCode(e), e.getMessage()));
}
}
private void calculateTooltip(MouseEvent event) {
final Point p = event.getPoint();
final int row = tree.getClosestRowForLocation(p.x, p.y);
final TreeCellRenderer r = tree.getCellRenderer();
if (r == null) {
return;
}
if (row == -1) {
clearTooltip();
return;
}
final TreePath path = tree.getPathForRow(row);
final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
lastHover = node;
final Component rComponent = r.getTreeCellRendererComponent(tree, node, tree.isRowSelected(row), tree.isExpanded(row),
tree.getModel().isLeaf(node), row, true);
final Rectangle pathBounds = tree.getPathBounds(path);
if (pathBounds == null) {
// Something went wrong and the path isn't really visible.
return;
}
p.translate(-pathBounds.x, -pathBounds.y);
if (rComponent == null) {
clearTooltip();
return;
}
String tooltip = null;
final DiagnosticsTreeCellRenderer renderer = (DiagnosticsTreeCellRenderer)rComponent;
final DiagnosticsNode diagnostic = TreeUtils.maybeGetDiagnostic(node);
if (diagnostic != null) {
if (diagnostic.hasTooltip()) {
tooltip = diagnostic.getTooltip();
}
final Icon icon = renderer.getIconAt(p.x);
if (icon != null) {
if (icon == panel.defaultIcon) {
tooltip = "default value";
}
}
else {
if (diagnostic.getShowName()) {
final int fragmentIndex = renderer.findFragmentAt(p.x);
if (fragmentIndex == 0) {
// The name fragment is being hovered over.
// Set property description in tooltip.
// TODO (pq):
// * consider tooltips for values
// * consider rich navigation hovers (w/ styling and navigable docs)
final CompletableFuture<String> propertyDoc = diagnostic.getPropertyDoc();
final String doc = propertyDoc.getNow(null);
if (doc != null) {
tooltip = doc;
}
else {
tooltip = "Loading dart docs...";
diagnostic.safeWhenComplete(propertyDoc, (String tip, Throwable th) -> {
if (th != null) {
FlutterUtils.warn(LOG, th);
}
if (lastHover == node) {
// We are still hovering of the same node so show the user the tooltip.
renderer.setToolTipText(tip);
}
});
}
}
else {
if (diagnostic.isEnumProperty()) {
// We can display a better tooltip as we have access to introspection
// via the observatory service.
diagnostic.safeWhenComplete(diagnostic.getValueProperties(), (properties, th) -> {
if (properties == null || lastHover != node) {
return;
}
renderer.setToolTipText("Allowed values:\n" + Joiner.on('\n').join(properties.keySet()));
});
}
else {
renderer.setToolTipText(diagnostic.getTooltip());
}
}
}
}
}
renderer.setToolTipText(tooltip);
}
@Override
protected void customizeCellRenderer(JTable table, @Nullable Object value, boolean selected, boolean hasFocus, int row, int column) {
setToolTipText(null);
if (value == null) return;
final DiagnosticsNode node = (DiagnosticsNode)value;
final SimpleTextAttributes textAttributes = textAttributesForLevel(node.getLevel());
boolean appendDescription = true;
if (node.getTooltip() != null) {
setToolTipText(node.getTooltip());
}
// TODO(jacobr): also provide custom UI display for padding, transform,
// and alignment properties.
final CompletableFuture<Map<String, InstanceRef>> propertiesFuture = node.getValueProperties();
if (propertiesFuture != null && propertiesFuture.isDone() && !propertiesFuture.isCompletedExceptionally()) {
final Map<String, InstanceRef> properties = propertiesFuture.getNow(null);
if (node.isEnumProperty() && properties != null) {
// We can display a better tooltip as we have access to introspection
// via the observatory service.
setToolTipText("Allowed values:\n" + Joiner.on('\n').join(properties.keySet()));
}
final String propertyType = node.getPropertyType();
if (propertyType != null) {
switch (propertyType) {
case "Color": {
final int alpha = getIntProperty(properties, "alpha");
final int red = getIntProperty(properties, "red");
final int green = getIntProperty(properties, "green");
final int blue = getIntProperty(properties, "blue");
//noinspection UseJBColor
final Color color = new Color(red, green, blue, alpha);
this.setIcon(colorIconMaker.getCustomIcon(color));
if (alpha == 255) {
append(String.format("#%02x%02x%02x", red, green, blue), textAttributes);
}
else {
append(String.format("#%02x%02x%02x%02x", alpha, red, green, blue), textAttributes);
}
appendDescription = false;
break;
}
case "IconData": {
// IconData(U+0E88F)
final int codePoint = getIntProperty(properties, "codePoint");
if (codePoint > 0) {
final Icon icon = FlutterMaterialIcons.getIconForHex(String.format("%1$04x", codePoint));
if (icon != null) {
this.setIcon(icon);
this.setIconOpaque(false);
this.setTransparentIconBackground(true);
}
}
break;
}
}
}
}
if (appendDescription) {
append(node.getDescription(), textAttributes);
}
}