77import com .fasterxml .jackson .annotation .JsonProperty ;
88import com .microsoft .bot .builder .BotTelemetryClient ;
99import com .microsoft .bot .builder .NullBotTelemetryClient ;
10+ import com .microsoft .bot .builder .StatePropertyAccessor ;
1011import com .microsoft .bot .builder .TurnContext ;
1112import java .util .concurrent .CompletableFuture ;
1213import org .apache .commons .lang3 .StringUtils ;
1516 * Base class for all dialogs.
1617 */
1718public abstract class Dialog {
19+
1820 /**
19- * A {@link DialogTurnResult} that indicates that the current dialog is
20- * still active and waiting for input from the user next turn.
21+ * A {@link DialogTurnResult} that indicates that the current dialog is still active and waiting
22+ * for input from the user next turn.
2123 */
22- public static final DialogTurnResult END_OF_TURN = new DialogTurnResult (DialogTurnStatus .WAITING );
24+ public static final DialogTurnResult END_OF_TURN = new DialogTurnResult (
25+ DialogTurnStatus .WAITING );
2326
2427 @ JsonIgnore
2528 private BotTelemetryClient telemetryClient ;
@@ -29,6 +32,7 @@ public abstract class Dialog {
2932
3033 /**
3134 * Initializes a new instance of the Dialog class.
35+ *
3236 * @param dialogId The ID to assign to this dialog.
3337 */
3438 public Dialog (String dialogId ) {
@@ -38,6 +42,7 @@ public Dialog(String dialogId) {
3842
3943 /**
4044 * Gets id for the dialog.
45+ *
4146 * @return Id for the dialog.
4247 */
4348 public String getId () {
@@ -49,6 +54,7 @@ public String getId() {
4954
5055 /**
5156 * Sets id for the dialog.
57+ *
5258 * @param withId Id for the dialog.
5359 */
5460 public void setId (String withId ) {
@@ -57,6 +63,7 @@ public void setId(String withId) {
5763
5864 /**
5965 * Gets the {@link BotTelemetryClient} to use for logging.
66+ *
6067 * @return The BotTelemetryClient to use for logging.
6168 */
6269 public BotTelemetryClient getTelemetryClient () {
@@ -65,6 +72,7 @@ public BotTelemetryClient getTelemetryClient() {
6572
6673 /**
6774 * Sets the {@link BotTelemetryClient} to use for logging.
75+ *
6876 * @param withTelemetryClient The BotTelemetryClient to use for logging.
6977 */
7078 public void setTelemetryClient (BotTelemetryClient withTelemetryClient ) {
@@ -74,10 +82,9 @@ public void setTelemetryClient(BotTelemetryClient withTelemetryClient) {
7482 /**
7583 * Called when the dialog is started and pushed onto the dialog stack.
7684 *
77- * @param dc The {@link DialogContext} for the current turn of
78- * conversation.
79- * @return If the task is successful, the result indicates whether the dialog is still
80- * active after the turn has been processed by the dialog.
85+ * @param dc The {@link DialogContext} for the current turn of conversation.
86+ * @return If the task is successful, the result indicates whether the dialog is still active
87+ * after the turn has been processed by the dialog.
8188 */
8289 public CompletableFuture <DialogTurnResult > beginDialog (DialogContext dc ) {
8390 return beginDialog (dc , null );
@@ -86,25 +93,25 @@ public CompletableFuture<DialogTurnResult> beginDialog(DialogContext dc) {
8693 /**
8794 * Called when the dialog is started and pushed onto the dialog stack.
8895 *
89- * @param dc The {@link DialogContext} for the current turn of
90- * conversation.
96+ * @param dc The {@link DialogContext} for the current turn of conversation.
9197 * @param options Initial information to pass to the dialog.
92- * @return If the task is successful, the result indicates whether the dialog is still
93- * active after the turn has been processed by the dialog.
98+ * @return If the task is successful, the result indicates whether the dialog is still active
99+ * after the turn has been processed by the dialog.
94100 */
95- public abstract CompletableFuture <DialogTurnResult > beginDialog (DialogContext dc , Object options );
101+ public abstract CompletableFuture <DialogTurnResult > beginDialog (
102+ DialogContext dc , Object options
103+ );
96104
97105 /**
98- * Called when the dialog is _continued_, where it is the active dialog and the
99- * user replies with a new activity.
106+ * Called when the dialog is _continued_, where it is the active dialog and the user replies
107+ * with a new activity.
100108 *
101- * <p>If this method is *not* overridden, the dialog automatically ends when the user replies.</p>
109+ * <p>If this method is *not* overridden, the dialog automatically ends when the user
110+ * replies.</p>
102111 *
103- * @param dc The {@link DialogContext} for the current turn of
104- * conversation.
105- * @return If the task is successful, the result indicates whether the dialog is still
106- * active after the turn has been processed by the dialog. The result may also contain a
107- * return value.
112+ * @param dc The {@link DialogContext} for the current turn of conversation.
113+ * @return If the task is successful, the result indicates whether the dialog is still active
114+ * after the turn has been processed by the dialog. The result may also contain a return value.
108115 */
109116 public CompletableFuture <DialogTurnResult > continueDialog (DialogContext dc ) {
110117 // By default just end the current dialog.
@@ -115,16 +122,17 @@ public CompletableFuture<DialogTurnResult> continueDialog(DialogContext dc) {
115122 * Called when a child dialog completed this turn, returning control to this dialog.
116123 *
117124 * <p>Generally, the child dialog was started with a call to
118- * {@link #beginDialog(DialogContext, Object)} However, if the
119- * {@link DialogContext#replaceDialog(String)} method
120- * is called, the logical child dialog may be different than the original.</p>
125+ * {@link #beginDialog(DialogContext, Object)} However, if the {@link
126+ * DialogContext#replaceDialog(String)} method is called, the logical child dialog may be
127+ * different than the original.</p>
121128 *
122- * <p>If this method is *not* overridden, the dialog automatically ends when the user replies.</p>
129+ * <p>If this method is *not* overridden, the dialog automatically ends when the user
130+ * replies.</p>
123131 *
124- * @param dc The dialog context for the current turn of the conversation.
132+ * @param dc The dialog context for the current turn of the conversation.
125133 * @param reason Reason why the dialog resumed.
126- * @return If the task is successful, the result indicates whether this dialog is still
127- * active after this dialog turn has been processed.
134+ * @return If the task is successful, the result indicates whether this dialog is still active
135+ * after this dialog turn has been processed.
128136 */
129137 public CompletableFuture <DialogTurnResult > resumeDialog (DialogContext dc , DialogReason reason ) {
130138 return resumeDialog (dc , reason , null );
@@ -134,51 +142,63 @@ public CompletableFuture<DialogTurnResult> resumeDialog(DialogContext dc, Dialog
134142 * Called when a child dialog completed this turn, returning control to this dialog.
135143 *
136144 * <p>Generally, the child dialog was started with a call to
137- * {@link #beginDialog(DialogContext, Object)} However, if the
138- * {@link DialogContext#replaceDialog(String, Object)} method
139- * is called, the logical child dialog may be different than the original.</p>
145+ * {@link #beginDialog(DialogContext, Object)} However, if the {@link
146+ * DialogContext#replaceDialog(String, Object)} method is called, the logical child dialog may
147+ * be different than the original.</p>
140148 *
141- * <p>If this method is *not* overridden, the dialog automatically ends when the user replies.</p>
149+ * <p>If this method is *not* overridden, the dialog automatically ends when the user
150+ * replies.</p>
142151 *
143- * @param dc The dialog context for the current turn of the conversation.
152+ * @param dc The dialog context for the current turn of the conversation.
144153 * @param reason Reason why the dialog resumed.
145- * @param result Optional, value returned from the dialog that was called. The type of the
146- * value returned is dependent on the child dialog.
147- * @return If the task is successful, the result indicates whether this dialog is still
148- * active after this dialog turn has been processed.
154+ * @param result Optional, value returned from the dialog that was called. The type of the value
155+ * returned is dependent on the child dialog.
156+ * @return If the task is successful, the result indicates whether this dialog is still active
157+ * after this dialog turn has been processed.
149158 */
150- public CompletableFuture <DialogTurnResult > resumeDialog (DialogContext dc , DialogReason reason , Object result ) {
159+ public CompletableFuture <DialogTurnResult > resumeDialog (
160+ DialogContext dc , DialogReason reason , Object result
161+ ) {
151162 // By default just end the current dialog and return result to parent.
152163 return dc .endDialog (result );
153164 }
154165
155166 /**
156167 * Called when the dialog should re-prompt the user for input.
168+ *
157169 * @param turnContext The context object for this turn.
158- * @param instance State information for this dialog.
170+ * @param instance State information for this dialog.
159171 * @return A CompletableFuture representing the asynchronous operation.
160172 */
161- public CompletableFuture <Void > repromptDialog (TurnContext turnContext , DialogInstance instance ) {
173+ public CompletableFuture <Void > repromptDialog (
174+ TurnContext turnContext , DialogInstance instance
175+ ) {
162176 // No-op by default
163177 return CompletableFuture .completedFuture (null );
164178 }
165179
166180 /**
167181 * Called when the dialog is ending.
182+ *
168183 * @param turnContext The context object for this turn.
169- * @param instance State information associated with the instance of this dialog on the dialog stack.
170- * @param reason Reason why the dialog ended.
184+ * @param instance State information associated with the instance of this dialog on the
185+ * dialog stack.
186+ * @param reason Reason why the dialog ended.
171187 * @return A CompletableFuture representing the asynchronous operation.
172188 */
173- public CompletableFuture <Void > endDialog (TurnContext turnContext , DialogInstance instance , DialogReason reason ) {
189+ public CompletableFuture <Void > endDialog (
190+ TurnContext turnContext , DialogInstance instance , DialogReason reason
191+ ) {
174192 // No-op by default
175193 return CompletableFuture .completedFuture (null );
176194 }
177195
178196 /**
179197 * Gets a unique String which represents the version of this dialog. If the version changes
180198 * between turns the dialog system will emit a DialogChanged event.
181- * @return Unique String which should only change when dialog has changed in a way that should restart the dialog.
199+ *
200+ * @return Unique String which should only change when dialog has changed in a way that should
201+ * restart the dialog.
182202 */
183203 @ JsonIgnore
184204 public String getVersion () {
@@ -188,8 +208,9 @@ public String getVersion() {
188208 /**
189209 * Called when an event has been raised, using `DialogContext.emitEvent()`, by either the
190210 * current dialog or a dialog that the current dialog started.
211+ *
191212 * @param dc The dialog context for the current turn of conversation.
192- * @param e The event being raised.
213+ * @param e The event being raised.
193214 * @return True if the event is handled by the current dialog and bubbling should stop.
194215 */
195216 public CompletableFuture <Boolean > onDialogEvent (DialogContext dc , DialogEvent e ) {
@@ -222,8 +243,9 @@ public CompletableFuture<Boolean> onDialogEvent(DialogContext dc, DialogEvent e)
222243 * dialogs from performing their default processing.</p>
223244 *
224245 * @param dc The dialog context for the current turn of conversation.
225- * @param e The event being raised.
226- * @return Whether the event is handled by the current dialog and further processing should stop.
246+ * @param e The event being raised.
247+ * @return Whether the event is handled by the current dialog and further processing should
248+ * stop.
227249 */
228250 protected CompletableFuture <Boolean > onPreBubbleEvent (DialogContext dc , DialogEvent e ) {
229251 return CompletableFuture .completedFuture (false );
@@ -232,22 +254,61 @@ protected CompletableFuture<Boolean> onPreBubbleEvent(DialogContext dc, DialogEv
232254 /**
233255 * Called after an event was bubbled to all parents and wasn't handled.
234256 *
235- * <p>This is a good place to perform default processing logic for an event. Returning `true` will
257+ * <p>This is a good place to perform default processing logic for an event. Returning `true`
258+ * will
236259 * prevent any processing of the event by child dialogs.</p>
237260 *
238261 * @param dc The dialog context for the current turn of conversation.
239- * @param e The event being raised.
240- * @return Whether the event is handled by the current dialog and further processing should stop.
262+ * @param e The event being raised.
263+ * @return Whether the event is handled by the current dialog and further processing should
264+ * stop.
241265 */
242266 protected CompletableFuture <Boolean > onPostBubbleEvent (DialogContext dc , DialogEvent e ) {
243267 return CompletableFuture .completedFuture (false );
244268 }
245269
246270 /**
247271 * Computes an id for the Dialog.
272+ *
248273 * @return The id.
249274 */
250275 protected String onComputeId () {
251276 return this .getClass ().getName ();
252277 }
278+
279+ /**
280+ * Creates a dialog stack and starts a dialog, pushing it onto the stack.
281+ *
282+ * @param dialog The dialog to start.
283+ * @param turnContext The context for the current turn of the conversation.
284+ * @param accessor The StatePropertyAccessor accessor with which to manage the state of the
285+ * dialog stack.
286+ * @return A Task representing the asynchronous operation.
287+ */
288+ public static CompletableFuture <Void > run (
289+ Dialog dialog ,
290+ TurnContext turnContext ,
291+ StatePropertyAccessor <DialogState > accessor
292+ ) {
293+ DialogSet dialogSet = new DialogSet (accessor );
294+ dialogSet .add (dialog );
295+ dialogSet .setTelemetryClient (dialog .getTelemetryClient ());
296+
297+ return dialogSet .createContext (turnContext )
298+ .thenCompose (dialogContext -> continueOrStart (dialogContext , dialog ))
299+ .thenApply (result -> null );
300+ }
301+
302+ private static CompletableFuture <DialogTurnResult > continueOrStart (
303+ DialogContext dialogContext , Dialog dialog
304+ ) {
305+ return dialogContext .continueDialog ()
306+ .thenCompose (result -> {
307+ if (result .getStatus () == DialogTurnStatus .EMPTY ) {
308+ return dialogContext .beginDialog (dialog .getId (), null );
309+ }
310+
311+ return CompletableFuture .completedFuture (result );
312+ });
313+ }
253314}
0 commit comments