1
0
Fork 0
mirror of https://codeberg.org/Mercury-IM/Smack synced 2024-11-23 06:42:05 +01:00

Initial version

git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@2260 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
Gaston Dombiak 2004-03-29 21:29:55 +00:00 committed by gdombiak
parent 6596515785
commit a5b33b4118
13 changed files with 3300 additions and 0 deletions

View file

@ -0,0 +1,297 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx;
import java.util.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smackx.packet.DataForm;
/**
* Represents a Form for gathering data. The form could be of the following types:
* <ul>
* <li>form -> Indicates a form to fill out.</li>
* <li>submit -> The form is filled out, and this is the data that is being returned from
* the form.</li>
* <li>cancel -> The form was cancelled. Tell the asker that piece of information.</li>
* <li>result -> Data results being returned from a search, or some other query.</li>
* </ul>
*
* Depending of the form's type different operations are available. For example, if the form
* is of type "submit", it's not possible to add a new Field to the form.
*
* @author Gaston Dombiak
*/
public class Form {
private DataForm dataForm;
/**
* Returns a new ReportedData if the packet is used for gathering data and includes an
* extension that matches the elementName and namespace "x","jabber:x:data".
*
* @param packet the packet used for gathering data.
*/
public static Form getFormFrom(Packet packet) {
// Check if the packet includes the DataForm extension
PacketExtension packetExtension = packet.getExtension("x","jabber:x:data");
if (packetExtension != null) {
// Check if the existing DataForm is not a result of a search
DataForm dataForm = (DataForm) packetExtension;
if (dataForm.getReportedData() == null)
return new Form(dataForm);
}
// Otherwise return null
return null;
}
/**
* Creates a new Form that will wrap an existing DataForm. The wrapped DataForm must be
* used for gathering data.
*
* @param dataForm the data form used for gathering data.
*/
private Form(DataForm dataForm) {
this.dataForm = dataForm;
}
/**
* Creates a new Form of a given type from scratch.<p>
*
* Possible form types are:
* <ul>
* <li>form -> Indicates a form to fill out.</li>
* <li>submit -> The form is filled out, and this is the data that is being returned from
* the form.</li>
* <li>cancel -> The form was cancelled. Tell the asker that piece of information.</li>
* <li>result -> Data results being returned from a search, or some other query.</li>
* </ul>
*
* @param type the form's type (e.g. form, submit,cancel,result).
*/
public Form(String type) {
this.dataForm = new DataForm(type);
}
/**
* Adds a new field to complete as part of the form.
*
* @param field the field to complete.
*/
public void addField(FormField field) {
if (!isFormType()) {
throw new IllegalStateException("Cannot add fields if the form is not of type \"form\"");
}
dataForm.addField(field);
}
/**
* Adds a new answer as part of the form. The answer to add is a FormField whose variable
* and value attributes are completed.
*
* @param variable the variable that was completed.
* @param value the value that was answered.
*/
public void addAnswer(String variable, String value) {
if (!isSubmitType()) {
throw new IllegalStateException("Cannot add fields if the form is not of type \"submit\"");
}
FormField field = new FormField();
field.setVariable(variable);
field.addValue(value);
dataForm.addField(field);
}
/**
* Adds a new answer as part of the form. The answer to add is a FormField whose variable
* and values attributes are completed.
*
* @param variable the variable that was completed.
* @param values the values that were answered.
*/
public void addAnswer(String variable, List values) {
if (!isSubmitType()) {
throw new IllegalStateException("Cannot add fields if the form is not of type \"submit\"");
}
FormField field = new FormField();
field.setVariable(variable);
field.addValues(values);
dataForm.addField(field);
}
/**
* Returns an Iterator for the fields that are part of the form.
*
* @return an Iterator for the fields that are part of the form.
*/
public Iterator getFields() {
return dataForm.getFields();
}
/**
* Returns the instructions that explain how to fill out the form and what the form is about.
*
* @return instructions that explain how to fill out the form.
*/
public String getInstructions() {
return dataForm.getInstructions();
}
/**
* Returns the description of the data. It is similar to the title on a web page or an X
* window. You can put a <title/> on either a form to fill out, or a set of data results.
*
* @return description of the data.
*/
public String getTitle() {
return dataForm.getTitle();
}
/**
* Returns the meaning of the data within the context. The data could be part of a form
* to fill out, a form submission or data results.<p>
*
* Possible form types are:
* <ul>
* <li>form -> Indicates a form to fill out.</li>
* <li>submit -> The form is filled out, and this is the data that is being returned from
* the form.</li>
* <li>cancel -> The form was cancelled. Tell the asker that piece of information.</li>
* <li>result -> Data results being returned from a search, or some other query.</li>
* </ul>
*
* @return the form's type.
*/
public String getType() {
return dataForm.getType();
}
/**
* Sets instructions that explain how to fill out the form and what the form is about.
*
* @param instructions instructions that explain how to fill out the form.
*/
public void setInstructions(String instructions) {
dataForm.setInstructions(instructions);
}
/**
* Sets the description of the data. It is similar to the title on a web page or an X window.
* You can put a <title/> on either a form to fill out, or a set of data results.
*
* @param title description of the data.
*/
public void setTitle(String title) {
dataForm.setTitle(title);
}
/**
* Returns the wrapped DataForm.
*
* @return the wrapped DataForm.
*/
DataForm getDataForm() {
return dataForm;
}
/**
* Returns true if the form is a form to fill out.
*
* @return if the form is a form to fill out.
*/
private boolean isFormType() {
return DataForm.TYPE_FORM.equals(dataForm.getType());
}
/**
* Returns true if the form is a form to submit.
*
* @return if the form is a form to submit.
*/
private boolean isSubmitType() {
return DataForm.TYPE_SUBMIT.equals(dataForm.getType());
}
/**
* Returns a new Form to submit the completed values. The new Form will include the hidden
* fields of the original form.
*
* @return a Form to submit the completed values.
*/
public Form createAnswerForm() {
if (!isFormType()) {
throw new IllegalStateException("Only forms of type \"form\" could be answered");
}
// Create a new Form
Form form = new Form(DataForm.TYPE_SUBMIT);
// Copy the hidden fields to the new form
for (Iterator fields=getFields(); fields.hasNext();) {
FormField field = (FormField)fields.next();
if (FormField.TYPE_HIDDEN.equals(field.getType())) {
// Since a hidden field could have many values we need to collect them in a list
List values = new ArrayList();
for (Iterator it=field.getValues();it.hasNext();) {
values.add((String)it.next());
}
form.addAnswer(field.getVariable(), values);
}
}
return form;
}
}

View file

