/** * Gets a reply to an input. Assumes that the input has already had all necessary substitutions * and pre-processing performed, and that the input is a single sentence. * * @param input the input sentence * @param that the input that value * @param topic the input topic value * @param userid the userid requesting the reply * @param botid * @return the reply to the input sentence */ private static String getReply( String input, String that, String topic, String userid, String botid) { // Push the input onto the <input/> stack. PredicateMaster.push(INPUT, input, userid, botid); // Create a new TemplateParser. TemplateParser parser; try { parser = new TemplateParser(input, userid, botid); } catch (TemplateParserException e) { throw new DeveloperError(e); } String reply = null; try { reply = getMatchResult(input, that, topic, userid, botid, parser); } catch (DeveloperError e) { Log.devfail(e); Log.devfail("Exiting due to developer error.", Log.ERROR); System.exit(1); } catch (UserError e) { Log.userfail(e); Log.devfail("Exiting due to user error.", Log.ERROR); System.exit(1); } catch (RuntimeException e) { Log.devfail(e); Log.devfail("Exiting due to unforeseen runtime exception.", Log.ERROR); System.exit(1); } if (reply == null) { Log.devfail("getMatchReply generated a null reply!", Log.ERROR); System.exit(1); } // Push the reply onto the <that/> stack. PredicateMaster.push(THAT, reply, userid, botid); return Toolkit.filterWhitespace(reply); }
/** * Gets the match result from the Graphmaster. * * @param input * @param that * @param topic * @param userid * @param botid * @param parser * @param timeout whether to control the match attempt with a timeout thread */ private static String getMatchResult( String input, String that, String topic, String userid, String botid, TemplateParser parser) { // Always show the input path (in any case, if match trace is on). if (SHOW_MATCH_TRACE) { Trace.userinfo( PredicateMaster.get(Globals.getClientNamePredicate(), userid, botid) + '>' + SPACE + input + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + that + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + topic + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + botid); } // Create a case-insensitive pattern-fitted version of the input. String inputIgnoreCase = InputNormalizer.patternFitIgnoreCase(input); Match match = null; try { match = Graphmaster.match(InputNormalizer.patternFitIgnoreCase(input), that, topic, botid); } catch (NoMatchException e) { Log.userinfo(e.getMessage(), Log.CHAT); return EMPTY_STRING; } if (match == null) { Log.userinfo("No match found for input \"" + input + "\".", Log.CHAT); return EMPTY_STRING; } if (SHOW_MATCH_TRACE) { Trace.userinfo(LABEL_MATCH + match.getPath()); Trace.userinfo(LABEL_FILENAME + QUOTE_MARK + match.getFileName() + QUOTE_MARK); } ArrayList stars = match.getInputStars(); if (stars.size() > 0) { parser.setInputStars(stars); } stars = match.getThatStars(); if (stars.size() > 0) { parser.setThatStars(stars); } stars = match.getTopicStars(); if (stars.size() > 0) { parser.setTopicStars(stars); } String template = match.getTemplate(); String reply = null; try { reply = parser.processResponse(template); } catch (ProcessorException e) { // Log the error message. Log.userinfo(e.getMessage(), Log.ERROR); // Set response to empty string. return EMPTY_STRING; } // Record activation, if targeting is in use. // Needs review in light of multi-bot update if (USE_TARGETING) { Nodemapper matchNodemapper = match.getNodemapper(); if (matchNodemapper == null) { Trace.devinfo("Match nodemapper is null!"); } else { Set activations = (Set) matchNodemapper.get(Graphmaster.ACTIVATIONS); if (activations == null) { activations = new HashSet(); } String path = match.getPath() + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + inputIgnoreCase + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + that + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + topic + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + botid + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + reply; if (!activations.contains(path)) { activations.add(path); match.getNodemapper().put(Graphmaster.ACTIVATIONS, activations); Graphmaster.activatedNode(match.getNodemapper()); } } } return reply; }