org.aksw.xoperator.Controller.java Source code

Java tutorial

Introduction

Here is the source code for org.aksw.xoperator.Controller.java

Source

/*
 * This file is part of the xOperator SPARQL/XMPP agent.
 * For further information see: http://xoperator.aksw.org
 * Copyright (C) 2007-2008  Jrg Unbehauen
    
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
    
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
    
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.aksw.xoperator;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.aksw.xoperator.aiml.AimlFacade;
import org.aksw.xoperator.command.Command;
import org.aksw.xoperator.security.IAccessControl;
import org.aksw.xoperator.sparql.ISparqlEndpoint;
import org.aksw.xoperator.sparql.SparqlEndpointFacade;
import org.aksw.xoperator.sparql.SparqlEndpointIdentifier;
import org.aksw.xoperator.sparql.SparqlQuery;
import org.aksw.xoperator.sparql.SparqlResult;
import org.aksw.xoperator.sparql.p2p.SPARQLQueryOverXmpp;
import org.aksw.xoperator.xmpp.JabberClientManager;
import org.aksw.xoperator.xmpp.JabberUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import org.jdom.xpath.XPath;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;

/**
 * Manages the interaction beween the ui and the other components.
 *
 * @author joerg
 */
public class Controller implements MessageListener, ChatManagerListener, PacketListener {
    private static Log log = LogFactory.getLog(Controller.class);
    private static Log conversationLog = LogFactory.getLog("conversation");
    private static Log p2pLog = LogFactory.getLog("p2p");
    private AimlFacade aimlFacade;
    private Collection<Command> commands;
    private JabberClientManager jcmanager;
    private ISparqlEndpoint endpointFacade;
    private IAccessControl accessControl;

    public Controller(List<Command> commands, AimlFacade aimlFacade, JabberClientManager jcmanager,
            SparqlEndpointFacade facade, IAccessControl accessControl) {
        super();
        this.commands = commands;
        this.aimlFacade = aimlFacade;
        this.jcmanager = jcmanager;
        this.endpointFacade = facade;
        this.accessControl = accessControl;
        jcmanager.addChatManagerListener(this);
        jcmanager.registerP2PListener(new SPARQLQueryOverXmpp.IQPaketListener(this, jcmanager));
        //sort the commands array alphabetically
        Collections.sort(commands, new Comparator<Command>() {
            public int compare(Command cmd1, Command cmd2) {
                return cmd1.getKeyWord().length() - cmd2.getKeyWord().length();
            }
        });
    }

    /**
     * Processes a Message received through the P2P facilities. Defines that only the built in store should be asked.
     *
     * @param query the incoming query
     *
     * @return the SPARQL Result, serialized as a String
     */
    public String processIncomingSparqlQuery(SPARQLQueryOverXmpp incomingQuery) {
        SparqlQuery query = incomingQuery.getSparqlQuery();
        p2pLog.info("received " + query.getQueryString());
        query.setAgentsToAsk(new ArrayList<SparqlEndpointIdentifier>());
        query.setStoresToAsk(new ArrayList<SparqlEndpointIdentifier>());
        query.setAskLocal(true);
        endpointFacade.process(query);

        List<String> results = new ArrayList<String>();

        for (SparqlResult sresult : query.getResults().values()) {
            results.add(sresult.getAnswer());
        }

        String result = uglySparqlResultCombiner(results);
        p2pLog.info("answered: " + StringUtils.substring(result, 0, 200));

        return result;
    }

    /**
     * Processes an incoming chat message.
     *
     * @param chat DOCUMENT ME!
     * @param message DOCUMENT ME!
     */
    public void processMessage(Chat chat, Message message) {

        //check if message is allowed to be further processed
        if (accessControl.allow(message)) {

            if (message.getBody() != null) {
                String composingId = RandomStringUtils.random(6);

                try {
                    chat.sendMessage(JabberUtils.composingNotification(composingId));

                    String messBody = message.getBody();
                    conversationLog.info("Received: " + messBody);

                    boolean isCmd = false;

                    for (Command command : commands) {
                        if (messBody.startsWith(command.getKeyWord())) {
                            command.perform(chat, message);
                            isCmd = true;

                            break;
                        }
                    }

                    if (isCmd == false) {
                        aimlFacade.letTheBotRespond(chat, message);
                    }

                    chat.sendMessage(JabberUtils.composingCancelNotification(composingId));
                } catch (Exception e) {
                    log.error("Error while processing content ", e);
                }
            }
        } else {
            try {
                chat.sendMessage(accessControl.getDenialResponse(message));
            } catch (XMPPException e) {
                log.error("Error sending the access denied message: ", e);
            }
        }
    }

    /**
     * Adds itself to the as a chatManager, required for chat control.
     *
     * @param chat DOCUMENT ME!
     * @param arg1 DOCUMENT ME!
     */
    public void chatCreated(Chat chat, boolean arg1) {
        chat.addMessageListener(this);
    }

    /**
     * Not yet implemented.
     *
     * @param packet DOCUMENT ME!
     */
    public void processPacket(Packet packet) {
    }

    /**
     * Merges SPARQL-Result sets.
     *
     * @param results the List of String-serialized SPARQL-Documents to be
     *        merged together.
     *
     * @return The XML-Document as one single String
     */
    public static String uglySparqlResultCombiner(List<String> results) {
        StringBuffer resultBuffer = new StringBuffer();
        SAXBuilder builder = new SAXBuilder();
        Document doc = null;
        XPath xpath;

        try {
            xpath = XPath.newInstance("/res:sparql/res:results");

            xpath.addNamespace(Constants.HTTP_WWW_W3_ORG_2005_SPARQL_RESULTS);

            for (String result : results) {
                Document scrapeDoc = builder.build(new StringReader(result));

                // check if there is content in it
                Object resResults = xpath.selectSingleNode(scrapeDoc);

                if (resResults != null) {
                    if (doc == null) {
                        doc = scrapeDoc;
                    } else {
                        List resultList = ((Element) resResults).getChildren();
                        List<Element> safeList = new ArrayList<Element>();

                        for (Object object : resultList) {
                            safeList.add((Element) object);
                        }

                        for (Element element : safeList) {
                            doc.getRootElement().getChild("results", Constants.HTTP_WWW_W3_ORG_2005_SPARQL_RESULTS)
                                    .addContent(element.detach());
                        }
                    }
                }
            }
        } catch (RuntimeException e) {
            log.error("Error while merging the results: ", e);
        } catch (JDOMException e) {
            log.error("Error in the xml structure: ", e);
        } catch (IOException e) {
            log.error("Error reading the input:", e);
        }

        if (doc != null) {
            XMLOutputter out = new XMLOutputter();
            resultBuffer.append(out.outputString(doc));
        }

        return resultBuffer.toString();
    }

}