package agents.qoagent; import java.util.StringTokenizer; /* * Created on 30/05/2004 * */ /** * Responsible for the generation of formatted messages for the * automated agent * @author raz * @version 1.0 * @see AutomatedAgent * @see AutomatedAgentCommunication */ public class AutomatedAgentMessages { // constants for response of message public final static int MESSAGE_RECEIVED = 0; public final static int MESSAGE_REJECTED = 1; //type of messages public final static int REGISTER = 0; public final static int THREAT = 1; public final static int COMMENT = 2; public final static int OFFER = 3; public final static int PROMISE = 4; public final static int QUERY = 5; public final static int ACCEPT = 6; public final static int REJECT = 7; public final static int OPT_OUT = 8; public final static int COUNTER_OFFER = 9; private AutomatedAgent m_agent; private AgentTools agentTools = null; private AbstractAutomatedAgent abstractAgent = null; /** * @param agent - saves the AutomatedAgent in the member variable */ public AutomatedAgentMessages(AutomatedAgent agent, AgentTools agentTools, AbstractAutomatedAgent abstractAgent) { m_agent = agent; this.agentTools = agentTools; this.abstractAgent = abstractAgent; } /** * Formats the message in the predefined structure for sending it * later to the server * @param nMessageKind - the message kind. Can be either: * REGISTER, THREAT, COMMENT, OFFER, PROMISE, QUERY, ACCEPT, REJECT, OPT_OUT, COUNTER_OFFER. * @param sMsgBody - the message body: additional data for creating the message. * sMsgBody differs for the different message types * @return the formatted message * @see AutomatedAgent * @see AutomatedAgentCommunication */ public String formatMessage(int nMessageKind, String sMsgBody) { String sFormattedMsg = ""; switch (nMessageKind) { case REGISTER: { sFormattedMsg = "type register tag " + m_agent.getMsgId() + " id " + sMsgBody + " side " + m_agent.getAgentSide() + " name " + m_agent.getAgentName() + " supportMediator " + m_agent.getSupportMediator() + " preferenceDetails automatedAgent"; ; } break; case THREAT: { sFormattedMsg = "type threat" + " source " + m_agent.getAgentId() + " target " + m_agent.getOpponentAgentId() + " tag " + m_agent.getMsgId() + " body "+ sMsgBody; } break; case COMMENT: { sFormattedMsg = "type comment" + " source " + m_agent.getAgentId() + " target " + m_agent.getOpponentAgentId() + " tag " + m_agent.getMsgId() + " body "+ sMsgBody; } break; case OFFER: { sFormattedMsg = "type offer" + " source " + m_agent.getAgentId() + " target " + m_agent.getOpponentAgentId() + " tag " + m_agent.getMsgId() + " issueSet "; sFormattedMsg += sMsgBody; } break; case COUNTER_OFFER: { sFormattedMsg = "type counter_offer" + " source " + m_agent.getAgentId() + " target " + m_agent.getOpponentAgentId() + " tag " + m_agent.getMsgId() + " issueSet "; sFormattedMsg += sMsgBody; } break; case PROMISE: { sFormattedMsg = "type promise" + " source " + m_agent.getAgentId() + " target " + m_agent.getOpponentAgentId() + " tag " + m_agent.getMsgId(); // build the agent's issue set String sAgentPromise = " myIssueSet "; // NOTE: In our scenario there are no actions // that only for one side. // We do not use the option of myIssueSet and yourIssueSet // this explains the commented lines below sAgentPromise += sMsgBody; /* QPromiseType agentPromise = m_agent.getPromiseList(); String sAttribute, sValue; ArrayList agentPromiseList = (ArrayList)agentPromise.agentIssueSet; for (int i = 0; i < agentPromiseList.size(); ++i) { QAttributeValue av = (QAttributeValue)agentPromiseList.get(i); sAttribute = av.sAttribute; sValue= av.sValue; sAgentPromise += sValue + "*" + sAttribute + "*"; } */ sFormattedMsg += sAgentPromise + " "; // build the opponent's issue set String sOpponentPromise = "yourIssueSet "; /* ArrayList opponentPromiseList = (ArrayList)agentPromise.opponentIssueSet; for (int i = 0; i < opponentPromiseList.size(); ++i) { QAttributeValue av = (QAttributeValue)opponentPromiseList.get(i); sAttribute = av.sAttribute; sValue= av.sValue; sOpponentPromise += sValue + "*" + sAttribute + "*"; } */ sFormattedMsg += sOpponentPromise; } break; case QUERY: { sFormattedMsg = "type query" + " source " + m_agent.getAgentId() + " target " + m_agent.getOpponentAgentId() + " tag " + m_agent.getMsgId() + " issueSet "; sFormattedMsg += sMsgBody; } break; case ACCEPT: { sFormattedMsg = "type response" + " source " + m_agent.getAgentId() + " target " + m_agent.getOpponentAgentId() + " tag " + m_agent.getMsgId() + " answer AGREE" + " message " + sMsgBody + " reason "; // NOTE: No reason is supplied on accept; // save accepted msg String sResponse = sFormattedMsg.substring(sFormattedMsg.indexOf("answer ")+7, sFormattedMsg.indexOf("reason")-1); String sMessage = sResponse.substring(sResponse.indexOf("message ") + 8); // message accepted - save message // parse message by its type (offer, promise, query) String sSavedMsg = ""; if (sMessage.startsWith("type query")) sSavedMsg = sMessage.substring(sMessage.indexOf("issueSet ") + 9); else if (sMessage.startsWith("type counter_offer")) sSavedMsg = sMessage.substring(sMessage.indexOf("issueSet ") + 9); else if (sMessage.startsWith("type offer")) sSavedMsg = sMessage.substring(sMessage.indexOf("issueSet ") + 9); else if (sMessage.startsWith("type promise")) { String sPromise = sMessage.substring(sMessage.indexOf("myIssueSet ") + 11); String sMyIssueSet = sPromise.substring(0, sPromise.indexOf("yourIssueSet ")); String sYourIssueSet = sPromise.substring(sPromise.indexOf("yourIssueSet ") + 13); // parse to one agreement sSavedMsg = sMyIssueSet + sYourIssueSet; } // only if accepted an offer - save it if ( sMessage.startsWith("type counter_offer") || sMessage.startsWith("type offer")) m_agent.saveAcceptedMsg(sSavedMsg); } break; case REJECT: { sFormattedMsg = "type response" + " source " + m_agent.getAgentId() + " target " + m_agent.getOpponentAgentId() + " tag " + m_agent.getMsgId() + " answer DISAGREE" + " message " + sMsgBody + " reason "; // NOTE: No reason is supplied } break; case OPT_OUT: { sFormattedMsg = "type opt-out tag " + m_agent.getMsgId(); } break; default: { System.out.println("[AA]ERROR: Invalid message kind: " + nMessageKind + " [AutomatedAgentMessages::formatMessage(234)]"); System.err.println("[AA]ERROR: Invalid message kind: " + nMessageKind + " [AutomatedAgentMessages::formatMessage(234)]"); } break; } return sFormattedMsg; } /** * Parses messages from the server. * NOTE: There is no validation that this agent is the * target for the message. Assuming correctness of server routing messages. * @param sServerLine - the server's message * @return the parsed string - relevant only if "nak" * @see AutomatedAgent * @see AutomatedAgentCommunication */ public String parseMessage(String sServerLine) { String sParsedString = ""; if (sServerLine.startsWith("type comment")) { String sComment=sServerLine.substring(sServerLine.indexOf(" body ")+6); abstractAgent.commentReceived(sComment); } else if (sServerLine.startsWith("type threat")) { String sThreat=sServerLine.substring(sServerLine.indexOf(" body ")+6); abstractAgent.threatReceived(sThreat); } else if (sServerLine.startsWith("type endTurn")) { // turn ended m_agent.incrementCurrentTurn(); } else if (sServerLine.startsWith("type endNegotiation")) { // negotiation ended m_agent.m_gtStopTurn.setRun(false); m_agent.m_gtStopNeg.setRun(false); System.out.println("[AA]Negotiation Ended"); System.err.println("[AA]Negotiation Ended"); m_agent.endNegotiation(); // NOTE: no need to parse the end reason, agreement // and score. They are saved in the file. } else if (sServerLine.startsWith("type response")) { String sResponse = sServerLine.substring(sServerLine.indexOf("answer ")+7, sServerLine.indexOf("reason")-1); String sAnswerType = sResponse.substring(0,sResponse.indexOf(" ")); String sMessage = sResponse.substring(sResponse.indexOf("message ") + 8); String sReason = sServerLine.substring(sServerLine.indexOf("reason ") + 7); if(sAnswerType.equals("AGREE")) { // message accepted - save message // parse message by its type (offer, promise, query) String sSavedMsg = ""; if (sMessage.startsWith("type query")) { sSavedMsg = sMessage.substring(sMessage.indexOf("issueSet ") + 9); abstractAgent.opponentAgreed(QUERY, m_agent.getAgreementIndices(sSavedMsg), sMessage); } else if (sMessage.startsWith("type counter_offer")) { sSavedMsg = sMessage.substring(sMessage.indexOf("issueSet ") + 9); abstractAgent.opponentAgreed(COUNTER_OFFER, m_agent.getAgreementIndices(sSavedMsg), sMessage); } else if (sMessage.startsWith("type offer")) { sSavedMsg = sMessage.substring(sMessage.indexOf("issueSet ") + 9); abstractAgent.opponentAgreed(OFFER, m_agent.getAgreementIndices(sSavedMsg), sMessage); } else if (sMessage.startsWith("type promise")) { String sPromise = sMessage.substring(sMessage.indexOf("myIssueSet ") + 11); String sMyIssueSet = sPromise.substring(0, sPromise.indexOf("yourIssueSet ")); String sYourIssueSet = sPromise.substring(sPromise.indexOf("yourIssueSet ") + 13); // parse to one agreement sSavedMsg = sMyIssueSet + sYourIssueSet; abstractAgent.opponentAgreed(PROMISE, m_agent.getAgreementIndices(sSavedMsg), sMessage); } // only if accepted an offer (and not promise/query) - save it in the agreed offers if ( sMessage.startsWith("type counter_offer") || sMessage.startsWith("type offer")) m_agent.saveAcceptedMsg(sSavedMsg); } else if(sAnswerType.equals("DISAGREE")) { // parse message by its type (offer, promise, query) String sSavedMsg = ""; if (sMessage.startsWith("type query")) { sSavedMsg = sMessage.substring(sMessage.indexOf("issueSet ") + 9); abstractAgent.opponentRejected(QUERY, m_agent.getAgreementIndices(sSavedMsg), sMessage); } else if (sMessage.startsWith("type counter_offer")) { sSavedMsg = sMessage.substring(sMessage.indexOf("issueSet ") + 9); abstractAgent.opponentRejected(COUNTER_OFFER, m_agent.getAgreementIndices(sSavedMsg), sMessage); } else if (sMessage.startsWith("type offer")) { sSavedMsg = sMessage.substring(sMessage.indexOf("issueSet ") + 9); abstractAgent.opponentRejected(OFFER, m_agent.getAgreementIndices(sSavedMsg), sMessage); } else if (sMessage.startsWith("type promise")) { String sPromise = sMessage.substring(sMessage.indexOf("myIssueSet ") + 11); String sMyIssueSet = sPromise.substring(0, sPromise.indexOf("yourIssueSet ")); String sYourIssueSet = sPromise.substring(sPromise.indexOf("yourIssueSet ") + 13); // parse to one agreement sSavedMsg = sMyIssueSet + sYourIssueSet; abstractAgent.opponentRejected(PROMISE, m_agent.getAgreementIndices(sSavedMsg), sMessage); } } } else if (sServerLine.startsWith("type registered")) { String sSecsForTurn = sServerLine.substring(sServerLine.indexOf("secForTurn ")+11); StringTokenizer st = new StringTokenizer(sSecsForTurn); long lSecondsForTurn = Long.parseLong(st.nextToken()); m_agent.setSecondsForTurn(lSecondsForTurn); String sMaxTurns=sServerLine.substring(sServerLine.indexOf("maxTurn ")+8); st = new StringTokenizer(sMaxTurns); m_agent.setMaxTurns(Integer.parseInt(st.nextToken())); long lTotalSec=lSecondsForTurn; int nHours=(int)lTotalSec/3600; lTotalSec -= nHours*3600; int nMinutes=(int)lTotalSec/60; lTotalSec -= nMinutes*60; m_agent.m_gtStopTurn = new AutomatedAgentGameTime(false,nHours,nMinutes,(int)lTotalSec,m_agent,true); m_agent.m_gtStopTurn.newGame(); // initializing the stop-watch new Thread(m_agent.m_gtStopTurn).start(); lTotalSec=lSecondsForTurn * m_agent.getMaxTurns(); nHours=(int)lTotalSec/3600; lTotalSec -= nHours*3600; nMinutes=(int)lTotalSec/60; lTotalSec -= nMinutes*60; m_agent.m_gtStopNeg = new AutomatedAgentGameTime(false,nHours,nMinutes,(int)lTotalSec,m_agent,false); m_agent.m_gtStopNeg.newGame(); // initializing the stop-watch new Thread(m_agent.m_gtStopNeg).start(); String sAgentID = sServerLine.substring(sServerLine.indexOf("agentID ")+8); m_agent.setHasOpponent(true, sAgentID); String sOpponentSide = null; AutomatedAgentType agentType = m_agent.getAgentType(); if (agentType.isTypeOf(AutomatedAgentType.SIDE_B_TYPE)) sOpponentSide = AutomatedAgent.SIDE_A_NAME; else if (agentType.isTypeOf(AutomatedAgentType.SIDE_A_TYPE)) sOpponentSide = AutomatedAgent.SIDE_B_NAME; abstractAgent.initialize(agentType, sOpponentSide); } else if (sServerLine.startsWith("type agentOptOut")) { m_agent.setHasOpponent(false, null); m_agent.m_gtStopTurn.setRun(false); m_agent.m_gtStopNeg.setRun(false); } else if (sServerLine.equals("type log request error")) { // not relevant for the Automated Agent } else if (sServerLine.startsWith("type log response")) { // not relevant for the Automated Agent } else if (sServerLine.startsWith("type query")) { //query received // get message id StringTokenizer st = new StringTokenizer(sServerLine); boolean bFound = false; while (st.hasMoreTokens() && !bFound) { if (st.nextToken().equals("tag")) { bFound = true; st.nextToken(); } } String sQuery=sServerLine.substring(sServerLine.indexOf("issueSet ")+9); int CurrentAgreementIdx[] = new int[AutomatedAgentType.MAX_ISSUES]; CurrentAgreementIdx = m_agent.getAgreementIndices(sQuery); agentTools.calculateResponse(AutomatedAgentMessages.QUERY, CurrentAgreementIdx, sServerLine); //abstractAgent.queryReceived(CurrentAgreementIdx, sServerLine); } else if (sServerLine.startsWith("type counter_offer")) { // counter_offer received // get message id StringTokenizer st = new StringTokenizer(sServerLine); boolean bFound = false; while (st.hasMoreTokens() && !bFound) { if (st.nextToken().equals("tag")) { bFound = true; st.nextToken(); } } String sOffer=sServerLine.substring(sServerLine.indexOf("issueSet ")+9); int CurrentAgreementIdx[] = new int[AutomatedAgentType.MAX_ISSUES]; CurrentAgreementIdx = m_agent.getAgreementIndices(sOffer); agentTools.calculateResponse(AutomatedAgentMessages.COUNTER_OFFER, CurrentAgreementIdx, sServerLine); //abstractAgent.counterOfferReceived(CurrentAgreementIdx, sServerLine); } else if (sServerLine.startsWith("type offer")) { // offer received // get message id StringTokenizer st = new StringTokenizer(sServerLine); boolean bFound = false; while (st.hasMoreTokens() && !bFound) { if (st.nextToken().equals("tag")) { bFound = true; st.nextToken(); } } String sOffer=sServerLine.substring(sServerLine.indexOf("issueSet ")+9); int CurrentAgreementIdx[] = new int[AutomatedAgentType.MAX_ISSUES]; CurrentAgreementIdx = m_agent.getAgreementIndices(sOffer); agentTools.calculateResponse(AutomatedAgentMessages.OFFER, CurrentAgreementIdx, sServerLine); //abstractAgent.offerReceived(CurrentAgreementIdx, sServerLine); } else if (sServerLine.startsWith("type promise")) { // promise received // get message id StringTokenizer st = new StringTokenizer(sServerLine); boolean bFound = false; while (st.hasMoreTokens() && !bFound) { if (st.nextToken().equals("tag")) { bFound = true; st.nextToken(); } } String sPromise=sServerLine.substring(sServerLine.indexOf("myIssueSet ")+11); String sMyIssueSet=sPromise.substring(0,sPromise.indexOf("yourIssueSet ")); String sYourIssueSet=sPromise.substring(sPromise.indexOf("yourIssueSet ")+13); // parse to one agreement int CurrentAgreementIdxMine[] = new int[AutomatedAgentType.MAX_ISSUES]; int CurrentAgreementIdxYours[] = new int[AutomatedAgentType.MAX_ISSUES]; CurrentAgreementIdxMine = m_agent.getAgreementIndices(sMyIssueSet); CurrentAgreementIdxYours = m_agent.getAgreementIndices(sYourIssueSet); // combine indices for (int i = 0; i < AutomatedAgentType.MAX_ISSUES; ++i) { if (CurrentAgreementIdxYours[i] != AutomatedAgentType.NO_VALUE) CurrentAgreementIdxMine[i] = CurrentAgreementIdxYours[i]; } agentTools.calculateResponse(AutomatedAgentMessages.PROMISE, CurrentAgreementIdxMine, sServerLine); //abstractAgent.promiseReceived(CurrentAgreementIdxMine, sServerLine); } else if (sServerLine.equals("nak") || sServerLine.equals("ack")) { sParsedString = sServerLine; } else // other unknown message { System.out.println("[AA]Unknown Message Error: " + sServerLine + " [AutomatedAgentMessages::parseMessage(590)]"); System.err.println("[AA]Unknown Message Error: " + sServerLine + " [AutomatedAgentMessages::parseMessage(590)]"); sParsedString = sServerLine; } return sParsedString; } }