@ -0,0 +1,362 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx;
import java.util.*;
/**
* Represents a field of a form. The field could be used to represent a question to complete,
* a completed question or a data returned from a search. The exact interpretation of the field
* depends on the context where the field is used.
*
* @author Gaston Dombiak
*/
public class FormField {
public static final String TYPE_BOOLEAN = "boolean";
public static final String TYPE_FIXED = "fixed";
public static final String TYPE_HIDDEN = "hidden";
public static final String TYPE_JID_MULTI = "jid-multi";
public static final String TYPE_JID_SINGLE = "jid-single";
public static final String TYPE_LIST_MULTI = "list-multi";
public static final String TYPE_LIST_SINGLE = "list-single";
public static final String TYPE_TEXT_MULTI = "text-multi";
public static final String TYPE_TEXT_PRIVATE = "text-private";
public static final String TYPE_TEXT_SINGLE = "text-single";
private String description;
private boolean required = false;
private String label;
private String variable;
private String type;
private List options = new ArrayList();
private List values = new ArrayList();
/**
* Returns a description that provides extra clarification about the question. This information
* could be presented to the user either in tool-tip, help button, or as a section of text
* before the question.<p>
*
* If the question is of type FIXED then the description should remain empty.
*
* @return description that provides extra clarification about the question.
*/
public String getDescription() {
return description;
}
/**
* Returns the label of the question which should give enough information to the user to
* fill out the form.
*
* @return label of the question.
*/
public String getLabel() {
return label;
}
/**
* Returns an Iterator for the available options that the user has in order to answer
* the question.
*
* @return Iterator for the available options.
*/
public Iterator getOptions() {
synchronized (options) {
return Collections.unmodifiableList(new ArrayList(options)).iterator();
}
}
/**
* Returns true if the question must be answered in order to complete the questionnaire.
*
* @return true if the question must be answered in order to complete the questionnaire.
*/
public boolean isRequired() {
return required;
}
/**
* Returns an indicative of the format for the data to answer. Valid formats are:
*
* <ul>
* <li>text-single -> single line or word of text
* <li>text-private -> instead of showing the user what they typed, you show ***** to
* protect it
* <li>text-multi -> multiple lines of text entry
* <li>list-single -> given a list of choices, pick one
* <li>list-multi -> given a list of choices, pick one or more
* <li>boolean -> 0 or 1, true or false, yes or no. Default value is 0
* <li>fixed -> fixed for putting in text to show sections, or just advertise your web
* site in the middle of the form
* <li>hidden -> is not given to the user at all, but returned with the questionnaire
* <li>jid-single -> Jabber ID - choosing a JID from your roster, and entering one based
* on the rules for a JID.
* <li>jid-multi -> multiple entries for JIDs
* </ul>
*
* @return format for the data to answer.
*/
public String getType() {
return type;
}
/**
* Returns an Iterator for the default values of the question if the question is part
* of a form to fill out. Otherwise, returns an Iterator for the answered values of
* the question.
*
* @return an Iterator for the default values or answered values of the question.
*/
public Iterator getValues() {
synchronized (values) {
return Collections.unmodifiableList(new ArrayList(values)).iterator();
}
}
/**
* Returns the variable name that the question is filling out.
*
* @return the variable name of the question.
*/
public String getVariable() {
return variable;
}
/**
* Sets a description that provides extra clarification about the question. This information
* could be presented to the user either in tool-tip, help button, or as a section of text
* before the question.<p>
*
* If the question is of type FIXED then the description should remain empty.
*
* @param description provides extra clarification about the question.
*/
public void setDescription(String description) {
this.description = description;
}
/**
* Sets the label of the question which should give enough information to the user to
* fill out the form.
*
* @param label the label of the question.
*/
public void setLabel(String label) {
this.label = label;
}
/**
* Sets if the question must be answered in order to complete the questionnaire.
*
* @param required if the question must be answered in order to complete the questionnaire.
*/
public void setRequired(boolean required) {
this.required = required;
}
/**
* Sets an indicative of the format for the data to answer. Valid formats are:
*
* <ul>
* <li>text-single -> single line or word of text
* <li>text-private -> instead of showing the user what they typed, you show ***** to
* protect it
* <li>text-multi -> multiple lines of text entry
* <li>list-single -> given a list of choices, pick one
* <li>list-multi -> given a list of choices, pick one or more
* <li>boolean -> 0 or 1, true or false, yes or no. Default value is 0
* <li>fixed -> fixed for putting in text to show sections, or just advertise your web
* site in the middle of the form
* <li>hidden -> is not given to the user at all, but returned with the questionnaire
* <li>jid-single -> Jabber ID - choosing a JID from your roster, and entering one based
* on the rules for a JID.
* <li>jid-multi -> multiple entries for JIDs
* </ul>
*
* @param type an indicative of the format for the data to answer.
*/
public void setType(String type) {
this.type = type;
}
/**
* Returns the variable name that the question is filling out.
*
* @param variable the variable name of the question.
*/
public void setVariable(String variable) {
this.variable = variable;
}
/**
* Adds a default value to the question if the question is part of a form to fill out.
* Otherwise, adds an answered value to the question.
*
* @param value a default value or an answered value of the question.
*/
public void addValue(String value) {
synchronized (values) {
values.add(value);
}
}
/**
* Adds a default values to the question if the question is part of a form to fill out.
* Otherwise, adds an answered values to the question.
*
* @param values default values or an answered values of the question.
*/
public void addValues(List newValues) {
synchronized (values) {
values.addAll(newValues);
}
}
/**
* Adss an available options to the question that the user has in order to answer
* the question.
*
* @param option a new available option for the question.
*/
public void addOption(Option option) {
synchronized (options) {
options.add(option);
}
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<field");
// Add attributes
if (getLabel() != null) {
buf.append(" label=\"").append(getLabel()).append("\"");
}
if (getVariable() != null) {
buf.append(" var=\"").append(getVariable()).append("\"");
}
if (getType() != null) {
buf.append(" type=\"").append(getType()).append("\"");
}
buf.append(">");
// Add elements
if (getDescription() != null) {
buf.append("<desc>").append(getDescription()).append("</desc>");
}
if (isRequired()) {
buf.append("<required/>");
}
// Loop through all the values and append them to the string buffer
for (Iterator i = getValues(); i.hasNext();) {
buf.append("<value>").append(i.next()).append("</value>");
}
// Loop through all the values and append them to the string buffer
for (Iterator i = getOptions(); i.hasNext();) {
buf.append(((Option)i.next()).toXML());
}
buf.append("</field>");
return buf.toString();
}
/**
*
* Represents the available option of a given FormField.
*
* @author Gaston Dombiak
*/
public static class Option {
private String label;
private String value;
public Option(String value) {
this.value = value;
}
public Option(String label, String value) {
this.label = label;
this.value = value;
}
/**
* Returns the label that represents the option.
*
* @return the label that represents the option.
*/
public String getLabel() {
return label;
}
/**
* Returns the value of the option.
*
* @return the value of the option.
*/
public String getValue() {
return value;
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<option");
// Add attribute
if (getLabel() != null) {
buf.append(" label=\"").append(getLabel()).append("\"");
}
buf.append(">");
// Add element
buf.append("<value>").append(getValue()).append("</value>");
buf.append("</option>");
return buf.toString();
}
}
}

View file

