mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-10-31 17:25:58 +01:00
Adding workgroup API (SMACK-185).
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@7400 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
939feb9017
commit
fe545abeae
64 changed files with 9744 additions and 0 deletions
67
source/org/jivesoftware/smackx/workgroup/MetaData.java
Normal file
67
source/org/jivesoftware/smackx/workgroup/MetaData.java
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.util.MetaDataUtils;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MetaData packet extension.
|
||||||
|
*/
|
||||||
|
public class MetaData implements PacketExtension {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "metadata";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
private Map metaData;
|
||||||
|
|
||||||
|
public MetaData(Map metaData) {
|
||||||
|
this.metaData = metaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the Map of metadata contained by this instance
|
||||||
|
*/
|
||||||
|
public Map getMetaData() {
|
||||||
|
return metaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML() {
|
||||||
|
return MetaDataUtils.serializeMetaData(this.getMetaData());
|
||||||
|
}
|
||||||
|
}
|
85
source/org/jivesoftware/smackx/workgroup/QueueUser.java
Normal file
85
source/org/jivesoftware/smackx/workgroup/QueueUser.java
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An immutable class which wraps up customer-in-queue data return from the server; depending on
|
||||||
|
* the type of information dispatched from the server, not all information will be available in
|
||||||
|
* any given instance.
|
||||||
|
*
|
||||||
|
* @author loki der quaeler
|
||||||
|
*/
|
||||||
|
public class QueueUser {
|
||||||
|
|
||||||
|
private String userID;
|
||||||
|
|
||||||
|
private int queuePosition;
|
||||||
|
private int estimatedTime;
|
||||||
|
private Date joinDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param uid the user jid of the customer in the queue
|
||||||
|
* @param position the position customer sits in the queue
|
||||||
|
* @param time the estimate of how much longer the customer will be in the queue in seconds
|
||||||
|
* @param joinedAt the timestamp of when the customer entered the queue
|
||||||
|
*/
|
||||||
|
public QueueUser (String uid, int position, int time, Date joinedAt) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.userID = uid;
|
||||||
|
this.queuePosition = position;
|
||||||
|
this.estimatedTime = time;
|
||||||
|
this.joinDate = joinedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the user jid of the customer in the queue
|
||||||
|
*/
|
||||||
|
public String getUserID () {
|
||||||
|
return this.userID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the position in the queue at which the customer sits, or -1 if the update which
|
||||||
|
* this instance embodies is only a time update instead
|
||||||
|
*/
|
||||||
|
public int getQueuePosition () {
|
||||||
|
return this.queuePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the estimated time remaining of the customer in the queue in seconds, or -1 if
|
||||||
|
* if the update which this instance embodies is only a position update instead
|
||||||
|
*/
|
||||||
|
public int getEstimatedRemainingTime () {
|
||||||
|
return this.estimatedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the timestamp of when this customer entered the queue, or null if the server did not
|
||||||
|
* provide this information
|
||||||
|
*/
|
||||||
|
public Date getQueueJoinTimestamp () {
|
||||||
|
return this.joinDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An immutable class wrapping up the basic information which comprises a group chat invitation.
|
||||||
|
*
|
||||||
|
* @author loki der quaeler
|
||||||
|
*/
|
||||||
|
public class WorkgroupInvitation {
|
||||||
|
|
||||||
|
protected String uniqueID;
|
||||||
|
|
||||||
|
protected String sessionID;
|
||||||
|
|
||||||
|
protected String groupChatName;
|
||||||
|
protected String issuingWorkgroupName;
|
||||||
|
protected String messageBody;
|
||||||
|
protected String invitationSender;
|
||||||
|
protected Map metaData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This calls the 5-argument constructor with a null MetaData argument value
|
||||||
|
*
|
||||||
|
* @param jid the jid string with which the issuing AgentSession or Workgroup instance
|
||||||
|
* was created
|
||||||
|
* @param group the jid of the room to which the person is invited
|
||||||
|
* @param workgroup the jid of the workgroup issuing the invitation
|
||||||
|
* @param sessID the session id associated with the pending chat
|
||||||
|
* @param msgBody the body of the message which contained the invitation
|
||||||
|
* @param from the user jid who issued the invitation, if known, null otherwise
|
||||||
|
*/
|
||||||
|
public WorkgroupInvitation (String jid, String group, String workgroup,
|
||||||
|
String sessID, String msgBody, String from) {
|
||||||
|
this(jid, group, workgroup, sessID, msgBody, from, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param jid the jid string with which the issuing AgentSession or Workgroup instance
|
||||||
|
* was created
|
||||||
|
* @param group the jid of the room to which the person is invited
|
||||||
|
* @param workgroup the jid of the workgroup issuing the invitation
|
||||||
|
* @param sessID the session id associated with the pending chat
|
||||||
|
* @param msgBody the body of the message which contained the invitation
|
||||||
|
* @param from the user jid who issued the invitation, if known, null otherwise
|
||||||
|
* @param metaData the metadata sent with the invitation
|
||||||
|
*/
|
||||||
|
public WorkgroupInvitation (String jid, String group, String workgroup, String sessID, String msgBody,
|
||||||
|
String from, Map metaData) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.uniqueID = jid;
|
||||||
|
this.sessionID = sessID;
|
||||||
|
this.groupChatName = group;
|
||||||
|
this.issuingWorkgroupName = workgroup;
|
||||||
|
this.messageBody = msgBody;
|
||||||
|
this.invitationSender = from;
|
||||||
|
this.metaData = metaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the jid string with which the issuing AgentSession or Workgroup instance
|
||||||
|
* was created.
|
||||||
|
*/
|
||||||
|
public String getUniqueID () {
|
||||||
|
return this.uniqueID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the session id associated with the pending chat; working backwards temporally,
|
||||||
|
* this session id should match the session id to the corresponding offer request
|
||||||
|
* which resulted in this invitation.
|
||||||
|
*/
|
||||||
|
public String getSessionID () {
|
||||||
|
return this.sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the jid of the room to which the person is invited.
|
||||||
|
*/
|
||||||
|
public String getGroupChatName () {
|
||||||
|
return this.groupChatName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name of the workgroup from which the invitation was issued.
|
||||||
|
*/
|
||||||
|
public String getWorkgroupName () {
|
||||||
|
return this.issuingWorkgroupName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the contents of the body-block of the message that housed this invitation.
|
||||||
|
*/
|
||||||
|
public String getMessageBody () {
|
||||||
|
return this.messageBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the user who issued the invitation, or null if it wasn't known.
|
||||||
|
*/
|
||||||
|
public String getInvitationSender () {
|
||||||
|
return this.invitationSender;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the meta data associated with the invitation, or null if this instance was
|
||||||
|
* constructed with none
|
||||||
|
*/
|
||||||
|
public Map getMetaData () {
|
||||||
|
return this.metaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface which all classes interested in hearing about group chat invitations should
|
||||||
|
* implement.
|
||||||
|
*
|
||||||
|
* @author loki der quaeler
|
||||||
|
*/
|
||||||
|
public interface WorkgroupInvitationListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The implementing class instance will be notified via this method when an invitation
|
||||||
|
* to join a group chat has been received from the server.
|
||||||
|
*
|
||||||
|
* @param invitation an Invitation instance embodying the information pertaining to the
|
||||||
|
* invitation
|
||||||
|
*/
|
||||||
|
public void invitationReceived(WorkgroupInvitation invitation);
|
||||||
|
|
||||||
|
}
|
138
source/org/jivesoftware/smackx/workgroup/agent/Agent.java
Normal file
138
source/org/jivesoftware/smackx/workgroup/agent/Agent.java
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.packet.AgentInfo;
|
||||||
|
import org.jivesoftware.smackx.workgroup.packet.AgentWorkgroups;
|
||||||
|
import org.jivesoftware.smack.PacketCollector;
|
||||||
|
import org.jivesoftware.smack.SmackConfiguration;
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
import org.jivesoftware.smack.filter.PacketIDFilter;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <code>Agent</code> class is used to represent one agent in a Workgroup Queue.
|
||||||
|
*
|
||||||
|
* @author Derek DeMoro
|
||||||
|
*/
|
||||||
|
public class Agent {
|
||||||
|
private XMPPConnection connection;
|
||||||
|
private String workgroupJID;
|
||||||
|
|
||||||
|
public static Collection getWorkgroups(String serviceJID, String agentJID, XMPPConnection connection) throws XMPPException {
|
||||||
|
AgentWorkgroups request = new AgentWorkgroups(agentJID);
|
||||||
|
request.setTo(serviceJID);
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
|
||||||
|
// Send the request
|
||||||
|
connection.sendPacket(request);
|
||||||
|
|
||||||
|
AgentWorkgroups response = (AgentWorkgroups)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server on status set.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return response.getWorkgroups();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an Agent.
|
||||||
|
*/
|
||||||
|
Agent(XMPPConnection connection, String workgroupJID) {
|
||||||
|
this.connection = connection;
|
||||||
|
this.workgroupJID = workgroupJID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the agents JID
|
||||||
|
*
|
||||||
|
* @return - the agents JID.
|
||||||
|
*/
|
||||||
|
public String getUser() {
|
||||||
|
return connection.getUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the agents name.
|
||||||
|
*
|
||||||
|
* @return - the agents name.
|
||||||
|
*/
|
||||||
|
public String getName() throws XMPPException {
|
||||||
|
AgentInfo agentInfo = new AgentInfo();
|
||||||
|
agentInfo.setType(IQ.Type.GET);
|
||||||
|
agentInfo.setTo(workgroupJID);
|
||||||
|
agentInfo.setFrom(getUser());
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(agentInfo.getPacketID()));
|
||||||
|
// Send the request
|
||||||
|
connection.sendPacket(agentInfo);
|
||||||
|
|
||||||
|
AgentInfo response = (AgentInfo)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server on status set.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return response.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the name of the agent in the server. The server may have this functionality
|
||||||
|
* disabled for all the agents or for this agent in particular. If the agent is not
|
||||||
|
* allowed to change his name then an exception will be thrown with a service_unavailable
|
||||||
|
* error code.
|
||||||
|
*
|
||||||
|
* @param newName the new name of the agent.
|
||||||
|
* @throws XMPPException if the agent is not allowed to change his name or no response was
|
||||||
|
* obtained from the server.
|
||||||
|
*/
|
||||||
|
public void setName(String newName) throws XMPPException {
|
||||||
|
AgentInfo agentInfo = new AgentInfo();
|
||||||
|
agentInfo.setType(IQ.Type.SET);
|
||||||
|
agentInfo.setTo(workgroupJID);
|
||||||
|
agentInfo.setFrom(getUser());
|
||||||
|
agentInfo.setName(newName);
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(agentInfo.getPacketID()));
|
||||||
|
// Send the request
|
||||||
|
connection.sendPacket(agentInfo);
|
||||||
|
|
||||||
|
IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server on status set.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
386
source/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java
Normal file
386
source/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java
Normal file
|
@ -0,0 +1,386 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.packet.AgentStatus;
|
||||||
|
import org.jivesoftware.smackx.workgroup.packet.AgentStatusRequest;
|
||||||
|
import org.jivesoftware.smack.PacketListener;
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.filter.PacketFilter;
|
||||||
|
import org.jivesoftware.smack.filter.PacketTypeFilter;
|
||||||
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
|
import org.jivesoftware.smack.packet.Presence;
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manges information about the agents in a workgroup and their presence.
|
||||||
|
*
|
||||||
|
* @author Matt Tucker
|
||||||
|
* @see AgentSession#getAgentRoster()
|
||||||
|
*/
|
||||||
|
public class AgentRoster {
|
||||||
|
|
||||||
|
private static final int EVENT_AGENT_ADDED = 0;
|
||||||
|
private static final int EVENT_AGENT_REMOVED = 1;
|
||||||
|
private static final int EVENT_PRESENCE_CHANGED = 2;
|
||||||
|
|
||||||
|
private XMPPConnection connection;
|
||||||
|
private String workgroupJID;
|
||||||
|
private List entries;
|
||||||
|
private List listeners;
|
||||||
|
private Map presenceMap;
|
||||||
|
// The roster is marked as initialized when at least a single roster packet
|
||||||
|
// has been recieved and processed.
|
||||||
|
boolean rosterInitialized = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new AgentRoster.
|
||||||
|
*
|
||||||
|
* @param connection an XMPP connection.
|
||||||
|
*/
|
||||||
|
AgentRoster(XMPPConnection connection, String workgroupJID) {
|
||||||
|
this.connection = connection;
|
||||||
|
this.workgroupJID = workgroupJID;
|
||||||
|
entries = new ArrayList();
|
||||||
|
listeners = new ArrayList();
|
||||||
|
presenceMap = new HashMap();
|
||||||
|
// Listen for any roster packets.
|
||||||
|
PacketFilter rosterFilter = new PacketTypeFilter(AgentStatusRequest.class);
|
||||||
|
connection.addPacketListener(new AgentStatusListener(), rosterFilter);
|
||||||
|
// Listen for any presence packets.
|
||||||
|
connection.addPacketListener(new PresencePacketListener(),
|
||||||
|
new PacketTypeFilter(Presence.class));
|
||||||
|
|
||||||
|
// Send request for roster.
|
||||||
|
AgentStatusRequest request = new AgentStatusRequest();
|
||||||
|
request.setTo(workgroupJID);
|
||||||
|
connection.sendPacket(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reloads the entire roster from the server. This is an asynchronous operation,
|
||||||
|
* which means the method will return immediately, and the roster will be
|
||||||
|
* reloaded at a later point when the server responds to the reload request.
|
||||||
|
*/
|
||||||
|
public void reload() {
|
||||||
|
AgentStatusRequest request = new AgentStatusRequest();
|
||||||
|
request.setTo(workgroupJID);
|
||||||
|
connection.sendPacket(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a listener to this roster. The listener will be fired anytime one or more
|
||||||
|
* changes to the roster are pushed from the server.
|
||||||
|
*
|
||||||
|
* @param listener an agent roster listener.
|
||||||
|
*/
|
||||||
|
public void addListener(AgentRosterListener listener) {
|
||||||
|
synchronized (listeners) {
|
||||||
|
if (!listeners.contains(listener)) {
|
||||||
|
listeners.add(listener);
|
||||||
|
|
||||||
|
// Fire events for the existing entries and presences in the roster
|
||||||
|
for (Iterator it = getAgents().iterator(); it.hasNext();) {
|
||||||
|
String jid = (String)it.next();
|
||||||
|
// Check again in case the agent is no longer in the roster (highly unlikely
|
||||||
|
// but possible)
|
||||||
|
if (entries.contains(jid)) {
|
||||||
|
// Fire the agent added event
|
||||||
|
listener.agentAdded(jid);
|
||||||
|
Map userPresences = (Map)presenceMap.get(jid);
|
||||||
|
if (userPresences != null) {
|
||||||
|
Iterator presences = userPresences.values().iterator();
|
||||||
|
while (presences.hasNext()) {
|
||||||
|
// Fire the presence changed event
|
||||||
|
listener.presenceChanged((Presence)presences.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a listener from this roster. The listener will be fired anytime one or more
|
||||||
|
* changes to the roster are pushed from the server.
|
||||||
|
*
|
||||||
|
* @param listener a roster listener.
|
||||||
|
*/
|
||||||
|
public void removeListener(AgentRosterListener listener) {
|
||||||
|
synchronized (listeners) {
|
||||||
|
listeners.remove(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a count of all agents in the workgroup.
|
||||||
|
*
|
||||||
|
* @return the number of agents in the workgroup.
|
||||||
|
*/
|
||||||
|
public int getAgentCount() {
|
||||||
|
return entries.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all agents (String JID values) in the workgroup.
|
||||||
|
*
|
||||||
|
* @return all entries in the roster.
|
||||||
|
*/
|
||||||
|
public Set getAgents() {
|
||||||
|
Set agents = new HashSet();
|
||||||
|
synchronized (entries) {
|
||||||
|
for (Iterator i = entries.iterator(); i.hasNext();) {
|
||||||
|
agents.add(i.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Collections.unmodifiableSet(agents);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the specified XMPP address is an agent in the workgroup.
|
||||||
|
*
|
||||||
|
* @param jid the XMPP address of the agent (eg "jsmith@example.com"). The
|
||||||
|
* address can be in any valid format (e.g. "domain/resource", "user@domain"
|
||||||
|
* or "user@domain/resource").
|
||||||
|
* @return true if the XMPP address is an agent in the workgroup.
|
||||||
|
*/
|
||||||
|
public boolean contains(String jid) {
|
||||||
|
if (jid == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
synchronized (entries) {
|
||||||
|
for (Iterator i = entries.iterator(); i.hasNext();) {
|
||||||
|
String entry = (String)i.next();
|
||||||
|
if (entry.toLowerCase().equals(jid.toLowerCase())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the presence info for a particular agent, or <tt>null</tt> if the agent
|
||||||
|
* is unavailable (offline) or if no presence information is available.<p>
|
||||||
|
*
|
||||||
|
* @param user a fully qualified xmpp JID. The address could be in any valid format (e.g.
|
||||||
|
* "domain/resource", "user@domain" or "user@domain/resource").
|
||||||
|
* @return the agent's current presence, or <tt>null</tt> if the agent is unavailable
|
||||||
|
* or if no presence information is available..
|
||||||
|
*/
|
||||||
|
public Presence getPresence(String user) {
|
||||||
|
String key = getPresenceMapKey(user);
|
||||||
|
Map userPresences = (Map)presenceMap.get(key);
|
||||||
|
if (userPresences == null) {
|
||||||
|
Presence presence = new Presence(Presence.Type.unavailable);
|
||||||
|
presence.setFrom(user);
|
||||||
|
return presence;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Find the resource with the highest priority
|
||||||
|
// Might be changed to use the resource with the highest availability instead.
|
||||||
|
Iterator it = userPresences.keySet().iterator();
|
||||||
|
Presence p;
|
||||||
|
Presence presence = null;
|
||||||
|
|
||||||
|
while (it.hasNext()) {
|
||||||
|
p = (Presence)userPresences.get(it.next());
|
||||||
|
if (presence == null){
|
||||||
|
presence = p;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (p.getPriority() > presence.getPriority()) {
|
||||||
|
presence = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (presence == null) {
|
||||||
|
presence = new Presence(Presence.Type.unavailable);
|
||||||
|
presence.setFrom(user);
|
||||||
|
return presence;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return presence;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key to use in the presenceMap for a fully qualified xmpp ID. The roster
|
||||||
|
* can contain any valid address format such us "domain/resource", "user@domain" or
|
||||||
|
* "user@domain/resource". If the roster contains an entry associated with the fully qualified
|
||||||
|
* xmpp ID then use the fully qualified xmpp ID as the key in presenceMap, otherwise use the
|
||||||
|
* bare address. Note: When the key in presenceMap is a fully qualified xmpp ID, the
|
||||||
|
* userPresences is useless since it will always contain one entry for the user.
|
||||||
|
*
|
||||||
|
* @param user the fully qualified xmpp ID, e.g. jdoe@example.com/Work.
|
||||||
|
* @return the key to use in the presenceMap for the fully qualified xmpp ID.
|
||||||
|
*/
|
||||||
|
private String getPresenceMapKey(String user) {
|
||||||
|
String key = user;
|
||||||
|
if (!contains(user)) {
|
||||||
|
key = StringUtils.parseBareAddress(user).toLowerCase();
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires event to listeners.
|
||||||
|
*/
|
||||||
|
private void fireEvent(int eventType, Object eventObject) {
|
||||||
|
AgentRosterListener[] listeners = null;
|
||||||
|
synchronized (this.listeners) {
|
||||||
|
listeners = new AgentRosterListener[this.listeners.size()];
|
||||||
|
this.listeners.toArray(listeners);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < listeners.length; i++) {
|
||||||
|
switch (eventType) {
|
||||||
|
case EVENT_AGENT_ADDED:
|
||||||
|
listeners[i].agentAdded((String)eventObject);
|
||||||
|
break;
|
||||||
|
case EVENT_AGENT_REMOVED:
|
||||||
|
listeners[i].agentRemoved((String)eventObject);
|
||||||
|
break;
|
||||||
|
case EVENT_PRESENCE_CHANGED:
|
||||||
|
listeners[i].presenceChanged((Presence)eventObject);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens for all presence packets and processes them.
|
||||||
|
*/
|
||||||
|
private class PresencePacketListener implements PacketListener {
|
||||||
|
public void processPacket(Packet packet) {
|
||||||
|
Presence presence = (Presence)packet;
|
||||||
|
String from = presence.getFrom();
|
||||||
|
if (from == null) {
|
||||||
|
// TODO Check if we need to ignore these presences or this is a server bug?
|
||||||
|
System.out.println("Presence with no FROM: " + presence.toXML());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String key = getPresenceMapKey(from);
|
||||||
|
|
||||||
|
// If an "available" packet, add it to the presence map. Each presence map will hold
|
||||||
|
// for a particular user a map with the presence packets saved for each resource.
|
||||||
|
if (presence.getType() == Presence.Type.available) {
|
||||||
|
// Ignore the presence packet unless it has an agent status extension.
|
||||||
|
AgentStatus agentStatus = (AgentStatus)presence.getExtension(
|
||||||
|
AgentStatus.ELEMENT_NAME, AgentStatus.NAMESPACE);
|
||||||
|
if (agentStatus == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Ensure that this presence is coming from an Agent of the same workgroup
|
||||||
|
// of this Agent
|
||||||
|
else if (!workgroupJID.equals(agentStatus.getWorkgroupJID())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map userPresences;
|
||||||
|
// Get the user presence map
|
||||||
|
if (presenceMap.get(key) == null) {
|
||||||
|
userPresences = new HashMap();
|
||||||
|
presenceMap.put(key, userPresences);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
userPresences = (Map)presenceMap.get(key);
|
||||||
|
}
|
||||||
|
// Add the new presence, using the resources as a key.
|
||||||
|
synchronized (userPresences) {
|
||||||
|
userPresences.put(StringUtils.parseResource(from), presence);
|
||||||
|
}
|
||||||
|
// Fire an event.
|
||||||
|
synchronized (entries) {
|
||||||
|
for (Iterator i = entries.iterator(); i.hasNext();) {
|
||||||
|
String entry = (String)i.next();
|
||||||
|
if (entry.toLowerCase().equals(StringUtils.parseBareAddress(key).toLowerCase())) {
|
||||||
|
fireEvent(EVENT_PRESENCE_CHANGED, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If an "unavailable" packet, remove any entries in the presence map.
|
||||||
|
else if (presence.getType() == Presence.Type.unavailable) {
|
||||||
|
if (presenceMap.get(key) != null) {
|
||||||
|
Map userPresences = (Map)presenceMap.get(key);
|
||||||
|
synchronized (userPresences) {
|
||||||
|
userPresences.remove(StringUtils.parseResource(from));
|
||||||
|
}
|
||||||
|
if (userPresences.isEmpty()) {
|
||||||
|
presenceMap.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fire an event.
|
||||||
|
synchronized (entries) {
|
||||||
|
for (Iterator i = entries.iterator(); i.hasNext();) {
|
||||||
|
String entry = (String)i.next();
|
||||||
|
if (entry.toLowerCase().equals(StringUtils.parseBareAddress(key).toLowerCase())) {
|
||||||
|
fireEvent(EVENT_PRESENCE_CHANGED, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens for all roster packets and processes them.
|
||||||
|
*/
|
||||||
|
private class AgentStatusListener implements PacketListener {
|
||||||
|
|
||||||
|
public void processPacket(Packet packet) {
|
||||||
|
if (packet instanceof AgentStatusRequest) {
|
||||||
|
AgentStatusRequest statusRequest = (AgentStatusRequest)packet;
|
||||||
|
for (Iterator i = statusRequest.getAgents().iterator(); i.hasNext();) {
|
||||||
|
AgentStatusRequest.Item item = (AgentStatusRequest.Item)i.next();
|
||||||
|
String agentJID = item.getJID();
|
||||||
|
if ("remove".equals(item.getType())) {
|
||||||
|
|
||||||
|
// Removing the user from the roster, so remove any presence information
|
||||||
|
// about them.
|
||||||
|
String key = StringUtils.parseName(StringUtils.parseName(agentJID) + "@" +
|
||||||
|
StringUtils.parseServer(agentJID));
|
||||||
|
presenceMap.remove(key);
|
||||||
|
// Fire event for roster listeners.
|
||||||
|
fireEvent(EVENT_AGENT_REMOVED, agentJID);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
entries.add(agentJID);
|
||||||
|
// Fire event for roster listeners.
|
||||||
|
fireEvent(EVENT_AGENT_ADDED, agentJID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark the roster as initialized.
|
||||||
|
rosterInitialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.Presence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Matt Tucker
|
||||||
|
*/
|
||||||
|
public interface AgentRosterListener {
|
||||||
|
|
||||||
|
public void agentAdded(String jid);
|
||||||
|
|
||||||
|
public void agentRemoved(String jid);
|
||||||
|
|
||||||
|
public void presenceChanged(Presence presence);
|
||||||
|
}
|
1184
source/org/jivesoftware/smackx/workgroup/agent/AgentSession.java
Normal file
1184
source/org/jivesoftware/smackx/workgroup/agent/AgentSession.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request sent by an agent to invite another agent or user.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public class InvitationRequest extends OfferContent {
|
||||||
|
|
||||||
|
private String inviter;
|
||||||
|
private String room;
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
public InvitationRequest(String inviter, String room, String reason) {
|
||||||
|
this.inviter = inviter;
|
||||||
|
this.room = room;
|
||||||
|
this.reason = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInviter() {
|
||||||
|
return inviter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRoom() {
|
||||||
|
return room;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReason() {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isUserRequest() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isInvitation() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isTransfer() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
222
source/org/jivesoftware/smackx/workgroup/agent/Offer.java
Normal file
222
source/org/jivesoftware/smackx/workgroup/agent/Offer.java
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class embodying the semantic agent chat offer; specific instances allow the acceptance or
|
||||||
|
* rejecting of the offer.<br>
|
||||||
|
*
|
||||||
|
* @author Matt Tucker
|
||||||
|
* @author loki der quaeler
|
||||||
|
* @author Derek DeMoro
|
||||||
|
*/
|
||||||
|
public class Offer {
|
||||||
|
|
||||||
|
private XMPPConnection connection;
|
||||||
|
private AgentSession session;
|
||||||
|
|
||||||
|
private String sessionID;
|
||||||
|
private String userJID;
|
||||||
|
private String userID;
|
||||||
|
private String workgroupName;
|
||||||
|
private Date expiresDate;
|
||||||
|
private Map metaData;
|
||||||
|
private OfferContent content;
|
||||||
|
|
||||||
|
private boolean accepted = false;
|
||||||
|
private boolean rejected = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new offer.
|
||||||
|
*
|
||||||
|
* @param conn the XMPP connection with which the issuing session was created.
|
||||||
|
* @param agentSession the agent session instance through which this offer was issued.
|
||||||
|
* @param userID the userID of the user from which the offer originates.
|
||||||
|
* @param userJID the XMPP address of the user from which the offer originates.
|
||||||
|
* @param workgroupName the fully qualified name of the workgroup.
|
||||||
|
* @param expiresDate the date at which this offer expires.
|
||||||
|
* @param sessionID the session id associated with the offer.
|
||||||
|
* @param metaData the metadata associated with the offer.
|
||||||
|
* @param content content of the offer. The content explains the reason for the offer
|
||||||
|
* (e.g. user request, transfer)
|
||||||
|
*/
|
||||||
|
Offer(XMPPConnection conn, AgentSession agentSession, String userID,
|
||||||
|
String userJID, String workgroupName, Date expiresDate,
|
||||||
|
String sessionID, Map metaData, OfferContent content)
|
||||||
|
{
|
||||||
|
this.connection = conn;
|
||||||
|
this.session = agentSession;
|
||||||
|
this.userID = userID;
|
||||||
|
this.userJID = userJID;
|
||||||
|
this.workgroupName = workgroupName;
|
||||||
|
this.expiresDate = expiresDate;
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
this.metaData = metaData;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accepts the offer.
|
||||||
|
*/
|
||||||
|
public void accept() {
|
||||||
|
Packet acceptPacket = new AcceptPacket(this.session.getWorkgroupJID());
|
||||||
|
connection.sendPacket(acceptPacket);
|
||||||
|
// TODO: listen for a reply.
|
||||||
|
accepted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rejects the offer.
|
||||||
|
*/
|
||||||
|
public void reject() {
|
||||||
|
RejectPacket rejectPacket = new RejectPacket(this.session.getWorkgroupJID());
|
||||||
|
connection.sendPacket(rejectPacket);
|
||||||
|
// TODO: listen for a reply.
|
||||||
|
rejected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the userID that the offer originates from. In most cases, the
|
||||||
|
* userID will simply be the JID of the requesting user. However, users can
|
||||||
|
* also manually specify a userID for their request. In that case, that value will
|
||||||
|
* be returned.
|
||||||
|
*
|
||||||
|
* @return the userID of the user from which the offer originates.
|
||||||
|
*/
|
||||||
|
public String getUserID() {
|
||||||
|
return userID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the JID of the user that made the offer request.
|
||||||
|
*
|
||||||
|
* @return the user's JID.
|
||||||
|
*/
|
||||||
|
public String getUserJID() {
|
||||||
|
return userJID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fully qualified name of the workgroup (eg support@example.com).
|
||||||
|
*
|
||||||
|
* @return the name of the workgroup.
|
||||||
|
*/
|
||||||
|
public String getWorkgroupName() {
|
||||||
|
return this.workgroupName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The date when the offer will expire. The agent must {@link #accept()}
|
||||||
|
* the offer before the expiration date or the offer will lapse and be
|
||||||
|
* routed to another agent. Alternatively, the agent can {@link #reject()}
|
||||||
|
* the offer at any time if they don't wish to accept it..
|
||||||
|
*
|
||||||
|
* @return the date at which this offer expires.
|
||||||
|
*/
|
||||||
|
public Date getExpiresDate() {
|
||||||
|
return this.expiresDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The session ID associated with the offer.
|
||||||
|
*
|
||||||
|
* @return the session id associated with the offer.
|
||||||
|
*/
|
||||||
|
public String getSessionID() {
|
||||||
|
return this.sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The meta-data associated with the offer.
|
||||||
|
*
|
||||||
|
* @return the offer meta-data.
|
||||||
|
*/
|
||||||
|
public Map getMetaData() {
|
||||||
|
return this.metaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the content of the offer. The content explains the reason for the offer
|
||||||
|
* (e.g. user request, transfer)
|
||||||
|
*
|
||||||
|
* @return the content of the offer.
|
||||||
|
*/
|
||||||
|
public OfferContent getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the agent accepted this offer.
|
||||||
|
*
|
||||||
|
* @return true if the agent accepted this offer.
|
||||||
|
*/
|
||||||
|
public boolean isAccepted() {
|
||||||
|
return accepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the agent rejected this offer.
|
||||||
|
*
|
||||||
|
* @return true if the agent rejected this offer.
|
||||||
|
*/
|
||||||
|
public boolean isRejected() {
|
||||||
|
return rejected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet for rejecting offers.
|
||||||
|
*/
|
||||||
|
private class RejectPacket extends IQ {
|
||||||
|
|
||||||
|
RejectPacket(String workgroup) {
|
||||||
|
this.setTo(workgroup);
|
||||||
|
this.setType(IQ.Type.SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
return "<offer-reject id=\"" + Offer.this.getSessionID() +
|
||||||
|
"\" xmlns=\"http://jabber.org/protocol/workgroup" + "\"/>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet for accepting an offer.
|
||||||
|
*/
|
||||||
|
private class AcceptPacket extends IQ {
|
||||||
|
|
||||||
|
AcceptPacket(String workgroup) {
|
||||||
|
this.setTo(workgroup);
|
||||||
|
this.setType(IQ.Type.SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
return "<offer-accept id=\"" + Offer.this.getSessionID() +
|
||||||
|
"\" xmlns=\"http://jabber.org/protocol/workgroup" + "\"/>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
|
||||||
|
public class OfferConfirmation extends IQ {
|
||||||
|
private String userJID;
|
||||||
|
private long sessionID;
|
||||||
|
|
||||||
|
public String getUserJID() {
|
||||||
|
return userJID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserJID(String userJID) {
|
||||||
|
this.userJID = userJID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSessionID() {
|
||||||
|
return sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSessionID(long sessionID) {
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void notifyService(XMPPConnection con, String workgroup, String createdRoomName) {
|
||||||
|
NotifyServicePacket packet = new NotifyServicePacket(workgroup, createdRoomName);
|
||||||
|
con.sendPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append("<offer-confirmation xmlns=\"http://jabber.org/protocol/workgroup\">");
|
||||||
|
buf.append("</offer-confirmation>");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Provider implements IQProvider {
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
final OfferConfirmation confirmation = new OfferConfirmation();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
parser.next();
|
||||||
|
String elementName = parser.getName();
|
||||||
|
if (parser.getEventType() == XmlPullParser.START_TAG && "user-jid".equals(elementName)) {
|
||||||
|
try {
|
||||||
|
confirmation.setUserJID(parser.nextText());
|
||||||
|
}
|
||||||
|
catch (NumberFormatException nfe) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (parser.getEventType() == XmlPullParser.START_TAG && "session-id".equals(elementName)) {
|
||||||
|
try {
|
||||||
|
confirmation.setSessionID(Long.valueOf(parser.nextText()));
|
||||||
|
}
|
||||||
|
catch (NumberFormatException nfe) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (parser.getEventType() == XmlPullParser.END_TAG && "offer-confirmation".equals(elementName)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return confirmation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet for notifying server of RoomName
|
||||||
|
*/
|
||||||
|
private class NotifyServicePacket extends IQ {
|
||||||
|
String roomName;
|
||||||
|
|
||||||
|
NotifyServicePacket(String workgroup, String roomName) {
|
||||||
|
this.setTo(workgroup);
|
||||||
|
this.setType(IQ.Type.RESULT);
|
||||||
|
|
||||||
|
this.roomName = roomName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
return "<offer-confirmation roomname=\"" + roomName + "\" xmlns=\"http://jabber.org/protocol/workgroup" + "\"/>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
public interface OfferConfirmationListener {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The implementing class instance will be notified via this when the AgentSession has confirmed
|
||||||
|
* the acceptance of the <code>Offer</code>. The instance will then have the ability to create the room and
|
||||||
|
* send the service the room name created for tracking.
|
||||||
|
*
|
||||||
|
* @param confirmedOffer the ConfirmedOffer
|
||||||
|
*/
|
||||||
|
void offerConfirmed(OfferConfirmation confirmedOffer);
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of content being included in the offer. The content actually explains the reason
|
||||||
|
* the agent is getting an offer.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public abstract class OfferContent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the content of the offer is related to a user request. This is the
|
||||||
|
* most common type of offers an agent should receive.
|
||||||
|
*
|
||||||
|
* @return true if the content of the offer is related to a user request.
|
||||||
|
*/
|
||||||
|
abstract boolean isUserRequest();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the content of the offer is related to a room invitation made by another
|
||||||
|
* agent. This type of offer include the room to join, metadata sent by the user while joining
|
||||||
|
* the queue and the reason why the agent is being invited.
|
||||||
|
*
|
||||||
|
* @return true if the content of the offer is related to a room invitation made by another agent.
|
||||||
|
*/
|
||||||
|
abstract boolean isInvitation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the content of the offer is related to a service transfer made by another
|
||||||
|
* agent. This type of offers include the room to join, metadata sent by the user while joining the
|
||||||
|
* queue and the reason why the agent is receiving the transfer offer.
|
||||||
|
*
|
||||||
|
* @return true if the content of the offer is related to a service transfer made by another agent.
|
||||||
|
*/
|
||||||
|
abstract boolean isTransfer();
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface which all classes interested in hearing about chat offers associated to a particular
|
||||||
|
* AgentSession instance should implement.<br>
|
||||||
|
*
|
||||||
|
* @author Matt Tucker
|
||||||
|
* @author loki der quaeler
|
||||||
|
* @see org.jivesoftware.smackx.workgroup.agent.AgentSession
|
||||||
|
*/
|
||||||
|
public interface OfferListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The implementing class instance will be notified via this when the AgentSession has received
|
||||||
|
* an offer for a chat. The instance will then have the ability to accept, reject, or ignore
|
||||||
|
* the request (resulting in a revocation-by-timeout).
|
||||||
|
*
|
||||||
|
* @param request the Offer instance embodying the details of the offer
|
||||||
|
*/
|
||||||
|
public void offerReceived (Offer request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The implementing class instance will be notified via this when the AgentSessino has received
|
||||||
|
* a revocation of a previously extended offer.
|
||||||
|
*
|
||||||
|
* @param revokedOffer the RevokedOffer instance embodying the details of the revoked offer
|
||||||
|
*/
|
||||||
|
public void offerRevoked (RevokedOffer revokedOffer);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public interface QueueUsersListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status of the queue was updated.
|
||||||
|
*
|
||||||
|
* @param queue the workgroup queue.
|
||||||
|
* @param status the status of queue.
|
||||||
|
*/
|
||||||
|
public void statusUpdated(WorkgroupQueue queue, WorkgroupQueue.Status status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The average wait time of the queue was updated.
|
||||||
|
*
|
||||||
|
* @param queue the workgroup queue.
|
||||||
|
* @param averageWaitTime the average wait time of the queue.
|
||||||
|
*/
|
||||||
|
public void averageWaitTimeUpdated(WorkgroupQueue queue, int averageWaitTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The date of oldest entry waiting in the queue was updated.
|
||||||
|
*
|
||||||
|
* @param queue the workgroup queue.
|
||||||
|
* @param oldestEntry the date of the oldest entry waiting in the queue.
|
||||||
|
*/
|
||||||
|
public void oldestEntryUpdated(WorkgroupQueue queue, Date oldestEntry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of users waiting in the queue was updated.
|
||||||
|
*
|
||||||
|
* @param queue the workgroup queue.
|
||||||
|
* @param users the list of users waiting in the queue.
|
||||||
|
*/
|
||||||
|
public void usersUpdated(WorkgroupQueue queue, Set users);
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An immutable simple class to embody the information concerning a revoked offer, this is namely
|
||||||
|
* the reason, the workgroup, the userJID, and the timestamp which the message was received.<br>
|
||||||
|
*
|
||||||
|
* @author loki der quaeler
|
||||||
|
*/
|
||||||
|
public class RevokedOffer {
|
||||||
|
|
||||||
|
private String userJID;
|
||||||
|
private String userID;
|
||||||
|
private String workgroupName;
|
||||||
|
private String sessionID;
|
||||||
|
private String reason;
|
||||||
|
private Date timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param userJID the JID of the user for which this revocation was issued.
|
||||||
|
* @param userID the user ID of the user for which this revocation was issued.
|
||||||
|
* @param workgroupName the fully qualified name of the workgroup
|
||||||
|
* @param sessionID the session id attributed to this chain of packets
|
||||||
|
* @param reason the server issued message as to why this revocation was issued.
|
||||||
|
* @param timestamp the timestamp at which the revocation was issued
|
||||||
|
*/
|
||||||
|
RevokedOffer(String userJID, String userID, String workgroupName, String sessionID,
|
||||||
|
String reason, Date timestamp) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.userJID = userJID;
|
||||||
|
this.userID = userID;
|
||||||
|
this.workgroupName = workgroupName;
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
this.reason = reason;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserJID() {
|
||||||
|
return userJID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the jid of the user for which this revocation was issued
|
||||||
|
*/
|
||||||
|
public String getUserID() {
|
||||||
|
return this.userID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fully qualified name of the workgroup
|
||||||
|
*/
|
||||||
|
public String getWorkgroupName() {
|
||||||
|
return this.workgroupName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the session id which will associate all packets for the pending chat
|
||||||
|
*/
|
||||||
|
public String getSessionID() {
|
||||||
|
return this.sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the server issued message as to why this revocation was issued
|
||||||
|
*/
|
||||||
|
public String getReason() {
|
||||||
|
return this.reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the timestamp at which the revocation was issued
|
||||||
|
*/
|
||||||
|
public Date getTimestamp() {
|
||||||
|
return this.timestamp;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.packet.Transcript;
|
||||||
|
import org.jivesoftware.smackx.workgroup.packet.Transcripts;
|
||||||
|
import org.jivesoftware.smack.PacketCollector;
|
||||||
|
import org.jivesoftware.smack.SmackConfiguration;
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
import org.jivesoftware.smack.filter.PacketIDFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A TranscriptManager helps to retrieve the full conversation transcript of a given session
|
||||||
|
* {@link #getTranscript(String, String)} or to retrieve a list with the summary of all the
|
||||||
|
* conversations that a user had {@link #getTranscripts(String, String)}.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public class TranscriptManager {
|
||||||
|
private XMPPConnection connection;
|
||||||
|
|
||||||
|
public TranscriptManager(XMPPConnection connection) {
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the full conversation transcript of a given session.
|
||||||
|
*
|
||||||
|
* @param sessionID the id of the session to get the full transcript.
|
||||||
|
* @param workgroupJID the JID of the workgroup that will process the request.
|
||||||
|
* @return the full conversation transcript of a given session.
|
||||||
|
* @throws XMPPException if an error occurs while getting the information.
|
||||||
|
*/
|
||||||
|
public Transcript getTranscript(String workgroupJID, String sessionID) throws XMPPException {
|
||||||
|
Transcript request = new Transcript(sessionID);
|
||||||
|
request.setTo(workgroupJID);
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
|
||||||
|
// Send the request
|
||||||
|
connection.sendPacket(request);
|
||||||
|
|
||||||
|
Transcript response = (Transcript) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server on status set.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the transcripts of a given user. The answer will contain the complete history of
|
||||||
|
* conversations that a user had.
|
||||||
|
*
|
||||||
|
* @param userID the id of the user to get his conversations.
|
||||||
|
* @param workgroupJID the JID of the workgroup that will process the request.
|
||||||
|
* @return the transcripts of a given user.
|
||||||
|
* @throws XMPPException if an error occurs while getting the information.
|
||||||
|
*/
|
||||||
|
public Transcripts getTranscripts(String workgroupJID, String userID) throws XMPPException {
|
||||||
|
Transcripts request = new Transcripts(userID);
|
||||||
|
request.setTo(workgroupJID);
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
|
||||||
|
// Send the request
|
||||||
|
connection.sendPacket(request);
|
||||||
|
|
||||||
|
Transcripts response = (Transcripts) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server on status set.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.packet.TranscriptSearch;
|
||||||
|
import org.jivesoftware.smack.PacketCollector;
|
||||||
|
import org.jivesoftware.smack.SmackConfiguration;
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
import org.jivesoftware.smack.filter.PacketIDFilter;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smackx.Form;
|
||||||
|
import org.jivesoftware.smackx.ReportedData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A TranscriptSearchManager helps to retrieve the form to use for searching transcripts
|
||||||
|
* {@link #getSearchForm(String)} or to submit a search form and return the results of
|
||||||
|
* the search {@link #submitSearch(String, Form)}.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public class TranscriptSearchManager {
|
||||||
|
private XMPPConnection connection;
|
||||||
|
|
||||||
|
public TranscriptSearchManager(XMPPConnection connection) {
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Form to use for searching transcripts. It is unlikely that the server
|
||||||
|
* will change the form (without a restart) so it is safe to keep the returned form
|
||||||
|
* for future submissions.
|
||||||
|
*
|
||||||
|
* @param serviceJID the address of the workgroup service.
|
||||||
|
* @return the Form to use for searching transcripts.
|
||||||
|
* @throws XMPPException if an error occurs while sending the request to the server.
|
||||||
|
*/
|
||||||
|
public Form getSearchForm(String serviceJID) throws XMPPException {
|
||||||
|
TranscriptSearch search = new TranscriptSearch();
|
||||||
|
search.setType(IQ.Type.GET);
|
||||||
|
search.setTo(serviceJID);
|
||||||
|
|
||||||
|
PacketCollector collector = connection.createPacketCollector(
|
||||||
|
new PacketIDFilter(search.getPacketID()));
|
||||||
|
connection.sendPacket(search);
|
||||||
|
|
||||||
|
TranscriptSearch response = (TranscriptSearch) collector.nextResult(
|
||||||
|
SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server on status set.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return Form.getFormFrom(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submits the completed form and returns the result of the transcript search. The result
|
||||||
|
* will include all the data returned from the server so be careful with the amount of
|
||||||
|
* data that the search may return.
|
||||||
|
*
|
||||||
|
* @param serviceJID the address of the workgroup service.
|
||||||
|
* @param completedForm the filled out search form.
|
||||||
|
* @return the result of the transcript search.
|
||||||
|
* @throws XMPPException if an error occurs while submiting the search to the server.
|
||||||
|
*/
|
||||||
|
public ReportedData submitSearch(String serviceJID, Form completedForm) throws XMPPException {
|
||||||
|
TranscriptSearch search = new TranscriptSearch();
|
||||||
|
search.setType(IQ.Type.GET);
|
||||||
|
search.setTo(serviceJID);
|
||||||
|
search.addExtension(completedForm.getDataFormToSend());
|
||||||
|
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(search.getPacketID()));
|
||||||
|
connection.sendPacket(search);
|
||||||
|
|
||||||
|
TranscriptSearch response = (TranscriptSearch) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server on status set.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return ReportedData.getReportedDataFrom(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request sent by an agent to transfer a support session to another agent or user.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public class TransferRequest extends OfferContent {
|
||||||
|
|
||||||
|
private String inviter;
|
||||||
|
private String room;
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
public TransferRequest(String inviter, String room, String reason) {
|
||||||
|
this.inviter = inviter;
|
||||||
|
this.room = room;
|
||||||
|
this.reason = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInviter() {
|
||||||
|
return inviter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRoom() {
|
||||||
|
return room;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReason() {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isUserRequest() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isInvitation() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isTransfer() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests made by users to get support by some agent.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public class UserRequest extends OfferContent {
|
||||||
|
// TODO Do we want to use a singleton? Should we store the userID here?
|
||||||
|
private static UserRequest instance = new UserRequest();
|
||||||
|
|
||||||
|
public static OfferContent getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isUserRequest() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isInvitation() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isTransfer() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,222 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.agent;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A queue in a workgroup, which is a pool of agents that are routed a specific type of
|
||||||
|
* chat request.
|
||||||
|
*/
|
||||||
|
public class WorkgroupQueue {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private Status status = Status.CLOSED;
|
||||||
|
|
||||||
|
private int averageWaitTime = -1;
|
||||||
|
private Date oldestEntry = null;
|
||||||
|
private Set users = Collections.EMPTY_SET;
|
||||||
|
|
||||||
|
private int maxChats = 0;
|
||||||
|
private int currentChats = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new workgroup queue instance.
|
||||||
|
*
|
||||||
|
* @param name the name of the queue.
|
||||||
|
*/
|
||||||
|
WorkgroupQueue(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the queue.
|
||||||
|
*
|
||||||
|
* @return the name of the queue.
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the status of the queue.
|
||||||
|
*
|
||||||
|
* @return the status of the queue.
|
||||||
|
*/
|
||||||
|
public Status getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setStatus(Status status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of users waiting in the queue waiting to be routed to
|
||||||
|
* an agent.
|
||||||
|
*
|
||||||
|
* @return the number of users waiting in the queue.
|
||||||
|
*/
|
||||||
|
public int getUserCount() {
|
||||||
|
if (users == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return users.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an Iterator for the users in the queue waiting to be routed to
|
||||||
|
* an agent (QueueUser instances).
|
||||||
|
*
|
||||||
|
* @return an Iterator for the users waiting in the queue.
|
||||||
|
*/
|
||||||
|
public Iterator getUsers() {
|
||||||
|
if (users == null) {
|
||||||
|
return Collections.EMPTY_SET.iterator();
|
||||||
|
}
|
||||||
|
return Collections.unmodifiableSet(users).iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUsers(Set users) {
|
||||||
|
this.users = users;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the average amount of time users wait in the queue before being
|
||||||
|
* routed to an agent. If average wait time info isn't available, -1 will
|
||||||
|
* be returned.
|
||||||
|
*
|
||||||
|
* @return the average wait time
|
||||||
|
*/
|
||||||
|
public int getAverageWaitTime() {
|
||||||
|
return averageWaitTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAverageWaitTime(int averageTime) {
|
||||||
|
this.averageWaitTime = averageTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the date of the oldest request waiting in the queue. If there
|
||||||
|
* are no requests waiting to be routed, this method will return <tt>null</tt>.
|
||||||
|
*
|
||||||
|
* @return the date of the oldest request in the queue.
|
||||||
|
*/
|
||||||
|
public Date getOldestEntry() {
|
||||||
|
return oldestEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOldestEntry(Date oldestEntry) {
|
||||||
|
this.oldestEntry = oldestEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum number of simultaneous chats the queue can handle.
|
||||||
|
*
|
||||||
|
* @return the max number of chats the queue can handle.
|
||||||
|
*/
|
||||||
|
public int getMaxChats() {
|
||||||
|
return maxChats;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMaxChats(int maxChats) {
|
||||||
|
this.maxChats = maxChats;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current number of active chat sessions in the queue.
|
||||||
|
*
|
||||||
|
* @return the current number of active chat sessions in the queue.
|
||||||
|
*/
|
||||||
|
public int getCurrentChats() {
|
||||||
|
return currentChats;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCurrentChats(int currentChats) {
|
||||||
|
this.currentChats = currentChats;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class to represent the status of the workgroup. The possible values are:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>WorkgroupQueue.Status.OPEN -- the queue is active and accepting new chat requests.
|
||||||
|
* <li>WorkgroupQueue.Status.ACTIVE -- the queue is active but NOT accepting new chat
|
||||||
|
* requests.
|
||||||
|
* <li>WorkgroupQueue.Status.CLOSED -- the queue is NOT active and NOT accepting new
|
||||||
|
* chat requests.
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public static class Status {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The queue is active and accepting new chat requests.
|
||||||
|
*/
|
||||||
|
public static final Status OPEN = new Status("open");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The queue is active but NOT accepting new chat requests. This state might
|
||||||
|
* occur when the workgroup has closed because regular support hours have closed,
|
||||||
|
* but there are still several requests left in the queue.
|
||||||
|
*/
|
||||||
|
public static final Status ACTIVE = new Status("active");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The queue is NOT active and NOT accepting new chat requests.
|
||||||
|
*/
|
||||||
|
public static final Status CLOSED = new Status("closed");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a String into the corresponding status. Valid String values
|
||||||
|
* that can be converted to a status are: "open", "active", and "closed".
|
||||||
|
*
|
||||||
|
* @param type the String value to covert.
|
||||||
|
* @return the corresponding Type.
|
||||||
|
*/
|
||||||
|
public static Status fromString(String type) {
|
||||||
|
if (type == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
type = type.toLowerCase();
|
||||||
|
if (OPEN.toString().equals(type)) {
|
||||||
|
return OPEN;
|
||||||
|
}
|
||||||
|
else if (ACTIVE.toString().equals(type)) {
|
||||||
|
return ACTIVE;
|
||||||
|
}
|
||||||
|
else if (CLOSED.toString().equals(type)) {
|
||||||
|
return CLOSED;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
private Status(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.ext.forms;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
public class WorkgroupForm extends IQ {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "workgroup-form";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
|
||||||
|
// Add packet extensions, if any are defined.
|
||||||
|
buf.append(getExtensionsXML());
|
||||||
|
buf.append("</").append(ELEMENT_NAME).append("> ");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IQProvider for WebForm packets.
|
||||||
|
*
|
||||||
|
* @author Derek DeMoro
|
||||||
|
*/
|
||||||
|
public static class InternalProvider implements IQProvider {
|
||||||
|
|
||||||
|
public InternalProvider() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
WorkgroupForm answer = new WorkgroupForm();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
// Parse the packet extension
|
||||||
|
answer.addExtension(PacketParserUtils.parsePacketExtension(parser.getName(),
|
||||||
|
parser.getNamespace(), parser));
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getName().equals(ELEMENT_NAME)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.ext.history;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IQ provider used to retrieve individual agent information. Each chat session can be mapped
|
||||||
|
* to one or more jids and therefore retrievable.
|
||||||
|
*/
|
||||||
|
public class AgentChatHistory extends IQ {
|
||||||
|
private String agentJID;
|
||||||
|
private int maxSessions;
|
||||||
|
private long startDate;
|
||||||
|
|
||||||
|
private List agentChatSessions = new ArrayList();
|
||||||
|
|
||||||
|
public AgentChatHistory(String agentJID, int maxSessions, Date startDate) {
|
||||||
|
this.agentJID = agentJID;
|
||||||
|
this.maxSessions = maxSessions;
|
||||||
|
this.startDate = startDate.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AgentChatHistory(String agentJID, int maxSessions) {
|
||||||
|
this.agentJID = agentJID;
|
||||||
|
this.maxSessions = maxSessions;
|
||||||
|
this.startDate = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AgentChatHistory() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addChatSession(AgentChatSession chatSession) {
|
||||||
|
agentChatSessions.add(chatSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection getAgentChatSessions() {
|
||||||
|
return agentChatSessions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "chat-sessions";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
|
||||||
|
buf.append('"');
|
||||||
|
buf.append(NAMESPACE);
|
||||||
|
buf.append('"');
|
||||||
|
buf.append(" agentJID=\"" + agentJID + "\"");
|
||||||
|
buf.append(" maxSessions=\"" + maxSessions + "\"");
|
||||||
|
buf.append(" startDate=\"" + startDate + "\"");
|
||||||
|
|
||||||
|
buf.append("></").append(ELEMENT_NAME).append("> ");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension provider for AgentHistory packets.
|
||||||
|
*/
|
||||||
|
public static class InternalProvider implements IQProvider {
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
throw new IllegalStateException("Parser not in proper position, or bad XML.");
|
||||||
|
}
|
||||||
|
|
||||||
|
AgentChatHistory agentChatHistory = new AgentChatHistory();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) && ("chat-session".equals(parser.getName()))) {
|
||||||
|
agentChatHistory.addChatSession(parseChatSetting(parser));
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && ELEMENT_NAME.equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return agentChatHistory;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AgentChatSession parseChatSetting(XmlPullParser parser) throws Exception {
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
Date date = null;
|
||||||
|
long duration = 0;
|
||||||
|
String visitorsName = null;
|
||||||
|
String visitorsEmail = null;
|
||||||
|
String sessionID = null;
|
||||||
|
String question = null;
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) && ("date".equals(parser.getName()))) {
|
||||||
|
String dateStr = parser.nextText();
|
||||||
|
long l = Long.valueOf(dateStr).longValue();
|
||||||
|
date = new Date(l);
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG) && ("duration".equals(parser.getName()))) {
|
||||||
|
duration = Long.valueOf(parser.nextText()).longValue();
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG) && ("visitorsName".equals(parser.getName()))) {
|
||||||
|
visitorsName = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG) && ("visitorsEmail".equals(parser.getName()))) {
|
||||||
|
visitorsEmail = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG) && ("sessionID".equals(parser.getName()))) {
|
||||||
|
sessionID = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG) && ("question".equals(parser.getName()))) {
|
||||||
|
question = parser.nextText();
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && "chat-session".equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new AgentChatSession(date, duration, visitorsName, visitorsEmail, sessionID, question);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.ext.history;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents one chat session for an agent.
|
||||||
|
*/
|
||||||
|
public class AgentChatSession {
|
||||||
|
public Date startDate;
|
||||||
|
public long duration;
|
||||||
|
public String visitorsName;
|
||||||
|
public String visitorsEmail;
|
||||||
|
public String sessionID;
|
||||||
|
public String question;
|
||||||
|
|
||||||
|
public AgentChatSession(Date date, long duration, String visitorsName, String visitorsEmail, String sessionID, String question) {
|
||||||
|
this.startDate = date;
|
||||||
|
this.duration = duration;
|
||||||
|
this.visitorsName = visitorsName;
|
||||||
|
this.visitorsEmail = visitorsEmail;
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
this.question = question;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getStartDate() {
|
||||||
|
return startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartDate(Date startDate) {
|
||||||
|
this.startDate = startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDuration() {
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDuration(long duration) {
|
||||||
|
this.duration = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVisitorsName() {
|
||||||
|
return visitorsName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVisitorsName(String visitorsName) {
|
||||||
|
this.visitorsName = visitorsName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVisitorsEmail() {
|
||||||
|
return visitorsEmail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVisitorsEmail(String visitorsEmail) {
|
||||||
|
this.visitorsEmail = visitorsEmail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSessionID() {
|
||||||
|
return sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSessionID(String sessionID) {
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuestion(String question){
|
||||||
|
this.question = question;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQuestion(){
|
||||||
|
return question;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.ext.history;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.util.MetaDataUtils;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ChatMetadata extends IQ {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "chat-metadata";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
|
||||||
|
private String sessionID;
|
||||||
|
|
||||||
|
public String getSessionID() {
|
||||||
|
return sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSessionID(String sessionID) {
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Map map = new HashMap();
|
||||||
|
|
||||||
|
public void setMetadata(Map metadata){
|
||||||
|
this.map = metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map getMetadata(){
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
|
||||||
|
buf.append("<sessionID>").append(getSessionID()).append("</sessionID>");
|
||||||
|
buf.append("</").append(ELEMENT_NAME).append("> ");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IQProvider for Metadata packets.
|
||||||
|
*
|
||||||
|
* @author Derek DeMoro
|
||||||
|
*/
|
||||||
|
public static class Provider implements IQProvider {
|
||||||
|
|
||||||
|
public Provider() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
final ChatMetadata chatM = new ChatMetadata();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
if (parser.getName().equals("sessionID")) {
|
||||||
|
chatM.setSessionID(parser.nextText());
|
||||||
|
}
|
||||||
|
else if (parser.getName().equals("metadata")) {
|
||||||
|
Map map = MetaDataUtils.parseMetaData(parser);
|
||||||
|
chatM.setMetadata(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getName().equals(ELEMENT_NAME)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return chatM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.ext.macros;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macro datamodel.
|
||||||
|
*/
|
||||||
|
public class Macro {
|
||||||
|
public static final int TEXT = 0;
|
||||||
|
public static final int URL = 1;
|
||||||
|
public static final int IMAGE = 2;
|
||||||
|
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
private String description;
|
||||||
|
private String response;
|
||||||
|
private int type;
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResponse() {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResponse(String response) {
|
||||||
|
this.response = response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.ext.macros;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MacroGroup datamodel.
|
||||||
|
*/
|
||||||
|
public class MacroGroup {
|
||||||
|
private List macros;
|
||||||
|
private List macroGroups;
|
||||||
|
|
||||||
|
|
||||||
|
// Define MacroGroup
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
public MacroGroup() {
|
||||||
|
macros = new ArrayList();
|
||||||
|
macroGroups = new ArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMacro(Macro macro) {
|
||||||
|
macros.add(macro);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeMacro(Macro macro) {
|
||||||
|
macros.remove(macro);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Macro getMacroByTitle(String title) {
|
||||||
|
Collection col = Collections.unmodifiableList(macros);
|
||||||
|
Iterator iter = col.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Macro macro = (Macro)iter.next();
|
||||||
|
if (macro.getTitle().equalsIgnoreCase(title)) {
|
||||||
|
return macro;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMacroGroup(MacroGroup group) {
|
||||||
|
macroGroups.add(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeMacroGroup(MacroGroup group) {
|
||||||
|
macroGroups.remove(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Macro getMacro(int location) {
|
||||||
|
return (Macro)macros.get(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MacroGroup getMacroGroupByTitle(String title) {
|
||||||
|
Collection col = Collections.unmodifiableList(macroGroups);
|
||||||
|
Iterator iter = col.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
MacroGroup group = (MacroGroup)iter.next();
|
||||||
|
if (group.getTitle().equalsIgnoreCase(title)) {
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MacroGroup getMacroGroup(int location) {
|
||||||
|
return (MacroGroup)macroGroups.get(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List getMacros() {
|
||||||
|
return macros;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMacros(List macros) {
|
||||||
|
this.macros = macros;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List getMacroGroups() {
|
||||||
|
return macroGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMacroGroups(List macroGroups) {
|
||||||
|
this.macroGroups = macroGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
}
|
144
source/org/jivesoftware/smackx/workgroup/ext/macros/Macros.java
Normal file
144
source/org/jivesoftware/smackx/workgroup/ext/macros/Macros.java
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.ext.macros;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macros iq is responsible for handling global and personal macros in the a Live Assistant
|
||||||
|
* Workgroup.
|
||||||
|
*/
|
||||||
|
public class Macros extends IQ {
|
||||||
|
|
||||||
|
private MacroGroup rootGroup;
|
||||||
|
private boolean personal;
|
||||||
|
private MacroGroup personalMacroGroup;
|
||||||
|
|
||||||
|
private static ClassLoader cl;
|
||||||
|
|
||||||
|
public static void setClassLoader(ClassLoader cloader) {
|
||||||
|
cl = cloader;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public MacroGroup getRootGroup() {
|
||||||
|
return rootGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRootGroup(MacroGroup rootGroup) {
|
||||||
|
this.rootGroup = rootGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPersonal() {
|
||||||
|
return personal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPersonal(boolean personal) {
|
||||||
|
this.personal = personal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MacroGroup getPersonalMacroGroup() {
|
||||||
|
return personalMacroGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPersonalMacroGroup(MacroGroup personalMacroGroup) {
|
||||||
|
this.personalMacroGroup = personalMacroGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "macros";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
|
||||||
|
if (isPersonal()) {
|
||||||
|
buf.append("<personal>true</personal>");
|
||||||
|
}
|
||||||
|
// TODO: REMOVE XSTREAM
|
||||||
|
// if (getPersonalMacroGroup() != null) {
|
||||||
|
// final XStream xstream = new XStream();
|
||||||
|
// xstream.alias("macro", Macro.class);
|
||||||
|
// xstream.alias("macrogroup", MacroGroup.class);
|
||||||
|
//
|
||||||
|
// if (cl != null) {
|
||||||
|
// xstream.setClassLoader(cl);
|
||||||
|
// }
|
||||||
|
// String persitedGroup = StringUtils.escapeForXML(xstream.toXML(getPersonalMacroGroup()));
|
||||||
|
// buf.append("<personalMacro>").append(persitedGroup).append("</personalMacro>");
|
||||||
|
// }
|
||||||
|
buf.append("</").append(ELEMENT_NAME).append("> ");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IQProvider for Macro packets.
|
||||||
|
*
|
||||||
|
* @author Derek DeMoro
|
||||||
|
*/
|
||||||
|
public static class InternalProvider implements IQProvider {
|
||||||
|
|
||||||
|
public InternalProvider() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
Macros macroGroup = new Macros();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
if (parser.getName().equals("model")) {
|
||||||
|
String macros = parser.nextText();
|
||||||
|
// TODO: REMOVE XSTREAM
|
||||||
|
// XStream xstream = new XStream();
|
||||||
|
// if(cl != null){
|
||||||
|
// xstream.setClassLoader(cl);
|
||||||
|
// }
|
||||||
|
// xstream.alias("macro", Macro.class);
|
||||||
|
// xstream.alias("macrogroup", MacroGroup.class);
|
||||||
|
// MacroGroup group = (MacroGroup)xstream.fromXML(macros);
|
||||||
|
// macroGroup.setRootGroup(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getName().equals(ELEMENT_NAME)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return macroGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.ext.notes;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IQ packet for retrieving and adding Chat Notes.
|
||||||
|
*/
|
||||||
|
public class ChatNotes extends IQ {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "chat-notes";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
|
||||||
|
private String sessionID;
|
||||||
|
private String notes;
|
||||||
|
|
||||||
|
public String getSessionID() {
|
||||||
|
return sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSessionID(String sessionID) {
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNotes() {
|
||||||
|
return notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNotes(String notes) {
|
||||||
|
this.notes = notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
|
||||||
|
buf.append("<sessionID>").append(getSessionID()).append("</sessionID>");
|
||||||
|
|
||||||
|
if (getNotes() != null) {
|
||||||
|
buf.append("<notes>").append(getNotes()).append("</notes>");
|
||||||
|
}
|
||||||
|
buf.append("</").append(ELEMENT_NAME).append("> ");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IQProvider for ChatNotes packets.
|
||||||
|
*
|
||||||
|
* @author Derek DeMoro
|
||||||
|
*/
|
||||||
|
public static class Provider implements IQProvider {
|
||||||
|
|
||||||
|
public Provider() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
ChatNotes chatNotes = new ChatNotes();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
if (parser.getName().equals("sessionID")) {
|
||||||
|
chatNotes.setSessionID(parser.nextText());
|
||||||
|
}
|
||||||
|
else if (parser.getName().equals("text")) {
|
||||||
|
String note = parser.nextText();
|
||||||
|
note = note.replaceAll("\\\\n", "\n");
|
||||||
|
chatNotes.setNotes(note);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getName().equals(ELEMENT_NAME)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return chatNotes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces all instances of oldString with newString in string.
|
||||||
|
*
|
||||||
|
* @param string the String to search to perform replacements on
|
||||||
|
* @param oldString the String that should be replaced by newString
|
||||||
|
* @param newString the String that will replace all instances of oldString
|
||||||
|
* @return a String will all instances of oldString replaced by newString
|
||||||
|
*/
|
||||||
|
public static final String replace(String string, String oldString, String newString) {
|
||||||
|
if (string == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// If the newString is null or zero length, just return the string since there's nothing
|
||||||
|
// to replace.
|
||||||
|
if (newString == null) {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
int i = 0;
|
||||||
|
// Make sure that oldString appears at least once before doing any processing.
|
||||||
|
if ((i = string.indexOf(oldString, i)) >= 0) {
|
||||||
|
// Use char []'s, as they are more efficient to deal with.
|
||||||
|
char[] string2 = string.toCharArray();
|
||||||
|
char[] newString2 = newString.toCharArray();
|
||||||
|
int oLength = oldString.length();
|
||||||
|
StringBuilder buf = new StringBuilder(string2.length);
|
||||||
|
buf.append(string2, 0, i).append(newString2);
|
||||||
|
i += oLength;
|
||||||
|
int j = i;
|
||||||
|
// Replace all remaining instances of oldString with newString.
|
||||||
|
while ((i = string.indexOf(oldString, i)) > 0) {
|
||||||
|
buf.append(string2, j, i - j).append(newString2);
|
||||||
|
i += oLength;
|
||||||
|
j = i;
|
||||||
|
}
|
||||||
|
buf.append(string2, j, string2.length - j);
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
132
source/org/jivesoftware/smackx/workgroup/packet/AgentInfo.java
Normal file
132
source/org/jivesoftware/smackx/workgroup/packet/AgentInfo.java
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IQ packet for retrieving and changing the Agent personal information.
|
||||||
|
*/
|
||||||
|
public class AgentInfo extends IQ {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "agent-info";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
private String jid;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Agent's jid.
|
||||||
|
*
|
||||||
|
* @return the Agent's jid.
|
||||||
|
*/
|
||||||
|
public String getJid() {
|
||||||
|
return jid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Agent's jid.
|
||||||
|
*
|
||||||
|
* @param jid the jid of the agent.
|
||||||
|
*/
|
||||||
|
public void setJid(String jid) {
|
||||||
|
this.jid = jid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Agent's name. The name of the agent may be different than the user's name.
|
||||||
|
* This property may be shown in the webchat client.
|
||||||
|
*
|
||||||
|
* @return the Agent's name.
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Agent's name. The name of the agent may be different than the user's name.
|
||||||
|
* This property may be shown in the webchat client.
|
||||||
|
*
|
||||||
|
* @param name the new name of the agent.
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
|
||||||
|
if (jid != null) {
|
||||||
|
buf.append("<jid>").append(getJid()).append("</jid>");
|
||||||
|
}
|
||||||
|
if (name != null) {
|
||||||
|
buf.append("<name>").append(getName()).append("</name>");
|
||||||
|
}
|
||||||
|
buf.append("</").append(ELEMENT_NAME).append("> ");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IQProvider for AgentInfo packets.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public static class Provider implements IQProvider {
|
||||||
|
|
||||||
|
public Provider() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
AgentInfo answer = new AgentInfo();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
if (parser.getName().equals("jid")) {
|
||||||
|
answer.setJid(parser.nextText());
|
||||||
|
}
|
||||||
|
else if (parser.getName().equals("name")) {
|
||||||
|
answer.setName(parser.nextText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getName().equals(ELEMENT_NAME)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
266
source/org/jivesoftware/smackx/workgroup/packet/AgentStatus.java
Normal file
266
source/org/jivesoftware/smackx/workgroup/packet/AgentStatus.java
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Agent status packet.
|
||||||
|
*
|
||||||
|
* @author Matt Tucker
|
||||||
|
*/
|
||||||
|
public class AgentStatus implements PacketExtension {
|
||||||
|
|
||||||
|
private static final SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
|
||||||
|
|
||||||
|
static {
|
||||||
|
UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "agent-status";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
|
||||||
|
|
||||||
|
private String workgroupJID;
|
||||||
|
private List currentChats = new ArrayList();
|
||||||
|
private int maxChats = -1;
|
||||||
|
|
||||||
|
AgentStatus() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWorkgroupJID() {
|
||||||
|
return workgroupJID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a collection of ChatInfo where each ChatInfo represents a Chat where this agent
|
||||||
|
* is participating.
|
||||||
|
*
|
||||||
|
* @return a collection of ChatInfo where each ChatInfo represents a Chat where this agent
|
||||||
|
* is participating.
|
||||||
|
*/
|
||||||
|
public List getCurrentChats() {
|
||||||
|
return Collections.unmodifiableList(currentChats);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxChats() {
|
||||||
|
return maxChats;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\"");
|
||||||
|
if (workgroupJID != null) {
|
||||||
|
buf.append(" jid=\"").append(workgroupJID).append("\"");
|
||||||
|
}
|
||||||
|
buf.append(">");
|
||||||
|
if (maxChats != -1) {
|
||||||
|
buf.append("<max-chats>").append(maxChats).append("</max-chats>");
|
||||||
|
}
|
||||||
|
if (!currentChats.isEmpty()) {
|
||||||
|
buf.append("<current-chats xmlns= \"http://jivesoftware.com/protocol/workgroup\">");
|
||||||
|
for (Iterator it = currentChats.iterator(); it.hasNext();) {
|
||||||
|
buf.append(((ChatInfo)it.next()).toXML());
|
||||||
|
}
|
||||||
|
buf.append("</current-chats>");
|
||||||
|
}
|
||||||
|
buf.append("</").append(this.getElementName()).append("> ");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents information about a Chat where this Agent is participating.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public static class ChatInfo {
|
||||||
|
|
||||||
|
private String sessionID;
|
||||||
|
private String userID;
|
||||||
|
private Date date;
|
||||||
|
private String email;
|
||||||
|
private String username;
|
||||||
|
private String question;
|
||||||
|
|
||||||
|
public ChatInfo(String sessionID, String userID, Date date, String email, String username, String question) {
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
this.userID = userID;
|
||||||
|
this.date = date;
|
||||||
|
this.email = email;
|
||||||
|
this.username = username;
|
||||||
|
this.question = question;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the sessionID associated to this chat. Each chat will have a unique sessionID
|
||||||
|
* that could be used for retrieving the whole transcript of the conversation.
|
||||||
|
*
|
||||||
|
* @return the sessionID associated to this chat.
|
||||||
|
*/
|
||||||
|
public String getSessionID() {
|
||||||
|
return sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user unique identification of the user that made the initial request and
|
||||||
|
* for which this chat was generated. If the user joined using an anonymous connection
|
||||||
|
* then the userID will be the value of the ID attribute of the USER element. Otherwise,
|
||||||
|
* the userID will be the bare JID of the user that made the request.
|
||||||
|
*
|
||||||
|
* @return the user unique identification of the user that made the initial request.
|
||||||
|
*/
|
||||||
|
public String getUserID() {
|
||||||
|
return userID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the date when this agent joined the chat.
|
||||||
|
*
|
||||||
|
* @return the date when this agent joined the chat.
|
||||||
|
*/
|
||||||
|
public Date getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the email address associated with the user.
|
||||||
|
*
|
||||||
|
* @return the email address associated with the user.
|
||||||
|
*/
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the username(nickname) associated with the user.
|
||||||
|
*
|
||||||
|
* @return the username associated with the user.
|
||||||
|
*/
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the question the user asked.
|
||||||
|
*
|
||||||
|
* @return the question the user asked, if any.
|
||||||
|
*/
|
||||||
|
public String getQuestion() {
|
||||||
|
return question;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<chat ");
|
||||||
|
if (sessionID != null) {
|
||||||
|
buf.append(" sessionID=\"").append(sessionID).append("\"");
|
||||||
|
}
|
||||||
|
if (userID != null) {
|
||||||
|
buf.append(" userID=\"").append(userID).append("\"");
|
||||||
|
}
|
||||||
|
if (date != null) {
|
||||||
|
buf.append(" startTime=\"").append(UTC_FORMAT.format(date)).append("\"");
|
||||||
|
}
|
||||||
|
if (email != null) {
|
||||||
|
buf.append(" email=\"").append(email).append("\"");
|
||||||
|
}
|
||||||
|
if (username != null) {
|
||||||
|
buf.append(" username=\"").append(username).append("\"");
|
||||||
|
}
|
||||||
|
if (question != null) {
|
||||||
|
buf.append(" question=\"").append(question).append("\"");
|
||||||
|
}
|
||||||
|
buf.append("/>");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension provider for AgentStatus packets.
|
||||||
|
*/
|
||||||
|
public static class Provider implements PacketExtensionProvider {
|
||||||
|
|
||||||
|
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
|
||||||
|
AgentStatus agentStatus = new AgentStatus();
|
||||||
|
|
||||||
|
agentStatus.workgroupJID = parser.getAttributeValue("", "jid");
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
if ("chat".equals(parser.getName())) {
|
||||||
|
agentStatus.currentChats.add(parseChatInfo(parser));
|
||||||
|
}
|
||||||
|
else if ("max-chats".equals(parser.getName())) {
|
||||||
|
agentStatus.maxChats = Integer.parseInt(parser.nextText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG &&
|
||||||
|
ELEMENT_NAME.equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return agentStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChatInfo parseChatInfo(XmlPullParser parser) {
|
||||||
|
|
||||||
|
String sessionID = parser.getAttributeValue("", "sessionID");
|
||||||
|
String userID = parser.getAttributeValue("", "userID");
|
||||||
|
Date date = null;
|
||||||
|
try {
|
||||||
|
date = UTC_FORMAT.parse(parser.getAttributeValue("", "startTime"));
|
||||||
|
}
|
||||||
|
catch (ParseException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
String email = parser.getAttributeValue("", "email");
|
||||||
|
String username = parser.getAttributeValue("", "username");
|
||||||
|
String question = parser.getAttributeValue("", "question");
|
||||||
|
|
||||||
|
return new ChatInfo(sessionID, userID, date, email, username, question);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,163 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Agent status request packet. This packet is used by agents to request the list of
|
||||||
|
* agents in a workgroup. The response packet contains a list of packets. Presence
|
||||||
|
* packets from individual agents follow.
|
||||||
|
*
|
||||||
|
* @author Matt Tucker
|
||||||
|
*/
|
||||||
|
public class AgentStatusRequest extends IQ {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "agent-status-request";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
|
||||||
|
|
||||||
|
private Set agents;
|
||||||
|
|
||||||
|
public AgentStatusRequest() {
|
||||||
|
agents = new HashSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAgentCount() {
|
||||||
|
return agents.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set getAgents() {
|
||||||
|
return Collections.unmodifiableSet(agents);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
|
||||||
|
synchronized (agents) {
|
||||||
|
for (Iterator i=agents.iterator(); i.hasNext(); ) {
|
||||||
|
Item item = (Item) i.next();
|
||||||
|
buf.append("<agent jid=\"").append(item.getJID()).append("\">");
|
||||||
|
if (item.getName() != null) {
|
||||||
|
buf.append("<name xmlns=\""+ AgentInfo.NAMESPACE + "\">");
|
||||||
|
buf.append(item.getName());
|
||||||
|
buf.append("</name>");
|
||||||
|
}
|
||||||
|
buf.append("</agent>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.append("</").append(this.getElementName()).append("> ");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Item {
|
||||||
|
|
||||||
|
private String jid;
|
||||||
|
private String type;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Item(String jid, String type, String name) {
|
||||||
|
this.jid = jid;
|
||||||
|
this.type = type;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJID() {
|
||||||
|
return jid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension provider for AgentStatusRequest packets.
|
||||||
|
*/
|
||||||
|
public static class Provider implements IQProvider {
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
AgentStatusRequest statusRequest = new AgentStatusRequest();
|
||||||
|
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
throw new IllegalStateException("Parser not in proper position, or bad XML.");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) && ("agent".equals(parser.getName()))) {
|
||||||
|
statusRequest.agents.add(parseAgent(parser));
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG &&
|
||||||
|
"agent-status-request".equals(parser.getName()))
|
||||||
|
{
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return statusRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Item parseAgent(XmlPullParser parser) throws Exception {
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
String jid = parser.getAttributeValue("", "jid");
|
||||||
|
String type = parser.getAttributeValue("", "type");
|
||||||
|
String name = null;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) && ("name".equals(parser.getName()))) {
|
||||||
|
name = parser.nextText();
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG &&
|
||||||
|
"agent".equals(parser.getName()))
|
||||||
|
{
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Item(jid, type, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a request for getting the jid of the workgroups where an agent can work or could
|
||||||
|
* represent the result of such request which will contain the list of workgroups JIDs where the
|
||||||
|
* agent can work.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public class AgentWorkgroups extends IQ {
|
||||||
|
|
||||||
|
private String agentJID;
|
||||||
|
private List workgroups;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an AgentWorkgroups request for the given agent. This IQ will be sent and an answer
|
||||||
|
* will be received with the jid of the workgroups where the agent can work.
|
||||||
|
*
|
||||||
|
* @param agentJID the id of the agent to get his workgroups.
|
||||||
|
*/
|
||||||
|
public AgentWorkgroups(String agentJID) {
|
||||||
|
this.agentJID = agentJID;
|
||||||
|
this.workgroups = new ArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an AgentWorkgroups which will contain the JIDs of the workgroups where an agent can
|
||||||
|
* work.
|
||||||
|
*
|
||||||
|
* @param agentJID the id of the agent that can work in the list of workgroups.
|
||||||
|
* @param workgroups the list of workgroup JIDs where the agent can work.
|
||||||
|
*/
|
||||||
|
public AgentWorkgroups(String agentJID, List workgroups) {
|
||||||
|
this.agentJID = agentJID;
|
||||||
|
this.workgroups = workgroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAgentJID() {
|
||||||
|
return agentJID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of workgroup JIDs where the agent can work.
|
||||||
|
*
|
||||||
|
* @return a list of workgroup JIDs where the agent can work.
|
||||||
|
*/
|
||||||
|
public List getWorkgroups() {
|
||||||
|
return Collections.unmodifiableList(workgroups);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<workgroups xmlns=\"http://jabber.org/protocol/workgroup\" jid=\"")
|
||||||
|
.append(agentJID)
|
||||||
|
.append("\">");
|
||||||
|
|
||||||
|
for (Iterator it=workgroups.iterator(); it.hasNext();) {
|
||||||
|
String workgroupJID = (String) it.next();
|
||||||
|
buf.append("<workgroup jid=\"" + workgroupJID + "\"/>");
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.append("</workgroups>");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IQProvider for AgentWorkgroups packets.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public static class Provider implements IQProvider {
|
||||||
|
|
||||||
|
public Provider() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
String agentJID = parser.getAttributeValue("", "jid");
|
||||||
|
List workgroups = new ArrayList();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
if (parser.getName().equals("workgroup")) {
|
||||||
|
workgroups.add(parser.getAttributeValue("", "jid"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getName().equals("workgroups")) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AgentWorkgroups(agentJID, workgroups);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A IQ packet used to depart a workgroup queue. There are two cases for issuing a depart
|
||||||
|
* queue request:<ul>
|
||||||
|
* <li>The user wants to leave the queue. In this case, an instance of this class
|
||||||
|
* should be created without passing in a user address.
|
||||||
|
* <li>An administrator or the server removes wants to remove a user from the queue.
|
||||||
|
* In that case, the address of the user to remove from the queue should be
|
||||||
|
* used to create an instance of this class.</ul>
|
||||||
|
*
|
||||||
|
* @author loki der quaeler
|
||||||
|
*/
|
||||||
|
public class DepartQueuePacket extends IQ {
|
||||||
|
|
||||||
|
private String user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a depart queue request packet to the specified workgroup.
|
||||||
|
*
|
||||||
|
* @param workgroup the workgroup to depart.
|
||||||
|
*/
|
||||||
|
public DepartQueuePacket(String workgroup) {
|
||||||
|
this(workgroup, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a depart queue request to the specified workgroup and for the
|
||||||
|
* specified user.
|
||||||
|
*
|
||||||
|
* @param workgroup the workgroup to depart.
|
||||||
|
* @param user the user to make depart from the queue.
|
||||||
|
*/
|
||||||
|
public DepartQueuePacket(String workgroup, String user) {
|
||||||
|
this.user = user;
|
||||||
|
|
||||||
|
setTo(workgroup);
|
||||||
|
setType(IQ.Type.SET);
|
||||||
|
setFrom(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder("<depart-queue xmlns=\"http://jabber.org/protocol/workgroup\"");
|
||||||
|
|
||||||
|
if (this.user != null) {
|
||||||
|
buf.append("><jid>").append(this.user).append("</jid></depart-queue>");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buf.append("/>");
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.MetaData;
|
||||||
|
import org.jivesoftware.smackx.workgroup.util.MetaDataUtils;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This provider parses meta data if it's not contained already in a larger extension provider.
|
||||||
|
*
|
||||||
|
* @author loki der quaeler
|
||||||
|
*/
|
||||||
|
public class MetaDataProvider implements PacketExtensionProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PacketExtensionProvider implementation
|
||||||
|
*/
|
||||||
|
public PacketExtension parseExtension (XmlPullParser parser)
|
||||||
|
throws Exception {
|
||||||
|
Map metaData = MetaDataUtils.parseMetaData(parser);
|
||||||
|
|
||||||
|
return new MetaData(metaData);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile: ,v $
|
||||||
|
* $Revision: $
|
||||||
|
* $Date: $
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999-2005 Jive Software. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is the proprietary information of Jive Software.
|
||||||
|
* Use is subject to license terms.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
public class MonitorPacket extends IQ {
|
||||||
|
|
||||||
|
private String sessionID;
|
||||||
|
|
||||||
|
private boolean isMonitor;
|
||||||
|
|
||||||
|
public boolean isMonitor() {
|
||||||
|
return isMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMonitor(boolean monitor) {
|
||||||
|
isMonitor = monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSessionID() {
|
||||||
|
return sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSessionID(String sessionID) {
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "monitor";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
|
||||||
|
buf.append('"');
|
||||||
|
buf.append(NAMESPACE);
|
||||||
|
buf.append('"');
|
||||||
|
buf.append(">");
|
||||||
|
if (sessionID != null) {
|
||||||
|
buf.append("<makeOwner sessionID=\""+sessionID+"\"></makeOwner>");
|
||||||
|
}
|
||||||
|
buf.append("</").append(ELEMENT_NAME).append("> ");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension provider for Monitor Packets.
|
||||||
|
*/
|
||||||
|
public static class InternalProvider implements IQProvider {
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
throw new IllegalStateException("Parser not in proper position, or bad XML.");
|
||||||
|
}
|
||||||
|
|
||||||
|
MonitorPacket packet = new MonitorPacket();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) && ("isMonitor".equals(parser.getName()))) {
|
||||||
|
String value = parser.nextText();
|
||||||
|
if ("false".equalsIgnoreCase(value)) {
|
||||||
|
packet.setMonitor(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
packet.setMonitor(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && "monitor".equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,173 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet used for requesting information about occupants of a room or for retrieving information
|
||||||
|
* such information.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public class OccupantsInfo extends IQ {
|
||||||
|
|
||||||
|
private static final SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
|
||||||
|
|
||||||
|
static {
|
||||||
|
UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "occupants-info";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
private String roomID;
|
||||||
|
private final Set<OccupantInfo> occupants;
|
||||||
|
|
||||||
|
public OccupantsInfo(String roomID) {
|
||||||
|
this.roomID = roomID;
|
||||||
|
this.occupants = new HashSet<OccupantInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRoomID() {
|
||||||
|
return roomID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOccupantsCount() {
|
||||||
|
return occupants.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<OccupantInfo> getOccupants() {
|
||||||
|
return Collections.unmodifiableSet(occupants);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE);
|
||||||
|
buf.append("\" roomID=\"").append(roomID).append("\">");
|
||||||
|
synchronized (occupants) {
|
||||||
|
for (OccupantInfo occupant : occupants) {
|
||||||
|
buf.append("<occupant>");
|
||||||
|
// Add the occupant jid
|
||||||
|
buf.append("<jid>");
|
||||||
|
buf.append(occupant.getJID());
|
||||||
|
buf.append("</jid>");
|
||||||
|
// Add the occupant nickname
|
||||||
|
buf.append("<name>");
|
||||||
|
buf.append(occupant.getNickname());
|
||||||
|
buf.append("</name>");
|
||||||
|
// Add the date when the occupant joined the room
|
||||||
|
buf.append("<joined>");
|
||||||
|
buf.append(UTC_FORMAT.format(occupant.getJoined()));
|
||||||
|
buf.append("</joined>");
|
||||||
|
buf.append("</occupant>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.append("</").append(ELEMENT_NAME).append("> ");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class OccupantInfo {
|
||||||
|
|
||||||
|
private String jid;
|
||||||
|
private String nickname;
|
||||||
|
private Date joined;
|
||||||
|
|
||||||
|
public OccupantInfo(String jid, String nickname, Date joined) {
|
||||||
|
this.jid = jid;
|
||||||
|
this.nickname = nickname;
|
||||||
|
this.joined = joined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJID() {
|
||||||
|
return jid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNickname() {
|
||||||
|
return nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getJoined() {
|
||||||
|
return joined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension provider for AgentStatusRequest packets.
|
||||||
|
*/
|
||||||
|
public static class Provider implements IQProvider {
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
throw new IllegalStateException("Parser not in proper position, or bad XML.");
|
||||||
|
}
|
||||||
|
OccupantsInfo occupantsInfo = new OccupantsInfo(parser.getAttributeValue("", "roomID"));
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) &&
|
||||||
|
("occupant".equals(parser.getName()))) {
|
||||||
|
occupantsInfo.occupants.add(parseOccupantInfo(parser));
|
||||||
|
} else if (eventType == XmlPullParser.END_TAG &&
|
||||||
|
ELEMENT_NAME.equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return occupantsInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OccupantInfo parseOccupantInfo(XmlPullParser parser) throws Exception {
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
String jid = null;
|
||||||
|
String nickname = null;
|
||||||
|
Date joined = null;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) && ("jid".equals(parser.getName()))) {
|
||||||
|
jid = parser.nextText();
|
||||||
|
} else if ((eventType == XmlPullParser.START_TAG) &&
|
||||||
|
("nickname".equals(parser.getName()))) {
|
||||||
|
nickname = parser.nextText();
|
||||||
|
} else if ((eventType == XmlPullParser.START_TAG) &&
|
||||||
|
("joined".equals(parser.getName()))) {
|
||||||
|
joined = UTC_FORMAT.parse(parser.nextText());
|
||||||
|
} else if (eventType == XmlPullParser.END_TAG &&
|
||||||
|
"occupant".equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new OccupantInfo(jid, nickname, joined);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,210 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.MetaData;
|
||||||
|
import org.jivesoftware.smackx.workgroup.agent.InvitationRequest;
|
||||||
|
import org.jivesoftware.smackx.workgroup.agent.OfferContent;
|
||||||
|
import org.jivesoftware.smackx.workgroup.agent.TransferRequest;
|
||||||
|
import org.jivesoftware.smackx.workgroup.agent.UserRequest;
|
||||||
|
import org.jivesoftware.smackx.workgroup.util.MetaDataUtils;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IQProvider for agent offer requests.
|
||||||
|
*
|
||||||
|
* @author loki der quaeler
|
||||||
|
*/
|
||||||
|
public class OfferRequestProvider implements IQProvider {
|
||||||
|
|
||||||
|
public OfferRequestProvider() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
int eventType = parser.getEventType();
|
||||||
|
String sessionID = null;
|
||||||
|
int timeout = -1;
|
||||||
|
OfferContent content = null;
|
||||||
|
boolean done = false;
|
||||||
|
Map metaData = new HashMap();
|
||||||
|
|
||||||
|
if (eventType != XmlPullParser.START_TAG) {
|
||||||
|
// throw exception
|
||||||
|
}
|
||||||
|
|
||||||
|
String userJID = parser.getAttributeValue("", "jid");
|
||||||
|
// Default userID to the JID.
|
||||||
|
String userID = userJID;
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
eventType = parser.next();
|
||||||
|
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
String elemName = parser.getName();
|
||||||
|
|
||||||
|
if ("timeout".equals(elemName)) {
|
||||||
|
timeout = Integer.parseInt(parser.nextText());
|
||||||
|
}
|
||||||
|
else if (MetaData.ELEMENT_NAME.equals(elemName)) {
|
||||||
|
metaData = MetaDataUtils.parseMetaData(parser);
|
||||||
|
}
|
||||||
|
else if (SessionID.ELEMENT_NAME.equals(elemName)) {
|
||||||
|
sessionID = parser.getAttributeValue("", "id");
|
||||||
|
}
|
||||||
|
else if (UserID.ELEMENT_NAME.equals(elemName)) {
|
||||||
|
userID = parser.getAttributeValue("", "id");
|
||||||
|
}
|
||||||
|
else if ("user-request".equals(elemName)) {
|
||||||
|
content = UserRequest.getInstance();
|
||||||
|
}
|
||||||
|
else if (RoomInvitation.ELEMENT_NAME.equals(elemName)) {
|
||||||
|
RoomInvitation invitation = (RoomInvitation) PacketParserUtils
|
||||||
|
.parsePacketExtension(RoomInvitation.ELEMENT_NAME, RoomInvitation.NAMESPACE, parser);
|
||||||
|
content = new InvitationRequest(invitation.getInviter(), invitation.getRoom(),
|
||||||
|
invitation.getReason());
|
||||||
|
}
|
||||||
|
else if (RoomTransfer.ELEMENT_NAME.equals(elemName)) {
|
||||||
|
RoomTransfer transfer = (RoomTransfer) PacketParserUtils
|
||||||
|
.parsePacketExtension(RoomTransfer.ELEMENT_NAME, RoomTransfer.NAMESPACE, parser);
|
||||||
|
content = new TransferRequest(transfer.getInviter(), transfer.getRoom(), transfer.getReason());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
if ("offer".equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OfferRequestPacket offerRequest =
|
||||||
|
new OfferRequestPacket(userJID, userID, timeout, metaData, sessionID, content);
|
||||||
|
offerRequest.setType(IQ.Type.SET);
|
||||||
|
|
||||||
|
return offerRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class OfferRequestPacket extends IQ {
|
||||||
|
|
||||||
|
private int timeout;
|
||||||
|
private String userID;
|
||||||
|
private String userJID;
|
||||||
|
private Map metaData;
|
||||||
|
private String sessionID;
|
||||||
|
private OfferContent content;
|
||||||
|
|
||||||
|
public OfferRequestPacket(String userJID, String userID, int timeout, Map metaData,
|
||||||
|
String sessionID, OfferContent content)
|
||||||
|
{
|
||||||
|
this.userJID = userJID;
|
||||||
|
this.userID = userID;
|
||||||
|
this.timeout = timeout;
|
||||||
|
this.metaData = metaData;
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the userID, which is either the same as the userJID or a special
|
||||||
|
* value that the user provided as part of their "join queue" request.
|
||||||
|
*
|
||||||
|
* @return the user ID.
|
||||||
|
*/
|
||||||
|
public String getUserID() {
|
||||||
|
return userID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The JID of the user that made the "join queue" request.
|
||||||
|
*
|
||||||
|
* @return the user JID.
|
||||||
|
*/
|
||||||
|
public String getUserJID() {
|
||||||
|
return userJID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the session ID associated with the request and ensuing chat. If the offer
|
||||||
|
* does not contain a session ID, <tt>null</tt> will be returned.
|
||||||
|
*
|
||||||
|
* @return the session id associated with the request.
|
||||||
|
*/
|
||||||
|
public String getSessionID() {
|
||||||
|
return sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of seconds the agent has to accept the offer before
|
||||||
|
* it times out.
|
||||||
|
*
|
||||||
|
* @return the offer timeout (in seconds).
|
||||||
|
*/
|
||||||
|
public int getTimeout() {
|
||||||
|
return this.timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferContent getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns any meta-data associated with the offer.
|
||||||
|
*
|
||||||
|
* @return meta-data associated with the offer.
|
||||||
|
*/
|
||||||
|
public Map getMetaData() {
|
||||||
|
return this.metaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML () {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<offer xmlns=\"http://jabber.org/protocol/workgroup\" jid=\"").append(userJID).append("\">");
|
||||||
|
buf.append("<timeout>").append(timeout).append("</timeout>");
|
||||||
|
|
||||||
|
if (sessionID != null) {
|
||||||
|
buf.append('<').append(SessionID.ELEMENT_NAME);
|
||||||
|
buf.append(" session=\"");
|
||||||
|
buf.append(getSessionID()).append("\" xmlns=\"");
|
||||||
|
buf.append(SessionID.NAMESPACE).append("\"/>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metaData != null) {
|
||||||
|
buf.append(MetaDataUtils.serializeMetaData(metaData));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userID != null) {
|
||||||
|
buf.append('<').append(UserID.ELEMENT_NAME);
|
||||||
|
buf.append(" id=\"");
|
||||||
|
buf.append(userID).append("\" xmlns=\"");
|
||||||
|
buf.append(UserID.NAMESPACE).append("\"/>");
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.append("</offer>");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IQProvider class which has savvy about the offer-revoke tag.<br>
|
||||||
|
*
|
||||||
|
* @author loki der quaeler
|
||||||
|
*/
|
||||||
|
public class OfferRevokeProvider implements IQProvider {
|
||||||
|
|
||||||
|
public IQ parseIQ (XmlPullParser parser) throws Exception {
|
||||||
|
// The parser will be positioned on the opening IQ tag, so get the JID attribute.
|
||||||
|
String userJID = parser.getAttributeValue("", "jid");
|
||||||
|
// Default the userID to the JID.
|
||||||
|
String userID = userJID;
|
||||||
|
String reason = null;
|
||||||
|
String sessionID = null;
|
||||||
|
boolean done = false;
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) && parser.getName().equals("reason")) {
|
||||||
|
reason = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG)
|
||||||
|
&& parser.getName().equals(SessionID.ELEMENT_NAME)) {
|
||||||
|
sessionID = parser.getAttributeValue("", "id");
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG)
|
||||||
|
&& parser.getName().equals(UserID.ELEMENT_NAME)) {
|
||||||
|
userID = parser.getAttributeValue("", "id");
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.END_TAG) && parser.getName().equals(
|
||||||
|
"offer-revoke"))
|
||||||
|
{
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OfferRevokePacket(userJID, userID, reason, sessionID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OfferRevokePacket extends IQ {
|
||||||
|
|
||||||
|
private String userJID;
|
||||||
|
private String userID;
|
||||||
|
private String sessionID;
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
public OfferRevokePacket (String userJID, String userID, String cause, String sessionID) {
|
||||||
|
this.userJID = userJID;
|
||||||
|
this.userID = userID;
|
||||||
|
this.reason = cause;
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserJID() {
|
||||||
|
return userJID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserID() {
|
||||||
|
return this.userID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReason() {
|
||||||
|
return this.reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSessionID() {
|
||||||
|
return this.sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML () {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append("<offer-revoke xmlns=\"http://jabber.org/protocol/workgroup\" jid=\"").append(userID).append("\">");
|
||||||
|
if (reason != null) {
|
||||||
|
buf.append("<reason>").append(reason).append("</reason>");
|
||||||
|
}
|
||||||
|
if (sessionID != null) {
|
||||||
|
buf.append(new SessionID(sessionID).toXML());
|
||||||
|
}
|
||||||
|
if (userID != null) {
|
||||||
|
buf.append(new UserID(userID).toXML());
|
||||||
|
}
|
||||||
|
buf.append("</offer-revoke>");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,200 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.QueueUser;
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue details packet extension, which contains details about the users
|
||||||
|
* currently in a queue.
|
||||||
|
*/
|
||||||
|
public class QueueDetails implements PacketExtension {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "notify-queue-details";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
|
||||||
|
|
||||||
|
private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of users in the queue.
|
||||||
|
*/
|
||||||
|
private Set users;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new QueueDetails packet
|
||||||
|
*/
|
||||||
|
private QueueDetails() {
|
||||||
|
users = new HashSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of users currently in the queue that are waiting to
|
||||||
|
* be routed to an agent.
|
||||||
|
*
|
||||||
|
* @return the number of users in the queue.
|
||||||
|
*/
|
||||||
|
public int getUserCount() {
|
||||||
|
return users.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set of users in the queue that are waiting to
|
||||||
|
* be routed to an agent (as QueueUser objects).
|
||||||
|
*
|
||||||
|
* @return a Set for the users waiting in a queue.
|
||||||
|
*/
|
||||||
|
public Set getUsers() {
|
||||||
|
synchronized (users) {
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a user to the packet.
|
||||||
|
*
|
||||||
|
* @param user the user.
|
||||||
|
*/
|
||||||
|
private void addUser(QueueUser user) {
|
||||||
|
synchronized (users) {
|
||||||
|
users.add(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
|
||||||
|
|
||||||
|
synchronized (users) {
|
||||||
|
for (Iterator i=users.iterator(); i.hasNext(); ) {
|
||||||
|
QueueUser user = (QueueUser)i.next();
|
||||||
|
int position = user.getQueuePosition();
|
||||||
|
int timeRemaining = user.getEstimatedRemainingTime();
|
||||||
|
Date timestamp = user.getQueueJoinTimestamp();
|
||||||
|
|
||||||
|
buf.append("<user jid=\"").append(user.getUserID()).append("\">");
|
||||||
|
|
||||||
|
if (position != -1) {
|
||||||
|
buf.append("<position>").append(position).append("</position>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeRemaining != -1) {
|
||||||
|
buf.append("<time>").append(timeRemaining).append("</time>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timestamp != null) {
|
||||||
|
buf.append("<join-time>");
|
||||||
|
buf.append(DATE_FORMATTER.format(timestamp));
|
||||||
|
buf.append("</join-time>");
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.append("</user>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.append("</").append(ELEMENT_NAME).append(">");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provider class for QueueDetails packet extensions.
|
||||||
|
*/
|
||||||
|
public static class Provider implements PacketExtensionProvider {
|
||||||
|
|
||||||
|
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
|
||||||
|
QueueDetails queueDetails = new QueueDetails();
|
||||||
|
|
||||||
|
int eventType = parser.getEventType();
|
||||||
|
while (eventType != XmlPullParser.END_TAG &&
|
||||||
|
"notify-queue-details".equals(parser.getName()))
|
||||||
|
{
|
||||||
|
eventType = parser.next();
|
||||||
|
while ((eventType == XmlPullParser.START_TAG) && "user".equals(parser.getName())) {
|
||||||
|
String uid = null;
|
||||||
|
int position = -1;
|
||||||
|
int time = -1;
|
||||||
|
Date joinTime = null;
|
||||||
|
|
||||||
|
uid = parser.getAttributeValue("", "jid");
|
||||||
|
|
||||||
|
if (uid == null) {
|
||||||
|
// throw exception
|
||||||
|
}
|
||||||
|
|
||||||
|
eventType = parser.next();
|
||||||
|
while ((eventType != XmlPullParser.END_TAG)
|
||||||
|
|| (! "user".equals(parser.getName())))
|
||||||
|
{
|
||||||
|
if ("position".equals(parser.getName())) {
|
||||||
|
position = Integer.parseInt(parser.nextText());
|
||||||
|
}
|
||||||
|
else if ("time".equals(parser.getName())) {
|
||||||
|
time = Integer.parseInt(parser.nextText());
|
||||||
|
}
|
||||||
|
else if ("join-time".equals(parser.getName())) {
|
||||||
|
joinTime = DATE_FORMATTER.parse(parser.nextText());
|
||||||
|
}
|
||||||
|
else if( parser.getName().equals( "waitTime" ) ) {
|
||||||
|
Date wait = DATE_FORMATTER.parse( parser.nextText() );
|
||||||
|
System.out.println( wait );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
eventType = parser.next();
|
||||||
|
|
||||||
|
if (eventType != XmlPullParser.END_TAG) {
|
||||||
|
// throw exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
queueDetails.addUser(new QueueUser(uid, position, time, joinTime));
|
||||||
|
|
||||||
|
eventType = parser.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return queueDetails;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,158 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.agent.WorkgroupQueue;
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class QueueOverview implements PacketExtension {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static String ELEMENT_NAME = "notify-queue";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static String NAMESPACE = "http://jabber.org/protocol/workgroup";
|
||||||
|
|
||||||
|
private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
|
||||||
|
|
||||||
|
private int averageWaitTime;
|
||||||
|
private Date oldestEntry;
|
||||||
|
private int userCount;
|
||||||
|
private WorkgroupQueue.Status status;
|
||||||
|
|
||||||
|
QueueOverview() {
|
||||||
|
this.averageWaitTime = -1;
|
||||||
|
this.oldestEntry = null;
|
||||||
|
this.userCount = -1;
|
||||||
|
this.status = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAverageWaitTime(int averageWaitTime) {
|
||||||
|
this.averageWaitTime = averageWaitTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAverageWaitTime () {
|
||||||
|
return averageWaitTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOldestEntry(Date oldestEntry) {
|
||||||
|
this.oldestEntry = oldestEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getOldestEntry() {
|
||||||
|
return oldestEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUserCount(int userCount) {
|
||||||
|
this.userCount = userCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserCount() {
|
||||||
|
return userCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WorkgroupQueue.Status getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setStatus(WorkgroupQueue.Status status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getElementName () {
|
||||||
|
return ELEMENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace () {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML () {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
|
||||||
|
|
||||||
|
if (userCount != -1) {
|
||||||
|
buf.append("<count>").append(userCount).append("</count>");
|
||||||
|
}
|
||||||
|
if (oldestEntry != null) {
|
||||||
|
buf.append("<oldest>").append(DATE_FORMATTER.format(oldestEntry)).append("</oldest>");
|
||||||
|
}
|
||||||
|
if (averageWaitTime != -1) {
|
||||||
|
buf.append("<time>").append(averageWaitTime).append("</time>");
|
||||||
|
}
|
||||||
|
if (status != null) {
|
||||||
|
buf.append("<status>").append(status).append("</status>");
|
||||||
|
}
|
||||||
|
buf.append("</").append(ELEMENT_NAME).append(">");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Provider implements PacketExtensionProvider {
|
||||||
|
|
||||||
|
public PacketExtension parseExtension (XmlPullParser parser) throws Exception {
|
||||||
|
int eventType = parser.getEventType();
|
||||||
|
QueueOverview queueOverview = new QueueOverview();
|
||||||
|
|
||||||
|
if (eventType != XmlPullParser.START_TAG) {
|
||||||
|
// throw exception
|
||||||
|
}
|
||||||
|
|
||||||
|
eventType = parser.next();
|
||||||
|
while ((eventType != XmlPullParser.END_TAG)
|
||||||
|
|| (!ELEMENT_NAME.equals(parser.getName())))
|
||||||
|
{
|
||||||
|
if ("count".equals(parser.getName())) {
|
||||||
|
queueOverview.setUserCount(Integer.parseInt(parser.nextText()));
|
||||||
|
}
|
||||||
|
else if ("time".equals(parser.getName())) {
|
||||||
|
queueOverview.setAverageWaitTime(Integer.parseInt(parser.nextText()));
|
||||||
|
}
|
||||||
|
else if ("oldest".equals(parser.getName())) {
|
||||||
|
queueOverview.setOldestEntry((DATE_FORMATTER.parse(parser.nextText())));
|
||||||
|
}
|
||||||
|
else if ("status".equals(parser.getName())) {
|
||||||
|
queueOverview.setStatus(WorkgroupQueue.Status.fromString(parser.nextText()));
|
||||||
|
}
|
||||||
|
|
||||||
|
eventType = parser.next();
|
||||||
|
|
||||||
|
if (eventType != XmlPullParser.END_TAG) {
|
||||||
|
// throw exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eventType != XmlPullParser.END_TAG) {
|
||||||
|
// throw exception
|
||||||
|
}
|
||||||
|
|
||||||
|
return queueOverview;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
122
source/org/jivesoftware/smackx/workgroup/packet/QueueUpdate.java
Normal file
122
source/org/jivesoftware/smackx/workgroup/packet/QueueUpdate.java
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IQ packet that encapsulates both types of workgroup queue
|
||||||
|
* status notifications -- position updates, and estimated time
|
||||||
|
* left in the queue updates.
|
||||||
|
*/
|
||||||
|
public class QueueUpdate implements PacketExtension {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "queue-status";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
|
||||||
|
|
||||||
|
private int position;
|
||||||
|
private int remainingTime;
|
||||||
|
|
||||||
|
public QueueUpdate(int position, int remainingTime) {
|
||||||
|
this.position = position;
|
||||||
|
this.remainingTime = remainingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user's position in the workgroup queue, or -1 if the
|
||||||
|
* value isn't set on this packet.
|
||||||
|
*
|
||||||
|
* @return the position in the workgroup queue.
|
||||||
|
*/
|
||||||
|
public int getPosition() {
|
||||||
|
return this.position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user's estimated time left in the workgroup queue, or
|
||||||
|
* -1 if the value isn't set on this packet.
|
||||||
|
*
|
||||||
|
* @return the estimated time left in the workgroup queue.
|
||||||
|
*/
|
||||||
|
public int getRemaingTime() {
|
||||||
|
return remainingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append("<queue-status xmlns=\"http://jabber.org/protocol/workgroup\">");
|
||||||
|
if (position != -1) {
|
||||||
|
buf.append("<position>").append(position).append("</position>");
|
||||||
|
}
|
||||||
|
if (remainingTime != -1) {
|
||||||
|
buf.append("<time>").append(remainingTime).append("</time>");
|
||||||
|
}
|
||||||
|
buf.append("</queue-status>");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Provider implements PacketExtensionProvider {
|
||||||
|
|
||||||
|
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
|
||||||
|
boolean done = false;
|
||||||
|
int position = -1;
|
||||||
|
int timeRemaining = -1;
|
||||||
|
while (!done) {
|
||||||
|
parser.next();
|
||||||
|
String elementName = parser.getName();
|
||||||
|
if (parser.getEventType() == XmlPullParser.START_TAG && "position".equals(elementName)) {
|
||||||
|
try {
|
||||||
|
position = Integer.parseInt(parser.nextText());
|
||||||
|
}
|
||||||
|
catch (NumberFormatException nfe) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (parser.getEventType() == XmlPullParser.START_TAG && "time".equals(elementName)) {
|
||||||
|
try {
|
||||||
|
timeRemaining = Integer.parseInt(parser.nextText());
|
||||||
|
}
|
||||||
|
catch (NumberFormatException nfe) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (parser.getEventType() == XmlPullParser.END_TAG && "queue-status".equals(elementName)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new QueueUpdate(position, timeRemaining);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,177 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension for {@link org.jivesoftware.smackx.workgroup.agent.InvitationRequest}.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public class RoomInvitation implements PacketExtension {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "invite";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of entity being invited to a groupchat support session.
|
||||||
|
*/
|
||||||
|
private Type type;
|
||||||
|
/**
|
||||||
|
* JID of the entity being invited. The entity could be another agent, user , a queue or a workgroup. In
|
||||||
|
* the case of a queue or a workgroup the server will select the best agent to invite.
|
||||||
|
*/
|
||||||
|
private String invitee;
|
||||||
|
/**
|
||||||
|
* Full JID of the user that sent the invitation.
|
||||||
|
*/
|
||||||
|
private String inviter;
|
||||||
|
/**
|
||||||
|
* ID of the session that originated the initial user request.
|
||||||
|
*/
|
||||||
|
private String sessionID;
|
||||||
|
/**
|
||||||
|
* JID of the room to join if offer is accepted.
|
||||||
|
*/
|
||||||
|
private String room;
|
||||||
|
/**
|
||||||
|
* Text provided by the inviter explaining the reason why the invitee is invited.
|
||||||
|
*/
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
public RoomInvitation(Type type, String invitee, String sessionID, String reason) {
|
||||||
|
this.type = type;
|
||||||
|
this.invitee = invitee;
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
this.reason = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RoomInvitation() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInviter() {
|
||||||
|
return inviter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRoom() {
|
||||||
|
return room;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReason() {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSessionID() {
|
||||||
|
return sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE);
|
||||||
|
buf.append("\" type=\"").append(type).append("\">");
|
||||||
|
buf.append("<session xmlns=\"http://jivesoftware.com/protocol/workgroup\" id=\"").append(sessionID).append("\"></session>");
|
||||||
|
if (invitee != null) {
|
||||||
|
buf.append("<invitee>").append(invitee).append("</invitee>");
|
||||||
|
}
|
||||||
|
if (inviter != null) {
|
||||||
|
buf.append("<inviter>").append(inviter).append("</inviter>");
|
||||||
|
}
|
||||||
|
if (reason != null) {
|
||||||
|
buf.append("<reason>").append(reason).append("</reason>");
|
||||||
|
}
|
||||||
|
// Add packet extensions, if any are defined.
|
||||||
|
buf.append("</").append(ELEMENT_NAME).append("> ");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of entity being invited to a groupchat support session.
|
||||||
|
*/
|
||||||
|
public static enum Type {
|
||||||
|
/**
|
||||||
|
* A user is being invited to a groupchat support session. The user could be another agent
|
||||||
|
* or just a regular XMPP user.
|
||||||
|
*/
|
||||||
|
user,
|
||||||
|
/**
|
||||||
|
* Some agent of the specified queue will be invited to the groupchat support session.
|
||||||
|
*/
|
||||||
|
queue,
|
||||||
|
/**
|
||||||
|
* Some agent of the specified workgroup will be invited to the groupchat support session.
|
||||||
|
*/
|
||||||
|
workgroup
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Provider implements PacketExtensionProvider {
|
||||||
|
|
||||||
|
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
|
||||||
|
final RoomInvitation invitation = new RoomInvitation();
|
||||||
|
invitation.type = Type.valueOf(parser.getAttributeValue("", "type"));
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
parser.next();
|
||||||
|
String elementName = parser.getName();
|
||||||
|
if (parser.getEventType() == XmlPullParser.START_TAG) {
|
||||||
|
if ("session".equals(elementName)) {
|
||||||
|
invitation.sessionID = parser.getAttributeValue("", "id");
|
||||||
|
}
|
||||||
|
else if ("invitee".equals(elementName)) {
|
||||||
|
invitation.invitee = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ("inviter".equals(elementName)) {
|
||||||
|
invitation.inviter = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ("reason".equals(elementName)) {
|
||||||
|
invitation.reason = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ("room".equals(elementName)) {
|
||||||
|
invitation.room = parser.nextText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (parser.getEventType() == XmlPullParser.END_TAG && ELEMENT_NAME.equals(elementName)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return invitation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,177 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension for {@link org.jivesoftware.smackx.workgroup.agent.TransferRequest}.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public class RoomTransfer implements PacketExtension {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "transfer";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of entity being invited to a groupchat support session.
|
||||||
|
*/
|
||||||
|
private RoomTransfer.Type type;
|
||||||
|
/**
|
||||||
|
* JID of the entity being invited. The entity could be another agent, user , a queue or a workgroup. In
|
||||||
|
* the case of a queue or a workgroup the server will select the best agent to invite.
|
||||||
|
*/
|
||||||
|
private String invitee;
|
||||||
|
/**
|
||||||
|
* Full JID of the user that sent the invitation.
|
||||||
|
*/
|
||||||
|
private String inviter;
|
||||||
|
/**
|
||||||
|
* ID of the session that originated the initial user request.
|
||||||
|
*/
|
||||||
|
private String sessionID;
|
||||||
|
/**
|
||||||
|
* JID of the room to join if offer is accepted.
|
||||||
|
*/
|
||||||
|
private String room;
|
||||||
|
/**
|
||||||
|
* Text provided by the inviter explaining the reason why the invitee is invited.
|
||||||
|
*/
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
public RoomTransfer(RoomTransfer.Type type, String invitee, String sessionID, String reason) {
|
||||||
|
this.type = type;
|
||||||
|
this.invitee = invitee;
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
this.reason = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RoomTransfer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInviter() {
|
||||||
|
return inviter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRoom() {
|
||||||
|
return room;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReason() {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSessionID() {
|
||||||
|
return sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE);
|
||||||
|
buf.append("\" type=\"").append(type).append("\">");
|
||||||
|
buf.append("<session xmlns=\"http://jivesoftware.com/protocol/workgroup\" id=\"").append(sessionID).append("\"></session>");
|
||||||
|
if (invitee != null) {
|
||||||
|
buf.append("<invitee>").append(invitee).append("</invitee>");
|
||||||
|
}
|
||||||
|
if (inviter != null) {
|
||||||
|
buf.append("<inviter>").append(inviter).append("</inviter>");
|
||||||
|
}
|
||||||
|
if (reason != null) {
|
||||||
|
buf.append("<reason>").append(reason).append("</reason>");
|
||||||
|
}
|
||||||
|
// Add packet extensions, if any are defined.
|
||||||
|
buf.append("</").append(ELEMENT_NAME).append("> ");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of entity being invited to a groupchat support session.
|
||||||
|
*/
|
||||||
|
public static enum Type {
|
||||||
|
/**
|
||||||
|
* A user is being invited to a groupchat support session. The user could be another agent
|
||||||
|
* or just a regular XMPP user.
|
||||||
|
*/
|
||||||
|
user,
|
||||||
|
/**
|
||||||
|
* Some agent of the specified queue will be invited to the groupchat support session.
|
||||||
|
*/
|
||||||
|
queue,
|
||||||
|
/**
|
||||||
|
* Some agent of the specified workgroup will be invited to the groupchat support session.
|
||||||
|
*/
|
||||||
|
workgroup
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Provider implements PacketExtensionProvider {
|
||||||
|
|
||||||
|
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
|
||||||
|
final RoomTransfer invitation = new RoomTransfer();
|
||||||
|
invitation.type = RoomTransfer.Type.valueOf(parser.getAttributeValue("", "type"));
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
parser.next();
|
||||||
|
String elementName = parser.getName();
|
||||||
|
if (parser.getEventType() == XmlPullParser.START_TAG) {
|
||||||
|
if ("session".equals(elementName)) {
|
||||||
|
invitation.sessionID = parser.getAttributeValue("", "id");
|
||||||
|
}
|
||||||
|
else if ("invitee".equals(elementName)) {
|
||||||
|
invitation.invitee = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ("inviter".equals(elementName)) {
|
||||||
|
invitation.inviter = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ("reason".equals(elementName)) {
|
||||||
|
invitation.reason = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ("room".equals(elementName)) {
|
||||||
|
invitation.room = parser.nextText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (parser.getEventType() == XmlPullParser.END_TAG && ELEMENT_NAME.equals(elementName)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return invitation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
public class SessionID implements PacketExtension {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "session";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
private String sessionID;
|
||||||
|
|
||||||
|
public SessionID(String sessionID) {
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSessionID() {
|
||||||
|
return this.sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\" ");
|
||||||
|
buf.append("id=\"").append(this.getSessionID());
|
||||||
|
buf.append("\"/>");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Provider implements PacketExtensionProvider {
|
||||||
|
|
||||||
|
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
|
||||||
|
String sessionID = parser.getAttributeValue("", "id");
|
||||||
|
|
||||||
|
// Advance to end of extension.
|
||||||
|
parser.next();
|
||||||
|
|
||||||
|
return new SessionID(sessionID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the conversation transcript that occured in a group chat room between an Agent
|
||||||
|
* and a user that requested assistance. The transcript contains all the Messages that were sent
|
||||||
|
* to the room as well as the sent presences.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public class Transcript extends IQ {
|
||||||
|
private String sessionID;
|
||||||
|
private List packets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a transcript request for the given sessionID.
|
||||||
|
*
|
||||||
|
* @param sessionID the id of the session to get the conversation transcript.
|
||||||
|
*/
|
||||||
|
public Transcript(String sessionID) {
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
this.packets = new ArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new transcript for the given sessionID and list of packets. The list of packets
|
||||||
|
* may include Messages and/or Presences.
|
||||||
|
*
|
||||||
|
* @param sessionID the id of the session that generated this conversation transcript.
|
||||||
|
* @param packets the list of messages and presences send to the room.
|
||||||
|
*/
|
||||||
|
public Transcript(String sessionID, List packets) {
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
this.packets = packets;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns id of the session that generated this conversation transcript. The sessionID is a
|
||||||
|
* value generated by the server when a new request is received.
|
||||||
|
*
|
||||||
|
* @return id of the session that generated this conversation transcript.
|
||||||
|
*/
|
||||||
|
public String getSessionID() {
|
||||||
|
return sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of Messages and Presences that were sent to the room.
|
||||||
|
*
|
||||||
|
* @return the list of Messages and Presences that were sent to the room.
|
||||||
|
*/
|
||||||
|
public List getPackets() {
|
||||||
|
return Collections.unmodifiableList(packets);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<transcript xmlns=\"http://jivesoftware.com/protocol/workgroup\" sessionID=\"")
|
||||||
|
.append(sessionID)
|
||||||
|
.append("\">");
|
||||||
|
|
||||||
|
for (Iterator it=packets.iterator(); it.hasNext();) {
|
||||||
|
Packet packet = (Packet) it.next();
|
||||||
|
buf.append(packet.toXML());
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.append("</transcript>");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IQProvider for transcripts.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public class TranscriptProvider implements IQProvider {
|
||||||
|
|
||||||
|
public TranscriptProvider() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
String sessionID = parser.getAttributeValue("", "sessionID");
|
||||||
|
List packets = new ArrayList();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
if (parser.getName().equals("message")) {
|
||||||
|
packets.add(PacketParserUtils.parseMessage(parser));
|
||||||
|
}
|
||||||
|
else if (parser.getName().equals("presence")) {
|
||||||
|
packets.add(PacketParserUtils.parsePresence(parser));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getName().equals("transcript")) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Transcript(sessionID, packets);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IQ packet for retrieving the transcript search form, submiting the completed search form
|
||||||
|
* or retrieving the answer of a transcript search.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public class TranscriptSearch extends IQ {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "transcript-search";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
|
||||||
|
// Add packet extensions, if any are defined.
|
||||||
|
buf.append(getExtensionsXML());
|
||||||
|
buf.append("</").append(ELEMENT_NAME).append("> ");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IQProvider for TranscriptSearch packets.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public static class Provider implements IQProvider {
|
||||||
|
|
||||||
|
public Provider() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
TranscriptSearch answer = new TranscriptSearch();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
// Parse the packet extension
|
||||||
|
answer.addExtension(PacketParserUtils.parsePacketExtension(parser.getName(), parser.getNamespace(), parser));
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getName().equals(ELEMENT_NAME)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
247
source/org/jivesoftware/smackx/workgroup/packet/Transcripts.java
Normal file
247
source/org/jivesoftware/smackx/workgroup/packet/Transcripts.java
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a list of conversation transcripts that a user had in all his history. Each
|
||||||
|
* transcript summary includes the sessionID which may be used for getting more detailed
|
||||||
|
* information about the conversation. {@link org.jivesoftware.smackx.workgroup.packet.Transcript}
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public class Transcripts extends IQ {
|
||||||
|
|
||||||
|
private static final SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
|
||||||
|
static {
|
||||||
|
UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String userID;
|
||||||
|
private List<Transcripts.TranscriptSummary> summaries;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a transcripts request for the given userID.
|
||||||
|
*
|
||||||
|
* @param userID the id of the user to get his conversations transcripts.
|
||||||
|
*/
|
||||||
|
public Transcripts(String userID) {
|
||||||
|
this.userID = userID;
|
||||||
|
this.summaries = new ArrayList<Transcripts.TranscriptSummary>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Transcripts which will contain the transcript summaries of the given user.
|
||||||
|
*
|
||||||
|
* @param userID the id of the user. Could be a real JID or a unique String that identifies
|
||||||
|
* anonymous users.
|
||||||
|
* @param summaries the list of TranscriptSummaries.
|
||||||
|
*/
|
||||||
|
public Transcripts(String userID, List<Transcripts.TranscriptSummary> summaries) {
|
||||||
|
this.userID = userID;
|
||||||
|
this.summaries = summaries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the id of the user that was involved in the conversations. The userID could be a
|
||||||
|
* real JID if the connected user was not anonymous. Otherwise, the userID will be a String
|
||||||
|
* that was provided by the anonymous user as a way to idenitify the user across many user
|
||||||
|
* sessions.
|
||||||
|
*
|
||||||
|
* @return the id of the user that was involved in the conversations.
|
||||||
|
*/
|
||||||
|
public String getUserID() {
|
||||||
|
return userID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of TranscriptSummary. A TranscriptSummary does not contain the conversation
|
||||||
|
* transcript but some summary information like the sessionID and the time when the
|
||||||
|
* conversation started and finished. Once you have the sessionID it is possible to get the
|
||||||
|
* full conversation transcript.
|
||||||
|
*
|
||||||
|
* @return a list of TranscriptSummary.
|
||||||
|
*/
|
||||||
|
public List<Transcripts.TranscriptSummary> getSummaries() {
|
||||||
|
return Collections.unmodifiableList(summaries);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<transcripts xmlns=\"http://jivesoftware.com/protocol/workgroup\" userID=\"")
|
||||||
|
.append(userID)
|
||||||
|
.append("\">");
|
||||||
|
|
||||||
|
for (TranscriptSummary transcriptSummary : summaries) {
|
||||||
|
buf.append(transcriptSummary.toXML());
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.append("</transcripts>");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A TranscriptSummary contains some information about a conversation such as the ID of the
|
||||||
|
* session or the date when the conversation started and finished. You will need to use the
|
||||||
|
* sessionID to get the full conversation transcript.
|
||||||
|
*/
|
||||||
|
public static class TranscriptSummary {
|
||||||
|
private String sessionID;
|
||||||
|
private Date joinTime;
|
||||||
|
private Date leftTime;
|
||||||
|
private List<AgentDetail> agentDetails;
|
||||||
|
|
||||||
|
public TranscriptSummary(String sessionID, Date joinTime, Date leftTime, List<AgentDetail> agentDetails) {
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
this.joinTime = joinTime;
|
||||||
|
this.leftTime = leftTime;
|
||||||
|
this.agentDetails = agentDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ID of the session that is related to this conversation transcript. The
|
||||||
|
* sessionID could be used for getting the full conversation transcript.
|
||||||
|
*
|
||||||
|
* @return the ID of the session that is related to this conversation transcript.
|
||||||
|
*/
|
||||||
|
public String getSessionID() {
|
||||||
|
return sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Date when the conversation started.
|
||||||
|
*
|
||||||
|
* @return the Date when the conversation started.
|
||||||
|
*/
|
||||||
|
public Date getJoinTime() {
|
||||||
|
return joinTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Date when the conversation finished.
|
||||||
|
*
|
||||||
|
* @return the Date when the conversation finished.
|
||||||
|
*/
|
||||||
|
public Date getLeftTime() {
|
||||||
|
return leftTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of AgentDetails. For each Agent that was involved in the conversation
|
||||||
|
* the list will include an AgentDetail. An AgentDetail contains the JID of the agent
|
||||||
|
* as well as the time when the Agent joined and left the conversation.
|
||||||
|
*
|
||||||
|
* @return a list of AgentDetails.
|
||||||
|
*/
|
||||||
|
public List<AgentDetail> getAgentDetails() {
|
||||||
|
return agentDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<transcript sessionID=\"")
|
||||||
|
.append(sessionID)
|
||||||
|
.append("\">");
|
||||||
|
|
||||||
|
if (joinTime != null) {
|
||||||
|
buf.append("<joinTime>").append(UTC_FORMAT.format(joinTime)).append("</joinTime>");
|
||||||
|
}
|
||||||
|
if (leftTime != null) {
|
||||||
|
buf.append("<leftTime>").append(UTC_FORMAT.format(leftTime)).append("</leftTime>");
|
||||||
|
}
|
||||||
|
buf.append("<agents>");
|
||||||
|
for (AgentDetail agentDetail : agentDetails) {
|
||||||
|
buf.append(agentDetail.toXML());
|
||||||
|
}
|
||||||
|
buf.append("</agents></transcript>");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An AgentDetail contains information of an Agent that was involved in a conversation.
|
||||||
|
*/
|
||||||
|
public static class AgentDetail {
|
||||||
|
private String agentJID;
|
||||||
|
private Date joinTime;
|
||||||
|
private Date leftTime;
|
||||||
|
|
||||||
|
public AgentDetail(String agentJID, Date joinTime, Date leftTime) {
|
||||||
|
this.agentJID = agentJID;
|
||||||
|
this.joinTime = joinTime;
|
||||||
|
this.leftTime = leftTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the bare JID of the Agent that was involved in the conversation.
|
||||||
|
*
|
||||||
|
* @return the bared JID of the Agent that was involved in the conversation.
|
||||||
|
*/
|
||||||
|
public String getAgentJID() {
|
||||||
|
return agentJID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Date when the Agent joined the conversation.
|
||||||
|
*
|
||||||
|
* @return the Date when the Agent joined the conversation.
|
||||||
|
*/
|
||||||
|
public Date getJoinTime() {
|
||||||
|
return joinTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Date when the Agent left the conversation.
|
||||||
|
*
|
||||||
|
* @return the Date when the Agent left the conversation.
|
||||||
|
*/
|
||||||
|
public Date getLeftTime() {
|
||||||
|
return leftTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<agent>");
|
||||||
|
|
||||||
|
if (agentJID != null) {
|
||||||
|
buf.append("<agentJID>").append(agentJID).append("</agentJID>");
|
||||||
|
}
|
||||||
|
if (joinTime != null) {
|
||||||
|
buf.append("<joinTime>").append(UTC_FORMAT.format(joinTime)).append("</joinTime>");
|
||||||
|
}
|
||||||
|
if (leftTime != null) {
|
||||||
|
buf.append("<leftTime>").append(UTC_FORMAT.format(leftTime)).append("</leftTime>");
|
||||||
|
}
|
||||||
|
buf.append("</agent>");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IQProvider for transcripts summaries.
|
||||||
|
*
|
||||||
|
* @author Gaston Dombiak
|
||||||
|
*/
|
||||||
|
public class TranscriptsProvider implements IQProvider {
|
||||||
|
|
||||||
|
private static final SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
|
||||||
|
static {
|
||||||
|
UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TranscriptsProvider() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
String userID = parser.getAttributeValue("", "userID");
|
||||||
|
List<Transcripts.TranscriptSummary> summaries = new ArrayList<Transcripts.TranscriptSummary>();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
if (parser.getName().equals("transcript")) {
|
||||||
|
summaries.add(parseSummary(parser));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getName().equals("transcripts")) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Transcripts(userID, summaries);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Transcripts.TranscriptSummary parseSummary(XmlPullParser parser) throws IOException,
|
||||||
|
XmlPullParserException {
|
||||||
|
String sessionID = parser.getAttributeValue("", "sessionID");
|
||||||
|
Date joinTime = null;
|
||||||
|
Date leftTime = null;
|
||||||
|
List<Transcripts.AgentDetail> agents = new ArrayList<Transcripts.AgentDetail>();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
if (parser.getName().equals("joinTime")) {
|
||||||
|
try {
|
||||||
|
joinTime = UTC_FORMAT.parse(parser.nextText());
|
||||||
|
} catch (ParseException e) {}
|
||||||
|
}
|
||||||
|
else if (parser.getName().equals("leftTime")) {
|
||||||
|
try {
|
||||||
|
leftTime = UTC_FORMAT.parse(parser.nextText());
|
||||||
|
} catch (ParseException e) {}
|
||||||
|
}
|
||||||
|
else if (parser.getName().equals("agents")) {
|
||||||
|
agents = parseAgents(parser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getName().equals("transcript")) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Transcripts.TranscriptSummary(sessionID, joinTime, leftTime, agents);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Transcripts.AgentDetail> parseAgents(XmlPullParser parser) throws IOException, XmlPullParserException {
|
||||||
|
List<Transcripts.AgentDetail> agents = new ArrayList<Transcripts.AgentDetail>();
|
||||||
|
String agentJID = null;
|
||||||
|
Date joinTime = null;
|
||||||
|
Date leftTime = null;
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
if (parser.getName().equals("agentJID")) {
|
||||||
|
agentJID = parser.nextText();
|
||||||
|
}
|
||||||
|
else if (parser.getName().equals("joinTime")) {
|
||||||
|
try {
|
||||||
|
joinTime = UTC_FORMAT.parse(parser.nextText());
|
||||||
|
} catch (ParseException e) {}
|
||||||
|
}
|
||||||
|
else if (parser.getName().equals("leftTime")) {
|
||||||
|
try {
|
||||||
|
leftTime = UTC_FORMAT.parse(parser.nextText());
|
||||||
|
} catch (ParseException e) {}
|
||||||
|
}
|
||||||
|
else if (parser.getName().equals("agent")) {
|
||||||
|
agentJID = null;
|
||||||
|
joinTime = null;
|
||||||
|
leftTime = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getName().equals("agents")) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
else if (parser.getName().equals("agent")) {
|
||||||
|
agents.add(new Transcripts.AgentDetail(agentJID, joinTime, leftTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return agents;
|
||||||
|
}
|
||||||
|
}
|
77
source/org/jivesoftware/smackx/workgroup/packet/UserID.java
Normal file
77
source/org/jivesoftware/smackx/workgroup/packet/UserID.java
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
public class UserID implements PacketExtension {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "user";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
private String userID;
|
||||||
|
|
||||||
|
public UserID(String userID) {
|
||||||
|
this.userID = userID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserID() {
|
||||||
|
return this.userID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\" ");
|
||||||
|
buf.append("id=\"").append(this.getUserID());
|
||||||
|
buf.append("\"/>");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Provider implements PacketExtensionProvider {
|
||||||
|
|
||||||
|
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
|
||||||
|
String userID = parser.getAttributeValue("", "id");
|
||||||
|
|
||||||
|
// Advance to end of extension.
|
||||||
|
parser.next();
|
||||||
|
|
||||||
|
return new UserID(userID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A packet extension that contains information about the user and agent in a
|
||||||
|
* workgroup chat. The packet extension is attached to group chat invitations.
|
||||||
|
*/
|
||||||
|
public class WorkgroupInformation implements PacketExtension {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "workgroup";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
|
||||||
|
|
||||||
|
private String workgroupJID;
|
||||||
|
|
||||||
|
public WorkgroupInformation(String workgroupJID){
|
||||||
|
this.workgroupJID = workgroupJID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWorkgroupJID() {
|
||||||
|
return workgroupJID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append('<').append(ELEMENT_NAME);
|
||||||
|
buf.append(" jid=\"").append(getWorkgroupJID()).append("\"");
|
||||||
|
buf.append(" xmlns=\"").append(NAMESPACE).append("\" />");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Provider implements PacketExtensionProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PacketExtensionProvider implementation
|
||||||
|
*/
|
||||||
|
public PacketExtension parseExtension (XmlPullParser parser)
|
||||||
|
throws Exception {
|
||||||
|
String workgroupJID = parser.getAttributeValue("", "jid");
|
||||||
|
|
||||||
|
// since this is a start and end tag, and we arrive on the start, this should guarantee
|
||||||
|
// we leave on the end
|
||||||
|
parser.next();
|
||||||
|
|
||||||
|
return new WorkgroupInformation(workgroupJID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.settings;
|
||||||
|
|
||||||
|
public class ChatSetting {
|
||||||
|
private String key;
|
||||||
|
private String value;
|
||||||
|
private int type;
|
||||||
|
|
||||||
|
public ChatSetting(String key, String value, int type){
|
||||||
|
setKey(key);
|
||||||
|
setValue(value);
|
||||||
|
setType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,179 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.settings;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ChatSettings extends IQ {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defined as image type.
|
||||||
|
*/
|
||||||
|
public static final int IMAGE_SETTINGS = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defined as Text settings type.
|
||||||
|
*/
|
||||||
|
public static final int TEXT_SETTINGS = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defined as Bot settings type.
|
||||||
|
*/
|
||||||
|
public static final int BOT_SETTINGS = 2;
|
||||||
|
|
||||||
|
private List settings;
|
||||||
|
private String key;
|
||||||
|
private int type = -1;
|
||||||
|
|
||||||
|
public ChatSettings() {
|
||||||
|
settings = new ArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatSettings(String key) {
|
||||||
|
setKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSetting(ChatSetting setting) {
|
||||||
|
settings.add(setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection getSettings() {
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatSetting getChatSetting(String key) {
|
||||||
|
Collection col = getSettings();
|
||||||
|
if (col != null) {
|
||||||
|
Iterator iter = col.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
ChatSetting chatSetting = (ChatSetting)iter.next();
|
||||||
|
if (chatSetting.getKey().equals(key)) {
|
||||||
|
return chatSetting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatSetting getFirstEntry() {
|
||||||
|
if (settings.size() > 0) {
|
||||||
|
return (ChatSetting)settings.get(0);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "chat-settings";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
|
||||||
|
buf.append('"');
|
||||||
|
buf.append(NAMESPACE);
|
||||||
|
buf.append('"');
|
||||||
|
if (key != null) {
|
||||||
|
buf.append(" key=\"" + key + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type != -1) {
|
||||||
|
buf.append(" type=\"" + type + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.append("></").append(ELEMENT_NAME).append("> ");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension provider for AgentStatusRequest packets.
|
||||||
|
*/
|
||||||
|
public static class InternalProvider implements IQProvider {
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
throw new IllegalStateException("Parser not in proper position, or bad XML.");
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatSettings chatSettings = new ChatSettings();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) && ("chat-setting".equals(parser.getName()))) {
|
||||||
|
chatSettings.addSetting(parseChatSetting(parser));
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && ELEMENT_NAME.equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chatSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChatSetting parseChatSetting(XmlPullParser parser) throws Exception {
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
String key = null;
|
||||||
|
String value = null;
|
||||||
|
int type = 0;
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) && ("key".equals(parser.getName()))) {
|
||||||
|
key = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG) && ("value".equals(parser.getName()))) {
|
||||||
|
value = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG) && ("type".equals(parser.getName()))) {
|
||||||
|
type = Integer.parseInt(parser.nextText());
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && "chat-setting".equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ChatSetting(key, value, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.settings;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.util.ModelUtil;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class GenericSettings extends IQ {
|
||||||
|
|
||||||
|
private Map map = new HashMap();
|
||||||
|
|
||||||
|
private String query;
|
||||||
|
|
||||||
|
public String getQuery() {
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuery(String query) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map getMap() {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMap(Map map) {
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "generic-metadata";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
|
||||||
|
buf.append('"');
|
||||||
|
buf.append(NAMESPACE);
|
||||||
|
buf.append('"');
|
||||||
|
buf.append(">");
|
||||||
|
if (ModelUtil.hasLength(getQuery())) {
|
||||||
|
buf.append("<query>" + getQuery() + "</query>");
|
||||||
|
}
|
||||||
|
buf.append("</").append(ELEMENT_NAME).append("> ");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension provider for SoundSetting Packets.
|
||||||
|
*/
|
||||||
|
public static class InternalProvider implements IQProvider {
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
throw new IllegalStateException("Parser not in proper position, or bad XML.");
|
||||||
|
}
|
||||||
|
|
||||||
|
GenericSettings setting = new GenericSettings();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) && ("entry".equals(parser.getName()))) {
|
||||||
|
eventType = parser.next();
|
||||||
|
String name = parser.nextText();
|
||||||
|
eventType = parser.next();
|
||||||
|
String value = parser.nextText();
|
||||||
|
setting.getMap().put(name, value);
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && ELEMENT_NAME.equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return setting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.settings;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.util.ModelUtil;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
public class OfflineSettings extends IQ {
|
||||||
|
private String redirectURL;
|
||||||
|
|
||||||
|
private String offlineText;
|
||||||
|
private String emailAddress;
|
||||||
|
private String subject;
|
||||||
|
|
||||||
|
public String getRedirectURL() {
|
||||||
|
if (!ModelUtil.hasLength(redirectURL)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return redirectURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRedirectURL(String redirectURL) {
|
||||||
|
this.redirectURL = redirectURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOfflineText() {
|
||||||
|
if (!ModelUtil.hasLength(offlineText)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return offlineText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOfflineText(String offlineText) {
|
||||||
|
this.offlineText = offlineText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmailAddress() {
|
||||||
|
if (!ModelUtil.hasLength(emailAddress)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return emailAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmailAddress(String emailAddress) {
|
||||||
|
this.emailAddress = emailAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubject() {
|
||||||
|
if (!ModelUtil.hasLength(subject)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubject(String subject) {
|
||||||
|
this.subject = subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean redirects() {
|
||||||
|
return (ModelUtil.hasLength(getRedirectURL()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConfigured(){
|
||||||
|
return ModelUtil.hasLength(getEmailAddress()) &&
|
||||||
|
ModelUtil.hasLength(getSubject()) &&
|
||||||
|
ModelUtil.hasLength(getOfflineText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "offline-settings";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
|
||||||
|
buf.append('"');
|
||||||
|
buf.append(NAMESPACE);
|
||||||
|
buf.append('"');
|
||||||
|
buf.append("></").append(ELEMENT_NAME).append("> ");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension provider for AgentStatusRequest packets.
|
||||||
|
*/
|
||||||
|
public static class InternalProvider implements IQProvider {
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
throw new IllegalStateException("Parser not in proper position, or bad XML.");
|
||||||
|
}
|
||||||
|
|
||||||
|
OfflineSettings offlineSettings = new OfflineSettings();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
String redirectPage = null;
|
||||||
|
String subject = null;
|
||||||
|
String offlineText = null;
|
||||||
|
String emailAddress = null;
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) && ("redirectPage".equals(parser.getName()))) {
|
||||||
|
redirectPage = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG) && ("subject".equals(parser.getName()))) {
|
||||||
|
subject = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG) && ("offlineText".equals(parser.getName()))) {
|
||||||
|
offlineText = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG) && ("emailAddress".equals(parser.getName()))) {
|
||||||
|
emailAddress = parser.nextText();
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && "offline-settings".equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offlineSettings.setEmailAddress(emailAddress);
|
||||||
|
offlineSettings.setRedirectURL(redirectPage);
|
||||||
|
offlineSettings.setSubject(subject);
|
||||||
|
offlineSettings.setOfflineText(offlineText);
|
||||||
|
return offlineSettings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision: 38648 $
|
||||||
|
* $Date: 2006-12-27 01:46:18 -0800 (Wed, 27 Dec 2006) $
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999-2005 Jive Software. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is the proprietary information of Jive Software. Use is
|
||||||
|
subject to license terms.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.settings;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.util.ModelUtil;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
public class SearchSettings extends IQ {
|
||||||
|
private String forumsLocation;
|
||||||
|
private String kbLocation;
|
||||||
|
|
||||||
|
public boolean isSearchEnabled() {
|
||||||
|
return ModelUtil.hasLength(getForumsLocation()) && ModelUtil.hasLength(getKbLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getForumsLocation() {
|
||||||
|
return forumsLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setForumsLocation(String forumsLocation) {
|
||||||
|
this.forumsLocation = forumsLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKbLocation() {
|
||||||
|
return kbLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKbLocation(String kbLocation) {
|
||||||
|
this.kbLocation = kbLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasKB(){
|
||||||
|
return ModelUtil.hasLength(getKbLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasForums(){
|
||||||
|
return ModelUtil.hasLength(getForumsLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "search-settings";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
|
||||||
|
buf.append('"');
|
||||||
|
buf.append(NAMESPACE);
|
||||||
|
buf.append('"');
|
||||||
|
buf.append("></").append(ELEMENT_NAME).append("> ");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension provider for AgentStatusRequest packets.
|
||||||
|
*/
|
||||||
|
public static class InternalProvider implements IQProvider {
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
throw new IllegalStateException("Parser not in proper position, or bad XML.");
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchSettings settings = new SearchSettings();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
String kb = null;
|
||||||
|
String forums = null;
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) && ("forums".equals(parser.getName()))) {
|
||||||
|
forums = parser.nextText();
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG) && ("kb".equals(parser.getName()))) {
|
||||||
|
kb = parser.nextText();
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && "search-settings".equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.setForumsLocation(forums);
|
||||||
|
settings.setKbLocation(kb);
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.settings;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
public class SoundSettings extends IQ {
|
||||||
|
private String outgoingSound;
|
||||||
|
private String incomingSound;
|
||||||
|
|
||||||
|
|
||||||
|
public void setOutgoingSound(String outgoingSound) {
|
||||||
|
this.outgoingSound = outgoingSound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIncomingSound(String incomingSound) {
|
||||||
|
this.incomingSound = incomingSound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getIncomingSoundBytes() {
|
||||||
|
return StringUtils.decodeBase64(incomingSound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getOutgoingSoundBytes() {
|
||||||
|
return StringUtils.decodeBase64(outgoingSound);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "sound-settings";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
|
||||||
|
buf.append('"');
|
||||||
|
buf.append(NAMESPACE);
|
||||||
|
buf.append('"');
|
||||||
|
buf.append("></").append(ELEMENT_NAME).append("> ");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension provider for SoundSetting Packets.
|
||||||
|
*/
|
||||||
|
public static class InternalProvider implements IQProvider {
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
throw new IllegalStateException("Parser not in proper position, or bad XML.");
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundSettings soundSettings = new SoundSettings();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) && ("outgoingSound".equals(parser.getName()))) {
|
||||||
|
soundSettings.setOutgoingSound(parser.nextText());
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG) && ("incomingSound".equals(parser.getName()))) {
|
||||||
|
soundSettings.setIncomingSound(parser.nextText());
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && "sound-settings".equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return soundSettings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.settings;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.util.ModelUtil;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
public class WorkgroupProperties extends IQ {
|
||||||
|
|
||||||
|
private boolean authRequired;
|
||||||
|
private String email;
|
||||||
|
private String fullName;
|
||||||
|
private String jid;
|
||||||
|
|
||||||
|
public boolean isAuthRequired() {
|
||||||
|
return authRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthRequired(boolean authRequired) {
|
||||||
|
this.authRequired = authRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFullName() {
|
||||||
|
return fullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFullName(String fullName) {
|
||||||
|
this.fullName = fullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJid() {
|
||||||
|
return jid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJid(String jid) {
|
||||||
|
this.jid = jid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element name of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT_NAME = "workgroup-properties";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace of the packet extension.
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<").append(ELEMENT_NAME).append(" xmlns=");
|
||||||
|
buf.append('"');
|
||||||
|
buf.append(NAMESPACE);
|
||||||
|
buf.append('"');
|
||||||
|
if (ModelUtil.hasLength(getJid())) {
|
||||||
|
buf.append("jid=\"" + getJid() + "\" ");
|
||||||
|
}
|
||||||
|
buf.append("></").append(ELEMENT_NAME).append("> ");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension provider for SoundSetting Packets.
|
||||||
|
*/
|
||||||
|
public static class InternalProvider implements IQProvider {
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
throw new IllegalStateException("Parser not in proper position, or bad XML.");
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkgroupProperties props = new WorkgroupProperties();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if ((eventType == XmlPullParser.START_TAG) && ("authRequired".equals(parser.getName()))) {
|
||||||
|
props.setAuthRequired(new Boolean(parser.nextText()).booleanValue());
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG) && ("email".equals(parser.getName()))) {
|
||||||
|
props.setEmail(parser.nextText());
|
||||||
|
}
|
||||||
|
else if ((eventType == XmlPullParser.START_TAG) && ("name".equals(parser.getName()))) {
|
||||||
|
props.setFullName(parser.nextText());
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && "workgroup-properties".equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2007 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener interface for those that wish to be notified of workgroup queue events.
|
||||||
|
*
|
||||||
|
* @see Workgroup#addQueueListener(QueueListener)
|
||||||
|
* @author loki der quaeler
|
||||||
|
*/
|
||||||
|
public interface QueueListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user joined the workgroup queue.
|
||||||
|
*/
|
||||||
|
public void joinedQueue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user departed the workgroup queue.
|
||||||
|
*/
|
||||||
|
public void departedQueue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user's queue position has been updated to a new value.
|
||||||
|
*
|
||||||
|
* @param currentPosition the user's current position in the queue.
|
||||||
|
*/
|
||||||
|
public void queuePositionUpdated(int currentPosition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user's estimated remaining wait time in the queue has been updated.
|
||||||
|
*
|
||||||
|
* @param secondsRemaining the estimated number of seconds remaining until the
|
||||||
|
* the user is routed to the agent.
|
||||||
|
*/
|
||||||
|
public void queueWaitTimeUpdated(int secondsRemaining);
|
||||||
|
|
||||||
|
}
|
938
source/org/jivesoftware/smackx/workgroup/user/Workgroup.java
Normal file
938
source/org/jivesoftware/smackx/workgroup/user/Workgroup.java
Normal file
|
@ -0,0 +1,938 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision: 38648 $
|
||||||
|
* $Date: 2006-12-27 01:46:18 -0800 (Wed, 27 Dec 2006) $
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003-2005 Jive Software. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is the proprietary information of Jive Software.
|
||||||
|
* Use is subject to license terms.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.user;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.MetaData;
|
||||||
|
import org.jivesoftware.smackx.workgroup.WorkgroupInvitation;
|
||||||
|
import org.jivesoftware.smackx.workgroup.WorkgroupInvitationListener;
|
||||||
|
import org.jivesoftware.smackx.workgroup.ext.email.EmailIQ;
|
||||||
|
import org.jivesoftware.smackx.workgroup.ext.forms.WorkgroupForm;
|
||||||
|
import org.jivesoftware.smackx.workgroup.packet.DepartQueuePacket;
|
||||||
|
import org.jivesoftware.smackx.workgroup.packet.QueueUpdate;
|
||||||
|
import org.jivesoftware.smackx.workgroup.packet.SessionID;
|
||||||
|
import org.jivesoftware.smackx.workgroup.packet.UserID;
|
||||||
|
import org.jivesoftware.smackx.workgroup.settings.*;
|
||||||
|
import org.jivesoftware.smack.*;
|
||||||
|
import org.jivesoftware.smack.filter.*;
|
||||||
|
import org.jivesoftware.smack.packet.*;
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
|
import org.jivesoftware.smackx.Form;
|
||||||
|
import org.jivesoftware.smackx.FormField;
|
||||||
|
import org.jivesoftware.smackx.ServiceDiscoveryManager;
|
||||||
|
import org.jivesoftware.smackx.muc.MultiUserChat;
|
||||||
|
import org.jivesoftware.smackx.packet.DataForm;
|
||||||
|
import org.jivesoftware.smackx.packet.DiscoverInfo;
|
||||||
|
import org.jivesoftware.smackx.packet.MUCUser;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides workgroup services for users. Users can join the workgroup queue, depart the
|
||||||
|
* queue, find status information about their placement in the queue, and register to
|
||||||
|
* be notified when they are routed to an agent.<p>
|
||||||
|
* <p/>
|
||||||
|
* This class only provides a users perspective into a workgroup and is not intended
|
||||||
|
* for use by agents.
|
||||||
|
*
|
||||||
|
* @author Matt Tucker
|
||||||
|
* @author Derek DeMoro
|
||||||
|
*/
|
||||||
|
public class Workgroup {
|
||||||
|
|
||||||
|
private String workgroupJID;
|
||||||
|
private XMPPConnection connection;
|
||||||
|
private boolean inQueue;
|
||||||
|
private List invitationListeners;
|
||||||
|
private List queueListeners;
|
||||||
|
private List siteInviteListeners;
|
||||||
|
|
||||||
|
private int queuePosition = -1;
|
||||||
|
private int queueRemainingTime = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new workgroup instance using the specified workgroup JID
|
||||||
|
* (eg support@workgroup.example.com) and XMPP connection. The connection must have
|
||||||
|
* undergone a successful login before being used to construct an instance of
|
||||||
|
* this class.
|
||||||
|
*
|
||||||
|
* @param workgroupJID the JID of the workgroup.
|
||||||
|
* @param connection an XMPP connection which must have already undergone a
|
||||||
|
* successful login.
|
||||||
|
*/
|
||||||
|
public Workgroup(String workgroupJID, XMPPConnection connection) {
|
||||||
|
// Login must have been done before passing in connection.
|
||||||
|
if (!connection.isAuthenticated()) {
|
||||||
|
throw new IllegalStateException("Must login to server before creating workgroup.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.workgroupJID = workgroupJID;
|
||||||
|
this.connection = connection;
|
||||||
|
inQueue = false;
|
||||||
|
invitationListeners = new ArrayList();
|
||||||
|
queueListeners = new ArrayList();
|
||||||
|
siteInviteListeners = new ArrayList();
|
||||||
|
|
||||||
|
// Register as a queue listener for internal usage by this instance.
|
||||||
|
addQueueListener(new QueueListener() {
|
||||||
|
public void joinedQueue() {
|
||||||
|
inQueue = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void departedQueue() {
|
||||||
|
inQueue = false;
|
||||||
|
queuePosition = -1;
|
||||||
|
queueRemainingTime = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void queuePositionUpdated(int currentPosition) {
|
||||||
|
queuePosition = currentPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void queueWaitTimeUpdated(int secondsRemaining) {
|
||||||
|
queueRemainingTime = secondsRemaining;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal handling of an invitation.Recieving an invitation removes the user from the queue.
|
||||||
|
*/
|
||||||
|
MultiUserChat.addInvitationListener(connection,
|
||||||
|
new org.jivesoftware.smackx.muc.InvitationListener() {
|
||||||
|
public void invitationReceived(XMPPConnection conn, String room, String inviter,
|
||||||
|
String reason, String password, Message message) {
|
||||||
|
inQueue = false;
|
||||||
|
queuePosition = -1;
|
||||||
|
queueRemainingTime = -1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register a packet listener for all the messages sent to this client.
|
||||||
|
PacketFilter typeFilter = new PacketTypeFilter(Message.class);
|
||||||
|
|
||||||
|
connection.addPacketListener(new PacketListener() {
|
||||||
|
public void processPacket(Packet packet) {
|
||||||
|
handlePacket(packet);
|
||||||
|
}
|
||||||
|
}, typeFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of this workgroup (eg support@example.com).
|
||||||
|
*
|
||||||
|
* @return the name of the workgroup.
|
||||||
|
*/
|
||||||
|
public String getWorkgroupJID() {
|
||||||
|
return workgroupJID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the user is currently waiting in the workgroup queue.
|
||||||
|
*
|
||||||
|
* @return true if currently waiting in the queue.
|
||||||
|
*/
|
||||||
|
public boolean isInQueue() {
|
||||||
|
return inQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the workgroup is available for receiving new requests. The workgroup will be
|
||||||
|
* available only when agents are available for this workgroup.
|
||||||
|
*
|
||||||
|
* @return true if the workgroup is available for receiving new requests.
|
||||||
|
*/
|
||||||
|
public boolean isAvailable() {
|
||||||
|
Presence directedPresence = new Presence(Presence.Type.available);
|
||||||
|
directedPresence.setTo(workgroupJID);
|
||||||
|
PacketFilter typeFilter = new PacketTypeFilter(Presence.class);
|
||||||
|
PacketFilter fromFilter = new FromContainsFilter(workgroupJID);
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new AndFilter(fromFilter,
|
||||||
|
typeFilter));
|
||||||
|
|
||||||
|
connection.sendPacket(directedPresence);
|
||||||
|
|
||||||
|
Presence response = (Presence)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (response.getError() != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Presence.Type.available == response.getType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the users current position in the workgroup queue. A value of 0 means
|
||||||
|
* the user is next in line to be routed; therefore, if the queue position
|
||||||
|
* is being displayed to the end user it is usually a good idea to add 1 to
|
||||||
|
* the value this method returns before display. If the user is not currently
|
||||||
|
* waiting in the workgroup, or no queue position information is available, -1
|
||||||
|
* will be returned.
|
||||||
|
*
|
||||||
|
* @return the user's current position in the workgroup queue, or -1 if the
|
||||||
|
* position isn't available or if the user isn't in the queue.
|
||||||
|
*/
|
||||||
|
public int getQueuePosition() {
|
||||||
|
return queuePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the estimated time (in seconds) that the user has to left wait in
|
||||||
|
* the workgroup queue before being routed. If the user is not currently waiting
|
||||||
|
* int he workgroup, or no queue time information is available, -1 will be
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* @return the estimated time remaining (in seconds) that the user has to
|
||||||
|
* wait inthe workgroupu queue, or -1 if time information isn't available
|
||||||
|
* or if the user isn't int the queue.
|
||||||
|
*/
|
||||||
|
public int getQueueRemainingTime() {
|
||||||
|
return queueRemainingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Joins the workgroup queue to wait to be routed to an agent. After joining
|
||||||
|
* the queue, queue status events will be sent to indicate the user's position and
|
||||||
|
* estimated time left in the queue. Once joining the queue, there are three ways
|
||||||
|
* the user can leave the queue: <ul>
|
||||||
|
* <p/>
|
||||||
|
* <li>The user is routed to an agent, which triggers a GroupChat invitation.
|
||||||
|
* <li>The user asks to leave the queue by calling the {@link #departQueue} method.
|
||||||
|
* <li>A server error occurs, or an administrator explicitly removes the user
|
||||||
|
* from the queue.
|
||||||
|
* </ul>
|
||||||
|
* <p/>
|
||||||
|
* A user cannot request to join the queue again if already in the queue. Therefore,
|
||||||
|
* this method will throw an IllegalStateException if the user is already in the queue.<p>
|
||||||
|
* <p/>
|
||||||
|
* Some servers may be configured to require certain meta-data in order to
|
||||||
|
* join the queue. In that case, the {@link #joinQueue(Form)} method should be
|
||||||
|
* used instead of this method so that meta-data may be passed in.<p>
|
||||||
|
* <p/>
|
||||||
|
* The server tracks the conversations that a user has with agents over time. By
|
||||||
|
* default, that tracking is done using the user's JID. However, this is not always
|
||||||
|
* possible. For example, when the user is logged in anonymously using a web client.
|
||||||
|
* In that case the user ID might be a randomly generated value put into a persistent
|
||||||
|
* cookie or a username obtained via the session. A userID can be explicitly
|
||||||
|
* passed in by using the {@link #joinQueue(Form, String)} method. When specified,
|
||||||
|
* that userID will be used instead of the user's JID to track conversations. The
|
||||||
|
* server will ignore a manually specified userID if the user's connection to the server
|
||||||
|
* is not anonymous.
|
||||||
|
*
|
||||||
|
* @throws XMPPException if an error occured joining the queue. An error may indicate
|
||||||
|
* that a connection failure occured or that the server explicitly rejected the
|
||||||
|
* request to join the queue.
|
||||||
|
*/
|
||||||
|
public void joinQueue() throws XMPPException {
|
||||||
|
joinQueue(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Joins the workgroup queue to wait to be routed to an agent. After joining
|
||||||
|
* the queue, queue status events will be sent to indicate the user's position and
|
||||||
|
* estimated time left in the queue. Once joining the queue, there are three ways
|
||||||
|
* the user can leave the queue: <ul>
|
||||||
|
* <p/>
|
||||||
|
* <li>The user is routed to an agent, which triggers a GroupChat invitation.
|
||||||
|
* <li>The user asks to leave the queue by calling the {@link #departQueue} method.
|
||||||
|
* <li>A server error occurs, or an administrator explicitly removes the user
|
||||||
|
* from the queue.
|
||||||
|
* </ul>
|
||||||
|
* <p/>
|
||||||
|
* A user cannot request to join the queue again if already in the queue. Therefore,
|
||||||
|
* this method will throw an IllegalStateException if the user is already in the queue.<p>
|
||||||
|
* <p/>
|
||||||
|
* Some servers may be configured to require certain meta-data in order to
|
||||||
|
* join the queue.<p>
|
||||||
|
* <p/>
|
||||||
|
* The server tracks the conversations that a user has with agents over time. By
|
||||||
|
* default, that tracking is done using the user's JID. However, this is not always
|
||||||
|
* possible. For example, when the user is logged in anonymously using a web client.
|
||||||
|
* In that case the user ID might be a randomly generated value put into a persistent
|
||||||
|
* cookie or a username obtained via the session. A userID can be explicitly
|
||||||
|
* passed in by using the {@link #joinQueue(Form, String)} method. When specified,
|
||||||
|
* that userID will be used instead of the user's JID to track conversations. The
|
||||||
|
* server will ignore a manually specified userID if the user's connection to the server
|
||||||
|
* is not anonymous.
|
||||||
|
*
|
||||||
|
* @param answerForm the completed form the send for the join request.
|
||||||
|
* @throws XMPPException if an error occured joining the queue. An error may indicate
|
||||||
|
* that a connection failure occured or that the server explicitly rejected the
|
||||||
|
* request to join the queue.
|
||||||
|
*/
|
||||||
|
public void joinQueue(Form answerForm) throws XMPPException {
|
||||||
|
joinQueue(answerForm, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Joins the workgroup queue to wait to be routed to an agent. After joining
|
||||||
|
* the queue, queue status events will be sent to indicate the user's position and
|
||||||
|
* estimated time left in the queue. Once joining the queue, there are three ways
|
||||||
|
* the user can leave the queue: <ul>
|
||||||
|
* <p/>
|
||||||
|
* <li>The user is routed to an agent, which triggers a GroupChat invitation.
|
||||||
|
* <li>The user asks to leave the queue by calling the {@link #departQueue} method.
|
||||||
|
* <li>A server error occurs, or an administrator explicitly removes the user
|
||||||
|
* from the queue.
|
||||||
|
* </ul>
|
||||||
|
* <p/>
|
||||||
|
* A user cannot request to join the queue again if already in the queue. Therefore,
|
||||||
|
* this method will throw an IllegalStateException if the user is already in the queue.<p>
|
||||||
|
* <p/>
|
||||||
|
* Some servers may be configured to require certain meta-data in order to
|
||||||
|
* join the queue.<p>
|
||||||
|
* <p/>
|
||||||
|
* The server tracks the conversations that a user has with agents over time. By
|
||||||
|
* default, that tracking is done using the user's JID. However, this is not always
|
||||||
|
* possible. For example, when the user is logged in anonymously using a web client.
|
||||||
|
* In that case the user ID might be a randomly generated value put into a persistent
|
||||||
|
* cookie or a username obtained via the session. When specified, that userID will
|
||||||
|
* be used instead of the user's JID to track conversations. The server will ignore a
|
||||||
|
* manually specified userID if the user's connection to the server is not anonymous.
|
||||||
|
*
|
||||||
|
* @param answerForm the completed form associated with the join reqest.
|
||||||
|
* @param userID String that represents the ID of the user when using anonymous sessions
|
||||||
|
* or <tt>null</tt> if a userID should not be used.
|
||||||
|
* @throws XMPPException if an error occured joining the queue. An error may indicate
|
||||||
|
* that a connection failure occured or that the server explicitly rejected the
|
||||||
|
* request to join the queue.
|
||||||
|
*/
|
||||||
|
public void joinQueue(Form answerForm, String userID) throws XMPPException {
|
||||||
|
// If already in the queue ignore the join request.
|
||||||
|
if (inQueue) {
|
||||||
|
throw new IllegalStateException("Already in queue " + workgroupJID);
|
||||||
|
}
|
||||||
|
|
||||||
|
JoinQueuePacket joinPacket = new JoinQueuePacket(workgroupJID, answerForm, userID);
|
||||||
|
|
||||||
|
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(joinPacket.getPacketID()));
|
||||||
|
|
||||||
|
this.connection.sendPacket(joinPacket);
|
||||||
|
|
||||||
|
IQ response = (IQ)collector.nextResult(10000);
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from the server.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify listeners that we've joined the queue.
|
||||||
|
fireQueueJoinedEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Joins the workgroup queue to wait to be routed to an agent. After joining
|
||||||
|
* the queue, queue status events will be sent to indicate the user's position and
|
||||||
|
* estimated time left in the queue. Once joining the queue, there are three ways
|
||||||
|
* the user can leave the queue: <ul>
|
||||||
|
* <p/>
|
||||||
|
* <li>The user is routed to an agent, which triggers a GroupChat invitation.
|
||||||
|
* <li>The user asks to leave the queue by calling the {@link #departQueue} method.
|
||||||
|
* <li>A server error occurs, or an administrator explicitly removes the user
|
||||||
|
* from the queue.
|
||||||
|
* </ul>
|
||||||
|
* <p/>
|
||||||
|
* A user cannot request to join the queue again if already in the queue. Therefore,
|
||||||
|
* this method will throw an IllegalStateException if the user is already in the queue.<p>
|
||||||
|
* <p/>
|
||||||
|
* Some servers may be configured to require certain meta-data in order to
|
||||||
|
* join the queue.<p>
|
||||||
|
* <p/>
|
||||||
|
* The server tracks the conversations that a user has with agents over time. By
|
||||||
|
* default, that tracking is done using the user's JID. However, this is not always
|
||||||
|
* possible. For example, when the user is logged in anonymously using a web client.
|
||||||
|
* In that case the user ID might be a randomly generated value put into a persistent
|
||||||
|
* cookie or a username obtained via the session. When specified, that userID will
|
||||||
|
* be used instead of the user's JID to track conversations. The server will ignore a
|
||||||
|
* manually specified userID if the user's connection to the server is not anonymous.
|
||||||
|
*
|
||||||
|
* @param metadata metadata to create a dataform from.
|
||||||
|
* @param userID String that represents the ID of the user when using anonymous sessions
|
||||||
|
* or <tt>null</tt> if a userID should not be used.
|
||||||
|
* @throws XMPPException if an error occured joining the queue. An error may indicate
|
||||||
|
* that a connection failure occured or that the server explicitly rejected the
|
||||||
|
* request to join the queue.
|
||||||
|
*/
|
||||||
|
public void joinQueue(Map metadata, String userID) throws XMPPException {
|
||||||
|
// If already in the queue ignore the join request.
|
||||||
|
if (inQueue) {
|
||||||
|
throw new IllegalStateException("Already in queue " + workgroupJID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build dataform from metadata
|
||||||
|
Form form = new Form(Form.TYPE_SUBMIT);
|
||||||
|
Iterator iter = metadata.keySet().iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
String name = (String)iter.next();
|
||||||
|
String value = (String)metadata.get(name).toString();
|
||||||
|
|
||||||
|
String escapedName = StringUtils.escapeForXML(name);
|
||||||
|
String escapedValue = StringUtils.escapeForXML(value);
|
||||||
|
|
||||||
|
FormField field = new FormField(escapedName);
|
||||||
|
field.setType(FormField.TYPE_TEXT_SINGLE);
|
||||||
|
form.addField(field);
|
||||||
|
form.setAnswer(escapedName, escapedValue);
|
||||||
|
}
|
||||||
|
joinQueue(form, userID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Departs the workgroup queue. If the user is not currently in the queue, this
|
||||||
|
* method will do nothing.<p>
|
||||||
|
* <p/>
|
||||||
|
* Normally, the user would not manually leave the queue. However, they may wish to
|
||||||
|
* under certain circumstances -- for example, if they no longer wish to be routed
|
||||||
|
* to an agent because they've been waiting too long.
|
||||||
|
*
|
||||||
|
* @throws XMPPException if an error occured trying to send the depart queue
|
||||||
|
* request to the server.
|
||||||
|
*/
|
||||||
|
public void departQueue() throws XMPPException {
|
||||||
|
// If not in the queue ignore the depart request.
|
||||||
|
if (!inQueue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DepartQueuePacket departPacket = new DepartQueuePacket(this.workgroupJID);
|
||||||
|
PacketCollector collector = this.connection.createPacketCollector(new PacketIDFilter(departPacket.getPacketID()));
|
||||||
|
|
||||||
|
connection.sendPacket(departPacket);
|
||||||
|
|
||||||
|
IQ response = (IQ)collector.nextResult(5000);
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from the server.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify listeners that we're no longer in the queue.
|
||||||
|
fireQueueDepartedEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a queue listener that will be notified of queue events for the user
|
||||||
|
* that created this Workgroup instance.
|
||||||
|
*
|
||||||
|
* @param queueListener the queue listener.
|
||||||
|
*/
|
||||||
|
public void addQueueListener(QueueListener queueListener) {
|
||||||
|
synchronized (queueListeners) {
|
||||||
|
if (!queueListeners.contains(queueListener)) {
|
||||||
|
queueListeners.add(queueListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a queue listener.
|
||||||
|
*
|
||||||
|
* @param queueListener the queue listener.
|
||||||
|
*/
|
||||||
|
public void removeQueueListener(QueueListener queueListener) {
|
||||||
|
synchronized (queueListeners) {
|
||||||
|
queueListeners.remove(queueListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an invitation listener that will be notified of groupchat invitations
|
||||||
|
* from the workgroup for the the user that created this Workgroup instance.
|
||||||
|
*
|
||||||
|
* @param invitationListener the invitation listener.
|
||||||
|
*/
|
||||||
|
public void addInvitationListener(WorkgroupInvitationListener invitationListener) {
|
||||||
|
synchronized (invitationListeners) {
|
||||||
|
if (!invitationListeners.contains(invitationListener)) {
|
||||||
|
invitationListeners.add(invitationListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an invitation listener.
|
||||||
|
*
|
||||||
|
* @param invitationListener the invitation listener.
|
||||||
|
*/
|
||||||
|
public void removeQueueListener(WorkgroupInvitationListener invitationListener) {
|
||||||
|
synchronized (invitationListeners) {
|
||||||
|
invitationListeners.remove(invitationListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireInvitationEvent(WorkgroupInvitation invitation) {
|
||||||
|
synchronized (invitationListeners) {
|
||||||
|
for (Iterator i = invitationListeners.iterator(); i.hasNext();) {
|
||||||
|
WorkgroupInvitationListener listener = (WorkgroupInvitationListener)i.next();
|
||||||
|
listener.invitationReceived(invitation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireQueueJoinedEvent() {
|
||||||
|
synchronized (queueListeners) {
|
||||||
|
for (Iterator i = queueListeners.iterator(); i.hasNext();) {
|
||||||
|
QueueListener listener = (QueueListener)i.next();
|
||||||
|
listener.joinedQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireQueueDepartedEvent() {
|
||||||
|
synchronized (queueListeners) {
|
||||||
|
for (Iterator i = queueListeners.iterator(); i.hasNext();) {
|
||||||
|
QueueListener listener = (QueueListener)i.next();
|
||||||
|
listener.departedQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireQueuePositionEvent(int currentPosition) {
|
||||||
|
synchronized (queueListeners) {
|
||||||
|
for (Iterator i = queueListeners.iterator(); i.hasNext();) {
|
||||||
|
QueueListener listener = (QueueListener)i.next();
|
||||||
|
listener.queuePositionUpdated(currentPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireQueueTimeEvent(int secondsRemaining) {
|
||||||
|
synchronized (queueListeners) {
|
||||||
|
for (Iterator i = queueListeners.iterator(); i.hasNext();) {
|
||||||
|
QueueListener listener = (QueueListener)i.next();
|
||||||
|
listener.queueWaitTimeUpdated(secondsRemaining);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PacketListener Implementation.
|
||||||
|
|
||||||
|
private void handlePacket(Packet packet) {
|
||||||
|
if (packet instanceof Message) {
|
||||||
|
Message msg = (Message)packet;
|
||||||
|
// Check to see if the user left the queue.
|
||||||
|
PacketExtension pe = msg.getExtension("depart-queue", "http://jabber.org/protocol/workgroup");
|
||||||
|
PacketExtension queueStatus = msg.getExtension("queue-status", "http://jabber.org/protocol/workgroup");
|
||||||
|
|
||||||
|
if (pe != null) {
|
||||||
|
fireQueueDepartedEvent();
|
||||||
|
}
|
||||||
|
else if (queueStatus != null) {
|
||||||
|
QueueUpdate queueUpdate = (QueueUpdate)queueStatus;
|
||||||
|
if (queueUpdate.getPosition() != -1) {
|
||||||
|
fireQueuePositionEvent(queueUpdate.getPosition());
|
||||||
|
}
|
||||||
|
if (queueUpdate.getRemaingTime() != -1) {
|
||||||
|
fireQueueTimeEvent(queueUpdate.getRemaingTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
// Check if a room invitation was sent and if the sender is the workgroup
|
||||||
|
MUCUser mucUser = (MUCUser)msg.getExtension("x", "http://jabber.org/protocol/muc#user");
|
||||||
|
MUCUser.Invite invite = mucUser != null ? mucUser.getInvite() : null;
|
||||||
|
if (invite != null && workgroupJID.equals(invite.getFrom())) {
|
||||||
|
String sessionID = null;
|
||||||
|
Map metaData = null;
|
||||||
|
|
||||||
|
pe = msg.getExtension(SessionID.ELEMENT_NAME,
|
||||||
|
SessionID.NAMESPACE);
|
||||||
|
if (pe != null) {
|
||||||
|
sessionID = ((SessionID)pe).getSessionID();
|
||||||
|
}
|
||||||
|
|
||||||
|
pe = msg.getExtension(MetaData.ELEMENT_NAME,
|
||||||
|
MetaData.NAMESPACE);
|
||||||
|
if (pe != null) {
|
||||||
|
metaData = ((MetaData)pe).getMetaData();
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkgroupInvitation inv = new WorkgroupInvitation(connection.getUser(), msg.getFrom(),
|
||||||
|
workgroupJID, sessionID, msg.getBody(),
|
||||||
|
msg.getFrom(), metaData);
|
||||||
|
|
||||||
|
fireInvitationEvent(inv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IQ packet to request joining the workgroup queue.
|
||||||
|
*/
|
||||||
|
private class JoinQueuePacket extends IQ {
|
||||||
|
|
||||||
|
private String userID = null;
|
||||||
|
private DataForm form;
|
||||||
|
|
||||||
|
public JoinQueuePacket(String workgroup, Form answerForm, String userID) {
|
||||||
|
this.userID = userID;
|
||||||
|
|
||||||
|
setTo(workgroup);
|
||||||
|
setType(IQ.Type.SET);
|
||||||
|
|
||||||
|
form = answerForm.getDataFormToSend();
|
||||||
|
addExtension(form);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
buf.append("<join-queue xmlns=\"http://jabber.org/protocol/workgroup\">");
|
||||||
|
buf.append("<queue-notifications/>");
|
||||||
|
// Add the user unique identification if the session is anonymous
|
||||||
|
if (connection.isAnonymous()) {
|
||||||
|
buf.append(new UserID(userID).toXML());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append data form text
|
||||||
|
buf.append(form.toXML());
|
||||||
|
|
||||||
|
buf.append("</join-queue>");
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a single chat setting based on it's identified key.
|
||||||
|
*
|
||||||
|
* @param key the key to find.
|
||||||
|
* @return the ChatSetting if found, otherwise false.
|
||||||
|
* @throws XMPPException if an error occurs while getting information from the server.
|
||||||
|
*/
|
||||||
|
public ChatSetting getChatSetting(String key) throws XMPPException {
|
||||||
|
ChatSettings chatSettings = getChatSettings(key, -1);
|
||||||
|
return chatSettings.getFirstEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns ChatSettings based on type.
|
||||||
|
*
|
||||||
|
* @param type the type of ChatSettings to return.
|
||||||
|
* @return the ChatSettings of given type, otherwise null.
|
||||||
|
* @throws XMPPException if an error occurs while getting information from the server.
|
||||||
|
*/
|
||||||
|
public ChatSettings getChatSettings(int type) throws XMPPException {
|
||||||
|
return getChatSettings(null, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all ChatSettings.
|
||||||
|
*
|
||||||
|
* @return all ChatSettings of a given workgroup.
|
||||||
|
* @throws XMPPException if an error occurs while getting information from the server.
|
||||||
|
*/
|
||||||
|
public ChatSettings getChatSettings() throws XMPPException {
|
||||||
|
return getChatSettings(null, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asks the workgroup for it's Chat Settings.
|
||||||
|
*
|
||||||
|
* @return key specify a key to retrieve only that settings. Otherwise for all settings, key should be null.
|
||||||
|
* @throws XMPPException if an error occurs while getting information from the server.
|
||||||
|
*/
|
||||||
|
private ChatSettings getChatSettings(String key, int type) throws XMPPException {
|
||||||
|
ChatSettings request = new ChatSettings();
|
||||||
|
if (key != null) {
|
||||||
|
request.setKey(key);
|
||||||
|
}
|
||||||
|
if (type != -1) {
|
||||||
|
request.setType(type);
|
||||||
|
}
|
||||||
|
request.setType(IQ.Type.GET);
|
||||||
|
request.setTo(workgroupJID);
|
||||||
|
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
|
||||||
|
connection.sendPacket(request);
|
||||||
|
|
||||||
|
|
||||||
|
ChatSettings response = (ChatSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The workgroup service may be configured to send email. This queries the Workgroup Service
|
||||||
|
* to see if the email service has been configured and is available.
|
||||||
|
*
|
||||||
|
* @return true if the email service is available, otherwise return false.
|
||||||
|
*/
|
||||||
|
public boolean isEmailAvailable() {
|
||||||
|
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||||
|
|
||||||
|
try {
|
||||||
|
String workgroupService = StringUtils.parseServer(workgroupJID);
|
||||||
|
DiscoverInfo infoResult = discoManager.discoverInfo(workgroupService);
|
||||||
|
return infoResult.containsFeature("jive:email:provider");
|
||||||
|
}
|
||||||
|
catch (XMPPException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an email from the workgroup.
|
||||||
|
*
|
||||||
|
* @param to the to address of the the user to send to.
|
||||||
|
* @param from who the email is from.
|
||||||
|
* @param subject the subject of the email.
|
||||||
|
* @param message the body of the email.
|
||||||
|
* @param sendAsHTML true if the message should be sent as html, otherwise specify false for plain text.
|
||||||
|
* @return true if the email was sent successfully, otherwise false.
|
||||||
|
* @throws XMPPException if an error occurs while sending the email.
|
||||||
|
*/
|
||||||
|
public boolean sendMail(String to, String from, String subject, String message, boolean sendAsHTML) throws XMPPException {
|
||||||
|
EmailIQ request = new EmailIQ();
|
||||||
|
request.setToAddress(to);
|
||||||
|
request.setFromAddress(from);
|
||||||
|
request.setSubject(subject);
|
||||||
|
request.setMessage(message);
|
||||||
|
request.setHtml(sendAsHTML);
|
||||||
|
|
||||||
|
request.setType(IQ.Type.SET);
|
||||||
|
request.setTo(workgroupJID);
|
||||||
|
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
|
||||||
|
connection.sendPacket(request);
|
||||||
|
|
||||||
|
|
||||||
|
Packet response = collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an email from the workgroup.
|
||||||
|
*
|
||||||
|
* @param to the to address of the the user to send to.
|
||||||
|
* @param sessionID the sessionID of the chat.
|
||||||
|
* @return true if the email was sent successfully, otherwise false.
|
||||||
|
* @throws XMPPException if an error occurs while sending the email.
|
||||||
|
*/
|
||||||
|
public boolean sendTranscript(String to, String sessionID) throws XMPPException {
|
||||||
|
EmailIQ request = new EmailIQ();
|
||||||
|
request.setToAddress(to);
|
||||||
|
request.setSessionID(sessionID);
|
||||||
|
|
||||||
|
request.setType(IQ.Type.SET);
|
||||||
|
request.setTo(workgroupJID);
|
||||||
|
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
|
||||||
|
connection.sendPacket(request);
|
||||||
|
|
||||||
|
|
||||||
|
Packet response = collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asks the workgroup for it's Offline Settings.
|
||||||
|
*
|
||||||
|
* @return offlineSettings the offline settings for this workgroup.
|
||||||
|
* @throws XMPPException if an error occurs while getting information from the server.
|
||||||
|
*/
|
||||||
|
public OfflineSettings getOfflineSettings() throws XMPPException {
|
||||||
|
OfflineSettings request = new OfflineSettings();
|
||||||
|
request.setType(IQ.Type.GET);
|
||||||
|
request.setTo(workgroupJID);
|
||||||
|
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
|
||||||
|
connection.sendPacket(request);
|
||||||
|
|
||||||
|
|
||||||
|
OfflineSettings response = (OfflineSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asks the workgroup for it's Sound Settings.
|
||||||
|
*
|
||||||
|
* @return soundSettings the sound settings for the specified workgroup.
|
||||||
|
* @throws XMPPException if an error occurs while getting information from the server.
|
||||||
|
*/
|
||||||
|
public SoundSettings getSoundSettings() throws XMPPException {
|
||||||
|
SoundSettings request = new SoundSettings();
|
||||||
|
request.setType(IQ.Type.GET);
|
||||||
|
request.setTo(workgroupJID);
|
||||||
|
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
|
||||||
|
connection.sendPacket(request);
|
||||||
|
|
||||||
|
|
||||||
|
SoundSettings response = (SoundSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asks the workgroup for it's Properties
|
||||||
|
*
|
||||||
|
* @return the WorkgroupProperties for the specified workgroup.
|
||||||
|
* @throws XMPPException if an error occurs while getting information from the server.
|
||||||
|
*/
|
||||||
|
public WorkgroupProperties getWorkgroupProperties() throws XMPPException {
|
||||||
|
WorkgroupProperties request = new WorkgroupProperties();
|
||||||
|
request.setType(IQ.Type.GET);
|
||||||
|
request.setTo(workgroupJID);
|
||||||
|
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
|
||||||
|
connection.sendPacket(request);
|
||||||
|
|
||||||
|
|
||||||
|
WorkgroupProperties response = (WorkgroupProperties)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asks the workgroup for it's Properties
|
||||||
|
*
|
||||||
|
* @param jid the jid of the user who's information you would like the workgroup to retreive.
|
||||||
|
* @return the WorkgroupProperties for the specified workgroup.
|
||||||
|
* @throws XMPPException if an error occurs while getting information from the server.
|
||||||
|
*/
|
||||||
|
public WorkgroupProperties getWorkgroupProperties(String jid) throws XMPPException {
|
||||||
|
WorkgroupProperties request = new WorkgroupProperties();
|
||||||
|
request.setJid(jid);
|
||||||
|
request.setType(IQ.Type.GET);
|
||||||
|
request.setTo(workgroupJID);
|
||||||
|
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
|
||||||
|
connection.sendPacket(request);
|
||||||
|
|
||||||
|
|
||||||
|
WorkgroupProperties response = (WorkgroupProperties)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Form to use for all clients of a workgroup. It is unlikely that the server
|
||||||
|
* will change the form (without a restart) so it is safe to keep the returned form
|
||||||
|
* for future submissions.
|
||||||
|
*
|
||||||
|
* @return the Form to use for searching transcripts.
|
||||||
|
* @throws XMPPException if an error occurs while sending the request to the server.
|
||||||
|
*/
|
||||||
|
public Form getWorkgroupForm() throws XMPPException {
|
||||||
|
WorkgroupForm workgroupForm = new WorkgroupForm();
|
||||||
|
workgroupForm.setType(IQ.Type.GET);
|
||||||
|
workgroupForm.setTo(workgroupJID);
|
||||||
|
|
||||||
|
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(workgroupForm.getPacketID()));
|
||||||
|
connection.sendPacket(workgroupForm);
|
||||||
|
|
||||||
|
WorkgroupForm response = (WorkgroupForm)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
// Cancel the collector.
|
||||||
|
collector.cancel();
|
||||||
|
if (response == null) {
|
||||||
|
throw new XMPPException("No response from server on status set.");
|
||||||
|
}
|
||||||
|
if (response.getError() != null) {
|
||||||
|
throw new XMPPException(response.getError());
|
||||||
|
}
|
||||||
|
return Form.getFormFrom(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
XMPPConnection con = new XMPPConnection("anteros");
|
||||||
|
con.connect();
|
||||||
|
con.loginAnonymously();
|
||||||
|
|
||||||
|
Workgroup workgroup = new Workgroup("demo@workgroup.anteros", con);
|
||||||
|
WorkgroupProperties props = workgroup.getWorkgroupProperties("derek@anteros.com");
|
||||||
|
|
||||||
|
System.out.print(props);
|
||||||
|
con.disconnect();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision: 19406 $
|
||||||
|
* $Date: 2005-07-28 18:12:09 -0700 (Thu, 28 Jul 2005) $
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003-2005 Jive Software. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is the proprietary information of Jive Software.
|
||||||
|
* Use is subject to license terms.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.util;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is a very flexible event dispatcher which implements Runnable so that it can
|
||||||
|
* dispatch easily from a newly created thread. The usage of this in code is more or less:
|
||||||
|
* create a new instance of this class, use addListenerTriplet to add as many listeners
|
||||||
|
* as desired to be messaged, create a new Thread using the instance of this class created
|
||||||
|
* as the argument to the constructor, start the new Thread instance.<p>
|
||||||
|
*
|
||||||
|
* Also, this is intended to be used to message methods that either return void, or have
|
||||||
|
* a return which the developer using this class is uninterested in receiving.
|
||||||
|
*
|
||||||
|
* @author loki der quaeler
|
||||||
|
*/
|
||||||
|
public class ListenerEventDispatcher
|
||||||
|
implements Runnable {
|
||||||
|
|
||||||
|
protected transient ArrayList triplets;
|
||||||
|
|
||||||
|
protected transient boolean hasFinishedDispatching;
|
||||||
|
protected transient boolean isRunning;
|
||||||
|
|
||||||
|
public ListenerEventDispatcher () {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.triplets = new ArrayList();
|
||||||
|
|
||||||
|
this.hasFinishedDispatching = false;
|
||||||
|
this.isRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a listener triplet - the instance of the listener to be messaged, the Method on which
|
||||||
|
* the listener should be messaged, and the Object array of arguments to be supplied to the
|
||||||
|
* Method. No attempts are made to determine whether this triplet was already added.<br>
|
||||||
|
*
|
||||||
|
* Messages are dispatched in the order in which they're added via this method; so if triplet
|
||||||
|
* X is added after triplet Z, then triplet Z will undergo messaging prior to triplet X.<br>
|
||||||
|
*
|
||||||
|
* This method should not be called once the owning Thread instance has been started; if it
|
||||||
|
* is called, the triplet will not be added to the messaging queue.<br>
|
||||||
|
*
|
||||||
|
* @param listenerInstance the instance of the listener to receive the associated notification
|
||||||
|
* @param listenerMethod the Method instance representing the method through which notification
|
||||||
|
* will occur
|
||||||
|
* @param methodArguments the arguments supplied to the notification method
|
||||||
|
*/
|
||||||
|
public void addListenerTriplet(Object listenerInstance, Method listenerMethod,
|
||||||
|
Object[] methodArguments)
|
||||||
|
{
|
||||||
|
if (!this.isRunning) {
|
||||||
|
this.triplets.add(new TripletContainer(listenerInstance, listenerMethod,
|
||||||
|
methodArguments));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return whether this instance has finished dispatching its messages
|
||||||
|
*/
|
||||||
|
public boolean hasFinished() {
|
||||||
|
return this.hasFinishedDispatching;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
ListIterator li = null;
|
||||||
|
|
||||||
|
this.isRunning = true;
|
||||||
|
|
||||||
|
li = this.triplets.listIterator();
|
||||||
|
while (li.hasNext()) {
|
||||||
|
TripletContainer tc = (TripletContainer)li.next();
|
||||||
|
|
||||||
|
try {
|
||||||
|
tc.getListenerMethod().invoke(tc.getListenerInstance(), tc.getMethodArguments());
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Exception dispatching an event: " + e);
|
||||||
|
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hasFinishedDispatching = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected class TripletContainer {
|
||||||
|
|
||||||
|
protected Object listenerInstance;
|
||||||
|
protected Method listenerMethod;
|
||||||
|
protected Object[] methodArguments;
|
||||||
|
|
||||||
|
protected TripletContainer (Object inst, Method meth, Object[] args) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.listenerInstance = inst;
|
||||||
|
this.listenerMethod = meth;
|
||||||
|
this.methodArguments = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object getListenerInstance() {
|
||||||
|
return this.listenerInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Method getListenerMethod() {
|
||||||
|
return this.listenerMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object[] getMethodArguments() {
|
||||||
|
return this.methodArguments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
106
source/org/jivesoftware/smackx/workgroup/util/MetaDataUtils.java
Normal file
106
source/org/jivesoftware/smackx/workgroup/util/MetaDataUtils.java
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision: 38648 $
|
||||||
|
* $Date: 2006-12-27 01:46:18 -0800 (Wed, 27 Dec 2006) $
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003-2005 Jive Software. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is the proprietary information of Jive Software.
|
||||||
|
* Use is subject to license terms.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.util;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.workgroup.MetaData;
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for meta-data parsing and writing.
|
||||||
|
*
|
||||||
|
* @author Matt Tucker
|
||||||
|
*/
|
||||||
|
public class MetaDataUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses any available meta-data and returns it as a Map of String name/value pairs. The
|
||||||
|
* parser must be positioned at an opening meta-data tag, or the an empty map will be returned.
|
||||||
|
*
|
||||||
|
* @param parser the XML parser positioned at an opening meta-data tag.
|
||||||
|
* @return the meta-data.
|
||||||
|
* @throws XmlPullParserException if an error occurs while parsing the XML.
|
||||||
|
* @throws IOException if an error occurs while parsing the XML.
|
||||||
|
*/
|
||||||
|
public static Map parseMetaData(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||||
|
int eventType = parser.getEventType();
|
||||||
|
|
||||||
|
// If correctly positioned on an opening meta-data tag, parse meta-data.
|
||||||
|
if ((eventType == XmlPullParser.START_TAG)
|
||||||
|
&& parser.getName().equals(MetaData.ELEMENT_NAME)
|
||||||
|
&& parser.getNamespace().equals(MetaData.NAMESPACE)) {
|
||||||
|
Map metaData = new Hashtable();
|
||||||
|
|
||||||
|
eventType = parser.nextTag();
|
||||||
|
|
||||||
|
// Keep parsing until we've gotten to end of meta-data.
|
||||||
|
while ((eventType != XmlPullParser.END_TAG)
|
||||||
|
|| (!parser.getName().equals(MetaData.ELEMENT_NAME))) {
|
||||||
|
String name = parser.getAttributeValue(0);
|
||||||
|
String value = parser.nextText();
|
||||||
|
|
||||||
|
if (metaData.containsKey(name)) {
|
||||||
|
List values = (List)metaData.get(name);
|
||||||
|
values.add(value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
List values = new ArrayList();
|
||||||
|
values.add(value);
|
||||||
|
metaData.put(name, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
eventType = parser.nextTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
return metaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.EMPTY_MAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes a Map of String name/value pairs into the meta-data XML format.
|
||||||
|
*
|
||||||
|
* @param metaData the Map of meta-data.
|
||||||
|
* @return the meta-data values in XML form.
|
||||||
|
*/
|
||||||
|
public static String serializeMetaData(Map metaData) {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
if (metaData != null && metaData.size() > 0) {
|
||||||
|
buf.append("<metadata xmlns=\"http://jivesoftware.com/protocol/workgroup\">");
|
||||||
|
for (Iterator i = metaData.keySet().iterator(); i.hasNext();) {
|
||||||
|
Object key = i.next();
|
||||||
|
Object value = metaData.get(key);
|
||||||
|
if (value instanceof List) {
|
||||||
|
List values = (List)metaData.get(key);
|
||||||
|
for (Iterator it = values.iterator(); it.hasNext();) {
|
||||||
|
String v = (String)it.next();
|
||||||
|
buf.append("<value name=\"").append(key).append("\">");
|
||||||
|
buf.append(StringUtils.escapeForXML(v));
|
||||||
|
buf.append("</value>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (value instanceof String) {
|
||||||
|
buf.append("<value name=\"").append(key).append("\">");
|
||||||
|
buf.append(StringUtils.escapeForXML((String)value));
|
||||||
|
buf.append("</value>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.append("</metadata>");
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
}
|
318
source/org/jivesoftware/smackx/workgroup/util/ModelUtil.java
Normal file
318
source/org/jivesoftware/smackx/workgroup/util/ModelUtil.java
Normal file
|
@ -0,0 +1,318 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision: 38648 $
|
||||||
|
* $Date: 2006-12-27 01:46:18 -0800 (Wed, 27 Dec 2006) $
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004-2005 Jive Software. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is the proprietary information of Jive Software.
|
||||||
|
* Use is subject to license terms.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.workgroup.util;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility methods frequently used by data classes and design-time
|
||||||
|
* classes.
|
||||||
|
*/
|
||||||
|
public final class ModelUtil {
|
||||||
|
private ModelUtil() {
|
||||||
|
// Prevents instantiation.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a utility method that compares two objects when one or
|
||||||
|
* both of the objects might be <CODE>null</CODE> The result of
|
||||||
|
* this method is determined as follows:
|
||||||
|
* <OL>
|
||||||
|
* <LI>If <CODE>o1</CODE> and <CODE>o2</CODE> are the same object
|
||||||
|
* according to the <CODE>==</CODE> operator, return
|
||||||
|
* <CODE>true</CODE>.
|
||||||
|
* <LI>Otherwise, if either <CODE>o1</CODE> or <CODE>o2</CODE> is
|
||||||
|
* <CODE>null</CODE>, return <CODE>false</CODE>.
|
||||||
|
* <LI>Otherwise, return <CODE>o1.equals(o2)</CODE>.
|
||||||
|
* </OL>
|
||||||
|
* <p/>
|
||||||
|
* This method produces the exact logically inverted result as the
|
||||||
|
* {@link #areDifferent(Object, Object)} method.<P>
|
||||||
|
* <p/>
|
||||||
|
* For array types, one of the <CODE>equals</CODE> methods in
|
||||||
|
* {@link java.util.Arrays} should be used instead of this method.
|
||||||
|
* Note that arrays with more than one dimension will require some
|
||||||
|
* custom code in order to implement <CODE>equals</CODE> properly.
|
||||||
|
*/
|
||||||
|
public static final boolean areEqual(Object o1, Object o2) {
|
||||||
|
if (o1 == o2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (o1 == null || o2 == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return o1.equals(o2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a utility method that compares two Booleans when one or
|
||||||
|
* both of the objects might be <CODE>null</CODE> The result of
|
||||||
|
* this method is determined as follows:
|
||||||
|
* <OL>
|
||||||
|
* <LI>If <CODE>b1</CODE> and <CODE>b2</CODE> are both TRUE or
|
||||||
|
* neither <CODE>b1</CODE> nor <CODE>b2</CODE> is TRUE,
|
||||||
|
* return <CODE>true</CODE>.
|
||||||
|
* <LI>Otherwise, return <CODE>false</CODE>.
|
||||||
|
* </OL>
|
||||||
|
* <p/>
|
||||||
|
*/
|
||||||
|
public static final boolean areBooleansEqual(Boolean b1, Boolean b2) {
|
||||||
|
// !jwetherb treat NULL the same as Boolean.FALSE
|
||||||
|
return (b1 == Boolean.TRUE && b2 == Boolean.TRUE) ||
|
||||||
|
(b1 != Boolean.TRUE && b2 != Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a utility method that compares two objects when one or
|
||||||
|
* both of the objects might be <CODE>null</CODE>. The result
|
||||||
|
* returned by this method is determined as follows:
|
||||||
|
* <OL>
|
||||||
|
* <LI>If <CODE>o1</CODE> and <CODE>o2</CODE> are the same object
|
||||||
|
* according to the <CODE>==</CODE> operator, return
|
||||||
|
* <CODE>false</CODE>.
|
||||||
|
* <LI>Otherwise, if either <CODE>o1</CODE> or <CODE>o2</CODE> is
|
||||||
|
* <CODE>null</CODE>, return <CODE>true</CODE>.
|
||||||
|
* <LI>Otherwise, return <CODE>!o1.equals(o2)</CODE>.
|
||||||
|
* </OL>
|
||||||
|
* <p/>
|
||||||
|
* This method produces the exact logically inverted result as the
|
||||||
|
* {@link #areEqual(Object, Object)} method.<P>
|
||||||
|
* <p/>
|
||||||
|
* For array types, one of the <CODE>equals</CODE> methods in
|
||||||
|
* {@link java.util.Arrays} should be used instead of this method.
|
||||||
|
* Note that arrays with more than one dimension will require some
|
||||||
|
* custom code in order to implement <CODE>equals</CODE> properly.
|
||||||
|
*/
|
||||||
|
public static final boolean areDifferent(Object o1, Object o2) {
|
||||||
|
return !areEqual(o1, o2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a utility method that compares two Booleans when one or
|
||||||
|
* both of the objects might be <CODE>null</CODE> The result of
|
||||||
|
* this method is determined as follows:
|
||||||
|
* <OL>
|
||||||
|
* <LI>If <CODE>b1</CODE> and <CODE>b2</CODE> are both TRUE or
|
||||||
|
* neither <CODE>b1</CODE> nor <CODE>b2</CODE> is TRUE,
|
||||||
|
* return <CODE>false</CODE>.
|
||||||
|
* <LI>Otherwise, return <CODE>true</CODE>.
|
||||||
|
* </OL>
|
||||||
|
* <p/>
|
||||||
|
* This method produces the exact logically inverted result as the
|
||||||
|
* {@link #areBooleansEqual(Boolean, Boolean)} method.<P>
|
||||||
|
*/
|
||||||
|
public static final boolean areBooleansDifferent(Boolean b1, Boolean b2) {
|
||||||
|
return !areBooleansEqual(b1, b2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <CODE>true</CODE> if the specified array is not null
|
||||||
|
* and contains a non-null element. Returns <CODE>false</CODE>
|
||||||
|
* if the array is null or if all the array elements are null.
|
||||||
|
*/
|
||||||
|
public static final boolean hasNonNullElement(Object[] array) {
|
||||||
|
if (array != null) {
|
||||||
|
final int n = array.length;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
if (array[i] != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a single string that is the concatenation of all the
|
||||||
|
* strings in the specified string array. A single space is
|
||||||
|
* put between each string array element. Null array elements
|
||||||
|
* are skipped. If the array itself is null, the empty string
|
||||||
|
* is returned. This method is guaranteed to return a non-null
|
||||||
|
* value, if no expections are thrown.
|
||||||
|
*/
|
||||||
|
public static final String concat(String[] strs) {
|
||||||
|
return concat(strs, " "); //NOTRANS
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a single string that is the concatenation of all the
|
||||||
|
* strings in the specified string array. The strings are separated
|
||||||
|
* by the specified delimiter. Null array elements are skipped. If
|
||||||
|
* the array itself is null, the empty string is returned. This
|
||||||
|
* method is guaranteed to return a non-null value, if no expections
|
||||||
|
* are thrown.
|
||||||
|
*/
|
||||||
|
public static final String concat(String[] strs, String delim) {
|
||||||
|
if (strs != null) {
|
||||||
|
final StringBuilder buf = new StringBuilder();
|
||||||
|
final int n = strs.length;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
final String str = strs[i];
|
||||||
|
if (str != null) {
|
||||||
|
buf.append(str).append(delim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final int length = buf.length();
|
||||||
|
if (length > 0) {
|
||||||
|
// Trim trailing space.
|
||||||
|
buf.setLength(length - 1);
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ""; // NOTRANS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <CODE>true</CODE> if the specified {@link String} is not
|
||||||
|
* <CODE>null</CODE> and has a length greater than zero. This is
|
||||||
|
* a very frequently occurring check.
|
||||||
|
*/
|
||||||
|
public static final boolean hasLength(String s) {
|
||||||
|
return (s != null && s.length() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <CODE>null</CODE> if the specified string is empty or
|
||||||
|
* <CODE>null</CODE>. Otherwise the string itself is returned.
|
||||||
|
*/
|
||||||
|
public static final String nullifyIfEmpty(String s) {
|
||||||
|
return ModelUtil.hasLength(s) ? s : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <CODE>null</CODE> if the specified object is null
|
||||||
|
* or if its <CODE>toString()</CODE> representation is empty.
|
||||||
|
* Otherwise, the <CODE>toString()</CODE> representation of the
|
||||||
|
* object itself is returned.
|
||||||
|
*/
|
||||||
|
public static final String nullifyingToString(Object o) {
|
||||||
|
return o != null ? nullifyIfEmpty(o.toString()) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a string has been changed.
|
||||||
|
*
|
||||||
|
* @param oldString is the initial value of the String
|
||||||
|
* @param newString is the new value of the String
|
||||||
|
* @return true If both oldString and newString are null or if they are
|
||||||
|
* both not null and equal to each other. Otherwise returns false.
|
||||||
|
*/
|
||||||
|
public static boolean hasStringChanged(String oldString, String newString) {
|
||||||
|
if (oldString == null && newString == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if ((oldString == null && newString != null)
|
||||||
|
|| (oldString != null && newString == null)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return !oldString.equals(newString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getTimeFromLong(long diff) {
|
||||||
|
final String HOURS = "h";
|
||||||
|
final String MINUTES = "min";
|
||||||
|
final String SECONDS = "sec";
|
||||||
|
|
||||||
|
final long MS_IN_A_DAY = 1000 * 60 * 60 * 24;
|
||||||
|
final long MS_IN_AN_HOUR = 1000 * 60 * 60;
|
||||||
|
final long MS_IN_A_MINUTE = 1000 * 60;
|
||||||
|
final long MS_IN_A_SECOND = 1000;
|
||||||
|
Date currentTime = new Date();
|
||||||
|
long numDays = diff / MS_IN_A_DAY;
|
||||||
|
diff = diff % MS_IN_A_DAY;
|
||||||
|
long numHours = diff / MS_IN_AN_HOUR;
|
||||||
|
diff = diff % MS_IN_AN_HOUR;
|
||||||
|
long numMinutes = diff / MS_IN_A_MINUTE;
|
||||||
|
diff = diff % MS_IN_A_MINUTE;
|
||||||
|
long numSeconds = diff / MS_IN_A_SECOND;
|
||||||
|
diff = diff % MS_IN_A_SECOND;
|
||||||
|
long numMilliseconds = diff;
|
||||||
|
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
if (numHours > 0) {
|
||||||
|
buf.append(numHours + " " + HOURS + ", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numMinutes > 0) {
|
||||||
|
buf.append(numMinutes + " " + MINUTES + ", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.append(numSeconds + " " + SECONDS);
|
||||||
|
|
||||||
|
String result = buf.toString();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a List of all elements in an Iterator.
|
||||||
|
*/
|
||||||
|
public static List iteratorAsList(Iterator i) {
|
||||||
|
ArrayList list = new ArrayList(10);
|
||||||
|
while (i.hasNext()) {
|
||||||
|
list.add(i.next());
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an Iterator that is the reverse of a ListIterator.
|
||||||
|
*/
|
||||||
|
public static Iterator reverseListIterator(ListIterator i) {
|
||||||
|
return new ReverseListIterator(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Iterator that is the reverse of a ListIterator.
|
||||||
|
*/
|
||||||
|
class ReverseListIterator implements Iterator {
|
||||||
|
private ListIterator _i;
|
||||||
|
|
||||||
|
ReverseListIterator(ListIterator i) {
|
||||||
|
_i = i;
|
||||||
|
while (_i.hasNext())
|
||||||
|
_i.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNext() {
|
||||||
|
return _i.hasPrevious();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object next() {
|
||||||
|
return _i.previous();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove() {
|
||||||
|
_i.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue