Skip to content
This repository was archived by the owner on Dec 4, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libraries/bot-dialogs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
<dependency>
<groupId>com.microsoft.bot</groupId>
<artifactId>bot-builder</artifactId>
<version>4.6.0-preview8</version>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.microsoft.bot</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.microsoft.bot.builder.BotTelemetryClient;
import com.microsoft.bot.builder.NullBotTelemetryClient;
import com.microsoft.bot.builder.StatePropertyAccessor;
import com.microsoft.bot.builder.TurnContext;
import java.util.concurrent.CompletableFuture;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -15,11 +16,13 @@
* Base class for all dialogs.
*/
public abstract class Dialog {

/**
* A {@link DialogTurnResult} that indicates that the current dialog is
* still active and waiting for input from the user next turn.
* A {@link DialogTurnResult} that indicates that the current dialog is still active and waiting
* for input from the user next turn.
*/
public static final DialogTurnResult END_OF_TURN = new DialogTurnResult(DialogTurnStatus.WAITING);
public static final DialogTurnResult END_OF_TURN = new DialogTurnResult(
DialogTurnStatus.WAITING);

@JsonIgnore
private BotTelemetryClient telemetryClient;
Expand All @@ -29,6 +32,7 @@ public abstract class Dialog {

/**
* Initializes a new instance of the Dialog class.
*
* @param dialogId The ID to assign to this dialog.
*/
public Dialog(String dialogId) {
Expand All @@ -38,6 +42,7 @@ public Dialog(String dialogId) {

/**
* Gets id for the dialog.
*
* @return Id for the dialog.
*/
public String getId() {
Expand All @@ -49,6 +54,7 @@ public String getId() {

/**
* Sets id for the dialog.
*
* @param withId Id for the dialog.
*/
public void setId(String withId) {
Expand All @@ -57,6 +63,7 @@ public void setId(String withId) {

/**
* Gets the {@link BotTelemetryClient} to use for logging.
*
* @return The BotTelemetryClient to use for logging.
*/
public BotTelemetryClient getTelemetryClient() {
Expand All @@ -65,6 +72,7 @@ public BotTelemetryClient getTelemetryClient() {

/**
* Sets the {@link BotTelemetryClient} to use for logging.
*
* @param withTelemetryClient The BotTelemetryClient to use for logging.
*/
public void setTelemetryClient(BotTelemetryClient withTelemetryClient) {
Expand All @@ -74,10 +82,9 @@ public void setTelemetryClient(BotTelemetryClient withTelemetryClient) {
/**
* Called when the dialog is started and pushed onto the dialog stack.
*
* @param dc The {@link DialogContext} for the current turn of
* conversation.
* @return If the task is successful, the result indicates whether the dialog is still
* active after the turn has been processed by the dialog.
* @param dc The {@link DialogContext} for the current turn of conversation.
* @return If the task is successful, the result indicates whether the dialog is still active
* after the turn has been processed by the dialog.
*/
public CompletableFuture<DialogTurnResult> beginDialog(DialogContext dc) {
return beginDialog(dc, null);
Expand All @@ -86,25 +93,25 @@ public CompletableFuture<DialogTurnResult> beginDialog(DialogContext dc) {
/**
* Called when the dialog is started and pushed onto the dialog stack.
*
* @param dc The {@link DialogContext} for the current turn of
* conversation.
* @param dc The {@link DialogContext} for the current turn of conversation.
* @param options Initial information to pass to the dialog.
* @return If the task is successful, the result indicates whether the dialog is still
* active after the turn has been processed by the dialog.
* @return If the task is successful, the result indicates whether the dialog is still active
* after the turn has been processed by the dialog.
*/
public abstract CompletableFuture<DialogTurnResult> beginDialog(DialogContext dc, Object options);
public abstract CompletableFuture<DialogTurnResult> beginDialog(
DialogContext dc, Object options
);

/**
* Called when the dialog is _continued_, where it is the active dialog and the
* user replies with a new activity.
* Called when the dialog is _continued_, where it is the active dialog and the user replies
* with a new activity.
*
* <p>If this method is *not* overridden, the dialog automatically ends when the user replies.</p>
* <p>If this method is *not* overridden, the dialog automatically ends when the user
* replies.</p>
*
* @param dc The {@link DialogContext} for the current turn of
* conversation.
* @return If the task is successful, the result indicates whether the dialog is still
* active after the turn has been processed by the dialog. The result may also contain a
* return value.
* @param dc The {@link DialogContext} for the current turn of conversation.
* @return If the task is successful, the result indicates whether the dialog is still active
* after the turn has been processed by the dialog. The result may also contain a return value.
*/
public CompletableFuture<DialogTurnResult> continueDialog(DialogContext dc) {
// By default just end the current dialog.
Expand All @@ -115,16 +122,17 @@ public CompletableFuture<DialogTurnResult> continueDialog(DialogContext dc) {
* Called when a child dialog completed this turn, returning control to this dialog.
*
* <p>Generally, the child dialog was started with a call to
* {@link #beginDialog(DialogContext, Object)} However, if the
* {@link DialogContext#replaceDialog(String)} method
* is called, the logical child dialog may be different than the original.</p>
* {@link #beginDialog(DialogContext, Object)} However, if the {@link
* DialogContext#replaceDialog(String)} method is called, the logical child dialog may be
* different than the original.</p>
*
* <p>If this method is *not* overridden, the dialog automatically ends when the user replies.</p>
* <p>If this method is *not* overridden, the dialog automatically ends when the user
* replies.</p>
*
* @param dc The dialog context for the current turn of the conversation.
* @param dc The dialog context for the current turn of the conversation.
* @param reason Reason why the dialog resumed.
* @return If the task is successful, the result indicates whether this dialog is still
* active after this dialog turn has been processed.
* @return If the task is successful, the result indicates whether this dialog is still active
* after this dialog turn has been processed.
*/
public CompletableFuture<DialogTurnResult> resumeDialog(DialogContext dc, DialogReason reason) {
return resumeDialog(dc, reason, null);
Expand All @@ -134,51 +142,63 @@ public CompletableFuture<DialogTurnResult> resumeDialog(DialogContext dc, Dialog
* Called when a child dialog completed this turn, returning control to this dialog.
*
* <p>Generally, the child dialog was started with a call to
* {@link #beginDialog(DialogContext, Object)} However, if the
* {@link DialogContext#replaceDialog(String, Object)} method
* is called, the logical child dialog may be different than the original.</p>
* {@link #beginDialog(DialogContext, Object)} However, if the {@link
* DialogContext#replaceDialog(String, Object)} method is called, the logical child dialog may
* be different than the original.</p>
*
* <p>If this method is *not* overridden, the dialog automatically ends when the user replies.</p>
* <p>If this method is *not* overridden, the dialog automatically ends when the user
* replies.</p>
*
* @param dc The dialog context for the current turn of the conversation.
* @param dc The dialog context for the current turn of the conversation.
* @param reason Reason why the dialog resumed.
* @param result Optional, value returned from the dialog that was called. The type of the
* value returned is dependent on the child dialog.
* @return If the task is successful, the result indicates whether this dialog is still
* active after this dialog turn has been processed.
* @param result Optional, value returned from the dialog that was called. The type of the value
* returned is dependent on the child dialog.
* @return If the task is successful, the result indicates whether this dialog is still active
* after this dialog turn has been processed.
*/
public CompletableFuture<DialogTurnResult> resumeDialog(DialogContext dc, DialogReason reason, Object result) {
public CompletableFuture<DialogTurnResult> resumeDialog(
DialogContext dc, DialogReason reason, Object result
) {
// By default just end the current dialog and return result to parent.
return dc.endDialog(result);
}

/**
* Called when the dialog should re-prompt the user for input.
*
* @param turnContext The context object for this turn.
* @param instance State information for this dialog.
* @param instance State information for this dialog.
* @return A CompletableFuture representing the asynchronous operation.
*/
public CompletableFuture<Void> repromptDialog(TurnContext turnContext, DialogInstance instance) {
public CompletableFuture<Void> repromptDialog(
TurnContext turnContext, DialogInstance instance
) {
// No-op by default
return CompletableFuture.completedFuture(null);
}

/**
* Called when the dialog is ending.
*
* @param turnContext The context object for this turn.
* @param instance State information associated with the instance of this dialog on the dialog stack.
* @param reason Reason why the dialog ended.
* @param instance State information associated with the instance of this dialog on the
* dialog stack.
* @param reason Reason why the dialog ended.
* @return A CompletableFuture representing the asynchronous operation.
*/
public CompletableFuture<Void> endDialog(TurnContext turnContext, DialogInstance instance, DialogReason reason) {
public CompletableFuture<Void> endDialog(
TurnContext turnContext, DialogInstance instance, DialogReason reason
) {
// No-op by default
return CompletableFuture.completedFuture(null);
}

/**
* Gets a unique String which represents the version of this dialog. If the version changes
* between turns the dialog system will emit a DialogChanged event.
* @return Unique String which should only change when dialog has changed in a way that should restart the dialog.
*
* @return Unique String which should only change when dialog has changed in a way that should
* restart the dialog.
*/
@JsonIgnore
public String getVersion() {
Expand All @@ -188,8 +208,9 @@ public String getVersion() {
/**
* Called when an event has been raised, using `DialogContext.emitEvent()`, by either the
* current dialog or a dialog that the current dialog started.
*
* @param dc The dialog context for the current turn of conversation.
* @param e The event being raised.
* @param e The event being raised.
* @return True if the event is handled by the current dialog and bubbling should stop.
*/
public CompletableFuture<Boolean> onDialogEvent(DialogContext dc, DialogEvent e) {
Expand Down Expand Up @@ -222,8 +243,9 @@ public CompletableFuture<Boolean> onDialogEvent(DialogContext dc, DialogEvent e)
* dialogs from performing their default processing.</p>
*
* @param dc The dialog context for the current turn of conversation.
* @param e The event being raised.
* @return Whether the event is handled by the current dialog and further processing should stop.
* @param e The event being raised.
* @return Whether the event is handled by the current dialog and further processing should
* stop.
*/
protected CompletableFuture<Boolean> onPreBubbleEvent(DialogContext dc, DialogEvent e) {
return CompletableFuture.completedFuture(false);
Expand All @@ -232,22 +254,61 @@ protected CompletableFuture<Boolean> onPreBubbleEvent(DialogContext dc, DialogEv
/**
* Called after an event was bubbled to all parents and wasn't handled.
*
* <p>This is a good place to perform default processing logic for an event. Returning `true` will
* <p>This is a good place to perform default processing logic for an event. Returning `true`
* will
* prevent any processing of the event by child dialogs.</p>
*
* @param dc The dialog context for the current turn of conversation.
* @param e The event being raised.
* @return Whether the event is handled by the current dialog and further processing should stop.
* @param e The event being raised.
* @return Whether the event is handled by the current dialog and further processing should
* stop.
*/
protected CompletableFuture<Boolean> onPostBubbleEvent(DialogContext dc, DialogEvent e) {
return CompletableFuture.completedFuture(false);
}

/**
* Computes an id for the Dialog.
*
* @return The id.
*/
protected String onComputeId() {
return this.getClass().getName();
}

/**
* Creates a dialog stack and starts a dialog, pushing it onto the stack.
*
* @param dialog The dialog to start.
* @param turnContext The context for the current turn of the conversation.
* @param accessor The StatePropertyAccessor accessor with which to manage the state of the
* dialog stack.
* @return A Task representing the asynchronous operation.
*/
public static CompletableFuture<Void> run(
Dialog dialog,
TurnContext turnContext,
StatePropertyAccessor<DialogState> accessor
) {
DialogSet dialogSet = new DialogSet(accessor);
dialogSet.add(dialog);
dialogSet.setTelemetryClient(dialog.getTelemetryClient());

return dialogSet.createContext(turnContext)
.thenCompose(dialogContext -> continueOrStart(dialogContext, dialog))
.thenApply(result -> null);
}

private static CompletableFuture<DialogTurnResult> continueOrStart(
DialogContext dialogContext, Dialog dialog
) {
return dialogContext.continueDialog()
.thenCompose(result -> {
if (result.getStatus() == DialogTurnStatus.EMPTY) {
return dialogContext.beginDialog(dialog.getId(), null);
}

return CompletableFuture.completedFuture(result);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ public CompletableFuture<DialogTurnResult> beginDialog(String dialogId, Object o
// Look up dialog
Dialog dialog = findDialog(dialogId);
if (dialog == null) {
Async.completeExceptionally(new Exception(String.format(
return Async.completeExceptionally(new Exception(String.format(
"DialogContext.beginDialog(): A dialog with an id of '%s' wasn't found."
+ " The dialog must be included in the current or parent DialogSet."
+ " For example, if subclassing a ComponentDialog you can call AddDialog()"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package com.microsoft.bot.dialogs;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -38,9 +37,9 @@ public class WaterfallDialog extends Dialog {
* @param dialogId The dialog ID.
* @param actions Optional actions to be defined by the caller.
*/
public WaterfallDialog(String dialogId, Collection<WaterfallStep> actions) {
public WaterfallDialog(String dialogId, List<WaterfallStep> actions) {
super(dialogId);
steps = actions != null ? new ArrayList<WaterfallStep>(actions) : new ArrayList<WaterfallStep>();
steps = actions != null ? actions : new ArrayList<WaterfallStep>();
}

/**
Expand Down Expand Up @@ -126,7 +125,7 @@ public CompletableFuture<DialogTurnResult> continueDialog(DialogContext dc) {
}

// Don't do anything for non-message activities.
if (dc.getContext().getActivity().getType() != ActivityTypes.MESSAGE) {
if (!dc.getContext().getActivity().isType(ActivityTypes.MESSAGE)) {
return CompletableFuture.completedFuture(END_OF_TURN);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.microsoft.bot.schema.HeroCard;
import com.microsoft.bot.schema.InputHints;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -376,6 +377,16 @@ public static List<Choice> toChoices(List<String> choices) {
return choices == null ? new ArrayList<>() : choices.stream().map(Choice::new).collect(Collectors.toList());
}

/**
* Returns a list of strings as a list of Choices.
*
* @param choices The strings to convert.
* @return A List of Choices.
*/
public static List<Choice> toChoices(String... choices) {
return toChoices(Arrays.asList(choices));
}

private static List<CardAction> extractActions(List<Choice> choices) {
if (choices == null) {
choices = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ protected CompletableFuture<PromptRecognizerResult<List<Attachment>>> onRecogniz
}

PromptRecognizerResult<List<Attachment>> result = new PromptRecognizerResult<List<Attachment>>();
if (turnContext.getActivity().getType() == ActivityTypes.MESSAGE) {
if (turnContext.getActivity().isType(ActivityTypes.MESSAGE)) {
Activity message = turnContext.getActivity();
if (message.getAttachments() != null && message.getAttachments().size() > 0) {
result.setSucceeded(true);
Expand Down
Loading