@ -0,0 +1,422 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx;
import java.util.*;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.filter.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smackx.packet.*;
/**
* A MultiUserChat is a conversation that takes place among many users in a virtual
* room. A room could have many occupants with different affiliation and roles.
* Possible affiliatons are "owner", "admin", "member", and "outcast". Possible roles
* are "moderator", "participant", and "visitor". Each role and affiliation guarantees
* different privileges (e.g. Send messages to all occupants, Kick participants and visitors,
* Grant voice, Edit member list, etc.).
*
* @author Gaston Dombiak
*/
public class MultiUserChat {
private XMPPConnection connection;
private String room;
private String nickname = null;
private boolean joined = false;
private List participants = new ArrayList();
private PacketFilter presenceFilter;
private PacketFilter messageFilter;
private PacketCollector messageCollector;
public MultiUserChat(XMPPConnection connection, String room) {
this.connection = connection;
this.room = room;
// Create a collector for all incoming messages.
messageFilter =
new AndFilter(new FromContainsFilter(room), new PacketTypeFilter(Message.class));
messageFilter = new AndFilter(messageFilter, new PacketFilter() {
public boolean accept(Packet packet) {
Message msg = (Message) packet;
return msg.getType() == Message.Type.GROUP_CHAT;
}
});
messageCollector = connection.createPacketCollector(messageFilter);
// Create a listener for all presence updates.
presenceFilter =
new AndFilter(new FromContainsFilter(room), new PacketTypeFilter(Presence.class));
connection.addPacketListener(new PacketListener() {
public void processPacket(Packet packet) {
Presence presence = (Presence) packet;
String from = presence.getFrom();
if (presence.getType() == Presence.Type.AVAILABLE) {
synchronized (participants) {
if (!participants.contains(from)) {
participants.add(from);
}
}
}
else if (presence.getType() == Presence.Type.UNAVAILABLE) {
synchronized (participants) {
participants.remove(from);
}
}
}
}, presenceFilter);
}
/**
* Returns the name of the room this GroupChat object represents.
*
* @return the groupchat room name.
*/
public String getRoom() {
return room;
}
public void join(String nickname) throws XMPPException {
join(nickname, SmackConfiguration.getPacketReplyTimeout(), null, -1, -1, -1, null);
}
public void join(String nickname, String password) throws XMPPException {
join(nickname, SmackConfiguration.getPacketReplyTimeout(), password, -1, -1, -1, null);
}
// TODO Review protocol (too many params). Use setters or history class?
public synchronized void join(
String nickname,
long timeout,
String password,
int maxchars,
int maxstanzas,
int seconds,
Date since)
throws XMPPException {
if (nickname == null || nickname.equals("")) {
throw new IllegalArgumentException("Nickname must not be null or blank.");
}
// If we've already joined the room, leave it before joining under a new
// nickname.
if (joined) {
leave();
}
// We join a room by sending a presence packet where the "to"
// field is in the form "roomName@service/nickname"
Presence joinPresence = new Presence(Presence.Type.AVAILABLE);
joinPresence.setTo(room + "/" + nickname);
// Indicate the the client supports MUC
MUCInitialPresence mucInitialPresence = new MUCInitialPresence();
if (password != null) {
mucInitialPresence.setPassword(password);
}
if (maxchars > -1 || maxstanzas > -1 || seconds > -1 || since != null) {
MUCInitialPresence.History history = new MUCInitialPresence.History();
if (maxchars > -1) {
history.setMaxChars(maxchars);
}
if (maxstanzas > -1) {
history.setMaxStanzas(maxstanzas);
}
if (seconds > -1) {
history.setSeconds(seconds);
}
if (since != null) {
history.setSince(since);
}
mucInitialPresence.setHistory(history);
}
joinPresence.addExtension(mucInitialPresence);
// Wait for a presence packet back from the server.
PacketFilter responseFilter =
new AndFilter(
new FromContainsFilter(room + "/" + nickname),
new PacketTypeFilter(Presence.class));
PacketCollector response = connection.createPacketCollector(responseFilter);
// Send join packet.
connection.sendPacket(joinPresence);
// Wait up to a certain number of seconds for a reply.
Presence presence = (Presence) response.nextResult(timeout);
if (presence == null) {
throw new XMPPException("No response from server.");
}
else if (presence.getError() != null) {
throw new XMPPException(presence.getError());
}
this.nickname = nickname;
joined = true;
}
/**
* Returns true if currently in the group chat (after calling the {@link
* #join(String)} method.
*
* @return true if currently in the group chat room.
*/
public boolean isJoined() {
return joined;
}
/**
* Leave the chat room.
*/
public synchronized void leave() {
// If not joined already, do nothing.
if (!joined) {
return;
}
// We leave a room by sending a presence packet where the "to"
// field is in the form "roomName@service/nickname"
Presence leavePresence = new Presence(Presence.Type.UNAVAILABLE);
leavePresence.setTo(room + "/" + nickname);
connection.sendPacket(leavePresence);
// Reset participant information.
participants = new ArrayList();
nickname = null;
joined = false;
}
/**
* Returns the room's configuration form that the room's owner can use. The configuration
* form allows to set the room's language, enable logging, specify room's type, etc..
*
* @return the Form that contains the fields to complete together with the instrucions.
* @throws XMPPException if an error occurs asking the configuration form for the room.
*/
public Form getConfigurationForm() throws XMPPException {
MUCOwner iq = new MUCOwner();
iq.setTo(room);
iq.setType(IQ.Type.GET);
// Wait for a presence packet back from the server.
PacketFilter responseFilter =
new AndFilter(
new FromContainsFilter(room),
new PacketTypeFilter(IQ.class));
PacketCollector response = connection.createPacketCollector(responseFilter);
// Request the configuration form to the server.
connection.sendPacket(iq);
// Wait up to a certain number of seconds for a reply.
IQ answer = (IQ) response.nextResult(SmackConfiguration.getPacketReplyTimeout());
// Stop queuing results
response.cancel();
if (answer == null) {
throw new XMPPException("No response from server.");
}
else if (answer.getError() != null) {
throw new XMPPException(iq.getError());
}
return Form.getFormFrom(answer);
}
/**
* Sends the completed configuration form to the server. The room will be configured
* with the new settings defined in the form.
*
* @param form the form with the new settings.
* @throws XMPPException if an error occurs setting the new rooms' configuration.
*/
public void submitConfigurationForm(Form form) throws XMPPException {
MUCOwner iq = new MUCOwner();
iq.setTo(room);
iq.setType(IQ.Type.SET);
iq.addExtension(form.getDataForm());
// Send the completed configuration form to the server.
connection.sendPacket(iq);
// TODO Check for possible returned errors? permission errors?
// TODO Check that the form is of type "submit"
}
/**
* Returns the nickname that was used to join the room, or <tt>null</tt> if not
* currently joined.
*
* @return the nickname currently being used.
*/
public String getNickname() {
return nickname;
}
/**
* Returns the number of participants in the group chat.<p>
*
* Note: this value will only be accurate after joining the group chat, and
* may fluctuate over time. If you query this value directly after joining the
* group chat it may not be accurate, as it takes a certain amount of time for
* the server to send all presence packets to this client.
*
* @return the number of participants in the group chat.
*/
public int getParticipantCount() {
synchronized (participants) {
return participants.size();
}
}
/**
* Returns an Iterator (of Strings) for the list of fully qualified participants
* in the group chat. For example, "conference@chat.jivesoftware.com/SomeUser".
* Typically, a client would only display the nickname of the participant. To
* get the nickname from the fully qualified name, use the
* {@link org.jivesoftware.smack.util.StringUtils#parseResource(String)} method.
* Note: this value will only be accurate after joining the group chat, and may
* fluctuate over time.
*
* @return an Iterator for the participants in the group chat.
*/
public Iterator getParticipants() {
synchronized (participants) {
return Collections.unmodifiableList(new ArrayList(participants)).iterator();
}
}
/**
* Adds a packet listener that will be notified of any new Presence packets
* sent to the group chat. Using a listener is a suitable way to know when the list
* of participants should be re-loaded due to any changes.
*
* @param listener a packet listener that will be notified of any presence packets
* sent to the group chat.
*/
public void addParticipantListener(PacketListener listener) {
connection.addPacketListener(listener, presenceFilter);
}
/**
* Sends a message to the chat room.
*
* @param text the text of the message to send.
* @throws XMPPException if sending the message fails.
*/
public void sendMessage(String text) throws XMPPException {
Message message = new Message(room, Message.Type.GROUP_CHAT);
message.setBody(text);
connection.sendPacket(message);
}
/**
* Creates a new Message to send to the chat room.
*
* @return a new Message addressed to the chat room.
*/
public Message createMessage() {
return new Message(room, Message.Type.GROUP_CHAT);
}
/**
* Sends a Message to the chat room.
*
* @param message the message.
* @throws XMPPException if sending the message fails.
*/
public void sendMessage(Message message) throws XMPPException {
connection.sendPacket(message);
}
/**
* Polls for and returns the next message, or <tt>null</tt> if there isn't
* a message immediately available. This method provides significantly different
* functionalty than the {@link #nextMessage()} method since it's non-blocking.
* In other words, the method call will always return immediately, whereas the
* nextMessage method will return only when a message is available (or after
* a specific timeout).
*
* @return the next message if one is immediately available and
* <tt>null</tt> otherwise.
*/
public Message pollMessage() {
return (Message) messageCollector.pollResult();
}
/**
* Returns the next available message in the chat. The method call will block
* (not return) until a message is available.
*
* @return the next message.
*/
public Message nextMessage() {
return (Message) messageCollector.nextResult();
}
/**
* Returns the next available message in the chat. The method call will block
* (not return) until a packet is available or the <tt>timeout</tt> has elapased.
* If the timeout elapses without a result, <tt>null</tt> will be returned.
*
* @param timeout the maximum amount of time to wait for the next message.
* @return the next message, or <tt>null</tt> if the timeout elapses without a
* message becoming available.
*/
public Message nextMessage(long timeout) {
return (Message) messageCollector.nextResult(timeout);
}
/**
* Adds a packet listener that will be notified of any new messages in the
* group chat. Only "group chat" messages addressed to this group chat will
* be delivered to the listener. If you wish to listen for other packets
* that may be associated with this group chat, you should register a
* PacketListener directly with the XMPPConnection with the appropriate
* PacketListener.
*
* @param listener a packet listener.
*/
public void addMessageListener(PacketListener listener) {
connection.addPacketListener(listener, messageFilter);
}
}

