Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class Main extends javax.swing.JFrame {
- private static Bot bot;
- public BlockingQueue<String> queue;
- public Main() {
- initComponents();
- //get the parser going
- DataParser dp = new DataParser();
- //make new bot with level 0 as default and given data parser
- bot = new Bot("0", dp);
- //dispaly the default message
- txtHistory.setText("Bot: " + bot.getMessage());
- }
- public Main(BlockingQueue<String>queue) {
- this.queue = queue;
- }
- // display bot response in the text area
- private static final String VOICENAME="kevin16";
- private static void addBotText(String message) {
- txtHistory.setText(txtHistory.getText() + "nBot: " + message);
- //turn the bot response to sound
- Voice voice;
- VoiceManager vm= VoiceManager.getInstance();
- voice=vm.getVoice(VOICENAME);
- voice.allocate();
- try{
- voice.speak(bot.getMessage());
- }catch(Exception e){
- }
- voice.deallocate();
- }
- public static void listen (String speech) {
- txtHistory.setText(txtHistory.getText() + "nYou: " + speech + "n");
- //send the input to the bot and get bot response
- package bot;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.HashMap;
- import javax.xml.parsers.DocumentBuilder;
- import javax.xml.parsers.DocumentBuilderFactory;
- import javax.xml.parsers.ParserConfigurationException;
- import org.w3c.dom.Document;
- import org.w3c.dom.Element;
- import org.w3c.dom.NodeList;
- import org.xml.sax.SAXException;
- public class DataParser {
- private Document dom;
- private HashMap<String, State> states = new HashMap<String, State>();
- private ArrayList<String> invalidMessages = new ArrayList();
- private int invalidMessageIndex = 0;
- public int stateCounter = 1000;
- public String fileSource;
- // default constructor
- public DataParser() {
- // Load the XML file and parse it
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- try {
- //get the filepath of source
- String fileSource = Context.getSource();
- DocumentBuilder db = dbf.newDocumentBuilder();
- //parse using builder to get DOM representation of the XML file
- dom = db.parse(fileSource);
- // Load configuration and states from the XML file
- loadConfiguration();
- loadStates();
- } catch (ParserConfigurationException pce) {
- pce.printStackTrace();
- } catch (SAXException se) {
- se.printStackTrace();
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
- // Load states from XML file
- private void loadStates() {
- // get document element object
- Element docEle = dom.getDocumentElement();
- // get all State node names
- NodeList nl = docEle.getElementsByTagName("State");
- // if node is not null and has children
- if (nl != null && nl.getLength() > 0) {
- // loop through all children
- for (int i = 0; i < nl.getLength(); i++) {
- // get state element
- Element el = (Element) nl.item(i);
- // get state id
- String id = el.getAttribute("id");
- // get all state messages
- ArrayList messages = new ArrayList();
- NodeList messagesNodeList = el.getElementsByTagName("message");
- // if messages node is not null and has children
- if (messagesNodeList != null && messagesNodeList.getLength() > 0) {
- // loop through all children
- for (int j = 0; j < messagesNodeList.getLength(); j++) {
- // get current message element
- Element elmsg = (Element) messagesNodeList.item(j);
- // append message node value to the messages list
- messages.add(elmsg.getFirstChild().getNodeValue());
- }
- }
- // get keywords in the current state
- ArrayList keywords = getKeywords(el);
- // construct a new State object
- State state = new State(id, messages, keywords);
- stateCounter ++;
- // add the state to the states hashmap
- states.put(id, state);
- }
- }
- }
- // get state object by id
- public State getState(String id) {
- return states.get(id);
- }
- // create a new state
- public void addState(State state){
- states.put(state.getId(), state);
- stateCounter++;
- }
- // get all keywords in an State tag
- public ArrayList getKeywords(Element ele) {
- // construct keywords arraylist
- ArrayList keywords = new ArrayList();
- // get all nodes by keyword tag name
- NodeList nl = ele.getElementsByTagName("keyword");
- // if the tag is not null and has children
- if (nl != null && nl.getLength() > 0) {
- // loop through all the children
- for (int i = 0; i < nl.getLength(); i++) {
- //get the keyword element
- Element el = (Element) nl.item(i);
- // find the keyword target, classname and argument attributes
- String wordTag = el.getFirstChild().getNodeValue();
- String target = el.getAttribute("target");
- String className = el.getAttribute("className");
- String arg = el.getAttribute("arg");
- String variable = el.getAttribute("variable");
- int points = 0;
- try{
- points = Integer.valueOf(el.getAttribute("points"));
- }catch (Exception e){
- }
- String learn = el.getAttribute("learn");
- // split keyword by comma
- String[] words = wordTag.split(",");
- // loop through all words
- for (String word : words) {
- // trim the word to remove spaces
- word = word.trim();
- // construct a new keyword
- Keyword keyword = new Keyword(word, target, className, arg, variable, points, learn );
- // add the keyword to keywords array list
- keywords.add(keyword);
- }
- }
- }
- // return all the keywords in the given node
- return keywords;
- }
- // returns one of the invalid messages and move the index to the next message
- public String getInvalidAnswer() {
- // get current answer
- String answer = invalidMessages.get(invalidMessageIndex);
- // increase the index, if it is end of messages, reset the index to 0
- invalidMessageIndex++;
- if (invalidMessageIndex >= invalidMessages.size()) {
- invalidMessageIndex = 0;
- }
- return answer;
- }
- // load cofig tags from data xml file
- private void loadConfiguration() {
- // get document element
- Element docEle = dom.getDocumentElement();
- // get all node names for invalid messages
- NodeList node = docEle.getElementsByTagName("InvalidMessages");
- // get all message nodes inside invalid messages node
- NodeList nl = ((Element) node.item(0)).getElementsByTagName("message");
- // if node is not null and has children
- if (nl != null && nl.getLength() > 0) {
- // loop through all children
- for (int i = 0; i < nl.getLength(); i++) {
- // get message node
- Element el = (Element) nl.item(i);
- // get message and add it to invalid messages array
- String message = el.getFirstChild().getNodeValue();
- invalidMessages.add(message);
- }
- }
- }
- }
- package bot;
- import smallTalk.Morning;
- import smallTalk.Afternoon;
- import smallTalk.Evening;
- import smallTalk.Night;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Map;
- public class Bot {
- // Store all regular expression matches
- private HashMap<String,String> dictionary;
- // Default state to start the bot
- String level = "0";
- DataParser parser;
- // default constructor
- public Bot(String level, DataParser parser) {
- dictionary = new HashMap<String,String>();
- this.level = level;
- this.parser = parser;
- }
- // get current state message
- public String getMessage() {
- State state = parser.getState(level);
- return replaceMatches(state.getMessage()).trim();
- }
- // send user message to the bot and get the response
- public String send(String message) {
- String response = "";
- State state = parser.getState(level);
- // end of the tree
- if (state.getKeywords().isEmpty()) {
- this.level = "0";
- }
- // match the keyword with given message
- Keyword match = parse(message, state.getKeywords());
- // if no keyword is matched, display one of the invalid answers
- if (match == null) {
- response = parser.getInvalidAnswer();
- } else {
- // if match classname is provided, check to get the dynamic response
- if (match.className.length() > 0) {
- // check for Weather dynamic response
- if (match.className.equals("Weather")) {
- Weather weather = new Weather();
- response = weather.getResponse(match.arg);
- this.level = "0";
- }
- // check for News dynamic response
- else if (match.className.equals("News")) {
- News news = new News();
- response = news.getResponse(match.arg);
- this.level = "0";
- }
- else if (match.className.equals("Morning")) {
- Morning morning = new Morning();
- morning.wakeup();
- }
- else if (match.className.equals("Afternoon")) {
- Afternoon afternoon = new Afternoon();
- afternoon.midday();
- }
- else if (match.className.equals("Evening")) {
- Evening evening = new Evening();
- evening.dinner();
- }
- else if (match.className.equals("Night")) {
- Night night = new Night();
- night.late();
- }
- // check for Topic dynamic response
- else if (match.className.equals("Topic")) {
- Topic topic = new Topic();
- topic.getTopic(match.arg);
- }
- } else {
- // get the new state and return the new message
- if (response.length() == 0) {
- this.level = match.target;
- state = parser.getState(level);
- // if it is end of the tree
- if (state.getKeywords().isEmpty()) {
- response = this.getMessage();
- this.level = "0";
- }
- }
- }
- }
- return response;
- }
- // parse the given text to find best match in the keywords
- private Keyword parse(String text, ArrayList<Keyword> keylist) {
- // set the default match to none
- int bestMatch = -1;
- Keyword match = null;
- // loop through keywords
- for (int i = 0; i < keylist.size(); i++) {
- // get number of matches of the keyword with given text
- int matches = getMatches(text, keylist.get(i));
- // if match is better than best match, replace it
- if (matches > -1 && matches > bestMatch) {
- match = keylist.get(i);
- bestMatch = matches;
- }
- }
- // add best answers regex variable value into the dictionary for future reference
- if (match != null){
- if(match.learn.length() > 0 ){
- // get training data keyword and description
- String subject = dictionary.get(match.learn);
- String result = match.variableValue;
- // create a new state for new trained data
- ArrayList<String> messages = new ArrayList<String>();
- messages.add(result);
- State myState = new State(String.valueOf(parser.stateCounter),messages,new ArrayList());
- parser.addState(myState);
- // add the new trained keyword
- Keyword keyword = new Keyword(subject, myState.getId(), "", "", "", 1, "" );
- State state = parser.getState("1");
- ArrayList<Keyword> keywords = state.getKeywords();
- keywords.add(keyword);
- }else{
- if (match.variableValue.length() > 0){
- dictionary.put(match.variable, match.variableValue);
- }
- }
- }
- return match;
- }
- // get number of matches of the given keywords in the given list
- private int getMatches(String text, Keyword keyword) {
- // no match by default
- int result = -1;
- // return 0 match when keyword is *
- if(keyword.keyword.equals("*")){
- return keyword.points;
- }
- // if regex is expected
- if(keyword.variable.length() > 0){
- String match = Regex.match(keyword.keyword, text);
- if(match.length() > 0){
- keyword.variableValue = match;
- return keyword.points;
- }
- }
- String[] words = keyword.keyword.split(" ");
- // loop through list of the keywords
- for (String word : words) {
- // if current keyword is in the text, add points
- if (text.toLowerCase().indexOf(word.toLowerCase()) >= 0) {
- result = result + keyword.points + 1;
- } else {
- // return null if one of the keywords does not exists
- return -1;
- }
- }
- return result;
- }
- // replace given text with variables in the dictionary
- public String replaceMatches(String text){
- // replace variables within dictionary in the text
- for (Map.Entry<String, String> entry : dictionary.entrySet()) {
- text = text.replaceAll("\["+entry.getKey() + "\]", entry.getValue());
- }
- // remove empty variables tags
- return Regex.clear(text);
- }
- }
- package bot;
- public class Context {
- public static String source = "newcontext.xml";
- //method to get value of source called in dataParser
- public static String getSource(){
- return source;
- }
- //get the new topic from Topic Class and prepare to reload DataParser/Bot
- public static void newSource(String currentTopic){
- source = currentTopic;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement