Java tutorial
/* * 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(); } }