View file

@ -0,0 +1,267 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx;
import java.util.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smackx.packet.DataForm;
/**
* Represents a set of data results returned as part of a search. The report is structured
* in columns and rows.
*
* @author Gaston Dombiak
*/
public class ReportedData {
private List columns = new ArrayList();
private List rows = new ArrayList();
private String title = "";
/**
* Returns a new ReportedData if the packet is used for reporting data and includes an
* extension that matches the elementName and namespace "x","jabber:x:data".
*
* @param packet the packet used for reporting data.
*/
public static ReportedData getReportedDataFrom(Packet packet) {
// Check if the packet includes the DataForm extension
PacketExtension packetExtension = packet.getExtension("x","jabber:x:data");
if (packetExtension != null) {
// Check if the existing DataForm is a result of a search
DataForm dataForm = (DataForm) packetExtension;
if (dataForm.getReportedData() != null)
return new ReportedData(dataForm);
}
// Otherwise return null
return null;
}
/**
* Creates a new ReportedData based on the returned dataForm from a search
*(namespace "jabber:iq:search").
*
* @param dataForm the dataForm returned from a search (namespace "jabber:iq:search").
*/
private ReportedData(DataForm dataForm) {
// Add the columns to the report based on the reported data fields
for (Iterator fields = dataForm.getReportedData().getFields(); fields.hasNext();) {
FormField field = (FormField)fields.next();
columns.add(new Column(field.getLabel(), field.getVariable(), field.getType()));
}
// Add the rows to the report based on the form's items
for (Iterator items = dataForm.getItems(); items.hasNext();) {
DataForm.Item item = (DataForm.Item)items.next();
List fieldList = new ArrayList(columns.size());
FormField field;
for (Iterator fields = item.getFields(); fields.hasNext();) {
field = (FormField) fields.next();
// Note: The field is created based on the FIRST value of the data form's field
fieldList.add(new Field(field.getVariable(), (String)field.getValues().next()));
}
rows.add(new Row(fieldList));
}
// Set the report's title
this.title = dataForm.getTitle();
}
/**
* Returns an Iterator for the rows returned from a search.
*
* @return an Iterator for the rows returned from a search.
*/
public Iterator getRows() {
return Collections.unmodifiableList(new ArrayList(rows)).iterator();
}
/**
* Returns an Iterator for the columns returned from a search.
*
* @return an Iterator for the columns returned from a search.
*/
public Iterator getColumns() {
return Collections.unmodifiableList(new ArrayList(columns)).iterator();
}
/**
* Returns the report's title. It is similar to the title on a web page or an X
* window.
*
* @return title of the report.
*/
public String getTitle() {
return title;
}
/**
*
* Represents the columns definition of the reported data.
*
* @author Gaston Dombiak
*/
public static class Column {
private String label;
private String variable;
private String type;
/**
* Creates a new column with the specified definition.
*
* @param label the columns's label.
* @param variable the variable name of the column.
* @param type the format for the returned data.
*/
private Column(String label, String variable, String type) {
this.label = label;
this.variable = variable;
this.type = type;
}
/**
* Returns the column's label.
*
* @return label of the column.
*/
public String getLabel() {
return label;
}
/**
* Returns the column's data format. Valid formats are:
*
* <ul>
* <li>text-single -> single line or word of text
* <li>text-private -> instead of showing the user what they typed, you show ***** to
* protect it
* <li>text-multi -> multiple lines of text entry
* <li>list-single -> given a list of choices, pick one
* <li>list-multi -> given a list of choices, pick one or more
* <li>boolean -> 0 or 1, true or false, yes or no. Default value is 0
* <li>fixed -> fixed for putting in text to show sections, or just advertise your web
* site in the middle of the form
* <li>hidden -> is not given to the user at all, but returned with the questionnaire
* <li>jid-single -> Jabber ID - choosing a JID from your roster, and entering one based
* on the rules for a JID.
* <li>jid-multi -> multiple entries for JIDs
* </ul>
*
* @return format for the returned data.
*/
public String getType() {
return type;
}
/**
* Returns the variable name that the column is showing.
*
* @return the variable name of the column.
*/
public String getVariable() {
return variable;
}
}
public static class Row {
private List fields = new ArrayList();
private Row(List fields) {
this.fields = fields;
}
/**
* Returns the fields that define the data that goes with the item.
*
* @return the fields that define the data that goes with the item.
*/
public Iterator getFields() {
return Collections.unmodifiableList(new ArrayList(fields)).iterator();
}
}
public static class Field {
private String variable;
private String value;
private Field(String variable, String value) {
this.variable = variable;
this.value = value;
}
/**
* Returns the variable name that the field represents.
*
* @return the variable name of the field.
*/
public String getVariable() {
return variable;
}
/**
* Returns the value reported as part of the search.
*
* @return the returned value of the search.
*/
public String getValue() {
return value;
}
}
}

View file

@ -0,0 +1,311 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx.packet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smackx.FormField;
/**
* Represents a form that could be use for gathering data as well as for reporting data
* returned from a search.
*
* @author Gaston Dombiak
*/
public class DataForm implements PacketExtension {
public static final String TYPE_FORM = "form";
public static final String TYPE_SUBMIT = "submit";
public static final String TYPE_RESULT = "result";
private String type;
private String title;
private String instructions;
private ReportedData reportedData;
private List items = new ArrayList();
private List fields = new ArrayList();
public DataForm(String type) {
this.type = type;
}
/**
* Returns the meaning of the data within the context. The data could be part of a form
* to fill out, a form submission or data results.<p>
*
* Possible form types are:
* <ul>
* <li>form -> This packet contains a form to fill out. Display it to the user (if your
* program can).</li>
* <li>submit -> The form is filled out, and this is the data that is being returned from
* the form.</li>
* <li>cancel -> The form was cancelled. Tell the asker that piece of information.</li>
* <li>result -> Data results being returned from a search, or some other query.</li>
* </ul>
*
* @return the form's type.
*/
public String getType() {
return type;
}
/**
* Returns the description of the data. It is similar to the title on a web page or an X
* window. You can put a <title/> on either a form to fill out, or a set of data results.
*
* @return description of the data.
*/
public String getTitle() {
return title;
}
/**
* Returns the instructions that explain how to fill out the form and what the form is about.
*
* @return instructions that explain how to fill out the form.
*/
public String getInstructions() {
return instructions;
}
/**
* Returns the fields that will be returned from a search.
*
* @return fields that will be returned from a search.
*/
public ReportedData getReportedData() {
return reportedData;
}
/**
* Returns an Iterator for the items returned from a search.
*
* @return an Iterator for the items returned from a search.
*/
public Iterator getItems() {
synchronized (items) {
return Collections.unmodifiableList(new ArrayList(items)).iterator();
}
}
/**
* Returns an Iterator for the fields that are part of the form.
*
* @return an Iterator for the fields that are part of the form.
*/
public Iterator getFields() {
synchronized (fields) {
return Collections.unmodifiableList(new ArrayList(fields)).iterator();
}
}
public String getElementName() {
return "x";
}
public String getNamespace() {
return "jabber:x:data";
}
/**
* Sets the description of the data. It is similar to the title on a web page or an X window.
* You can put a <title/> on either a form to fill out, or a set of data results.
*
* @param title description of the data.
*/
public void setTitle(String title) {
this.title = title;
}
/**
* Sets instructions that explain how to fill out the form and what the form is about.
*
* @param instructions instructions that explain how to fill out the form.
*/
public void setInstructions(String instructions) {
this.instructions = instructions;
}
/**
* Sets the fields that will be returned from a search.
*
* @param reportedData the fields that will be returned from a search.
*/
public void setReportedData(ReportedData reportedData) {
this.reportedData = reportedData;
}
/**
* Adds a new field as part of the form.
*
* @param field the field to add to the form.
*/
public void addField(FormField field) {
synchronized (fields) {
fields.add(field);
}
}
/**
* Adds a new item returned from a search.
*
* @param field the item returned from a search.
*/
public void addItem(Item item) {
synchronized (items) {
items.add(item);
}
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
"\" type=\"" + getType() +"\">");
if (getTitle() != null) {
buf.append("<title>").append(getTitle()).append("</title>");
}
if (getInstructions() != null) {
buf.append("<instructions>").append(getInstructions()).append("</instructions>");
}
// Append the list of fields returned from a search
if (getReportedData() != null) {
buf.append(getReportedData().toXML());
}
// Loop through all the items returned from a search and append them to the string buffer
for (Iterator i = getItems(); i.hasNext();) {
Item item = (Item) i.next();
buf.append(item.toXML());
}
// Loop through all the form fields and append them to the string buffer
for (Iterator i = getFields(); i.hasNext();) {
FormField field = (FormField) i.next();
buf.append(field.toXML());
}
buf.append("</").append(getElementName()).append(">");
return buf.toString();
}
/**
*
* Represents the fields that will be returned from a search. This information is useful when
* you try to use the jabber:iq:search namespace to return dynamic form information.
*
* @author Gaston Dombiak
*/
public static class ReportedData {
private List fields = new ArrayList();
public ReportedData(List fields) {
this.fields = fields;
}
/**
* Returns the fields returned from a search.
*
* @return the fields returned from a search.
*/
public Iterator getFields() {
return Collections.unmodifiableList(new ArrayList(fields)).iterator();
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<reported>");
// Loop through all the form items and append them to the string buffer
for (Iterator i = getFields(); i.hasNext();) {
FormField field = (FormField) i.next();
buf.append(field.toXML());
}
buf.append("</reported>");
return buf.toString();
}
}
/**
*
* Represents items of reported data.
*
* @author Gaston Dombiak
*/
public static class Item {
private List fields = new ArrayList();
public Item(List fields) {
this.fields = fields;
}
/**
* Returns the fields that define the data that goes with the item.
*
* @return the fields that define the data that goes with the item.
*/
public Iterator getFields() {
return Collections.unmodifiableList(new ArrayList(fields)).iterator();
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<item>");
// Loop through all the form items and append them to the string buffer
for (Iterator i = getFields(); i.hasNext();) {
FormField field = (FormField) i.next();
buf.append(field.toXML());
}
buf.append("</item>");
return buf.toString();
}
}
}

View file

@ -0,0 +1,68 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx.packet;
import org.jivesoftware.smack.packet.IQ;
/**
* Represents .....
*
* @author Gaston Dombiak
*/
public class MUCAdmin extends IQ {
public String getChildElementXML() {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -0,0 +1,202 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx.packet;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.jivesoftware.smack.packet.PacketExtension;
/**
* Represents...
*
* @author Gaston Dombiak
*/
public class MUCInitialPresence implements PacketExtension {
private String password;
private History history;
public String getElementName() {
return "x";
}
public String getNamespace() {
return "http://jabber.org/protocol/muc";
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
"\">");
if (getPassword() != null) {
buf.append(" password=\"").append(getPassword()).append("\"");
}
if (getHistory() != null) {
buf.append(getHistory().toXML());
}
buf.append("</").append(getElementName()).append(">");
return buf.toString();
}
/**
* @return
*/
public History getHistory() {
return history;
}
/**
* @return
*/
public String getPassword() {
return password;
}
/**
* @param history
*/
public void setHistory(History history) {
this.history = history;
}
/**
* @param string
*/
public void setPassword(String string) {
password = string;
}
public static class History {
private int maxChars = -1;
private int maxStanzas = -1;
private int seconds = -1;
private Date since;
/**
* @return
*/
public int getMaxChars() {
return maxChars;
}
/**
* @return
*/
public int getMaxStanzas() {
return maxStanzas;
}
/**
* @return
*/
public int getSeconds() {
return seconds;
}
/**
* @return
*/
public Date getSince() {
return since;
}
/**
* @param i
*/
public void setMaxChars(int i) {
maxChars = i;
}
/**
* @param i
*/
public void setMaxStanzas(int i) {
maxStanzas = i;
}
/**
* @param i
*/
public void setSeconds(int i) {
seconds = i;
}
/**
* @param date
*/
public void setSince(Date date) {
since = date;
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<history");
if (getMaxChars() != -1) {
buf.append(" maxchars=\"").append(getMaxChars()).append("\"");
}
if (getMaxStanzas() != -1) {
buf.append(" maxstanzas=\"").append(getMaxStanzas()).append("\"");
}
if (getSeconds() != -1) {
buf.append(" seconds=\"").append(getSeconds()).append("\"");
}
if (getSince() != null) {
SimpleDateFormat utcFormat = new SimpleDateFormat("yyyyMMdd'T'hh:mm:ss");
buf.append(" seconds=\"").append(utcFormat.format(getSince())).append("\"");
}
buf.append("/>");
return buf.toString();
}
}
}

View file

@ -0,0 +1,303 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx.packet;
import java.util.*;
import org.jivesoftware.smack.packet.IQ;
/**
* Represents .....
*
* @author Gaston Dombiak
*/
public class MUCOwner extends IQ {
private List items = new ArrayList();
private Destroy destroy;
public Iterator getItems() {
synchronized (items) {
return Collections.unmodifiableList(new ArrayList(items)).iterator();
}
}
public Destroy getDestroy() {
return destroy;
}
public void setDestroy(Destroy destroy) {
this.destroy = destroy;
}
public void addItem(Item item) {
synchronized (items) {
items.add(item);
}
}
public String getChildElementXML() {
StringBuffer buf = new StringBuffer();
buf.append("<query xmlns=\"http://jabber.org/protocol/muc#owner\">");
synchronized (items) {
for (int i = 0; i < items.size(); i++) {
Item item = (Item) items.get(i);
buf.append(item.toXML());
}
}
if (getDestroy() != null) {
buf.append(getDestroy().toXML());
}
// Add packet extensions, if any are defined.
buf.append(getExtensionsXML());
buf.append("</query>");
return buf.toString();
}
/**
*
* Item child that holds information about affiliation, jids and nicks.
*
* @author Gaston Dombiak
*/
public static class Item {
// TODO repasar si los comentarios estan OK porque son copy&paste
private String actor;
private String reason;
private String affiliation;
private String jid;
private String nick;
/**
* Creates a new item child.
*
* @param affiliation the actor's affiliation to the room
*/
public Item(String affiliation) {
this.affiliation = affiliation;
}
/**
* Returns the actor (JID of an occupant in the room) that was kicked or banned.
*
* @return the JID of an occupant in the room that was kicked or banned.
*/
public String getActor() {
return actor;
}
/**
* Returns the reason for the item child. The reason is optional and could be used to
* explain the reason why a user (occupant) was kicked or banned.
*
* @return the reason for the item child.
*/
public String getReason() {
return reason;
}
/**
* Returns the occupant's affiliation to the room. The affiliation is a semi-permanent
* association or connection with a room. The possible affiliations are "owner", "admin",
* "member", and "outcast" (naturally it is also possible to have no affiliation). An
* affiliation lasts across a user's visits to a room.
*
* @return the actor's affiliation to the room
*/
public String getAffiliation() {
return affiliation;
}
/**
* Returns the <room@service/nick> by which an occupant is identified within the context
* of a room. If the room is non-anonymous, the JID will be included in the item.
*
* @return the room JID by which an occupant is identified within the room.
*/
public String getJid() {
return jid;
}
/**
* Returns the new nickname of an occupant that is changing his/her nickname. The new
* nickname is sent as part of the unavailable presence.
*
* @return the new nickname of an occupant that is changing his/her nickname.
*/
public String getNick() {
return nick;
}
/**
* Sets the actor (JID of an occupant in the room) that was kicked or banned.
*
* @param actor the actor (JID of an occupant in the room) that was kicked or banned.
*/
public void setActor(String actor) {
this.actor = actor;
}
/**
* Sets the reason for the item child. The reason is optional and could be used to
* explain the reason why a user (occupant) was kicked or banned.
*
* @param reason the reason why a user (occupant) was kicked or banned.
*/
public void setReason(String reason) {
this.reason = reason;
}
/**
* Sets the <room@service/nick> by which an occupant is identified within the context
* of a room. If the room is non-anonymous, the JID will be included in the item.
*
* @param jid the JID by which an occupant is identified within a room.
*/
public void setJid(String jid) {
this.jid = jid;
}
/**
* Sets the new nickname of an occupant that is changing his/her nickname. The new
* nickname is sent as part of the unavailable presence.
*
* @param nick the new nickname of an occupant that is changing his/her nickname.
*/
public void setNick(String nick) {
this.nick = nick;
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<item");
if (getAffiliation() != null) {
buf.append(" affiliation=\"").append(getAffiliation()).append("\"");
}
if (getJid() != null) {
buf.append(" jid=\"").append(getJid()).append("\"");
}
if (getNick() != null) {
buf.append(" nick=\"").append(getNick()).append("\"");
}
if (getReason() == null && getActor() == null) {
buf.append("/>");
}
else {
buf.append(">");
if (getReason() != null) {
buf.append("<reason>").append(getReason()).append("</reason>");
}
if (getActor() != null) {
buf.append("<actor jid=\"").append(getActor()).append("\"/>");
}
buf.append("</item>");
}
return buf.toString();
}
};
public static class Destroy {
private String reason;
private String jid;
/**
* @return
*/
public String getJid() {
return jid;
}
/**
* @return
*/
public String getReason() {
return reason;
}
/**
* @param jid
*/
public void setJid(String jid) {
this.jid = jid;
}
/**
* @param reason
*/
public void setReason(String reason) {
this.reason = reason;
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<destroy");
if (getJid() != null) {
buf.append(" jid=\"").append(getJid()).append("\"");
}
if (getReason() == null) {
buf.append("/>");
}
else {
buf.append(">");
if (getReason() != null) {
buf.append("<reason>").append(getReason()).append("</reason>");
}
buf.append("</destroy>");
}
return buf.toString();
}
}
}

View file

@ -0,0 +1,523 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx.packet;
import org.jivesoftware.smack.packet.PacketExtension;
/**
* Represents extended presence information about roles, affiliations, full JIDs,
* or status codes scoped by the 'http://jabber.org/protocol/muc#user' namespace.
*
* @author Gaston Dombiak
*/
public class MUCUser implements PacketExtension {
private String alt;
private Invite invite;
private Decline decline;
private Item item;
private String password;
private Status status;
public String getElementName() {
return "x";
}
public String getNamespace() {
return "http://jabber.org/protocol/muc#user";
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
"\">");
if (getAlt() != null) {
buf.append("<alt>").append(getAlt()).append("</alt>");
}
if (getInvite() != null) {
buf.append(getInvite().toXML());
}
if (getDecline() != null) {
buf.append(getDecline().toXML());
}
if (getItem() != null) {
buf.append(getItem().toXML());
}
if (getPassword() != null) {
buf.append("<password>").append(getPassword()).append("</password>");
}
if (getStatus() != null) {
buf.append(getStatus().toXML());
}
buf.append("</").append(getElementName()).append(">");
return buf.toString();
}
/**
* @return
*/
public String getAlt() {
return alt;
}
/**
* @return
*/
public Invite getInvite() {
return invite;
}
/**
* @return
*/
public Decline getDecline() {
return decline;
}
/**
* @return
*/
public Item getItem() {
return item;
}
/**
* @return
*/
public String getPassword() {
return password;
}
/**
* @return
*/
public Status getStatus() {
return status;
}
/**
* @param string
*/
public void setAlt(String string) {
alt = string;
}
/**
* @param invite
*/
public void setInvite(Invite invite) {
this.invite = invite;
}
/**
* @param decline
*/
public void setDecline(Decline decline) {
this.decline = decline;
}
/**
* @param item
*/
public void setItem(Item item) {
this.item = item;
}
/**
* @param string
*/
public void setPassword(String string) {
password = string;
}
/**
* @param status
*/
public void setStatus(Status status) {
this.status = status;
}
/**
*
* Represents an invitation for another user to a room. The sender of the invitation
* must be an occupant of the room. The invitation will be sent to the room which in turn
* will forward the invitation to the invitee.
*
* @author Gaston Dombiak
*/
public static class Invite {
private String reason;
private String from;
private String to;
/**
* @return
*/
public String getFrom() {
return from;
}
/**
* @return
*/
public String getReason() {
return reason;
}
/**
* @return
*/
public String getTo() {
return to;
}
/**
* @param string
*/
public void setFrom(String string) {
from = string;
}
/**
* @param string
*/
public void setReason(String string) {
reason = string;
}
/**
* @param string
*/
public void setTo(String string) {
to = string;
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<invite ");
if (getTo() != null) {
buf.append(" to=\"").append(getTo()).append("\"");
}
if (getFrom() != null) {
buf.append(" from=\"").append(getFrom()).append("\"");
}
buf.append(">");
if (getReason() != null) {
buf.append("<reason>").append(getReason()).append("</reason>");
}
buf.append("</invite>");
return buf.toString();
}
};
/**
*
* Represents a rejection to an invitation from another user to a room. The rejection will be
* sent to the room which in turn will forward the refusal to the inviter.
*
* @author Gaston Dombiak
*/
public static class Decline {
private String reason;
private String from;
private String to;
/**
* @return
*/
public String getFrom() {
return from;
}
/**
* @return
*/
public String getReason() {
return reason;
}
/**
* @return
*/
public String getTo() {
return to;
}
/**
* @param string
*/
public void setFrom(String string) {
from = string;
}
/**
* @param string
*/
public void setReason(String string) {
reason = string;
}
/**
* @param string
*/
public void setTo(String string) {
to = string;
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<decline ");
if (getTo() != null) {
buf.append(" to=\"").append(getTo()).append("\"");
}
if (getFrom() != null) {
buf.append(" from=\"").append(getFrom()).append("\"");
}
buf.append(">");
if (getReason() != null) {
buf.append("<reason>").append(getReason()).append("</reason>");
}
buf.append("</decline>");
return buf.toString();
}
};
/**
*
* Item child that holds information about roles, affiliation, jids and nicks.
*
* @author Gaston Dombiak
*/
public static class Item {
private String actor;
private String reason;
private String affiliation;
private String jid;
private String nick;
private String role;
/**
* Creates a new item child.
*
* @param affiliation the actor's affiliation to the room
* @param role the privilege level of an occupant within a room.
*/
public Item(String affiliation, String role) {
this.affiliation = affiliation;
this.role = role;
}
/**
* Returns the actor (JID of an occupant in the room) that was kicked or banned.
*
* @return the JID of an occupant in the room that was kicked or banned.
*/
public String getActor() {
return actor;
}
/**
* Returns the reason for the item child. The reason is optional and could be used to
* explain the reason why a user (occupant) was kicked or banned.
*
* @return the reason for the item child.
*/
public String getReason() {
return reason;
}
/**
* Returns the occupant's affiliation to the room. The affiliation is a semi-permanent
* association or connection with a room. The possible affiliations are "owner", "admin",
* "member", and "outcast" (naturally it is also possible to have no affiliation). An
* affiliation lasts across a user's visits to a room.
*
* @return the actor's affiliation to the room
*/
public String getAffiliation() {
return affiliation;
}
/**
* Returns the <room@service/nick> by which an occupant is identified within the context
* of a room. If the room is non-anonymous, the JID will be included in the item.
*
* @return the room JID by which an occupant is identified within the room.
*/
public String getJid() {
return jid;
}
/**
* Returns the new nickname of an occupant that is changing his/her nickname. The new
* nickname is sent as part of the unavailable presence.
*
* @return the new nickname of an occupant that is changing his/her nickname.
*/
public String getNick() {
return nick;
}
/**
* Returns the temporary position or privilege level of an occupant within a room. The
* possible roles are "moderator", "participant", and "visitor" (it is also possible to
* have no defined role). A role lasts only for the duration of an occupant's visit to
* a room.
*
* @return the privilege level of an occupant within a room.
*/
public String getRole() {
return role;
}
/**
* Sets the actor (JID of an occupant in the room) that was kicked or banned.
*
* @param actor the actor (JID of an occupant in the room) that was kicked or banned.
*/
public void setActor(String actor) {
this.actor = actor;
}
/**
* Sets the reason for the item child. The reason is optional and could be used to
* explain the reason why a user (occupant) was kicked or banned.
*
* @param reason the reason why a user (occupant) was kicked or banned.
*/
public void setReason(String reason) {
this.reason = reason;
}
/**
* Sets the <room@service/nick> by which an occupant is identified within the context
* of a room. If the room is non-anonymous, the JID will be included in the item.
*
* @param jid the JID by which an occupant is identified within a room.
*/
public void setJid(String jid) {
this.jid = jid;
}
/**
* Sets the new nickname of an occupant that is changing his/her nickname. The new
* nickname is sent as part of the unavailable presence.
*
* @param nick the new nickname of an occupant that is changing his/her nickname.
*/
public void setNick(String nick) {
this.nick = nick;
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<item");
if (getAffiliation() != null) {
buf.append(" affiliation=\"").append(getAffiliation()).append("\"");
}
if (getJid() != null) {
buf.append(" jid=\"").append(getJid()).append("\"");
}
if (getNick() != null) {
buf.append(" nick=\"").append(getNick()).append("\"");
}
if (getRole() != null) {
buf.append(" role=\"").append(getRole()).append("\"");
}
if (getReason() == null && getActor() == null) {
buf.append("/>");
}
else {
buf.append(">");
if (getReason() != null) {
buf.append("<reason>").append(getReason()).append("</reason>");
}
if (getActor() != null) {
buf.append("<actor jid=\"").append(getActor()).append("\"/>");
}
buf.append("</item>");
}
return buf.toString();
}
};
/**
*
* Status code assists in presenting notification messages.
*
* @author Gaston Dombiak
*/
public static class Status {
private String code;
/**
*
* @param code
*/
public Status(String code) {
this.code = code;
}
/**
* @return
*/
public String getCode() {
return code;
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<status code=\"").append(getCode()).append("\"/>");
return buf.toString();
}
};
}

View file

@ -0,0 +1,193 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx.provider;
import java.util.ArrayList;
import java.util.List;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.provider.PacketExtensionProvider;
import org.jivesoftware.smackx.FormField;
import org.jivesoftware.smackx.packet.DataForm;
import org.xmlpull.v1.XmlPullParser;
/**
* The DataFormProvider parses DataForm packets.
*
* @author Gaston Dombiak
*/
public class DataFormProvider implements PacketExtensionProvider {
/**
* Creates a new DataFormProvider.
* ProviderManager requires that every PacketExtensionProvider has a public, no-argument constructor
*/
public DataFormProvider() {
}
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
boolean done = false;
StringBuffer buffer = null;
DataForm dataForm = new DataForm(parser.getAttributeValue("", "type"));
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("instructions")) {
dataForm.setInstructions(parser.nextText());
}
else if (parser.getName().equals("title")) {
dataForm.setTitle(parser.nextText());
}
else if (parser.getName().equals("field")) {
dataForm.addField(parseField(parser));
}
else if (parser.getName().equals("item")) {
dataForm.addItem(parseItem(parser));
}
else if (parser.getName().equals("reported")) {
dataForm.setReportedData(parseReported(parser));
}
} else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals(dataForm.getElementName())) {
done = true;
}
}
}
return dataForm;
}
private FormField parseField(XmlPullParser parser) throws Exception {
boolean done = false;
FormField formField = new FormField();
formField.setLabel(parser.getAttributeValue("", "label"));
formField.setVariable(parser.getAttributeValue("", "var"));
formField.setType(parser.getAttributeValue("", "type"));
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("desc")) {
formField.setDescription(parser.nextText());
}
else if (parser.getName().equals("value")) {
formField.addValue(parser.nextText());
}
else if (parser.getName().equals("required")) {
formField.setRequired(true);
}
else if (parser.getName().equals("option")) {
formField.addOption(parseOption(parser));
}
} else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("field")) {
done = true;
}
}
}
return formField;
}
private DataForm.Item parseItem(XmlPullParser parser) throws Exception {
boolean done = false;
List fields = new ArrayList();
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("field")) {
fields.add(parseField(parser));
}
} else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("item")) {
done = true;
}
}
}
return new DataForm.Item(fields);
}
private DataForm.ReportedData parseReported(XmlPullParser parser) throws Exception {
boolean done = false;
List fields = new ArrayList();
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("field")) {
fields.add(parseField(parser));
}
} else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("reported")) {
done = true;
}
}
}
return new DataForm.ReportedData(fields);
}
private FormField.Option parseOption(XmlPullParser parser) throws Exception {
boolean done = false;
FormField.Option option = null;
String label = parser.getAttributeValue("", "label");
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("value")) {
option = new FormField.Option(label, parser.nextText());
}
} else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("option")) {
done = true;
}
}
}
return option;
}
}

View file

@ -0,0 +1,74 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx.provider;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.provider.IQProvider;
import org.xmlpull.v1.XmlPullParser;
/**
* Represents .....
*
* @author Gaston Dombiak
*/
public class MUCAdminProvider implements IQProvider {
/* (non-Javadoc)
* @see org.jivesoftware.smack.provider.IQProvider#parseIQ(org.xmlpull.v1.XmlPullParser)
*/
public IQ parseIQ(XmlPullParser parser) throws Exception {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -0,0 +1,143 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx.provider;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.provider.*;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smackx.packet.MUCOwner;
import org.xmlpull.v1.XmlPullParser;
/**
* Represents .....
*
* @author Gaston Dombiak
*/
public class MUCOwnerProvider implements IQProvider {
public IQ parseIQ(XmlPullParser parser) throws Exception {
MUCOwner mucOwner = new MUCOwner();
boolean done = false;
MUCOwner.Item item = null;
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("item")) {
mucOwner.addItem(parseItem(parser));
}
if (parser.getName().equals("destroy")) {
mucOwner.setDestroy(parseDestroy(parser));
}
// Otherwise, it must be a packet extension.
else {
mucOwner.addExtension(
PacketParserUtils.parsePacketExtension(
parser.getName(),
parser.getNamespace(),
parser));
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("query")) {
done = true;
}
}
}
return mucOwner;
}
private MUCOwner.Item parseItem(XmlPullParser parser) throws Exception {
boolean done = false;
MUCOwner.Item item = new MUCOwner.Item(parser.getAttributeValue("", "affiliation"));
item.setNick(parser.getAttributeValue("", "nick"));
item.setJid(parser.getAttributeValue("", "jid"));
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("actor")) {
item.setActor(parser.getAttributeValue("", "jid"));
}
if (parser.getName().equals("reason")) {
item.setReason(parser.getText());
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("item")) {
done = true;
}
}
}
return item;
}
private MUCOwner.Destroy parseDestroy(XmlPullParser parser) throws Exception {
boolean done = false;
MUCOwner.Destroy destroy = new MUCOwner.Destroy();
destroy.setJid(parser.getAttributeValue("", "jid"));
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("reason")) {
destroy.setReason(parser.getText());
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("destroy")) {
done = true;
}
}
}
return destroy;
}
}

View file

@ -0,0 +1,135 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2002-2003 Jive Software. All rights reserved.
* ====================================================================
* The Jive Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Jive Software (http://www.jivesoftware.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Smack" and "Jive Software" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@jivesoftware.com.
*
* 5. Products derived from this software may not be called "Smack",
* nor may "Smack" appear in their name, without prior written
* permission of Jive Software.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.jivesoftware.smackx.provider;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.provider.*;
import org.jivesoftware.smackx.packet.*;
import org.xmlpull.v1.XmlPullParser;
/**
* The MUCUserProvider parses packets with extended presence information about
* roles and affiliations.
*
* @author Gaston Dombiak
*/
public class MUCUserProvider implements PacketExtensionProvider {
/**
* Creates a new MUCUserProvider.
* ProviderManager requires that every PacketExtensionProvider has a public, no-argument
* constructor
*/
public MUCUserProvider() {
}
/**
* Parses a MUCUser packet (extension sub-packet).
*
* @param parser the XML parser, positioned at the starting element of the extension.
* @return a PacketExtension.
* @throws Exception if a parsing error occurs.
*/
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
MUCUser mucUser = new MUCUser();
boolean done = false;
MUCUser.Item item = null;
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("item")) {
item =
new MUCUser.Item(
parser.getAttributeValue("", "affiliation"),
parser.getAttributeValue("", "role"));
item.setNick(parser.getAttributeValue("", "nick"));
item.setJid(parser.getAttributeValue("", "jid"));
}
if (parser.getName().equals("actor")) {
item.setActor(parser.getAttributeValue("", "jid"));
}
if (parser.getName().equals("reason")) {
item.setReason(parser.getText());
}
if (parser.getName().equals("password")) {
mucUser.setPassword(parser.getText());
}
if (parser.getName().equals("alt")) {
// TODO Implement alt? Is it being used?
System.out.println("alt - Not implemented yet!");
}
if (parser.getName().equals("invite")) {
// TODO Implement invitation decoding
System.out.println("invite - Not implemented yet!");
}
if (parser.getName().equals("decline")) {
// TODO Implement decline decoding
System.out.println("decline - Not implemented yet!");
}
if (parser.getName().equals("status")) {
mucUser.setStatus(new MUCUser.Status(parser.getAttributeValue("", "code")));
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("item")) {
mucUser.setItem(item);
}
if (parser.getName().equals("x")) {
done = true;
}
}
}
return mucUser;
}
}