mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2025-12-08 22:21:08 +01:00
Deleting.
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@2656 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
37231ec646
commit
d4550a6356
276 changed files with 0 additions and 40430 deletions
|
|
@ -1,55 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
/**
|
||||
*
|
||||
* Default implementation of the MessageEventRequestListener interface.<p>
|
||||
*
|
||||
* This class automatically sends a delivered notification to the sender of the message
|
||||
* if the sender has requested to be notified when the message is delivered.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class DefaultMessageEventRequestListener implements MessageEventRequestListener {
|
||||
|
||||
public void deliveredNotificationRequested(String from, String packetID,
|
||||
MessageEventManager messageEventManager)
|
||||
{
|
||||
// Send to the message's sender that the message has been delivered
|
||||
messageEventManager.sendDeliveredNotification(from, packetID);
|
||||
}
|
||||
|
||||
public void displayedNotificationRequested(String from, String packetID,
|
||||
MessageEventManager messageEventManager)
|
||||
{
|
||||
}
|
||||
|
||||
public void composingNotificationRequested(String from, String packetID,
|
||||
MessageEventManager messageEventManager)
|
||||
{
|
||||
}
|
||||
|
||||
public void offlineNotificationRequested(String from, String packetID,
|
||||
MessageEventManager messageEventManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,539 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
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, it's only possible
|
||||
* to set answers if the form is of type "submit".
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class Form {
|
||||
|
||||
public static final String TYPE_FORM = "form";
|
||||
public static final String TYPE_SUBMIT = "submit";
|
||||
public static final String TYPE_CANCEL = "cancel";
|
||||
public static final String TYPE_RESULT = "result";
|
||||
|
||||
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) {
|
||||
dataForm.addField(field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new String value to a given form's field. The field whose variable matches the
|
||||
* requested variable will be completed with the specified value. If no field could be found
|
||||
* for the specified variable then an exception will be raised.<p>
|
||||
*
|
||||
* If the value to set to the field is not a basic type (e.g. String, boolean, int, etc.) you
|
||||
* can use this message where the String value is the String representation of the object.
|
||||
*
|
||||
* @param variable the variable name that was completed.
|
||||
* @param value the String value that was answered.
|
||||
* @throws IllegalStateException if the form is not of type "submit".
|
||||
* @throws IllegalArgumentException if the form does not include the specified variable.
|
||||
* @throws IllegalArgumentException if the answer type does not correspond with the field type.
|
||||
*/
|
||||
public void setAnswer(String variable, String value) {
|
||||
FormField field = getField(variable);
|
||||
if (field == null) {
|
||||
throw new IllegalArgumentException("Field not found for the specified variable name.");
|
||||
}
|
||||
if (!FormField.TYPE_TEXT_MULTI.equals(field.getType())
|
||||
&& !FormField.TYPE_TEXT_PRIVATE.equals(field.getType())
|
||||
&& !FormField.TYPE_TEXT_SINGLE.equals(field.getType())
|
||||
&& !FormField.TYPE_JID_SINGLE.equals(field.getType())
|
||||
&& !FormField.TYPE_HIDDEN.equals(field.getType())) {
|
||||
throw new IllegalArgumentException("This field is not of type String.");
|
||||
}
|
||||
setAnswer(field, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new int value to a given form's field. The field whose variable matches the
|
||||
* requested variable will be completed with the specified value. If no field could be found
|
||||
* for the specified variable then an exception will be raised.
|
||||
*
|
||||
* @param variable the variable name that was completed.
|
||||
* @param value the int value that was answered.
|
||||
* @throws IllegalStateException if the form is not of type "submit".
|
||||
* @throws IllegalArgumentException if the form does not include the specified variable.
|
||||
* @throws IllegalArgumentException if the answer type does not correspond with the field type.
|
||||
*/
|
||||
public void setAnswer(String variable, int value) {
|
||||
FormField field = getField(variable);
|
||||
if (field == null) {
|
||||
throw new IllegalArgumentException("Field not found for the specified variable name.");
|
||||
}
|
||||
if (!FormField.TYPE_TEXT_MULTI.equals(field.getType())
|
||||
&& !FormField.TYPE_TEXT_PRIVATE.equals(field.getType())
|
||||
&& !FormField.TYPE_TEXT_SINGLE.equals(field.getType())) {
|
||||
throw new IllegalArgumentException("This field is not of type int.");
|
||||
}
|
||||
setAnswer(field, new Integer(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new long value to a given form's field. The field whose variable matches the
|
||||
* requested variable will be completed with the specified value. If no field could be found
|
||||
* for the specified variable then an exception will be raised.
|
||||
*
|
||||
* @param variable the variable name that was completed.
|
||||
* @param value the long value that was answered.
|
||||
* @throws IllegalStateException if the form is not of type "submit".
|
||||
* @throws IllegalArgumentException if the form does not include the specified variable.
|
||||
* @throws IllegalArgumentException if the answer type does not correspond with the field type.
|
||||
*/
|
||||
public void setAnswer(String variable, long value) {
|
||||
FormField field = getField(variable);
|
||||
if (field == null) {
|
||||
throw new IllegalArgumentException("Field not found for the specified variable name.");
|
||||
}
|
||||
if (!FormField.TYPE_TEXT_MULTI.equals(field.getType())
|
||||
&& !FormField.TYPE_TEXT_PRIVATE.equals(field.getType())
|
||||
&& !FormField.TYPE_TEXT_SINGLE.equals(field.getType())) {
|
||||
throw new IllegalArgumentException("This field is not of type long.");
|
||||
}
|
||||
setAnswer(field, new Long(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new float value to a given form's field. The field whose variable matches the
|
||||
* requested variable will be completed with the specified value. If no field could be found
|
||||
* for the specified variable then an exception will be raised.
|
||||
*
|
||||
* @param variable the variable name that was completed.
|
||||
* @param value the float value that was answered.
|
||||
* @throws IllegalStateException if the form is not of type "submit".
|
||||
* @throws IllegalArgumentException if the form does not include the specified variable.
|
||||
* @throws IllegalArgumentException if the answer type does not correspond with the field type.
|
||||
*/
|
||||
public void setAnswer(String variable, float value) {
|
||||
FormField field = getField(variable);
|
||||
if (field == null) {
|
||||
throw new IllegalArgumentException("Field not found for the specified variable name.");
|
||||
}
|
||||
if (!FormField.TYPE_TEXT_MULTI.equals(field.getType())
|
||||
&& !FormField.TYPE_TEXT_PRIVATE.equals(field.getType())
|
||||
&& !FormField.TYPE_TEXT_SINGLE.equals(field.getType())) {
|
||||
throw new IllegalArgumentException("This field is not of type float.");
|
||||
}
|
||||
setAnswer(field, new Float(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new double value to a given form's field. The field whose variable matches the
|
||||
* requested variable will be completed with the specified value. If no field could be found
|
||||
* for the specified variable then an exception will be raised.
|
||||
*
|
||||
* @param variable the variable name that was completed.
|
||||
* @param value the double value that was answered.
|
||||
* @throws IllegalStateException if the form is not of type "submit".
|
||||
* @throws IllegalArgumentException if the form does not include the specified variable.
|
||||
* @throws IllegalArgumentException if the answer type does not correspond with the field type.
|
||||
*/
|
||||
public void setAnswer(String variable, double value) {
|
||||
FormField field = getField(variable);
|
||||
if (field == null) {
|
||||
throw new IllegalArgumentException("Field not found for the specified variable name.");
|
||||
}
|
||||
if (!FormField.TYPE_TEXT_MULTI.equals(field.getType())
|
||||
&& !FormField.TYPE_TEXT_PRIVATE.equals(field.getType())
|
||||
&& !FormField.TYPE_TEXT_SINGLE.equals(field.getType())) {
|
||||
throw new IllegalArgumentException("This field is not of type double.");
|
||||
}
|
||||
setAnswer(field, new Double(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new boolean value to a given form's field. The field whose variable matches the
|
||||
* requested variable will be completed with the specified value. If no field could be found
|
||||
* for the specified variable then an exception will be raised.
|
||||
*
|
||||
* @param variable the variable name that was completed.
|
||||
* @param value the boolean value that was answered.
|
||||
* @throws IllegalStateException if the form is not of type "submit".
|
||||
* @throws IllegalArgumentException if the form does not include the specified variable.
|
||||
* @throws IllegalArgumentException if the answer type does not correspond with the field type.
|
||||
*/
|
||||
public void setAnswer(String variable, boolean value) {
|
||||
FormField field = getField(variable);
|
||||
if (field == null) {
|
||||
throw new IllegalArgumentException("Field not found for the specified variable name.");
|
||||
}
|
||||
if (!FormField.TYPE_BOOLEAN.equals(field.getType())) {
|
||||
throw new IllegalArgumentException("This field is not of type boolean.");
|
||||
}
|
||||
setAnswer(field, (value ? "1" : "0"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new Object value to a given form's field. In fact, the object representation
|
||||
* (i.e. #toString) will be the actual value of the field.<p>
|
||||
*
|
||||
* If the value to set to the field is not a basic type (e.g. String, boolean, int, etc.) you
|
||||
* will need to use {@link #setAnswer(String, String))} where the String value is the
|
||||
* String representation of the object.<p>
|
||||
*
|
||||
* Before setting the new value to the field we will check if the form is of type submit. If
|
||||
* the form isn't of type submit means that it's not possible to complete the form and an
|
||||
* exception will be thrown.
|
||||
*
|
||||
* @param field the form field that was completed.
|
||||
* @param value the Object value that was answered. The object representation will be the
|
||||
* actual value.
|
||||
* @throws IllegalStateException if the form is not of type "submit".
|
||||
*/
|
||||
private void setAnswer(FormField field, Object value) {
|
||||
if (!isSubmitType()) {
|
||||
throw new IllegalStateException("Cannot set an answer if the form is not of type " +
|
||||
"\"submit\"");
|
||||
}
|
||||
field.resetValues();
|
||||
field.addValue(value.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new values to a given form's field. The field whose variable matches the requested
|
||||
* variable will be completed with the specified values. If no field could be found for
|
||||
* the specified variable then an exception will be raised.<p>
|
||||
*
|
||||
* The Objects contained in the List could be of any type. The String representation of them
|
||||
* (i.e. #toString) will be actually used when sending the answer to the server.
|
||||
*
|
||||
* @param variable the variable that was completed.
|
||||
* @param values the values that were answered.
|
||||
* @throws IllegalStateException if the form is not of type "submit".
|
||||
* @throws IllegalArgumentException if the form does not include the specified variable.
|
||||
*/
|
||||
public void setAnswer(String variable, List values) {
|
||||
if (!isSubmitType()) {
|
||||
throw new IllegalStateException("Cannot set an answer if the form is not of type " +
|
||||
"\"submit\"");
|
||||
}
|
||||
FormField field = getField(variable);
|
||||
if (field != null) {
|
||||
// Check that the field can accept a collection of values
|
||||
if (!FormField.TYPE_JID_MULTI.equals(field.getType())
|
||||
&& !FormField.TYPE_LIST_MULTI.equals(field.getType())
|
||||
&& !FormField.TYPE_LIST_SINGLE.equals(field.getType())
|
||||
&& !FormField.TYPE_HIDDEN.equals(field.getType())) {
|
||||
throw new IllegalArgumentException("This field only accept list of values.");
|
||||
}
|
||||
// Clear the old values
|
||||
field.resetValues();
|
||||
// Set the new values. The string representation of each value will be actually used.
|
||||
field.addValues(values);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Couldn't find a field for the specified variable.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default value as the value of a given form's field. The field whose variable matches
|
||||
* the requested variable will be completed with its default value. If no field could be found
|
||||
* for the specified variable then an exception will be raised.
|
||||
*
|
||||
* @param variable the variable to complete with its default value.
|
||||
* @throws IllegalStateException if the form is not of type "submit".
|
||||
* @throws IllegalArgumentException if the form does not include the specified variable.
|
||||
*/
|
||||
public void setDefaultAnswer(String variable) {
|
||||
if (!isSubmitType()) {
|
||||
throw new IllegalStateException("Cannot set an answer if the form is not of type " +
|
||||
"\"submit\"");
|
||||
}
|
||||
FormField field = getField(variable);
|
||||
if (field != null) {
|
||||
// Clear the old values
|
||||
field.resetValues();
|
||||
// Set the default value
|
||||
for (Iterator it = field.getValues(); it.hasNext();) {
|
||||
field.addValue((String) it.next());
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Couldn't find a field for the specified variable.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 field of the form whose variable matches the specified variable.
|
||||
* The fields of type FIXED will never be returned since they do not specify a
|
||||
* variable.
|
||||
*
|
||||
* @param variable the variable to look for in the form fields.
|
||||
* @return the field of the form whose variable matches the specified variable.
|
||||
*/
|
||||
public FormField getField(String variable) {
|
||||
if (variable == null || variable.equals("")) {
|
||||
throw new IllegalArgumentException("Variable must not be null or blank.");
|
||||
}
|
||||
// Look for the field whose variable matches the requested variable
|
||||
FormField field;
|
||||
for (Iterator it=getFields();it.hasNext();) {
|
||||
field = (FormField)it.next();
|
||||
if (variable.equals(field.getVariable())) {
|
||||
return field;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
// Join the list of instructions together separated by newlines
|
||||
for (Iterator it = dataForm.getInstructions(); it.hasNext();) {
|
||||
sb.append((String) it.next());
|
||||
// If this is not the last instruction then append a newline
|
||||
if (it.hasNext()) {
|
||||
sb.append("\n");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
// Split the instructions into multiple instructions for each existent newline
|
||||
ArrayList instructionsList = new ArrayList();
|
||||
StringTokenizer st = new StringTokenizer(instructions, "\n");
|
||||
while (st.hasMoreTokens()) {
|
||||
instructionsList.add(st.nextToken());
|
||||
}
|
||||
// Set the new list of instructions
|
||||
dataForm.setInstructions(instructionsList);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 a DataForm that serves to send this Form to the server. If the form is of type
|
||||
* submit, it may contain fields with no value. These fields will be removed since they only
|
||||
* exist to assist the user while editing/completing the form in a UI.
|
||||
*
|
||||
* @return the wrapped DataForm.
|
||||
*/
|
||||
public DataForm getDataFormToSend() {
|
||||
if (isSubmitType()) {
|
||||
// Create a new DataForm that contains only the answered fields
|
||||
DataForm dataFormToSend = new DataForm(getType());
|
||||
for(Iterator it=getFields();it.hasNext();) {
|
||||
FormField field = (FormField)it.next();
|
||||
if (field.getValues().hasNext()) {
|
||||
dataFormToSend.addField(field);
|
||||
}
|
||||
}
|
||||
return dataFormToSend;
|
||||
}
|
||||
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 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 TYPE_SUBMIT.equals(dataForm.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Form to submit the completed values. The new Form will include all the fields
|
||||
* of the original form except for the fields of type FIXED. Only the HIDDEN fields will
|
||||
* include the same value of the original form. The other fields of the new form MUST be
|
||||
* completed. If a field remains with no answer when sending the completed form, then it won't
|
||||
* be included as part of the completed form.<p>
|
||||
*
|
||||
* The reason why the fields with variables are included in the new form is to provide a model
|
||||
* for binding with any UI. This means that the UIs will use the original form (of type
|
||||
* "form") to learn how to render the form, but the UIs will bind the fields to the form of
|
||||
* type submit.
|
||||
*
|
||||
* @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(TYPE_SUBMIT);
|
||||
for (Iterator fields=getFields(); fields.hasNext();) {
|
||||
FormField field = (FormField)fields.next();
|
||||
// Add to the new form any type of field that includes a variable.
|
||||
// Note: The fields of type FIXED are the only ones that don't specify a variable
|
||||
if (field.getVariable() != null) {
|
||||
FormField newField = new FormField(field.getVariable());
|
||||
newField.setType(field.getType());
|
||||
form.addField(newField);
|
||||
// Set the answer ONLY to the hidden fields
|
||||
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.setAnswer(field.getVariable(), values);
|
||||
}
|
||||
}
|
||||
}
|
||||
return form;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,350 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
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();
|
||||
|
||||
/**
|
||||
* Creates a new FormField with the variable name that uniquely identifies the field
|
||||
* in the context of the form.
|
||||
*
|
||||
* @param variable the variable name of the question.
|
||||
*/
|
||||
public FormField(String variable) {
|
||||
this.variable = variable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new FormField of type FIXED. The fields of type FIXED do not define a variable
|
||||
* name.
|
||||
*
|
||||
*/
|
||||
public FormField() {
|
||||
this.type = FormField.TYPE_FIXED;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 newValues default values or an answered values of the question.
|
||||
*/
|
||||
public void addValues(List newValues) {
|
||||
synchronized (values) {
|
||||
values.addAll(newValues);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all the values of the field.
|
||||
*
|
||||
*/
|
||||
protected void resetValues() {
|
||||
synchronized (values) {
|
||||
values.removeAll(new ArrayList(values));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* A group chat invitation packet extension, which is used to invite other
|
||||
* users to a group chat room. To invite a user to a group chat room, address
|
||||
* a new message to the user and set the room name appropriately, as in the
|
||||
* following code example:
|
||||
*
|
||||
* <pre>
|
||||
* Message message = new Message("user@chat.example.com");
|
||||
* message.setBody("Join me for a group chat!");
|
||||
* message.addExtension(new GroupChatInvitation("room@chat.example.com"););
|
||||
* con.sendPacket(message);
|
||||
* </pre>
|
||||
*
|
||||
* To listen for group chat invitations, use a PacketExtensionFilter for the
|
||||
* <tt>x</tt> element name and <tt>jabber:x:conference</tt> namespace, as in the
|
||||
* following code example:
|
||||
*
|
||||
* <pre>
|
||||
* PacketFilter filter = new PacketExtensionFilter("x", "jabber:x:conference");
|
||||
* // Create a packet collector or packet listeners using the filter...
|
||||
* </pre>
|
||||
*
|
||||
* <b>Note</b>: this protocol is outdated now that the Multi-User Chat (MUC) JEP is available
|
||||
* (<a href="http://www.jabber.org/jeps/jep-0045.html">JEP-45</a>). However, most
|
||||
* existing clients still use this older protocol. Once MUC support becomes more
|
||||
* widespread, this API may be deprecated.
|
||||
*
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public class GroupChatInvitation implements PacketExtension {
|
||||
|
||||
/**
|
||||
* Element name of the packet extension.
|
||||
*/
|
||||
public static final String ELEMENT_NAME = "x";
|
||||
|
||||
/**
|
||||
* Namespace of the packet extension.
|
||||
*/
|
||||
public static final String NAMESPACE = "jabber:x:conference";
|
||||
|
||||
private String roomAddress;
|
||||
|
||||
/**
|
||||
* Creates a new group chat invitation to the specified room address.
|
||||
* GroupChat room addresses are in the form <tt>room@service</tt>,
|
||||
* where <tt>service</tt> is the name of groupchat server, such as
|
||||
* <tt>chat.example.com</tt>.
|
||||
*
|
||||
* @param roomAddress the address of the group chat room.
|
||||
*/
|
||||
public GroupChatInvitation(String roomAddress) {
|
||||
this.roomAddress = roomAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address of the group chat room. GroupChat room addresses
|
||||
* are in the form <tt>room@service</tt>, where <tt>service</tt> is
|
||||
* the name of groupchat server, such as <tt>chat.example.com</tt>.
|
||||
*
|
||||
* @return the address of the group chat room.
|
||||
*/
|
||||
public String getRoomAddress() {
|
||||
return roomAddress;
|
||||
}
|
||||
|
||||
public String getElementName() {
|
||||
return ELEMENT_NAME;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<x xmlns=\"jabber:x:conference\" jid=\"").append(roomAddress).append("\"/>");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static class Provider implements PacketExtensionProvider {
|
||||
public PacketExtension parseExtension (XmlPullParser parser) throws Exception {
|
||||
String roomAddress = parser.getAttributeValue("", "jid");
|
||||
// Advance to end of extension.
|
||||
parser.next();
|
||||
return new GroupChatInvitation(roomAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,304 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
import org.jivesoftware.smack.*;
|
||||
import org.jivesoftware.smack.filter.*;
|
||||
import org.jivesoftware.smack.packet.*;
|
||||
import org.jivesoftware.smackx.packet.*;
|
||||
|
||||
/**
|
||||
* Manages message events requests and notifications. A MessageEventManager provides a high
|
||||
* level access to request for notifications and send event notifications. It also provides
|
||||
* an easy way to hook up custom logic when requests or notifications are received.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class MessageEventManager {
|
||||
|
||||
private List messageEventNotificationListeners = new ArrayList();
|
||||
private List messageEventRequestListeners = new ArrayList();
|
||||
|
||||
private XMPPConnection con;
|
||||
|
||||
private PacketFilter packetFilter = new PacketExtensionFilter("x", "jabber:x:event");
|
||||
private PacketListener packetListener;
|
||||
|
||||
/**
|
||||
* Creates a new message event manager.
|
||||
*
|
||||
* @param con an XMPPConnection.
|
||||
*/
|
||||
public MessageEventManager(XMPPConnection con) {
|
||||
this.con = con;
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds event notification requests to a message. For each event type that
|
||||
* the user wishes event notifications from the message recepient for, <tt>true</tt>
|
||||
* should be passed in to this method.
|
||||
*
|
||||
* @param message the message to add the requested notifications.
|
||||
* @param offline specifies if the offline event is requested.
|
||||
* @param delivered specifies if the delivered event is requested.
|
||||
* @param displayed specifies if the displayed event is requested.
|
||||
* @param composing specifies if the composing event is requested.
|
||||
*/
|
||||
public static void addNotificationsRequests(Message message, boolean offline,
|
||||
boolean delivered, boolean displayed, boolean composing)
|
||||
{
|
||||
// Create a MessageEvent Package and add it to the message
|
||||
MessageEvent messageEvent = new MessageEvent();
|
||||
messageEvent.setOffline(offline);
|
||||
messageEvent.setDelivered(delivered);
|
||||
messageEvent.setDisplayed(displayed);
|
||||
messageEvent.setComposing(composing);
|
||||
message.addExtension(messageEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a message event request listener. The listener will be fired anytime a request for
|
||||
* event notification is received.
|
||||
*
|
||||
* @param messageEventRequestListener a message event request listener.
|
||||
*/
|
||||
public void addMessageEventRequestListener(MessageEventRequestListener messageEventRequestListener) {
|
||||
synchronized (messageEventRequestListeners) {
|
||||
if (!messageEventRequestListeners.contains(messageEventRequestListener)) {
|
||||
messageEventRequestListeners.add(messageEventRequestListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a message event request listener. The listener will be fired anytime a request for
|
||||
* event notification is received.
|
||||
*
|
||||
* @param messageEventRequestListener a message event request listener.
|
||||
*/
|
||||
public void removeMessageEventRequestListener(MessageEventRequestListener messageEventRequestListener) {
|
||||
synchronized (messageEventRequestListeners) {
|
||||
messageEventRequestListeners.remove(messageEventRequestListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a message event notification listener. The listener will be fired anytime a notification
|
||||
* event is received.
|
||||
*
|
||||
* @param messageEventNotificationListener a message event notification listener.
|
||||
*/
|
||||
public void addMessageEventNotificationListener(MessageEventNotificationListener messageEventNotificationListener) {
|
||||
synchronized (messageEventNotificationListeners) {
|
||||
if (!messageEventNotificationListeners.contains(messageEventNotificationListener)) {
|
||||
messageEventNotificationListeners.add(messageEventNotificationListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a message event notification listener. The listener will be fired anytime a notification
|
||||
* event is received.
|
||||
*
|
||||
* @param messageEventNotificationListener a message event notification listener.
|
||||
*/
|
||||
public void removeMessageEventNotificationListener(MessageEventNotificationListener messageEventNotificationListener) {
|
||||
synchronized (messageEventNotificationListeners) {
|
||||
messageEventNotificationListeners.remove(messageEventNotificationListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires message event request listeners.
|
||||
*/
|
||||
private void fireMessageEventRequestListeners(
|
||||
String from,
|
||||
String packetID,
|
||||
String methodName) {
|
||||
MessageEventRequestListener[] listeners = null;
|
||||
Method method;
|
||||
synchronized (messageEventRequestListeners) {
|
||||
listeners = new MessageEventRequestListener[messageEventRequestListeners.size()];
|
||||
messageEventRequestListeners.toArray(listeners);
|
||||
}
|
||||
try {
|
||||
method =
|
||||
MessageEventRequestListener.class.getDeclaredMethod(
|
||||
methodName,
|
||||
new Class[] { String.class, String.class, MessageEventManager.class });
|
||||
for (int i = 0; i < listeners.length; i++) {
|
||||
method.invoke(listeners[i], new Object[] { from, packetID, this });
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires message event notification listeners.
|
||||
*/
|
||||
private void fireMessageEventNotificationListeners(
|
||||
String from,
|
||||
String packetID,
|
||||
String methodName) {
|
||||
MessageEventNotificationListener[] listeners = null;
|
||||
Method method;
|
||||
synchronized (messageEventNotificationListeners) {
|
||||
listeners =
|
||||
new MessageEventNotificationListener[messageEventNotificationListeners.size()];
|
||||
messageEventNotificationListeners.toArray(listeners);
|
||||
}
|
||||
try {
|
||||
method =
|
||||
MessageEventNotificationListener.class.getDeclaredMethod(
|
||||
methodName,
|
||||
new Class[] { String.class, String.class });
|
||||
for (int i = 0; i < listeners.length; i++) {
|
||||
method.invoke(listeners[i], new Object[] { from, packetID });
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
// Listens for all message event packets and fire the proper message event listeners.
|
||||
packetListener = new PacketListener() {
|
||||
public void processPacket(Packet packet) {
|
||||
Message message = (Message) packet;
|
||||
MessageEvent messageEvent =
|
||||
(MessageEvent) message.getExtension("x", "jabber:x:event");
|
||||
if (messageEvent.isMessageEventRequest()) {
|
||||
// Fire event for requests of message events
|
||||
for (Iterator it = messageEvent.getEventTypes(); it.hasNext();)
|
||||
fireMessageEventRequestListeners(
|
||||
message.getFrom(),
|
||||
message.getPacketID(),
|
||||
((String) it.next()).concat("NotificationRequested"));
|
||||
} else
|
||||
// Fire event for notifications of message events
|
||||
for (Iterator it = messageEvent.getEventTypes(); it.hasNext();)
|
||||
fireMessageEventNotificationListeners(
|
||||
message.getFrom(),
|
||||
messageEvent.getPacketID(),
|
||||
((String) it.next()).concat("Notification"));
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
con.addPacketListener(packetListener, packetFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the notification that the message was delivered to the sender of the original message
|
||||
*
|
||||
* @param to the recipient of the notification.
|
||||
* @param packetID the id of the message to send.
|
||||
*/
|
||||
public void sendDeliveredNotification(String to, String packetID) {
|
||||
// Create the message to send
|
||||
Message msg = new Message(to);
|
||||
// Create a MessageEvent Package and add it to the message
|
||||
MessageEvent messageEvent = new MessageEvent();
|
||||
messageEvent.setDelivered(true);
|
||||
messageEvent.setPacketID(packetID);
|
||||
msg.addExtension(messageEvent);
|
||||
// Send the packet
|
||||
con.sendPacket(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the notification that the message was displayed to the sender of the original message
|
||||
*
|
||||
* @param to the recipient of the notification.
|
||||
* @param packetID the id of the message to send.
|
||||
*/
|
||||
public void sendDisplayedNotification(String to, String packetID) {
|
||||
// Create the message to send
|
||||
Message msg = new Message(to);
|
||||
// Create a MessageEvent Package and add it to the message
|
||||
MessageEvent messageEvent = new MessageEvent();
|
||||
messageEvent.setDisplayed(true);
|
||||
messageEvent.setPacketID(packetID);
|
||||
msg.addExtension(messageEvent);
|
||||
// Send the packet
|
||||
con.sendPacket(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the notification that the receiver of the message is composing a reply
|
||||
*
|
||||
* @param to the recipient of the notification.
|
||||
* @param packetID the id of the message to send.
|
||||
*/
|
||||
public void sendComposingNotification(String to, String packetID) {
|
||||
// Create the message to send
|
||||
Message msg = new Message(to);
|
||||
// Create a MessageEvent Package and add it to the message
|
||||
MessageEvent messageEvent = new MessageEvent();
|
||||
messageEvent.setComposing(true);
|
||||
messageEvent.setPacketID(packetID);
|
||||
msg.addExtension(messageEvent);
|
||||
// Send the packet
|
||||
con.sendPacket(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the notification that the receiver of the message has cancelled composing a reply.
|
||||
*
|
||||
* @param to the recipient of the notification.
|
||||
* @param packetID the id of the message to send.
|
||||
*/
|
||||
public void sendCancelledNotification(String to, String packetID) {
|
||||
// Create the message to send
|
||||
Message msg = new Message(to);
|
||||
// Create a MessageEvent Package and add it to the message
|
||||
MessageEvent messageEvent = new MessageEvent();
|
||||
messageEvent.setCancelled(true);
|
||||
messageEvent.setPacketID(packetID);
|
||||
msg.addExtension(messageEvent);
|
||||
// Send the packet
|
||||
con.sendPacket(msg);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (con != null) {
|
||||
con.removePacketListener(packetListener);
|
||||
}
|
||||
}
|
||||
|
||||
public void finalize() {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
/**
|
||||
*
|
||||
* A listener that is fired anytime a message event notification is received.
|
||||
* Message event notifications are received as a consequence of the request
|
||||
* to receive notifications when sending a message.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public interface MessageEventNotificationListener {
|
||||
|
||||
/**
|
||||
* Called when a notification of message delivered is received.
|
||||
*
|
||||
* @param from the user that sent the notification.
|
||||
* @param packetID the id of the message that was sent.
|
||||
*/
|
||||
public void deliveredNotification(String from, String packetID);
|
||||
|
||||
/**
|
||||
* Called when a notification of message displayed is received.
|
||||
*
|
||||
* @param from the user that sent the notification.
|
||||
* @param packetID the id of the message that was sent.
|
||||
*/
|
||||
public void displayedNotification(String from, String packetID);
|
||||
|
||||
/**
|
||||
* Called when a notification that the receiver of the message is composing a reply is
|
||||
* received.
|
||||
*
|
||||
* @param from the user that sent the notification.
|
||||
* @param packetID the id of the message that was sent.
|
||||
*/
|
||||
public void composingNotification(String from, String packetID);
|
||||
|
||||
/**
|
||||
* Called when a notification that the receiver of the message is offline is received.
|
||||
*
|
||||
* @param from the user that sent the notification.
|
||||
* @param packetID the id of the message that was sent.
|
||||
*/
|
||||
public void offlineNotification(String from, String packetID);
|
||||
|
||||
/**
|
||||
* Called when a notification that the receiver of the message cancelled the reply
|
||||
* is received.
|
||||
*
|
||||
* @param from the user that sent the notification.
|
||||
* @param packetID the id of the message that was sent.
|
||||
*/
|
||||
public void cancelledNotification(String from, String packetID);
|
||||
}
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
/**
|
||||
*
|
||||
* A listener that is fired anytime a message event request is received.
|
||||
* Message event requests are received when the received message includes an extension
|
||||
* like this:
|
||||
*
|
||||
* <pre>
|
||||
* <x xmlns='jabber:x:event'>
|
||||
* <offline/>
|
||||
* <delivered/>
|
||||
* <composing/>
|
||||
* </x>
|
||||
* </pre>
|
||||
*
|
||||
* In this example you can see that the sender of the message requests to be notified
|
||||
* when the user couldn't receive the message because he/she is offline, the message
|
||||
* was delivered or when the receiver of the message is composing a reply.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public interface MessageEventRequestListener {
|
||||
|
||||
/**
|
||||
* Called when a request for message delivered notification is received.
|
||||
*
|
||||
* @param from the user that sent the notification.
|
||||
* @param packetID the id of the message that was sent.
|
||||
* @param messageEventManager the messageEventManager that fired the listener.
|
||||
*/
|
||||
public void deliveredNotificationRequested(String from, String packetID,
|
||||
MessageEventManager messageEventManager);
|
||||
|
||||
/**
|
||||
* Called when a request for message displayed notification is received.
|
||||
*
|
||||
* @param from the user that sent the notification.
|
||||
* @param packetID the id of the message that was sent.
|
||||
* @param messageEventManager the messageEventManager that fired the listener.
|
||||
*/
|
||||
public void displayedNotificationRequested(String from, String packetID,
|
||||
MessageEventManager messageEventManager);
|
||||
|
||||
/**
|
||||
* Called when a request that the receiver of the message is composing a reply notification is
|
||||
* received.
|
||||
*
|
||||
* @param from the user that sent the notification.
|
||||
* @param packetID the id of the message that was sent.
|
||||
* @param messageEventManager the messageEventManager that fired the listener.
|
||||
*/
|
||||
public void composingNotificationRequested(String from, String packetID,
|
||||
MessageEventManager messageEventManager);
|
||||
|
||||
/**
|
||||
* Called when a request that the receiver of the message is offline is received.
|
||||
*
|
||||
* @param from the user that sent the notification.
|
||||
* @param packetID the id of the message that was sent.
|
||||
* @param messageEventManager the messageEventManager that fired the listener.
|
||||
*/
|
||||
public void offlineNotificationRequested(String from, String packetID,
|
||||
MessageEventManager messageEventManager);
|
||||
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
/**
|
||||
* The NodeInformationProvider is responsible for providing information (i.e. DiscoverItems.Item)
|
||||
* about a given node. This information will be requested each time this XMPPP client receives a
|
||||
* disco items requests on the given node.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public interface NodeInformationProvider {
|
||||
|
||||
/**
|
||||
* Returns an Iterator on the Items {@link org.jivesoftware.smackx.packet.DiscoverItems.Item}
|
||||
* defined in the node. For example, the MUC protocol specifies that an XMPP client should
|
||||
* answer an Item for each joined room when asked for the rooms where the use has joined.
|
||||
*
|
||||
* @return an Iterator on the Items defined in the node.
|
||||
*/
|
||||
public abstract Iterator getNodeItems();
|
||||
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
import org.jivesoftware.smackx.packet.DiscoverItems;
|
||||
|
||||
/**
|
||||
* The OfflineMessageHeader holds header information of an offline message. The header
|
||||
* information was retrieved using the {@link OfflineMessageManager} class.<p>
|
||||
*
|
||||
* Each offline message is identified by the target user of the offline message and a unique stamp.
|
||||
* Use {@link OfflineMessageManager#getMessages(java.util.List)} to retrieve the whole message.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class OfflineMessageHeader {
|
||||
/**
|
||||
* Bare JID of the user that was offline when the message was sent.
|
||||
*/
|
||||
private String user;
|
||||
/**
|
||||
* Full JID of the user that sent the message.
|
||||
*/
|
||||
private String jid;
|
||||
/**
|
||||
* Stamp that uniquely identifies the offline message. This stamp will be used for
|
||||
* getting the specific message or delete it. The stamp may be of the form UTC timestamps
|
||||
* but it is not required to have that format.
|
||||
*/
|
||||
private String stamp;
|
||||
|
||||
public OfflineMessageHeader(DiscoverItems.Item item) {
|
||||
super();
|
||||
user = item.getEntityID();
|
||||
jid = item.getName();
|
||||
stamp = item.getNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bare JID of the user that was offline when the message was sent.
|
||||
*
|
||||
* @return the bare JID of the user that was offline when the message was sent.
|
||||
*/
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full JID of the user that sent the message.
|
||||
*
|
||||
* @return the full JID of the user that sent the message.
|
||||
*/
|
||||
public String getJid() {
|
||||
return jid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stamp that uniquely identifies the offline message. This stamp will
|
||||
* be used for getting the specific message or delete it. The stamp may be of the
|
||||
* form UTC timestamps but it is not required to have that format.
|
||||
*
|
||||
* @return the stamp that uniquely identifies the offline message.
|
||||
*/
|
||||
public String getStamp() {
|
||||
return stamp;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,284 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
import org.jivesoftware.smack.PacketCollector;
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.filter.*;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smackx.packet.DiscoverInfo;
|
||||
import org.jivesoftware.smackx.packet.DiscoverItems;
|
||||
import org.jivesoftware.smackx.packet.OfflineMessageInfo;
|
||||
import org.jivesoftware.smackx.packet.OfflineMessageRequest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The OfflineMessageManager helps manage offline messages even before the user has sent an
|
||||
* available presence. When a user asks for his offline messages before sending an available
|
||||
* presence then the server will not send a flood with all the offline messages when the user
|
||||
* becomes online. The server will not send a flood with all the offline messages to the session
|
||||
* that made the offline messages request or to any other session used by the user that becomes
|
||||
* online.<p>
|
||||
*
|
||||
* Once the session that made the offline messages request has been closed and the user becomes
|
||||
* offline in all the resources then the server will resume storing the messages offline and will
|
||||
* send all the offline messages to the user when he becomes online. Therefore, the server will
|
||||
* flood the user when he becomes online unless the user uses this class to manage his offline
|
||||
* messages.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class OfflineMessageManager {
|
||||
|
||||
private final static String namespace = "http://jabber.org/protocol/offline";
|
||||
|
||||
private XMPPConnection connection;
|
||||
|
||||
private PacketFilter packetFilter;
|
||||
|
||||
public OfflineMessageManager(XMPPConnection connection) {
|
||||
this.connection = connection;
|
||||
packetFilter =
|
||||
new AndFilter(new PacketExtensionFilter("offline", namespace),
|
||||
new PacketTypeFilter(Message.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the server supports Flexible Offline Message Retrieval. When the server
|
||||
* supports Flexible Offline Message Retrieval it is possible to get the header of the offline
|
||||
* messages, get specific messages, delete specific messages, etc.
|
||||
*
|
||||
* @return a boolean indicating if the server supports Flexible Offline Message Retrieval.
|
||||
* @throws XMPPException If the user is not allowed to make this request.
|
||||
*/
|
||||
public boolean supportsFlexibleRetrieval() throws XMPPException {
|
||||
DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(null);
|
||||
return info.containsFeature(namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of offline messages for the user of the connection.
|
||||
*
|
||||
* @return the number of offline messages for the user of the connection.
|
||||
* @throws XMPPException If the user is not allowed to make this request or the server does
|
||||
* not support offline message retrieval.
|
||||
*/
|
||||
public int getMessageCount() throws XMPPException {
|
||||
DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(null,
|
||||
namespace);
|
||||
Form extendedInfo = Form.getFormFrom(info);
|
||||
if (extendedInfo != null) {
|
||||
String value = (String) extendedInfo.getField("number_of_messages").getValues().next();
|
||||
return Integer.parseInt(value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator on <tt>OfflineMessageHeader</tt> that keep information about the
|
||||
* offline message. The OfflineMessageHeader includes a stamp that could be used to retrieve
|
||||
* the complete message or delete the specific message.
|
||||
*
|
||||
* @return an iterator on <tt>OfflineMessageHeader</tt> that keep information about the offline
|
||||
* message.
|
||||
* @throws XMPPException If the user is not allowed to make this request or the server does
|
||||
* not support offline message retrieval.
|
||||
*/
|
||||
public Iterator getHeaders() throws XMPPException {
|
||||
List answer = new ArrayList();
|
||||
DiscoverItems items = ServiceDiscoveryManager.getInstanceFor(connection).discoverItems(
|
||||
null, namespace);
|
||||
for (Iterator it = items.getItems(); it.hasNext();) {
|
||||
DiscoverItems.Item item = (DiscoverItems.Item) it.next();
|
||||
answer.add(new OfflineMessageHeader(item));
|
||||
}
|
||||
return answer.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator with the offline <tt>Messages</tt> whose stamp matches the specified
|
||||
* request. The request will include the list of stamps that uniquely identifies
|
||||
* the offline messages to retrieve. The returned offline messages will not be deleted
|
||||
* from the server. Use {@link #deleteMessages(java.util.List)} to delete the messages.
|
||||
*
|
||||
* @param nodes the list of stamps that uniquely identifies offline message.
|
||||
* @return an Iterator with the offline <tt>Messages</tt> that were received as part of
|
||||
* this request.
|
||||
* @throws XMPPException If the user is not allowed to make this request or the server does
|
||||
* not support offline message retrieval.
|
||||
*/
|
||||
public Iterator getMessages(final List nodes) throws XMPPException {
|
||||
List messages = new ArrayList();
|
||||
OfflineMessageRequest request = new OfflineMessageRequest();
|
||||
for (Iterator it = nodes.iterator(); it.hasNext();) {
|
||||
OfflineMessageRequest.Item item = new OfflineMessageRequest.Item((String) it.next());
|
||||
item.setAction("view");
|
||||
request.addItem(item);
|
||||
}
|
||||
// Filter packets looking for an answer from the server.
|
||||
PacketFilter responseFilter = new PacketIDFilter(request.getPacketID());
|
||||
PacketCollector response = connection.createPacketCollector(responseFilter);
|
||||
// Filter offline messages that were requested by this request
|
||||
PacketFilter messageFilter = new AndFilter(packetFilter, new PacketFilter() {
|
||||
public boolean accept(Packet packet) {
|
||||
OfflineMessageInfo info = (OfflineMessageInfo) packet.getExtension("offline",
|
||||
namespace);
|
||||
return nodes.contains(info.getNode());
|
||||
}
|
||||
});
|
||||
PacketCollector messageCollector = connection.createPacketCollector(messageFilter);
|
||||
// Send the retrieval request to the server.
|
||||
connection.sendPacket(request);
|
||||
// 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(answer.getError());
|
||||
}
|
||||
|
||||
// Collect the received offline messages
|
||||
Message message = (Message) messageCollector.nextResult(
|
||||
SmackConfiguration.getPacketReplyTimeout());
|
||||
while (message != null) {
|
||||
messages.add(message);
|
||||
message =
|
||||
(Message) messageCollector.nextResult(
|
||||
SmackConfiguration.getPacketReplyTimeout());
|
||||
}
|
||||
// Stop queuing offline messages
|
||||
messageCollector.cancel();
|
||||
return messages.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator with all the offline <tt>Messages</tt> of the user. The returned offline
|
||||
* messages will not be deleted from the server. Use {@link #deleteMessages(java.util.List)}
|
||||
* to delete the messages.
|
||||
*
|
||||
* @return an Iterator with all the offline <tt>Messages</tt> of the user.
|
||||
* @throws XMPPException If the user is not allowed to make this request or the server does
|
||||
* not support offline message retrieval.
|
||||
*/
|
||||
public Iterator getMessages() throws XMPPException {
|
||||
List messages = new ArrayList();
|
||||
OfflineMessageRequest request = new OfflineMessageRequest();
|
||||
request.setFetch(true);
|
||||
// Filter packets looking for an answer from the server.
|
||||
PacketFilter responseFilter = new PacketIDFilter(request.getPacketID());
|
||||
PacketCollector response = connection.createPacketCollector(responseFilter);
|
||||
// Filter offline messages that were requested by this request
|
||||
PacketCollector messageCollector = connection.createPacketCollector(packetFilter);
|
||||
// Send the retrieval request to the server.
|
||||
connection.sendPacket(request);
|
||||
// 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(answer.getError());
|
||||
}
|
||||
|
||||
// Collect the received offline messages
|
||||
Message message = (Message) messageCollector.nextResult(
|
||||
SmackConfiguration.getPacketReplyTimeout());
|
||||
while (message != null) {
|
||||
messages.add(message);
|
||||
message =
|
||||
(Message) messageCollector.nextResult(
|
||||
SmackConfiguration.getPacketReplyTimeout());
|
||||
}
|
||||
// Stop queuing offline messages
|
||||
messageCollector.cancel();
|
||||
return messages.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the specified list of offline messages. The request will include the list of
|
||||
* stamps that uniquely identifies the offline messages to delete.
|
||||
*
|
||||
* @param nodes the list of stamps that uniquely identifies offline message.
|
||||
* @throws XMPPException If the user is not allowed to make this request or the server does
|
||||
* not support offline message retrieval.
|
||||
*/
|
||||
public void deleteMessages(List nodes) throws XMPPException {
|
||||
OfflineMessageRequest request = new OfflineMessageRequest();
|
||||
for (Iterator it = nodes.iterator(); it.hasNext();) {
|
||||
OfflineMessageRequest.Item item = new OfflineMessageRequest.Item((String) it.next());
|
||||
item.setAction("remove");
|
||||
request.addItem(item);
|
||||
}
|
||||
// Filter packets looking for an answer from the server.
|
||||
PacketFilter responseFilter = new PacketIDFilter(request.getPacketID());
|
||||
PacketCollector response = connection.createPacketCollector(responseFilter);
|
||||
// Send the deletion request to the server.
|
||||
connection.sendPacket(request);
|
||||
// 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(answer.getError());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all offline messages of the user.
|
||||
*
|
||||
* @throws XMPPException If the user is not allowed to make this request or the server does
|
||||
* not support offline message retrieval.
|
||||
*/
|
||||
public void deleteMessages() throws XMPPException {
|
||||
OfflineMessageRequest request = new OfflineMessageRequest();
|
||||
request.setPurge(true);
|
||||
// Filter packets looking for an answer from the server.
|
||||
PacketFilter responseFilter = new PacketIDFilter(request.getPacketID());
|
||||
PacketCollector response = connection.createPacketCollector(responseFilter);
|
||||
// Send the deletion request to the server.
|
||||
connection.sendPacket(request);
|
||||
// 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(answer.getError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,345 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
import org.jivesoftware.smack.*;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.jivesoftware.smack.filter.PacketIDFilter;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smackx.packet.*;
|
||||
import org.jivesoftware.smackx.provider.*;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* Manages private data, which is a mechanism to allow users to store arbitrary XML
|
||||
* data on an XMPP server. Each private data chunk is defined by a element name and
|
||||
* XML namespace. Example private data:
|
||||
*
|
||||
* <pre>
|
||||
* <color xmlns="http://example.com/xmpp/color">
|
||||
* <favorite>blue</blue>
|
||||
* <leastFavorite>puce</leastFavorite>
|
||||
* </color>
|
||||
* </pre>
|
||||
*
|
||||
* {@link PrivateDataProvider} instances are responsible for translating the XML into objects.
|
||||
* If no PrivateDataProvider is registered for a given element name and namespace, then
|
||||
* a {@link DefaultPrivateData} instance will be returned.<p>
|
||||
*
|
||||
* Warning: this is an non-standard protocol documented by
|
||||
* <a href="http://www.jabber.org/jeps/jep-0049.html">JEP-49</a>. Because this is a
|
||||
* non-standard protocol, it is subject to change.
|
||||
*
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public class PrivateDataManager {
|
||||
|
||||
/**
|
||||
* Map of provider instances.
|
||||
*/
|
||||
private static Map privateDataProviders = new Hashtable();
|
||||
|
||||
/**
|
||||
* Returns the private data provider registered to the specified XML element name and namespace.
|
||||
* For example, if a provider was registered to the element name "prefs" and the
|
||||
* namespace "http://www.xmppclient.com/prefs", then the following packet would trigger
|
||||
* the provider:
|
||||
*
|
||||
* <pre>
|
||||
* <iq type='result' to='joe@example.com' from='mary@example.com' id='time_1'>
|
||||
* <query xmlns='jabber:iq:private'>
|
||||
* <prefs xmlns='http://www.xmppclient.com/prefs'>
|
||||
* <value1>ABC</value1>
|
||||
* <value2>XYZ</value2>
|
||||
* </prefs>
|
||||
* </query>
|
||||
* </iq></pre>
|
||||
*
|
||||
* <p>Note: this method is generally only called by the internal Smack classes.
|
||||
*
|
||||
* @param elementName the XML element name.
|
||||
* @param namespace the XML namespace.
|
||||
* @return the PrivateData provider.
|
||||
*/
|
||||
public static PrivateDataProvider getPrivateDataProvider(String elementName, String namespace) {
|
||||
String key = getProviderKey(elementName, namespace);
|
||||
return (PrivateDataProvider)privateDataProviders.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a private data provider with the specified element name and name space. The provider
|
||||
* will override any providers loaded through the classpath.
|
||||
*
|
||||
* @param elementName the XML element name.
|
||||
* @param namespace the XML namespace.
|
||||
* @param provider the private data provider.
|
||||
*/
|
||||
public static void addPrivateDataProvider(String elementName, String namespace,
|
||||
PrivateDataProvider provider)
|
||||
{
|
||||
String key = getProviderKey(elementName, namespace);
|
||||
privateDataProviders.put(key, provider);
|
||||
}
|
||||
|
||||
|
||||
private XMPPConnection connection;
|
||||
|
||||
/**
|
||||
* The user to get and set private data for. In most cases, this value should
|
||||
* be <tt>null</tt>, as the typical use of private data is to get and set
|
||||
* your own private data and not others.
|
||||
*/
|
||||
private String user;
|
||||
|
||||
/**
|
||||
* Creates a new private data manager. The connection must have
|
||||
* undergone a successful login before being used to construct an instance of
|
||||
* this class.
|
||||
*
|
||||
* @param connection an XMPP connection which must have already undergone a
|
||||
* successful login.
|
||||
*/
|
||||
public PrivateDataManager(XMPPConnection connection) {
|
||||
if (!connection.isAuthenticated()) {
|
||||
throw new IllegalStateException("Must be logged in to XMPP server.");
|
||||
}
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new private data manager for a specific user (special case). Most
|
||||
* servers only support getting and setting private data for the user that
|
||||
* authenticated via the connection. However, some servers support the ability
|
||||
* to get and set private data for other users (for example, if you are the
|
||||
* administrator). The connection must have undergone a successful login before
|
||||
* being used to construct an instance of this class.
|
||||
*
|
||||
* @param connection an XMPP connection which must have already undergone a
|
||||
* successful login.
|
||||
* @param user the XMPP address of the user to get and set private data for.
|
||||
*/
|
||||
public PrivateDataManager(XMPPConnection connection, String user) {
|
||||
if (!connection.isAuthenticated()) {
|
||||
throw new IllegalStateException("Must be logged in to XMPP server.");
|
||||
}
|
||||
this.connection = connection;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the private data specified by the given element name and namespace. Each chunk
|
||||
* of private data is uniquely identified by an element name and namespace pair.<p>
|
||||
*
|
||||
* If a PrivateDataProvider is registered for the specified element name/namespace pair then
|
||||
* that provider will determine the specific object type that is returned. If no provider
|
||||
* is registered, a {@link DefaultPrivateData} instance will be returned.
|
||||
*
|
||||
* @param elementName the element name.
|
||||
* @param namespace the namespace.
|
||||
* @return the private data.
|
||||
* @throws XMPPException if an error occurs getting the private data.
|
||||
*/
|
||||
public PrivateData getPrivateData(final String elementName, final String namespace)
|
||||
throws XMPPException
|
||||
{
|
||||
// Create an IQ packet to get the private data.
|
||||
IQ privateDataGet = new IQ() {
|
||||
public String getChildElementXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<query xmlns=\"jabber:iq:private\">");
|
||||
buf.append("<").append(elementName).append(" xmlns=\"").append(namespace).append("\"/>");
|
||||
buf.append("</query>");
|
||||
return buf.toString();
|
||||
}
|
||||
};
|
||||
privateDataGet.setType(IQ.Type.GET);
|
||||
// Address the packet to the other account if user has been set.
|
||||
if (user != null) {
|
||||
privateDataGet.setTo(user);
|
||||
}
|
||||
|
||||
// Setup a listener for the reply to the set operation.
|
||||
String packetID = privateDataGet.getPacketID();
|
||||
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(packetID));
|
||||
|
||||
// Send the private data.
|
||||
connection.sendPacket(privateDataGet);
|
||||
|
||||
// Wait up to five seconds for a response from the server.
|
||||
IQ response = (IQ)collector.nextResult(5000);
|
||||
// Stop queuing results
|
||||
collector.cancel();
|
||||
if (response == null) {
|
||||
throw new XMPPException("No response from the server.");
|
||||
}
|
||||
// If the server replied with an error, throw an exception.
|
||||
else if (response.getType() == IQ.Type.ERROR) {
|
||||
throw new XMPPException(response.getError());
|
||||
}
|
||||
return ((PrivateDataResult)response).getPrivateData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a private data value. Each chunk of private data is uniquely identified by an
|
||||
* element name and namespace pair. If private data has already been set with the
|
||||
* element name and namespace, then the new private data will overwrite the old value.
|
||||
*
|
||||
* @param privateData the private data.
|
||||
* @throws XMPPException if setting the private data fails.
|
||||
*/
|
||||
public void setPrivateData(final PrivateData privateData) throws XMPPException {
|
||||
// Create an IQ packet to set the private data.
|
||||
IQ privateDataSet = new IQ() {
|
||||
public String getChildElementXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<query xmlns=\"jabber:iq:private\">");
|
||||
buf.append(privateData.toXML());
|
||||
buf.append("</query>");
|
||||
return buf.toString();
|
||||
}
|
||||
};
|
||||
privateDataSet.setType(IQ.Type.SET);
|
||||
// Address the packet to the other account if user has been set.
|
||||
if (user != null) {
|
||||
privateDataSet.setTo(user);
|
||||
}
|
||||
|
||||
// Setup a listener for the reply to the set operation.
|
||||
String packetID = privateDataSet.getPacketID();
|
||||
PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(packetID));
|
||||
|
||||
// Send the private data.
|
||||
connection.sendPacket(privateDataSet);
|
||||
|
||||
// Wait up to five seconds for a response from the server.
|
||||
IQ response = (IQ)collector.nextResult(5000);
|
||||
// Stop queuing results
|
||||
collector.cancel();
|
||||
if (response == null) {
|
||||
throw new XMPPException("No response from the server.");
|
||||
}
|
||||
// If the server replied with an error, throw an exception.
|
||||
else if (response.getType() == IQ.Type.ERROR) {
|
||||
throw new XMPPException(response.getError());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String key for a given element name and namespace.
|
||||
*
|
||||
* @param elementName the element name.
|
||||
* @param namespace the namespace.
|
||||
* @return a unique key for the element name and namespace pair.
|
||||
*/
|
||||
private static String getProviderKey(String elementName, String namespace) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<").append(elementName).append("/><").append(namespace).append("/>");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* An IQ provider to parse IQ results containing private data.
|
||||
*/
|
||||
public static class PrivateDataIQProvider implements IQProvider {
|
||||
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||
PrivateData privateData = null;
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
String elementName = parser.getName();
|
||||
String namespace = parser.getNamespace();
|
||||
// See if any objects are registered to handle this private data type.
|
||||
PrivateDataProvider provider = getPrivateDataProvider(elementName, namespace);
|
||||
// If there is a registered provider, use it.
|
||||
if (provider != null) {
|
||||
privateData = provider.parsePrivateData(parser);
|
||||
}
|
||||
// Otherwise, use a DefaultPrivateData instance to store the private data.
|
||||
else {
|
||||
DefaultPrivateData data = new DefaultPrivateData(elementName, namespace);
|
||||
boolean finished = false;
|
||||
while (!finished) {
|
||||
int event = parser.next();
|
||||
if (event == XmlPullParser.START_TAG) {
|
||||
String name = parser.getName();
|
||||
// If an empty element, set the value with the empty string.
|
||||
if (parser.isEmptyElementTag()) {
|
||||
data.setValue(name,"");
|
||||
}
|
||||
// Otherwise, get the the element text.
|
||||
else {
|
||||
event = parser.next();
|
||||
if (event == XmlPullParser.TEXT) {
|
||||
String value = parser.getText();
|
||||
data.setValue(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals(elementName)) {
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
privateData = data;
|
||||
}
|
||||
}
|
||||
else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("query")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
IQ result = new PrivateDataResult(privateData);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An IQ packet to hold PrivateData GET results.
|
||||
*/
|
||||
private static class PrivateDataResult extends IQ {
|
||||
|
||||
private PrivateData privateData;
|
||||
|
||||
PrivateDataResult(PrivateData privateData) {
|
||||
this.privateData = privateData;
|
||||
}
|
||||
|
||||
public PrivateData getPrivateData() {
|
||||
return privateData;
|
||||
}
|
||||
|
||||
public String getChildElementXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<query xmlns=\"jabber:iq:private\">");
|
||||
if (privateData != null) {
|
||||
privateData.toXML();
|
||||
}
|
||||
buf.append("</query>");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Represents a roster item, which consists of a JID and , their name and
|
||||
* the groups the roster item belongs to. This roster item does not belong
|
||||
* to the local roster. Therefore, it does not persist in the server.<p>
|
||||
*
|
||||
* The idea of a RemoteRosterEntry is to be used as part of a roster exchange.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class RemoteRosterEntry {
|
||||
|
||||
private String user;
|
||||
private String name;
|
||||
private List groupNames = new ArrayList();
|
||||
|
||||
/**
|
||||
* Creates a new remote roster entry.
|
||||
*
|
||||
* @param user the user.
|
||||
* @param name the user's name.
|
||||
* @param groups the list of group names the entry will belong to, or <tt>null</tt> if the
|
||||
* the roster entry won't belong to a group.
|
||||
*/
|
||||
public RemoteRosterEntry(String user, String name, String [] groups) {
|
||||
this.user = user;
|
||||
this.name = name;
|
||||
if (groups != null) {
|
||||
groupNames = new ArrayList(Arrays.asList(groups));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user.
|
||||
*
|
||||
* @return the user.
|
||||
*/
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user's name.
|
||||
*
|
||||
* @return the user's name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for the group names (as Strings) that the roster entry
|
||||
* belongs to.
|
||||
*
|
||||
* @return an Iterator for the group names.
|
||||
*/
|
||||
public Iterator getGroupNames() {
|
||||
synchronized (groupNames) {
|
||||
return Collections.unmodifiableList(groupNames).iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String array for the group names that the roster entry
|
||||
* belongs to.
|
||||
*
|
||||
* @return a String[] for the group names.
|
||||
*/
|
||||
public String[] getGroupArrayNames() {
|
||||
synchronized (groupNames) {
|
||||
return (String[])
|
||||
(Collections
|
||||
.unmodifiableList(groupNames)
|
||||
.toArray(new String[groupNames.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<item jid=\"").append(user).append("\"");
|
||||
if (name != null) {
|
||||
buf.append(" name=\"").append(name).append("\"");
|
||||
}
|
||||
buf.append(">");
|
||||
synchronized (groupNames) {
|
||||
for (int i = 0; i < groupNames.size(); i++) {
|
||||
String groupName = (String) groupNames.get(i);
|
||||
buf.append("<group>").append(groupName).append("</group>");
|
||||
}
|
||||
}
|
||||
buf.append("</item>");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,255 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
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();
|
||||
// The field is created with all the values of the data form's field
|
||||
List values = new ArrayList();
|
||||
for (Iterator it=field.getValues(); it.hasNext();) {
|
||||
values.add(it.next());
|
||||
}
|
||||
fieldList.add(new Field(field.getVariable(), values));
|
||||
}
|
||||
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 values of the field whose variable matches the requested variable.
|
||||
*
|
||||
* @param variable the variable to match.
|
||||
* @return the values of the field whose variable matches the requested variable.
|
||||
*/
|
||||
public Iterator getValues(String variable) {
|
||||
for(Iterator it=getFields();it.hasNext();) {
|
||||
Field field = (Field) it.next();
|
||||
if (variable.equals(field.getVariable())) {
|
||||
return field.getValues();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fields that define the data that goes with the item.
|
||||
*
|
||||
* @return the fields that define the data that goes with the item.
|
||||
*/
|
||||
private Iterator getFields() {
|
||||
return Collections.unmodifiableList(new ArrayList(fields)).iterator();
|
||||
}
|
||||
}
|
||||
|
||||
private static class Field {
|
||||
private String variable;
|
||||
private List values;
|
||||
|
||||
private Field(String variable, List values) {
|
||||
this.variable = variable;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the variable name that the field represents.
|
||||
*
|
||||
* @return the variable name of the field.
|
||||
*/
|
||||
public String getVariable() {
|
||||
return variable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator on the values reported as part of the search.
|
||||
*
|
||||
* @return the returned values of the search.
|
||||
*/
|
||||
public Iterator getValues() {
|
||||
return Collections.unmodifiableList(values).iterator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
*
|
||||
* A listener that is fired anytime a roster exchange is received.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public interface RosterExchangeListener {
|
||||
|
||||
/**
|
||||
* Called when roster entries are received as part of a roster exchange.
|
||||
*
|
||||
* @param from the user that sent the entries.
|
||||
* @param remoteRosterEntries the entries sent by the user. The entries are instances of
|
||||
* RemoteRosterEntry.
|
||||
*/
|
||||
public void entriesReceived(String from, Iterator remoteRosterEntries);
|
||||
|
||||
}
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jivesoftware.smack.*;
|
||||
import org.jivesoftware.smack.filter.*;
|
||||
import org.jivesoftware.smack.packet.*;
|
||||
import org.jivesoftware.smackx.packet.RosterExchange;
|
||||
|
||||
/**
|
||||
*
|
||||
* Manages Roster exchanges. A RosterExchangeManager provides a high level access to send
|
||||
* rosters, roster groups and roster entries to XMPP clients. It also provides an easy way
|
||||
* to hook up custom logic when entries are received from another XMPP client through
|
||||
* RosterExchangeListeners.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class RosterExchangeManager {
|
||||
|
||||
private List rosterExchangeListeners = new ArrayList();
|
||||
|
||||
private XMPPConnection con;
|
||||
|
||||
private PacketFilter packetFilter = new PacketExtensionFilter("x", "jabber:x:roster");
|
||||
private PacketListener packetListener;
|
||||
|
||||
/**
|
||||
* Creates a new roster exchange manager.
|
||||
*
|
||||
* @param con an XMPPConnection.
|
||||
*/
|
||||
public RosterExchangeManager(XMPPConnection con) {
|
||||
this.con = con;
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener to roster exchanges. The listener will be fired anytime roster entries
|
||||
* are received from remote XMPP clients.
|
||||
*
|
||||
* @param rosterExchangeListener a roster exchange listener.
|
||||
*/
|
||||
public void addRosterListener(RosterExchangeListener rosterExchangeListener) {
|
||||
synchronized (rosterExchangeListeners) {
|
||||
if (!rosterExchangeListeners.contains(rosterExchangeListener)) {
|
||||
rosterExchangeListeners.add(rosterExchangeListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a listener from roster exchanges. The listener will be fired anytime roster
|
||||
* entries are received from remote XMPP clients.
|
||||
*
|
||||
* @param rosterExchangeListener a roster exchange listener..
|
||||
*/
|
||||
public void removeRosterListener(RosterExchangeListener rosterExchangeListener) {
|
||||
synchronized (rosterExchangeListeners) {
|
||||
rosterExchangeListeners.remove(rosterExchangeListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a roster to userID. All the entries of the roster will be sent to the
|
||||
* target user.
|
||||
*
|
||||
* @param roster the roster to send
|
||||
* @param targetUserID the user that will receive the roster entries
|
||||
*/
|
||||
public void send(Roster roster, String targetUserID) {
|
||||
// Create a new message to send the roster
|
||||
Message msg = new Message(targetUserID);
|
||||
// Create a RosterExchange Package and add it to the message
|
||||
RosterExchange rosterExchange = new RosterExchange(roster);
|
||||
msg.addExtension(rosterExchange);
|
||||
|
||||
// Send the message that contains the roster
|
||||
con.sendPacket(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a roster entry to userID.
|
||||
*
|
||||
* @param rosterEntry the roster entry to send
|
||||
* @param targetUserID the user that will receive the roster entries
|
||||
*/
|
||||
public void send(RosterEntry rosterEntry, String targetUserID) {
|
||||
// Create a new message to send the roster
|
||||
Message msg = new Message(targetUserID);
|
||||
// Create a RosterExchange Package and add it to the message
|
||||
RosterExchange rosterExchange = new RosterExchange();
|
||||
rosterExchange.addRosterEntry(rosterEntry);
|
||||
msg.addExtension(rosterExchange);
|
||||
|
||||
// Send the message that contains the roster
|
||||
con.sendPacket(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a roster group to userID. All the entries of the group will be sent to the
|
||||
* target user.
|
||||
*
|
||||
* @param rosterGroup the roster group to send
|
||||
* @param targetUserID the user that will receive the roster entries
|
||||
*/
|
||||
public void send(RosterGroup rosterGroup, String targetUserID) {
|
||||
// Create a new message to send the roster
|
||||
Message msg = new Message(targetUserID);
|
||||
// Create a RosterExchange Package and add it to the message
|
||||
RosterExchange rosterExchange = new RosterExchange();
|
||||
for (Iterator it = rosterGroup.getEntries(); it.hasNext();)
|
||||
rosterExchange.addRosterEntry((RosterEntry) it.next());
|
||||
msg.addExtension(rosterExchange);
|
||||
|
||||
// Send the message that contains the roster
|
||||
con.sendPacket(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires roster exchange listeners.
|
||||
*/
|
||||
private void fireRosterExchangeListeners(String from, Iterator remoteRosterEntries) {
|
||||
RosterExchangeListener[] listeners = null;
|
||||
synchronized (rosterExchangeListeners) {
|
||||
listeners = new RosterExchangeListener[rosterExchangeListeners.size()];
|
||||
rosterExchangeListeners.toArray(listeners);
|
||||
}
|
||||
for (int i = 0; i < listeners.length; i++) {
|
||||
listeners[i].entriesReceived(from, remoteRosterEntries);
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
// Listens for all roster exchange packets and fire the roster exchange listeners.
|
||||
packetListener = new PacketListener() {
|
||||
public void processPacket(Packet packet) {
|
||||
Message message = (Message) packet;
|
||||
RosterExchange rosterExchange =
|
||||
(RosterExchange) message.getExtension("x", "jabber:x:roster");
|
||||
// Fire event for roster exchange listeners
|
||||
fireRosterExchangeListeners(message.getFrom(), rosterExchange.getRosterEntries());
|
||||
};
|
||||
|
||||
};
|
||||
con.addPacketListener(packetListener, packetFilter);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (con != null)
|
||||
con.removePacketListener(packetListener);
|
||||
|
||||
}
|
||||
public void finalize() {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,476 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jivesoftware.smack.*;
|
||||
import org.jivesoftware.smack.filter.*;
|
||||
import org.jivesoftware.smack.packet.*;
|
||||
import org.jivesoftware.smackx.packet.*;
|
||||
|
||||
/**
|
||||
* Manages discovery of services in XMPP entities. This class provides:
|
||||
* <ol>
|
||||
* <li>A registry of supported features in this XMPP entity.
|
||||
* <li>Automatic response when this XMPP entity is queried for information.
|
||||
* <li>Ability to discover items and information of remote XMPP entities.
|
||||
* <li>Ability to publish publicly available items.
|
||||
* </ol>
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class ServiceDiscoveryManager {
|
||||
|
||||
private static String identityName = "Smack";
|
||||
private static String identityType = "pc";
|
||||
|
||||
private static Map instances = new Hashtable();
|
||||
|
||||
private XMPPConnection connection;
|
||||
private List features = new ArrayList();
|
||||
private Map nodeInformationProviders = new Hashtable();
|
||||
|
||||
// Create a new ServiceDiscoveryManager on every established connection
|
||||
static {
|
||||
XMPPConnection.addConnectionListener(new ConnectionEstablishedListener() {
|
||||
public void connectionEstablished(XMPPConnection connection) {
|
||||
new ServiceDiscoveryManager(connection);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ServiceDiscoveryManager for a given XMPPConnection. This means that the
|
||||
* service manager will respond to any service discovery request that the connection may
|
||||
* receive.
|
||||
*
|
||||
* @param connection the connection to which a ServiceDiscoveryManager is going to be created.
|
||||
*/
|
||||
public ServiceDiscoveryManager(XMPPConnection connection) {
|
||||
this.connection = connection;
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ServiceDiscoveryManager instance associated with a given XMPPConnection.
|
||||
*
|
||||
* @param connection the connection used to look for the proper ServiceDiscoveryManager.
|
||||
* @return the ServiceDiscoveryManager associated with a given XMPPConnection.
|
||||
*/
|
||||
public static ServiceDiscoveryManager getInstanceFor(XMPPConnection connection) {
|
||||
return (ServiceDiscoveryManager) instances.get(connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the client that will be returned when asked for the client identity
|
||||
* in a disco request. The name could be any value you need to identity this client.
|
||||
*
|
||||
* @return the name of the client that will be returned when asked for the client identity
|
||||
* in a disco request.
|
||||
*/
|
||||
public static String getIdentityName() {
|
||||
return identityName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the client that will be returned when asked for the client identity
|
||||
* in a disco request. The name could be any value you need to identity this client.
|
||||
*
|
||||
* @param name the name of the client that will be returned when asked for the client identity
|
||||
* in a disco request.
|
||||
*/
|
||||
public static void setIdentityName(String name) {
|
||||
identityName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of client that will be returned when asked for the client identity in a
|
||||
* disco request. The valid types are defined by the category client. Follow this link to learn
|
||||
* the possible types: <a href="http://www.jabber.org/registrar/disco-categories.html#client">Jabber::Registrar</a>.
|
||||
*
|
||||
* @return the type of client that will be returned when asked for the client identity in a
|
||||
* disco request.
|
||||
*/
|
||||
public static String getIdentityType() {
|
||||
return identityType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of client that will be returned when asked for the client identity in a
|
||||
* disco request. The valid types are defined by the category client. Follow this link to learn
|
||||
* the possible types: <a href="http://www.jabber.org/registrar/disco-categories.html#client">Jabber::Registrar</a>.
|
||||
*
|
||||
* @param type the type of client that will be returned when asked for the client identity in a
|
||||
* disco request.
|
||||
*/
|
||||
public static void setIdentityType(String type) {
|
||||
identityType = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the packet listeners of the connection that will answer to any
|
||||
* service discovery request.
|
||||
*/
|
||||
private void init() {
|
||||
// Register the new instance and associate it with the connection
|
||||
instances.put(connection, this);
|
||||
// Add a listener to the connection that removes the registered instance when
|
||||
// the connection is closed
|
||||
connection.addConnectionListener(new ConnectionListener() {
|
||||
public void connectionClosed() {
|
||||
// Unregister this instance since the connection has been closed
|
||||
instances.remove(connection);
|
||||
}
|
||||
|
||||
public void connectionClosedOnError(Exception e) {
|
||||
// Unregister this instance since the connection has been closed
|
||||
instances.remove(connection);
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for disco#items requests and answer with an empty result
|
||||
PacketFilter packetFilter = new PacketTypeFilter(DiscoverItems.class);
|
||||
PacketListener packetListener = new PacketListener() {
|
||||
public void processPacket(Packet packet) {
|
||||
DiscoverItems discoverItems = (DiscoverItems) packet;
|
||||
// Send back the items defined in the client if the request is of type GET
|
||||
if (discoverItems != null && discoverItems.getType() == IQ.Type.GET) {
|
||||
DiscoverItems response = new DiscoverItems();
|
||||
response.setType(IQ.Type.RESULT);
|
||||
response.setTo(discoverItems.getFrom());
|
||||
response.setPacketID(discoverItems.getPacketID());
|
||||
|
||||
// Add the defined items related to the requested node. Look for
|
||||
// the NodeInformationProvider associated with the requested node.
|
||||
if (getNodeInformationProvider(discoverItems.getNode()) != null) {
|
||||
Iterator items =
|
||||
getNodeInformationProvider(discoverItems.getNode()).getNodeItems();
|
||||
while (items.hasNext()) {
|
||||
response.addItem((DiscoverItems.Item) items.next());
|
||||
}
|
||||
}
|
||||
connection.sendPacket(response);
|
||||
}
|
||||
}
|
||||
};
|
||||
connection.addPacketListener(packetListener, packetFilter);
|
||||
|
||||
// Listen for disco#info requests and answer the client's supported features
|
||||
// To add a new feature as supported use the #addFeature message
|
||||
packetFilter = new PacketTypeFilter(DiscoverInfo.class);
|
||||
packetListener = new PacketListener() {
|
||||
public void processPacket(Packet packet) {
|
||||
DiscoverInfo discoverInfo = (DiscoverInfo) packet;
|
||||
// Answer the client's supported features if the request is of the GET type
|
||||
if (discoverInfo != null && discoverInfo.getType() == IQ.Type.GET) {
|
||||
DiscoverInfo response = new DiscoverInfo();
|
||||
response.setType(IQ.Type.RESULT);
|
||||
response.setTo(discoverInfo.getFrom());
|
||||
response.setPacketID(discoverInfo.getPacketID());
|
||||
// Add the client's identity and features only if "node" is null
|
||||
if (discoverInfo.getNode() == null) {
|
||||
// Set this client identity
|
||||
DiscoverInfo.Identity identity = new DiscoverInfo.Identity("client",
|
||||
getIdentityName());
|
||||
identity.setType(getIdentityType());
|
||||
response.addIdentity(identity);
|
||||
// Add the registered features to the response
|
||||
synchronized (features) {
|
||||
for (Iterator it = getFeatures(); it.hasNext();) {
|
||||
response.addFeature((String) it.next());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Return an <item-not-found/> error since a client doesn't have nodes
|
||||
response.setType(IQ.Type.ERROR);
|
||||
response.setError(new XMPPError(404, "item-not-found"));
|
||||
}
|
||||
connection.sendPacket(response);
|
||||
}
|
||||
}
|
||||
};
|
||||
connection.addPacketListener(packetListener, packetFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the NodeInformationProvider responsible for providing information
|
||||
* (ie items) related to a given node or <tt>null</null> if none.<p>
|
||||
*
|
||||
* In MUC, a node could be 'http://jabber.org/protocol/muc#rooms' which means that the
|
||||
* NodeInformationProvider will provide information about the rooms where the user has joined.
|
||||
*
|
||||
* @param node the node that contains items associated with an entity not addressable as a JID.
|
||||
* @return the NodeInformationProvider responsible for providing information related
|
||||
* to a given node.
|
||||
*/
|
||||
private NodeInformationProvider getNodeInformationProvider(String node) {
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
return (NodeInformationProvider) nodeInformationProviders.get(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the NodeInformationProvider responsible for providing information
|
||||
* (ie items) related to a given node. Every time this client receives a disco request
|
||||
* regarding the items of a given node, the provider associated to that node will be the
|
||||
* responsible for providing the requested information.<p>
|
||||
*
|
||||
* In MUC, a node could be 'http://jabber.org/protocol/muc#rooms' which means that the
|
||||
* NodeInformationProvider will provide information about the rooms where the user has joined.
|
||||
*
|
||||
* @param node the node whose items will be provided by the NodeInformationProvider.
|
||||
* @param listener the NodeInformationProvider responsible for providing items related
|
||||
* to the node.
|
||||
*/
|
||||
public void setNodeInformationProvider(String node, NodeInformationProvider listener) {
|
||||
nodeInformationProviders.put(node, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the NodeInformationProvider responsible for providing information
|
||||
* (ie items) related to a given node. This means that no more information will be
|
||||
* available for the specified node.
|
||||
*
|
||||
* In MUC, a node could be 'http://jabber.org/protocol/muc#rooms' which means that the
|
||||
* NodeInformationProvider will provide information about the rooms where the user has joined.
|
||||
*
|
||||
* @param node the node to remove the associated NodeInformationProvider.
|
||||
*/
|
||||
public void removeNodeInformationProvider(String node) {
|
||||
nodeInformationProviders.remove(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the supported features by this XMPP entity.
|
||||
*
|
||||
* @return an Iterator on the supported features by this XMPP entity.
|
||||
*/
|
||||
public Iterator getFeatures() {
|
||||
synchronized (features) {
|
||||
return Collections.unmodifiableList(new ArrayList(features)).iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers that a new feature is supported by this XMPP entity. When this client is
|
||||
* queried for its information the registered features will be answered.<p>
|
||||
*
|
||||
* Since no packet is actually sent to the server it is safe to perform this operation
|
||||
* before logging to the server. In fact, you may want to configure the supported features
|
||||
* before logging to the server so that the information is already available if it is required
|
||||
* upon login.
|
||||
*
|
||||
* @param feature the feature to register as supported.
|
||||
*/
|
||||
public void addFeature(String feature) {
|
||||
synchronized (features) {
|
||||
features.add(feature);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified feature from the supported features by this XMPP entity.<p>
|
||||
*
|
||||
* Since no packet is actually sent to the server it is safe to perform this operation
|
||||
* before logging to the server.
|
||||
*
|
||||
* @param feature the feature to remove from the supported features.
|
||||
*/
|
||||
public void removeFeature(String feature) {
|
||||
synchronized (features) {
|
||||
features.remove(feature);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified feature is registered in the ServiceDiscoveryManager.
|
||||
*
|
||||
* @param feature the feature to look for.
|
||||
* @return a boolean indicating if the specified featured is registered or not.
|
||||
*/
|
||||
public boolean includesFeature(String feature) {
|
||||
synchronized (features) {
|
||||
return features.contains(feature);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the discovered information of a given XMPP entity addressed by its JID.
|
||||
*
|
||||
* @param entityID the address of the XMPP entity.
|
||||
* @return the discovered information.
|
||||
* @throws XMPPException if the operation failed for some reason.
|
||||
*/
|
||||
public DiscoverInfo discoverInfo(String entityID) throws XMPPException {
|
||||
return discoverInfo(entityID, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the discovered information of a given XMPP entity addressed by its JID and
|
||||
* note attribute. Use this message only when trying to query information which is not
|
||||
* directly addressable.
|
||||
*
|
||||
* @param entityID the address of the XMPP entity.
|
||||
* @param node the attribute that supplements the 'jid' attribute.
|
||||
* @return the discovered information.
|
||||
* @throws XMPPException if the operation failed for some reason.
|
||||
*/
|
||||
public DiscoverInfo discoverInfo(String entityID, String node) throws XMPPException {
|
||||
// Discover the entity's info
|
||||
DiscoverInfo disco = new DiscoverInfo();
|
||||
disco.setType(IQ.Type.GET);
|
||||
disco.setTo(entityID);
|
||||
disco.setNode(node);
|
||||
|
||||
// Create a packet collector to listen for a response.
|
||||
PacketCollector collector =
|
||||
connection.createPacketCollector(new PacketIDFilter(disco.getPacketID()));
|
||||
|
||||
connection.sendPacket(disco);
|
||||
|
||||
// Wait up to 5 seconds for a result.
|
||||
IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||
// Stop queuing results
|
||||
collector.cancel();
|
||||
if (result == null) {
|
||||
throw new XMPPException("No response from the server.");
|
||||
}
|
||||
if (result.getType() == IQ.Type.ERROR) {
|
||||
throw new XMPPException(result.getError());
|
||||
}
|
||||
return (DiscoverInfo) result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the discovered items of a given XMPP entity addressed by its JID.
|
||||
*
|
||||
* @param entityID the address of the XMPP entity.
|
||||
* @return the discovered information.
|
||||
* @throws XMPPException if the operation failed for some reason.
|
||||
*/
|
||||
public DiscoverItems discoverItems(String entityID) throws XMPPException {
|
||||
return discoverItems(entityID, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the discovered items of a given XMPP entity addressed by its JID and
|
||||
* note attribute. Use this message only when trying to query information which is not
|
||||
* directly addressable.
|
||||
*
|
||||
* @param entityID the address of the XMPP entity.
|
||||
* @param node the attribute that supplements the 'jid' attribute.
|
||||
* @return the discovered items.
|
||||
* @throws XMPPException if the operation failed for some reason.
|
||||
*/
|
||||
public DiscoverItems discoverItems(String entityID, String node) throws XMPPException {
|
||||
// Discover the entity's items
|
||||
DiscoverItems disco = new DiscoverItems();
|
||||
disco.setType(IQ.Type.GET);
|
||||
disco.setTo(entityID);
|
||||
disco.setNode(node);
|
||||
|
||||
// Create a packet collector to listen for a response.
|
||||
PacketCollector collector =
|
||||
connection.createPacketCollector(new PacketIDFilter(disco.getPacketID()));
|
||||
|
||||
connection.sendPacket(disco);
|
||||
|
||||
// Wait up to 5 seconds for a result.
|
||||
IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||
// Stop queuing results
|
||||
collector.cancel();
|
||||
if (result == null) {
|
||||
throw new XMPPException("No response from the server.");
|
||||
}
|
||||
if (result.getType() == IQ.Type.ERROR) {
|
||||
throw new XMPPException(result.getError());
|
||||
}
|
||||
return (DiscoverItems) result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the server supports publishing of items. A client may wish to publish items
|
||||
* to the server so that the server can provide items associated to the client. These items will
|
||||
* be returned by the server whenever the server receives a disco request targeted to the bare
|
||||
* address of the client (i.e. user@host.com).
|
||||
*
|
||||
* @param entityID the address of the XMPP entity.
|
||||
* @return true if the server supports publishing of items.
|
||||
* @throws XMPPException if the operation failed for some reason.
|
||||
*/
|
||||
public boolean canPublishItems(String entityID) throws XMPPException {
|
||||
DiscoverInfo info = discoverInfo(entityID);
|
||||
return info.containsFeature("http://jabber.org/protocol/disco#publish");
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes new items to a parent entity. The item elements to publish MUST have at least
|
||||
* a 'jid' attribute specifying the Entity ID of the item, and an action attribute which
|
||||
* specifies the action being taken for that item. Possible action values are: "update" and
|
||||
* "remove".
|
||||
*
|
||||
* @param entityID the address of the XMPP entity.
|
||||
* @param discoverItems the DiscoveryItems to publish.
|
||||
* @throws XMPPException if the operation failed for some reason.
|
||||
*/
|
||||
public void publishItems(String entityID, DiscoverItems discoverItems)
|
||||
throws XMPPException {
|
||||
publishItems(entityID, null, discoverItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes new items to a parent entity and node. The item elements to publish MUST have at
|
||||
* least a 'jid' attribute specifying the Entity ID of the item, and an action attribute which
|
||||
* specifies the action being taken for that item. Possible action values are: "update" and
|
||||
* "remove".
|
||||
*
|
||||
* @param entityID the address of the XMPP entity.
|
||||
* @param node the attribute that supplements the 'jid' attribute.
|
||||
* @param discoverItems the DiscoveryItems to publish.
|
||||
* @throws XMPPException if the operation failed for some reason.
|
||||
*/
|
||||
public void publishItems(String entityID, String node, DiscoverItems discoverItems)
|
||||
throws XMPPException {
|
||||
discoverItems.setType(IQ.Type.SET);
|
||||
discoverItems.setTo(entityID);
|
||||
discoverItems.setNode(node);
|
||||
|
||||
// Create a packet collector to listen for a response.
|
||||
PacketCollector collector =
|
||||
connection.createPacketCollector(new PacketIDFilter(discoverItems.getPacketID()));
|
||||
|
||||
connection.sendPacket(discoverItems);
|
||||
|
||||
// Wait up to 5 seconds for a result.
|
||||
IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||
// Stop queuing results
|
||||
collector.cancel();
|
||||
if (result == null) {
|
||||
throw new XMPPException("No response from the server.");
|
||||
}
|
||||
if (result.getType() == IQ.Type.ERROR) {
|
||||
throw new XMPPException(result.getError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.jivesoftware.smack.*;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smackx.packet.*;
|
||||
|
||||
/**
|
||||
* Manages XHTML formatted texts within messages. A XHTMLManager provides a high level access to
|
||||
* get and set XHTML bodies to messages, enable and disable XHTML support and check if remote XMPP
|
||||
* clients support XHTML.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class XHTMLManager {
|
||||
|
||||
private final static String namespace = "http://jabber.org/protocol/xhtml-im";
|
||||
|
||||
// Enable the XHTML support on every established connection
|
||||
// The ServiceDiscoveryManager class should have been already initialized
|
||||
static {
|
||||
XMPPConnection.addConnectionListener(new ConnectionEstablishedListener() {
|
||||
public void connectionEstablished(XMPPConnection connection) {
|
||||
XHTMLManager.setServiceEnabled(connection, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for the XHTML bodies in the message. Returns null if
|
||||
* the message does not contain an XHTML extension.
|
||||
*
|
||||
* @param message an XHTML message
|
||||
* @return an Iterator for the bodies in the message or null if none.
|
||||
*/
|
||||
public static Iterator getBodies(Message message) {
|
||||
XHTMLExtension xhtmlExtension = (XHTMLExtension) message.getExtension("html", namespace);
|
||||
if (xhtmlExtension != null)
|
||||
return xhtmlExtension.getBodies();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an XHTML body to the message.
|
||||
*
|
||||
* @param message the message that will receive the XHTML body
|
||||
* @param body the string to add as an XHTML body to the message
|
||||
*/
|
||||
public static void addBody(Message message, String body) {
|
||||
XHTMLExtension xhtmlExtension = (XHTMLExtension) message.getExtension("html", namespace);
|
||||
if (xhtmlExtension == null) {
|
||||
// Create an XHTMLExtension and add it to the message
|
||||
xhtmlExtension = new XHTMLExtension();
|
||||
message.addExtension(xhtmlExtension);
|
||||
}
|
||||
// Add the required bodies to the message
|
||||
xhtmlExtension.addBody(body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the message contains an XHTML extension.
|
||||
*
|
||||
* @param message the message to check if contains an XHTML extentsion or not
|
||||
* @return a boolean indicating whether the message is an XHTML message
|
||||
*/
|
||||
public static boolean isXHTMLMessage(Message message) {
|
||||
return message.getExtension("html", namespace) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables the XHTML support on a given connection.<p>
|
||||
*
|
||||
* Before starting to send XHTML messages to a user, check that the user can handle XHTML
|
||||
* messages. Enable the XHTML support to indicate that this client handles XHTML messages.
|
||||
*
|
||||
* @param connection the connection where the service will be enabled or disabled
|
||||
* @param enabled indicates if the service will be enabled or disabled
|
||||
*/
|
||||
public synchronized static void setServiceEnabled(XMPPConnection connection, boolean enabled) {
|
||||
if (isServiceEnabled(connection) == enabled)
|
||||
return;
|
||||
|
||||
if (enabled) {
|
||||
ServiceDiscoveryManager.getInstanceFor(connection).addFeature(namespace);
|
||||
}
|
||||
else {
|
||||
ServiceDiscoveryManager.getInstanceFor(connection).removeFeature(namespace);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the XHTML support is enabled for the given connection.
|
||||
*
|
||||
* @param connection the connection to look for XHTML support
|
||||
* @return a boolean indicating if the XHTML support is enabled for the given connection
|
||||
*/
|
||||
public static boolean isServiceEnabled(XMPPConnection connection) {
|
||||
return ServiceDiscoveryManager.getInstanceFor(connection).includesFeature(namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified user handles XHTML messages.
|
||||
*
|
||||
* @param connection the connection to use to perform the service discovery
|
||||
* @param userID the user to check. A fully qualified xmpp ID, e.g. jdoe@example.com
|
||||
* @return a boolean indicating whether the specified user handles XHTML messages
|
||||
*/
|
||||
public static boolean isServiceEnabled(XMPPConnection connection, String userID) {
|
||||
try {
|
||||
DiscoverInfo result =
|
||||
ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(userID);
|
||||
return result.containsFeature(namespace);
|
||||
}
|
||||
catch (XMPPException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,429 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx;
|
||||
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
/**
|
||||
* An XHTMLText represents formatted text. This class also helps to build valid
|
||||
* XHTML tags.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class XHTMLText {
|
||||
|
||||
private StringBuffer text = new StringBuffer(30);
|
||||
|
||||
/**
|
||||
* Creates a new XHTMLText with body tag params.
|
||||
*
|
||||
* @param style the XHTML style of the body
|
||||
* @param lang the language of the body
|
||||
*/
|
||||
public XHTMLText(String style, String lang) {
|
||||
appendOpenBodyTag(style, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that an anchor section begins.
|
||||
*
|
||||
* @param href indicates the URL being linked to
|
||||
* @param style the XHTML style of the anchor
|
||||
*/
|
||||
public void appendOpenAnchorTag(String href, String style) {
|
||||
StringBuffer sb = new StringBuffer("<a");
|
||||
if (href != null) {
|
||||
sb.append(" href=\"");
|
||||
sb.append(href);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that an anchor section ends.
|
||||
*
|
||||
*/
|
||||
public void appendCloseAnchorTag() {
|
||||
text.append("</a>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that a blockquote section begins.
|
||||
*
|
||||
* @param style the XHTML style of the blockquote
|
||||
*/
|
||||
public void appendOpenBlockQuoteTag(String style) {
|
||||
StringBuffer sb = new StringBuffer("<blockquote");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that a blockquote section ends.
|
||||
*
|
||||
*/
|
||||
public void appendCloseBlockQuoteTag() {
|
||||
text.append("</blockquote>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that a body section begins.
|
||||
*
|
||||
* @param style the XHTML style of the body
|
||||
* @param lang the language of the body
|
||||
*/
|
||||
private void appendOpenBodyTag(String style, String lang) {
|
||||
StringBuffer sb = new StringBuffer("<body");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (lang != null) {
|
||||
sb.append(" xml:lang=\"");
|
||||
sb.append(lang);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that a body section ends.
|
||||
*
|
||||
*/
|
||||
private String closeBodyTag() {
|
||||
return "</body>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that inserts a single carriage return.
|
||||
*
|
||||
*/
|
||||
public void appendBrTag() {
|
||||
text.append("<br>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates a reference to work, such as a book, report or web site.
|
||||
*
|
||||
*/
|
||||
public void appendOpenCiteTag() {
|
||||
text.append("<cite>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates text that is the code for a program.
|
||||
*
|
||||
*/
|
||||
public void appendOpenCodeTag() {
|
||||
text.append("<code>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates end of text that is the code for a program.
|
||||
*
|
||||
*/
|
||||
public void appendCloseCodeTag() {
|
||||
text.append("</code>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates emphasis.
|
||||
*
|
||||
*/
|
||||
public void appendOpenEmTag() {
|
||||
text.append("<em>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates end of emphasis.
|
||||
*
|
||||
*/
|
||||
public void appendCloseEmTag() {
|
||||
text.append("</em>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates a header, a title of a section of the message.
|
||||
*
|
||||
* @param level the level of the Header. It should be a value between 1 and 3
|
||||
* @param style the XHTML style of the blockquote
|
||||
*/
|
||||
public void appendOpenHeaderTag(int level, String style) {
|
||||
if (level > 3 || level < 1) {
|
||||
return;
|
||||
}
|
||||
StringBuffer sb = new StringBuffer("<h");
|
||||
sb.append(level);
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that a header section ends.
|
||||
*
|
||||
* @param level the level of the Header. It should be a value between 1 and 3
|
||||
*/
|
||||
public void appendCloseHeaderTag(int level) {
|
||||
if (level > 3 || level < 1) {
|
||||
return;
|
||||
}
|
||||
StringBuffer sb = new StringBuffer("</h");
|
||||
sb.append(level);
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates an image.
|
||||
*
|
||||
* @param align how text should flow around the picture
|
||||
* @param alt the text to show if you don't show the picture
|
||||
* @param height how tall is the picture
|
||||
* @param src where to get the picture
|
||||
* @param width how wide is the picture
|
||||
*/
|
||||
public void appendImageTag(String align, String alt, String height, String src, String width) {
|
||||
StringBuffer sb = new StringBuffer("<img");
|
||||
if (align != null) {
|
||||
sb.append(" align=\"");
|
||||
sb.append(align);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (alt != null) {
|
||||
sb.append(" alt=\"");
|
||||
sb.append(alt);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (height != null) {
|
||||
sb.append(" height=\"");
|
||||
sb.append(height);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (src != null) {
|
||||
sb.append(" src=\"");
|
||||
sb.append(src);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (width != null) {
|
||||
sb.append(" width=\"");
|
||||
sb.append(width);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates the start of a new line item within a list.
|
||||
*
|
||||
* @param style the style of the line item
|
||||
*/
|
||||
public void appendLineItemTag(String style) {
|
||||
StringBuffer sb = new StringBuffer("<li");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that creates an ordered list. "Ordered" means that the order of the items
|
||||
* in the list is important. To show this, browsers automatically number the list.
|
||||
*
|
||||
* @param style the style of the ordered list
|
||||
*/
|
||||
public void appendOpenOrderedListTag(String style) {
|
||||
StringBuffer sb = new StringBuffer("<ol");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that an ordered list section ends.
|
||||
*
|
||||
*/
|
||||
public void appendCloseOrderedListTag() {
|
||||
text.append("</ol>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that creates an unordered list. The unordered part means that the items
|
||||
* in the list are not in any particular order.
|
||||
*
|
||||
* @param style the style of the unordered list
|
||||
*/
|
||||
public void appendOpenUnorderedListTag(String style) {
|
||||
StringBuffer sb = new StringBuffer("<ul");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that an unordered list section ends.
|
||||
*
|
||||
*/
|
||||
public void appendCloseUnorderedListTag() {
|
||||
text.append("</ul>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates the start of a new paragraph. This is usually rendered
|
||||
* with two carriage returns, producing a single blank line in between the two paragraphs.
|
||||
*
|
||||
* @param style the style of the paragraph
|
||||
*/
|
||||
public void appendOpenParagraphTag(String style) {
|
||||
StringBuffer sb = new StringBuffer("<p");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates the end of a new paragraph. This is usually rendered
|
||||
* with two carriage returns, producing a single blank line in between the two paragraphs.
|
||||
*
|
||||
*/
|
||||
public void appendCloseParagraphTag() {
|
||||
text.append("</p>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that an inlined quote section begins.
|
||||
*
|
||||
* @param style the style of the inlined quote
|
||||
*/
|
||||
public void appendOpenInlinedQuoteTag(String style) {
|
||||
StringBuffer sb = new StringBuffer("<q");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that an inlined quote section ends.
|
||||
*
|
||||
*/
|
||||
public void appendCloseInlinedQuoteTag() {
|
||||
text.append("</q>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that allows to set the fonts for a span of text.
|
||||
*
|
||||
* @param style the style for a span of text
|
||||
*/
|
||||
public void appendOpenSpanTag(String style) {
|
||||
StringBuffer sb = new StringBuffer("<span");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that a span section ends.
|
||||
*
|
||||
*/
|
||||
public void appendCloseSpanTag() {
|
||||
text.append("</span>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates text which should be more forceful than surrounding text.
|
||||
*
|
||||
*/
|
||||
public void appendOpenStrongTag() {
|
||||
text.append("<strong>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that a strong section ends.
|
||||
*
|
||||
*/
|
||||
public void appendCloseStrongTag() {
|
||||
text.append("</strong>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a given text to the XHTMLText.
|
||||
*
|
||||
* @param textToAppend the text to append
|
||||
*/
|
||||
public void append(String textToAppend) {
|
||||
text.append(StringUtils.escapeForXML(textToAppend));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text of the XHTMLText.
|
||||
*
|
||||
* Note: Automatically adds the closing body tag.
|
||||
*
|
||||
* @return the text of the XHTMLText
|
||||
*/
|
||||
public String toString() {
|
||||
return text.toString().concat(closeBodyTag());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,858 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.debugger;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.text.*;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.table.*;
|
||||
import javax.xml.transform.*;
|
||||
import javax.xml.transform.stream.*;
|
||||
|
||||
import org.jivesoftware.smack.*;
|
||||
import org.jivesoftware.smack.debugger.*;
|
||||
import org.jivesoftware.smack.packet.*;
|
||||
import org.jivesoftware.smack.util.*;
|
||||
|
||||
/**
|
||||
* The EnhancedDebugger is a debugger that allows to debug sent, received and interpreted messages
|
||||
* but also provides the ability to send ad-hoc messages composed by the user.<p>
|
||||
*
|
||||
* A new EnhancedDebugger will be created for each connection to debug. All the EnhancedDebuggers
|
||||
* will be shown in the same debug window provided by the class EnhancedDebuggerWindow.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class EnhancedDebugger implements SmackDebugger {
|
||||
|
||||
private static final String NEWLINE = "\n";
|
||||
|
||||
private static ImageIcon packetReceivedIcon;
|
||||
private static ImageIcon packetSentIcon;
|
||||
private static ImageIcon presencePacketIcon;
|
||||
private static ImageIcon iqPacketIcon;
|
||||
private static ImageIcon messagePacketIcon;
|
||||
private static ImageIcon unknownPacketTypeIcon;
|
||||
|
||||
{
|
||||
URL url;
|
||||
// Load the image icons
|
||||
url =
|
||||
Thread.currentThread().getContextClassLoader().getResource("images/nav_left_blue.png");
|
||||
if (url != null) {
|
||||
packetReceivedIcon = new ImageIcon(url);
|
||||
}
|
||||
url =
|
||||
Thread.currentThread().getContextClassLoader().getResource("images/nav_right_red.png");
|
||||
if (url != null) {
|
||||
packetSentIcon = new ImageIcon(url);
|
||||
}
|
||||
url =
|
||||
Thread.currentThread().getContextClassLoader().getResource("images/photo_portrait.png");
|
||||
if (url != null) {
|
||||
presencePacketIcon = new ImageIcon(url);
|
||||
}
|
||||
url =
|
||||
Thread.currentThread().getContextClassLoader().getResource(
|
||||
"images/question_and_answer.png");
|
||||
if (url != null) {
|
||||
iqPacketIcon = new ImageIcon(url);
|
||||
}
|
||||
url = Thread.currentThread().getContextClassLoader().getResource("images/message.png");
|
||||
if (url != null) {
|
||||
messagePacketIcon = new ImageIcon(url);
|
||||
}
|
||||
url = Thread.currentThread().getContextClassLoader().getResource("images/unknown.png");
|
||||
if (url != null) {
|
||||
unknownPacketTypeIcon = new ImageIcon(url);
|
||||
}
|
||||
}
|
||||
|
||||
private DefaultTableModel messagesTable = null;
|
||||
private JTextArea messageTextArea = null;
|
||||
private JFormattedTextField userField = null;
|
||||
private JFormattedTextField statusField = null;
|
||||
|
||||
private XMPPConnection connection = null;
|
||||
|
||||
private PacketListener packetReaderListener = null;
|
||||
private PacketListener packetWriterListener = null;
|
||||
private ConnectionListener connListener = null;
|
||||
|
||||
private Writer writer;
|
||||
private Reader reader;
|
||||
private ReaderListener readerListener;
|
||||
private WriterListener writerListener;
|
||||
|
||||
private Date creationTime = new Date();
|
||||
|
||||
// Statistics variables
|
||||
private DefaultTableModel statisticsTable = null;
|
||||
private int sentPackets = 0;
|
||||
private int receivedPackets = 0;
|
||||
private int sentIQPackets = 0;
|
||||
private int receivedIQPackets = 0;
|
||||
private int sentMessagePackets = 0;
|
||||
private int receivedMessagePackets = 0;
|
||||
private int sentPresencePackets = 0;
|
||||
private int receivedPresencePackets = 0;
|
||||
private int sentOtherPackets = 0;
|
||||
private int receivedOtherPackets = 0;
|
||||
|
||||
JTabbedPane tabbedPane;
|
||||
|
||||
public EnhancedDebugger(XMPPConnection connection, Writer writer, Reader reader) {
|
||||
this.connection = connection;
|
||||
this.writer = writer;
|
||||
this.reader = reader;
|
||||
createDebug();
|
||||
EnhancedDebuggerWindow.addDebugger(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the debug process, which is a GUI window that displays XML traffic.
|
||||
*/
|
||||
private void createDebug() {
|
||||
// We'll arrange the UI into six tabs. The first tab contains all data, the second
|
||||
// client generated XML, the third server generated XML, the fourth allows to send
|
||||
// ad-hoc messages and the fifth contains connection information.
|
||||
tabbedPane = new JTabbedPane();
|
||||
|
||||
// Add the All Packets, Sent, Received and Interpreted panels
|
||||
addBasicPanels();
|
||||
|
||||
// Add the panel to send ad-hoc messages
|
||||
addAdhocPacketPanel();
|
||||
|
||||
// Add the connection information panel
|
||||
addInformationPanel();
|
||||
|
||||
// Create a thread that will listen for all incoming packets and write them to
|
||||
// the GUI. This is what we call "interpreted" packet data, since it's the packet
|
||||
// data as Smack sees it and not as it's coming in as raw XML.
|
||||
packetReaderListener = new PacketListener() {
|
||||
SimpleDateFormat dateFormatter = new SimpleDateFormat("hh:mm:ss aaa");
|
||||
public void processPacket(Packet packet) {
|
||||
addReadPacketToTable(dateFormatter, packet);
|
||||
}
|
||||
};
|
||||
|
||||
// Create a thread that will listen for all outgoing packets and write them to
|
||||
// the GUI.
|
||||
packetWriterListener = new PacketListener() {
|
||||
SimpleDateFormat dateFormatter = new SimpleDateFormat("hh:mm:ss aaa");
|
||||
public void processPacket(Packet packet) {
|
||||
addSentPacketToTable(dateFormatter, packet);
|
||||
}
|
||||
};
|
||||
|
||||
// Create a thread that will listen for any connection closed event
|
||||
connListener = new ConnectionListener() {
|
||||
public void connectionClosed() {
|
||||
statusField.setValue("Closed");
|
||||
EnhancedDebuggerWindow.connectionClosed(EnhancedDebugger.this);
|
||||
}
|
||||
|
||||
public void connectionClosedOnError(Exception e) {
|
||||
statusField.setValue("Closed due to an exception");
|
||||
EnhancedDebuggerWindow.connectionClosedOnError(EnhancedDebugger.this, e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void addBasicPanels() {
|
||||
JPanel allPane = new JPanel();
|
||||
allPane.setLayout(new GridLayout(2, 1));
|
||||
tabbedPane.add("All Packets", allPane);
|
||||
tabbedPane.setToolTipTextAt(0, "Sent and received packets processed by Smack");
|
||||
|
||||
messagesTable =
|
||||
new DefaultTableModel(
|
||||
new Object[] { "Hide", "Timestamp", "", "", "Message", "Id", "Type", "To", "From" },
|
||||
0) {
|
||||
public boolean isCellEditable(int rowIndex, int mColIndex) {
|
||||
return false;
|
||||
}
|
||||
public Class getColumnClass(int columnIndex) {
|
||||
if (columnIndex == 2 || columnIndex == 3) {
|
||||
return Icon.class;
|
||||
}
|
||||
return super.getColumnClass(columnIndex);
|
||||
}
|
||||
|
||||
};
|
||||
JTable table = new JTable(messagesTable);
|
||||
// Allow only single a selection
|
||||
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
// Hide the first column
|
||||
table.getColumnModel().getColumn(0).setMaxWidth(0);
|
||||
table.getColumnModel().getColumn(0).setMinWidth(0);
|
||||
table.getTableHeader().getColumnModel().getColumn(0).setMaxWidth(0);
|
||||
table.getTableHeader().getColumnModel().getColumn(0).setMinWidth(0);
|
||||
// Set the column "timestamp" size
|
||||
table.getColumnModel().getColumn(1).setMaxWidth(300);
|
||||
table.getColumnModel().getColumn(1).setPreferredWidth(70);
|
||||
// Set the column "direction" icon size
|
||||
table.getColumnModel().getColumn(2).setMaxWidth(50);
|
||||
table.getColumnModel().getColumn(2).setPreferredWidth(30);
|
||||
// Set the column "packet type" icon size
|
||||
table.getColumnModel().getColumn(3).setMaxWidth(50);
|
||||
table.getColumnModel().getColumn(3).setPreferredWidth(30);
|
||||
// Set the column "Id" size
|
||||
table.getColumnModel().getColumn(5).setMaxWidth(100);
|
||||
table.getColumnModel().getColumn(5).setPreferredWidth(55);
|
||||
// Set the column "type" size
|
||||
table.getColumnModel().getColumn(6).setMaxWidth(200);
|
||||
table.getColumnModel().getColumn(6).setPreferredWidth(50);
|
||||
// Set the column "to" size
|
||||
table.getColumnModel().getColumn(7).setMaxWidth(300);
|
||||
table.getColumnModel().getColumn(7).setPreferredWidth(90);
|
||||
// Set the column "from" size
|
||||
table.getColumnModel().getColumn(8).setMaxWidth(300);
|
||||
table.getColumnModel().getColumn(8).setPreferredWidth(90);
|
||||
// Create a table listener that listen for row selection events
|
||||
SelectionListener selectionListener = new SelectionListener(table);
|
||||
table.getSelectionModel().addListSelectionListener(selectionListener);
|
||||
table.getColumnModel().getSelectionModel().addListSelectionListener(selectionListener);
|
||||
allPane.add(new JScrollPane(table));
|
||||
messageTextArea = new JTextArea();
|
||||
messageTextArea.setEditable(false);
|
||||
// Add pop-up menu.
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
JMenuItem menuItem1 = new JMenuItem("Copy");
|
||||
menuItem1.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// Get the clipboard
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
// Set the sent text as the new content of the clipboard
|
||||
clipboard.setContents(new StringSelection(messageTextArea.getText()), null);
|
||||
}
|
||||
});
|
||||
menu.add(menuItem1);
|
||||
// Add listener to the text area so the popup menu can come up.
|
||||
messageTextArea.addMouseListener(new PopupListener(menu));
|
||||
allPane.add(new JScrollPane(messageTextArea));
|
||||
|
||||
// Create UI elements for client generated XML traffic.
|
||||
final JTextArea sentText = new JTextArea();
|
||||
sentText.setEditable(false);
|
||||
sentText.setForeground(new Color(112, 3, 3));
|
||||
tabbedPane.add("Raw Sent Packets", new JScrollPane(sentText));
|
||||
tabbedPane.setToolTipTextAt(1, "Raw text of the sent packets");
|
||||
|
||||
// Add pop-up menu.
|
||||
menu = new JPopupMenu();
|
||||
menuItem1 = new JMenuItem("Copy");
|
||||
menuItem1.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// Get the clipboard
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
// Set the sent text as the new content of the clipboard
|
||||
clipboard.setContents(new StringSelection(sentText.getText()), null);
|
||||
}
|
||||
});
|
||||
|
||||
JMenuItem menuItem2 = new JMenuItem("Clear");
|
||||
menuItem2.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
sentText.setText("");
|
||||
}
|
||||
});
|
||||
|
||||
// Add listener to the text area so the popup menu can come up.
|
||||
sentText.addMouseListener(new PopupListener(menu));
|
||||
menu.add(menuItem1);
|
||||
menu.add(menuItem2);
|
||||
|
||||
// Create UI elements for server generated XML traffic.
|
||||
final JTextArea receivedText = new JTextArea();
|
||||
receivedText.setEditable(false);
|
||||
receivedText.setForeground(new Color(6, 76, 133));
|
||||
tabbedPane.add("Raw Received Packets", new JScrollPane(receivedText));
|
||||
tabbedPane.setToolTipTextAt(
|
||||
2,
|
||||
"Raw text of the received packets before Smack process them");
|
||||
|
||||
// Add pop-up menu.
|
||||
menu = new JPopupMenu();
|
||||
menuItem1 = new JMenuItem("Copy");
|
||||
menuItem1.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// Get the clipboard
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
// Set the sent text as the new content of the clipboard
|
||||
clipboard.setContents(new StringSelection(receivedText.getText()), null);
|
||||
}
|
||||
});
|
||||
|
||||
menuItem2 = new JMenuItem("Clear");
|
||||
menuItem2.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
receivedText.setText("");
|
||||
}
|
||||
});
|
||||
|
||||
// Add listener to the text area so the popup menu can come up.
|
||||
receivedText.addMouseListener(new PopupListener(menu));
|
||||
menu.add(menuItem1);
|
||||
menu.add(menuItem2);
|
||||
|
||||
// Create a special Reader that wraps the main Reader and logs data to the GUI.
|
||||
ObservableReader debugReader = new ObservableReader(reader);
|
||||
readerListener = new ReaderListener() {
|
||||
public void read(String str) {
|
||||
int index = str.lastIndexOf(">");
|
||||
if (index != -1) {
|
||||
receivedText.append(str.substring(0, index + 1));
|
||||
receivedText.append(NEWLINE);
|
||||
if (str.length() > index) {
|
||||
receivedText.append(str.substring(index + 1));
|
||||
}
|
||||
}
|
||||
else {
|
||||
receivedText.append(str);
|
||||
}
|
||||
}
|
||||
};
|
||||
debugReader.addReaderListener(readerListener);
|
||||
|
||||
// Create a special Writer that wraps the main Writer and logs data to the GUI.
|
||||
ObservableWriter debugWriter = new ObservableWriter(writer);
|
||||
writerListener = new WriterListener() {
|
||||
public void write(String str) {
|
||||
sentText.append(str);
|
||||
if (str.endsWith(">")) {
|
||||
sentText.append(NEWLINE);
|
||||
}
|
||||
}
|
||||
};
|
||||
debugWriter.addWriterListener(writerListener);
|
||||
|
||||
// Assign the reader/writer objects to use the debug versions. The packet reader
|
||||
// and writer will use the debug versions when they are created.
|
||||
reader = debugReader;
|
||||
writer = debugWriter;
|
||||
|
||||
}
|
||||
|
||||
private void addAdhocPacketPanel() {
|
||||
// Create UI elements for sending ad-hoc messages.
|
||||
final JTextArea adhocMessages = new JTextArea();
|
||||
adhocMessages.setEditable(true);
|
||||
adhocMessages.setForeground(new Color(1, 94, 35));
|
||||
tabbedPane.add("Ad-hoc message", new JScrollPane(adhocMessages));
|
||||
tabbedPane.setToolTipTextAt(3, "Panel that allows you to send adhoc packets");
|
||||
|
||||
// Add pop-up menu.
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
JMenuItem menuItem = new JMenuItem("Message");
|
||||
menuItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
adhocMessages.setText(
|
||||
"<message to=\"\" id=\""
|
||||
+ StringUtils.randomString(5)
|
||||
+ "-X\"><body></body></message>");
|
||||
}
|
||||
});
|
||||
menu.add(menuItem);
|
||||
|
||||
menuItem = new JMenuItem("IQ Get");
|
||||
menuItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
adhocMessages.setText(
|
||||
"<iq type=\"get\" to=\"\" id=\""
|
||||
+ StringUtils.randomString(5)
|
||||
+ "-X\"><query xmlns=\"\"></query></iq>");
|
||||
}
|
||||
});
|
||||
menu.add(menuItem);
|
||||
|
||||
menuItem = new JMenuItem("IQ Set");
|
||||
menuItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
adhocMessages.setText(
|
||||
"<iq type=\"set\" to=\"\" id=\""
|
||||
+ StringUtils.randomString(5)
|
||||
+ "-X\"><query xmlns=\"\"></query></iq>");
|
||||
}
|
||||
});
|
||||
menu.add(menuItem);
|
||||
|
||||
menuItem = new JMenuItem("Presence");
|
||||
menuItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
adhocMessages.setText(
|
||||
"<presence to=\"\" id=\"" + StringUtils.randomString(5) + "-X\"/>");
|
||||
}
|
||||
});
|
||||
menu.add(menuItem);
|
||||
menu.addSeparator();
|
||||
|
||||
menuItem = new JMenuItem("Send");
|
||||
menuItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (!"".equals(adhocMessages.getText())) {
|
||||
AdHocPacket packetToSend = new AdHocPacket(adhocMessages.getText());
|
||||
connection.sendPacket(packetToSend);
|
||||
}
|
||||
}
|
||||
});
|
||||
menu.add(menuItem);
|
||||
|
||||
menuItem = new JMenuItem("Clear");
|
||||
menuItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
adhocMessages.setText(null);
|
||||
}
|
||||
});
|
||||
menu.add(menuItem);
|
||||
|
||||
// Add listener to the text area so the popup menu can come up.
|
||||
adhocMessages.addMouseListener(new PopupListener(menu));
|
||||
}
|
||||
|
||||
private void addInformationPanel() {
|
||||
// Create UI elements for connection information.
|
||||
JPanel informationPanel = new JPanel();
|
||||
informationPanel.setLayout(new BorderLayout());
|
||||
|
||||
// Add the Host information
|
||||
JPanel connPanel = new JPanel();
|
||||
connPanel.setLayout(new GridBagLayout());
|
||||
connPanel.setBorder(BorderFactory.createTitledBorder("Connection information"));
|
||||
|
||||
JLabel label = new JLabel("Host: ");
|
||||
label.setMinimumSize(new java.awt.Dimension(150, 14));
|
||||
label.setMaximumSize(new java.awt.Dimension(150, 14));
|
||||
connPanel.add(
|
||||
label,
|
||||
new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, 21, 0, new Insets(0, 0, 0, 0), 0, 0));
|
||||
JFormattedTextField field = new JFormattedTextField(connection.getHost());
|
||||
field.setMinimumSize(new java.awt.Dimension(150, 20));
|
||||
field.setMaximumSize(new java.awt.Dimension(150, 20));
|
||||
field.setEditable(false);
|
||||
field.setBorder(null);
|
||||
connPanel.add(
|
||||
field,
|
||||
new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, 10, 2, new Insets(0, 0, 0, 0), 0, 0));
|
||||
|
||||
// Add the Port information
|
||||
label = new JLabel("Port: ");
|
||||
label.setMinimumSize(new java.awt.Dimension(150, 14));
|
||||
label.setMaximumSize(new java.awt.Dimension(150, 14));
|
||||
connPanel.add(
|
||||
label,
|
||||
new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, 21, 0, new Insets(0, 0, 0, 0), 0, 0));
|
||||
field = new JFormattedTextField(new Integer(connection.getPort()));
|
||||
field.setMinimumSize(new java.awt.Dimension(150, 20));
|
||||
field.setMaximumSize(new java.awt.Dimension(150, 20));
|
||||
field.setEditable(false);
|
||||
field.setBorder(null);
|
||||
connPanel.add(
|
||||
field,
|
||||
new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, 10, 2, new Insets(0, 0, 0, 0), 0, 0));
|
||||
|
||||
// Add the connection's User information
|
||||
label = new JLabel("User: ");
|
||||
label.setMinimumSize(new java.awt.Dimension(150, 14));
|
||||
label.setMaximumSize(new java.awt.Dimension(150, 14));
|
||||
connPanel.add(
|
||||
label,
|
||||
new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, 21, 0, new Insets(0, 0, 0, 0), 0, 0));
|
||||
userField = new JFormattedTextField();
|
||||
userField.setMinimumSize(new java.awt.Dimension(150, 20));
|
||||
userField.setMaximumSize(new java.awt.Dimension(150, 20));
|
||||
userField.setEditable(false);
|
||||
userField.setBorder(null);
|
||||
connPanel.add(
|
||||
userField,
|
||||
new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0, 10, 2, new Insets(0, 0, 0, 0), 0, 0));
|
||||
|
||||
// Add the connection's creationTime information
|
||||
label = new JLabel("Creation time: ");
|
||||
label.setMinimumSize(new java.awt.Dimension(150, 14));
|
||||
label.setMaximumSize(new java.awt.Dimension(150, 14));
|
||||
connPanel.add(
|
||||
label,
|
||||
new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, 21, 0, new Insets(0, 0, 0, 0), 0, 0));
|
||||
field = new JFormattedTextField(new SimpleDateFormat("yyyy.MM.dd hh:mm:ss aaa"));
|
||||
field.setMinimumSize(new java.awt.Dimension(150, 20));
|
||||
field.setMaximumSize(new java.awt.Dimension(150, 20));
|
||||
field.setValue(creationTime);
|
||||
field.setEditable(false);
|
||||
field.setBorder(null);
|
||||
connPanel.add(
|
||||
field,
|
||||
new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, 10, 2, new Insets(0, 0, 0, 0), 0, 0));
|
||||
|
||||
// Add the connection's creationTime information
|
||||
label = new JLabel("Status: ");
|
||||
label.setMinimumSize(new java.awt.Dimension(150, 14));
|
||||
label.setMaximumSize(new java.awt.Dimension(150, 14));
|
||||
connPanel.add(
|
||||
label,
|
||||
new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, 21, 0, new Insets(0, 0, 0, 0), 0, 0));
|
||||
statusField = new JFormattedTextField();
|
||||
statusField.setMinimumSize(new java.awt.Dimension(150, 20));
|
||||
statusField.setMaximumSize(new java.awt.Dimension(150, 20));
|
||||
statusField.setValue("Active");
|
||||
statusField.setEditable(false);
|
||||
statusField.setBorder(null);
|
||||
connPanel.add(
|
||||
statusField,
|
||||
new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0, 10, 2, new Insets(0, 0, 0, 0), 0, 0));
|
||||
// Add the connection panel to the information panel
|
||||
informationPanel.add(connPanel, BorderLayout.NORTH);
|
||||
|
||||
// Add the Number of sent packets information
|
||||
JPanel packetsPanel = new JPanel();
|
||||
packetsPanel.setLayout(new GridLayout(1, 1));
|
||||
packetsPanel.setBorder(BorderFactory.createTitledBorder("Transmitted Packets"));
|
||||
|
||||
statisticsTable =
|
||||
new DefaultTableModel(new Object[][] { { "IQ", new Integer(0), new Integer(0)}, {
|
||||
"Message", new Integer(0), new Integer(0)
|
||||
}, {
|
||||
"Presence", new Integer(0), new Integer(0)
|
||||
}, {
|
||||
"Other", new Integer(0), new Integer(0)
|
||||
}, {
|
||||
"Total", new Integer(0), new Integer(0)
|
||||
}
|
||||
}, new Object[] { "Type", "Received", "Sent" }) {
|
||||
public boolean isCellEditable(int rowIndex, int mColIndex) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
JTable table = new JTable(statisticsTable);
|
||||
// Allow only single a selection
|
||||
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
packetsPanel.add(new JScrollPane(table));
|
||||
|
||||
// Add the packets panel to the information panel
|
||||
informationPanel.add(packetsPanel, BorderLayout.CENTER);
|
||||
|
||||
tabbedPane.add("Information", new JScrollPane(informationPanel));
|
||||
tabbedPane.setToolTipTextAt(4, "Information and statistics about the debugged connection");
|
||||
}
|
||||
|
||||
public void userHasLogged(String user) {
|
||||
userField.setText(user);
|
||||
EnhancedDebuggerWindow.userHasLogged(this, user);
|
||||
// Add the connection listener to the connection so that the debugger can be notified
|
||||
// whenever the connection is closed.
|
||||
connection.addConnectionListener(connListener);
|
||||
}
|
||||
|
||||
public Reader getReader() {
|
||||
return reader;
|
||||
}
|
||||
|
||||
public Writer getWriter() {
|
||||
return writer;
|
||||
}
|
||||
|
||||
public PacketListener getReaderListener() {
|
||||
return packetReaderListener;
|
||||
}
|
||||
|
||||
public PacketListener getWriterListener() {
|
||||
return packetWriterListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the statistics table
|
||||
*/
|
||||
private void updateStatistics() {
|
||||
statisticsTable.setValueAt(new Integer(receivedIQPackets), 0, 1);
|
||||
statisticsTable.setValueAt(new Integer(sentIQPackets), 0, 2);
|
||||
|
||||
statisticsTable.setValueAt(new Integer(receivedMessagePackets), 1, 1);
|
||||
statisticsTable.setValueAt(new Integer(sentMessagePackets), 1, 2);
|
||||
|
||||
statisticsTable.setValueAt(new Integer(receivedPresencePackets), 2, 1);
|
||||
statisticsTable.setValueAt(new Integer(sentPresencePackets), 2, 2);
|
||||
|
||||
statisticsTable.setValueAt(new Integer(receivedOtherPackets), 3, 1);
|
||||
statisticsTable.setValueAt(new Integer(sentOtherPackets), 3, 2);
|
||||
|
||||
statisticsTable.setValueAt(new Integer(receivedPackets), 4, 1);
|
||||
statisticsTable.setValueAt(new Integer(sentPackets), 4, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the received packet detail to the messages table.
|
||||
*
|
||||
* @param dateFormatter the SimpleDateFormat to use to format Dates
|
||||
* @param packet the read packet to add to the table
|
||||
*/
|
||||
private void addReadPacketToTable(SimpleDateFormat dateFormatter, Packet packet) {
|
||||
String messageType = null;
|
||||
String from = packet.getFrom();
|
||||
String type = "";
|
||||
Icon packetTypeIcon;
|
||||
receivedPackets++;
|
||||
if (packet instanceof IQ) {
|
||||
packetTypeIcon = iqPacketIcon;
|
||||
messageType = "IQ Received (class=" + packet.getClass().getName() + ")";
|
||||
type = ((IQ) packet).getType().toString();
|
||||
receivedIQPackets++;
|
||||
}
|
||||
else if (packet instanceof Message) {
|
||||
packetTypeIcon = messagePacketIcon;
|
||||
messageType = "Message Received";
|
||||
type = ((Message) packet).getType().toString();
|
||||
receivedMessagePackets++;
|
||||
}
|
||||
else if (packet instanceof Presence) {
|
||||
packetTypeIcon = presencePacketIcon;
|
||||
messageType = "Presence Received";
|
||||
type = ((Presence) packet).getType().toString();
|
||||
receivedPresencePackets++;
|
||||
}
|
||||
else {
|
||||
packetTypeIcon = unknownPacketTypeIcon;
|
||||
messageType = packet.getClass().getName() + " Received";
|
||||
receivedOtherPackets++;
|
||||
}
|
||||
|
||||
messagesTable.addRow(
|
||||
new Object[] {
|
||||
formatXML(packet.toXML()),
|
||||
dateFormatter.format(new Date()),
|
||||
packetReceivedIcon,
|
||||
packetTypeIcon,
|
||||
messageType,
|
||||
packet.getPacketID(),
|
||||
type,
|
||||
"",
|
||||
from });
|
||||
// Update the statistics table
|
||||
updateStatistics();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the sent packet detail to the messages table.
|
||||
*
|
||||
* @param dateFormatter the SimpleDateFormat to use to format Dates
|
||||
* @param packet the sent packet to add to the table
|
||||
*/
|
||||
private void addSentPacketToTable(SimpleDateFormat dateFormatter, Packet packet) {
|
||||
String messageType = null;
|
||||
String to = packet.getTo();
|
||||
String type = "";
|
||||
Icon packetTypeIcon;
|
||||
sentPackets++;
|
||||
if (packet instanceof IQ) {
|
||||
packetTypeIcon = iqPacketIcon;
|
||||
messageType = "IQ Sent (class=" + packet.getClass().getName() + ")";
|
||||
type = ((IQ) packet).getType().toString();
|
||||
sentIQPackets++;
|
||||
}
|
||||
else if (packet instanceof Message) {
|
||||
packetTypeIcon = messagePacketIcon;
|
||||
messageType = "Message Sent";
|
||||
type = ((Message) packet).getType().toString();
|
||||
sentMessagePackets++;
|
||||
}
|
||||
else if (packet instanceof Presence) {
|
||||
packetTypeIcon = presencePacketIcon;
|
||||
messageType = "Presence Sent";
|
||||
type = ((Presence) packet).getType().toString();
|
||||
sentPresencePackets++;
|
||||
}
|
||||
else {
|
||||
packetTypeIcon = unknownPacketTypeIcon;
|
||||
messageType = packet.getClass().getName() + " Sent";
|
||||
sentOtherPackets++;
|
||||
}
|
||||
|
||||
messagesTable.addRow(
|
||||
new Object[] {
|
||||
formatXML(packet.toXML()),
|
||||
dateFormatter.format(new Date()),
|
||||
packetSentIcon,
|
||||
packetTypeIcon,
|
||||
messageType,
|
||||
packet.getPacketID(),
|
||||
type,
|
||||
to,
|
||||
"" });
|
||||
|
||||
// Update the statistics table
|
||||
updateStatistics();
|
||||
}
|
||||
|
||||
private String formatXML(String str) {
|
||||
try {
|
||||
// Use a Transformer for output
|
||||
TransformerFactory tFactory = TransformerFactory.newInstance();
|
||||
// Surround this setting in a try/catch for compatibility with Java 1.4. This setting is required
|
||||
// for Java 1.5
|
||||
try {
|
||||
tFactory.setAttribute("indent-number", new Integer(2));
|
||||
}
|
||||
catch (IllegalArgumentException e) {}
|
||||
Transformer transformer = tFactory.newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
|
||||
|
||||
// Transform the requested string into a nice formatted XML string
|
||||
StreamSource source = new StreamSource(new StringReader(str));
|
||||
StringWriter sw = new StringWriter();
|
||||
StreamResult result = new StreamResult(sw);
|
||||
transformer.transform(source, result);
|
||||
return sw.toString();
|
||||
|
||||
}
|
||||
catch (TransformerConfigurationException tce) {
|
||||
// Error generated by the parser
|
||||
System.out.println("\n** Transformer Factory error");
|
||||
System.out.println(" " + tce.getMessage());
|
||||
|
||||
// Use the contained exception, if any
|
||||
Throwable x = tce;
|
||||
if (tce.getException() != null)
|
||||
x = tce.getException();
|
||||
x.printStackTrace();
|
||||
|
||||
}
|
||||
catch (TransformerException te) {
|
||||
// Error generated by the parser
|
||||
System.out.println("\n** Transformation error");
|
||||
System.out.println(" " + te.getMessage());
|
||||
|
||||
// Use the contained exception, if any
|
||||
Throwable x = te;
|
||||
if (te.getException() != null)
|
||||
x = te.getException();
|
||||
x.printStackTrace();
|
||||
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the debugger's connection with the server is up and running.
|
||||
*
|
||||
* @return true if the connection with the server is active.
|
||||
*/
|
||||
boolean isConnectionActive() {
|
||||
return connection.isConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops debugging the connection. Removes any listener on the connection.
|
||||
*
|
||||
*/
|
||||
void cancel() {
|
||||
connection.removeConnectionListener(connListener);
|
||||
connection.removePacketListener(packetReaderListener);
|
||||
connection.removePacketWriterListener(packetWriterListener);
|
||||
((ObservableReader)reader).removeReaderListener(readerListener);
|
||||
((ObservableWriter)writer).removeWriterListener(writerListener);
|
||||
messagesTable = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An ad-hoc packet is like any regular packet but with the exception that it's intention is
|
||||
* to be used only <b>to send packets</b>.<p>
|
||||
*
|
||||
* The whole text to send must be passed to the constructor. This implies that the client of
|
||||
* this class is responsible for sending a valid text to the constructor.
|
||||
*
|
||||
*/
|
||||
private class AdHocPacket extends Packet {
|
||||
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* Create a new AdHocPacket with the text to send. The passed text must be a valid text to
|
||||
* send to the server, no validation will be done on the passed text.
|
||||
*
|
||||
* @param text the whole text of the packet to send
|
||||
*/
|
||||
public AdHocPacket(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
return text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for debug window popup dialog events.
|
||||
*/
|
||||
private class PopupListener extends MouseAdapter {
|
||||
JPopupMenu popup;
|
||||
|
||||
PopupListener(JPopupMenu popupMenu) {
|
||||
popup = popupMenu;
|
||||
}
|
||||
|
||||
public void mousePressed(MouseEvent e) {
|
||||
maybeShowPopup(e);
|
||||
}
|
||||
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
maybeShowPopup(e);
|
||||
}
|
||||
|
||||
private void maybeShowPopup(MouseEvent e) {
|
||||
if (e.isPopupTrigger()) {
|
||||
popup.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SelectionListener implements ListSelectionListener {
|
||||
JTable table;
|
||||
|
||||
// It is necessary to keep the table since it is not possible
|
||||
// to determine the table from the event's source
|
||||
SelectionListener(JTable table) {
|
||||
this.table = table;
|
||||
}
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if (table.getSelectedRow() == -1) {
|
||||
// Clear the messageTextArea since there is none packet selected
|
||||
messageTextArea.setText(null);
|
||||
}
|
||||
else {
|
||||
// Set the detail of the packet in the messageTextArea
|
||||
messageTextArea.setText(
|
||||
(String) table.getModel().getValueAt(table.getSelectedRow(), 0));
|
||||
// Scroll up to the top
|
||||
messageTextArea.setCaretPosition(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,348 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.debugger;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
import org.jivesoftware.smack.provider.ProviderManager;
|
||||
|
||||
/**
|
||||
* The EnhancedDebuggerWindow is the main debug window that will show all the EnhancedDebuggers.
|
||||
* For each connection to debug there will be an EnhancedDebugger that will be shown in the
|
||||
* EnhancedDebuggerWindow.<p>
|
||||
*
|
||||
* This class also provides information about Smack like for example the Smack version and the
|
||||
* installed providers.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
class EnhancedDebuggerWindow {
|
||||
|
||||
private static EnhancedDebuggerWindow instance;
|
||||
|
||||
private static ImageIcon connectionCreatedIcon;
|
||||
private static ImageIcon connectionActiveIcon;
|
||||
private static ImageIcon connectionClosedIcon;
|
||||
private static ImageIcon connectionClosedOnErrorIcon;
|
||||
|
||||
{
|
||||
URL url;
|
||||
|
||||
url =
|
||||
Thread.currentThread().getContextClassLoader().getResource(
|
||||
"images/trafficlight_off.png");
|
||||
if (url != null) {
|
||||
connectionCreatedIcon = new ImageIcon(url);
|
||||
}
|
||||
url =
|
||||
Thread.currentThread().getContextClassLoader().getResource(
|
||||
"images/trafficlight_green.png");
|
||||
if (url != null) {
|
||||
connectionActiveIcon = new ImageIcon(url);
|
||||
}
|
||||
url =
|
||||
Thread.currentThread().getContextClassLoader().getResource(
|
||||
"images/trafficlight_red.png");
|
||||
if (url != null) {
|
||||
connectionClosedIcon = new ImageIcon(url);
|
||||
}
|
||||
url = Thread.currentThread().getContextClassLoader().getResource("images/warning.png");
|
||||
if (url != null) {
|
||||
connectionClosedOnErrorIcon = new ImageIcon(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private JFrame frame = null;
|
||||
private JTabbedPane tabbedPane = null;
|
||||
private java.util.List debuggers = new ArrayList();
|
||||
|
||||
private EnhancedDebuggerWindow() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique EnhancedDebuggerWindow instance available in the system.
|
||||
*
|
||||
* @return the unique EnhancedDebuggerWindow instance
|
||||
*/
|
||||
private static EnhancedDebuggerWindow getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new EnhancedDebuggerWindow();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the new specified debugger to the list of debuggers to show in the main window.
|
||||
*
|
||||
* @param debugger the new debugger to show in the debug window
|
||||
*/
|
||||
synchronized static void addDebugger(EnhancedDebugger debugger) {
|
||||
getInstance().showNewDebugger(debugger);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the new debugger in the debug window.
|
||||
*
|
||||
* @param debugger the new debugger to show
|
||||
*/
|
||||
private void showNewDebugger(EnhancedDebugger debugger) {
|
||||
if (frame == null) {
|
||||
createDebug();
|
||||
}
|
||||
debugger.tabbedPane.setName("Connection_" + tabbedPane.getComponentCount());
|
||||
tabbedPane.add(debugger.tabbedPane, tabbedPane.getComponentCount() - 1);
|
||||
tabbedPane.setIconAt(tabbedPane.indexOfComponent(debugger.tabbedPane), connectionCreatedIcon);
|
||||
frame.setTitle(
|
||||
"Smack Debug Window -- Total connections: " + (tabbedPane.getComponentCount() - 1));
|
||||
// Keep the added debugger for later access
|
||||
debuggers.add(debugger);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification that a user has logged in to the server. A new title will be set
|
||||
* to the tab of the given debugger.
|
||||
*
|
||||
* @param debugger the debugger whose connection logged in to the server
|
||||
* @param user the user@host/resource that has just logged in
|
||||
*/
|
||||
synchronized static void userHasLogged(EnhancedDebugger debugger, String user) {
|
||||
int index = getInstance().tabbedPane.indexOfComponent(debugger.tabbedPane);
|
||||
getInstance().tabbedPane.setTitleAt(
|
||||
index,
|
||||
user);
|
||||
getInstance().tabbedPane.setIconAt(
|
||||
index,
|
||||
connectionActiveIcon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification that the connection was properly closed.
|
||||
*
|
||||
* @param debugger the debugger whose connection was properly closed.
|
||||
*/
|
||||
synchronized static void connectionClosed(EnhancedDebugger debugger) {
|
||||
getInstance().tabbedPane.setIconAt(
|
||||
getInstance().tabbedPane.indexOfComponent(debugger.tabbedPane),
|
||||
connectionClosedIcon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification that the connection was closed due to an exception.
|
||||
*
|
||||
* @param debugger the debugger whose connection was closed due to an exception.
|
||||
* @param e the exception.
|
||||
*/
|
||||
synchronized static void connectionClosedOnError(EnhancedDebugger debugger, Exception e) {
|
||||
int index = getInstance().tabbedPane.indexOfComponent(debugger.tabbedPane);
|
||||
getInstance().tabbedPane.setToolTipTextAt(
|
||||
index,
|
||||
"Connection closed due to the exception: " + e.getMessage());
|
||||
getInstance().tabbedPane.setIconAt(
|
||||
index,
|
||||
connectionClosedOnErrorIcon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the main debug window that provides information about Smack and also shows
|
||||
* a tab panel for each connection that is being debugged.
|
||||
*/
|
||||
private void createDebug() {
|
||||
|
||||
frame = new JFrame("Smack Debug Window");
|
||||
|
||||
// Add listener for window closing event
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent evt) {
|
||||
rootWindowClosing(evt);
|
||||
}
|
||||
});
|
||||
|
||||
// We'll arrange the UI into tabs. The last tab contains Smack's information.
|
||||
// All the connection debugger tabs will be shown before the Smack info tab.
|
||||
tabbedPane = new JTabbedPane();
|
||||
|
||||
// Create the Smack info panel
|
||||
JPanel informationPanel = new JPanel();
|
||||
informationPanel.setLayout(new BoxLayout(informationPanel, BoxLayout.Y_AXIS));
|
||||
|
||||
// Add the Smack version label
|
||||
JPanel versionPanel = new JPanel();
|
||||
versionPanel.setLayout(new BoxLayout(versionPanel, BoxLayout.X_AXIS));
|
||||
versionPanel.setMaximumSize(new Dimension(2000, 31));
|
||||
versionPanel.add(new JLabel(" Smack version: "));
|
||||
JFormattedTextField field = new JFormattedTextField(SmackConfiguration.getVersion());
|
||||
field.setEditable(false);
|
||||
field.setBorder(null);
|
||||
versionPanel.add(field);
|
||||
informationPanel.add(versionPanel);
|
||||
|
||||
// Add the list of installed IQ Providers
|
||||
JPanel iqProvidersPanel = new JPanel();
|
||||
iqProvidersPanel.setLayout(new GridLayout(1, 1));
|
||||
iqProvidersPanel.setBorder(BorderFactory.createTitledBorder("Installed IQ Providers"));
|
||||
Vector providers = new Vector();
|
||||
for (Iterator it = ProviderManager.getIQProviders(); it.hasNext();) {
|
||||
Object provider = it.next();
|
||||
if (provider.getClass() == Class.class) {
|
||||
providers.add(((Class) provider).getName());
|
||||
}
|
||||
else {
|
||||
providers.add(provider.getClass().getName());
|
||||
}
|
||||
}
|
||||
// Sort the collection of providers
|
||||
Collections.sort(providers);
|
||||
JList list = new JList(providers);
|
||||
iqProvidersPanel.add(new JScrollPane(list));
|
||||
informationPanel.add(iqProvidersPanel);
|
||||
|
||||
// Add the list of installed Extension Providers
|
||||
JPanel extensionProvidersPanel = new JPanel();
|
||||
extensionProvidersPanel.setLayout(new GridLayout(1, 1));
|
||||
extensionProvidersPanel.setBorder(BorderFactory.createTitledBorder("Installed Extension Providers"));
|
||||
providers = new Vector();
|
||||
for (Iterator it = ProviderManager.getExtensionProviders(); it.hasNext();) {
|
||||
Object provider = it.next();
|
||||
if (provider.getClass() == Class.class) {
|
||||
providers.add(((Class) provider).getName());
|
||||
}
|
||||
else {
|
||||
providers.add(provider.getClass().getName());
|
||||
}
|
||||
}
|
||||
// Sort the collection of providers
|
||||
Collections.sort(providers);
|
||||
list = new JList(providers);
|
||||
extensionProvidersPanel.add(new JScrollPane(list));
|
||||
informationPanel.add(extensionProvidersPanel);
|
||||
|
||||
tabbedPane.add("Smack Info", informationPanel);
|
||||
|
||||
// Add pop-up menu.
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
// Add a menu item that allows to close the current selected tab
|
||||
JMenuItem menuItem = new JMenuItem("Close");
|
||||
menuItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// Remove the selected tab pane if it's not the Smack info pane
|
||||
if (tabbedPane.getSelectedIndex() < tabbedPane.getComponentCount() - 1) {
|
||||
int index = tabbedPane.getSelectedIndex();
|
||||
// Notify to the debugger to stop debugging
|
||||
EnhancedDebugger debugger = (EnhancedDebugger)debuggers.get(index);
|
||||
debugger.cancel();
|
||||
// Remove the debugger from the root window
|
||||
tabbedPane.remove(debugger.tabbedPane);
|
||||
debuggers.remove(debugger);
|
||||
// Update the root window title
|
||||
frame.setTitle(
|
||||
"Smack Debug Window -- Total connections: "
|
||||
+ (tabbedPane.getComponentCount() - 1));
|
||||
}
|
||||
}
|
||||
});
|
||||
menu.add(menuItem);
|
||||
// Add a menu item that allows to close all the tabs that have their connections closed
|
||||
menuItem = new JMenuItem("Close All Not Active");
|
||||
menuItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ArrayList debuggersToRemove = new ArrayList();
|
||||
// Remove all the debuggers of which their connections are no longer valid
|
||||
for (int index=0; index < tabbedPane.getComponentCount()-1; index++) {
|
||||
EnhancedDebugger debugger = (EnhancedDebugger)debuggers.get(index);
|
||||
if (!debugger.isConnectionActive()) {
|
||||
// Notify to the debugger to stop debugging
|
||||
debugger.cancel();
|
||||
debuggersToRemove.add(debugger);
|
||||
}
|
||||
}
|
||||
for (Iterator it=debuggersToRemove.iterator(); it.hasNext();) {
|
||||
EnhancedDebugger debugger = (EnhancedDebugger)it.next();
|
||||
// Remove the debugger from the root window
|
||||
tabbedPane.remove(debugger.tabbedPane);
|
||||
debuggers.remove(debugger);
|
||||
}
|
||||
// Update the root window title
|
||||
frame.setTitle(
|
||||
"Smack Debug Window -- Total connections: "
|
||||
+ (tabbedPane.getComponentCount() - 1));
|
||||
}
|
||||
});
|
||||
menu.add(menuItem);
|
||||
// Add listener to the text area so the popup menu can come up.
|
||||
tabbedPane.addMouseListener(new PopupListener(menu));
|
||||
|
||||
frame.getContentPane().add(tabbedPane);
|
||||
|
||||
frame.setSize(650, 400);
|
||||
frame.setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification that the root window is closing. Stop listening for received and
|
||||
* transmitted packets in all the debugged connections.
|
||||
*
|
||||
* @param evt the event that indicates that the root window is closing
|
||||
*/
|
||||
public void rootWindowClosing(WindowEvent evt) {
|
||||
// Notify to all the debuggers to stop debugging
|
||||
for (Iterator it = debuggers.iterator(); it.hasNext();) {
|
||||
EnhancedDebugger debugger = (EnhancedDebugger)it.next();
|
||||
debugger.cancel();
|
||||
}
|
||||
// Release any reference to the debuggers
|
||||
debuggers.removeAll(debuggers);
|
||||
// Release the default instance
|
||||
instance = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for debug window popup dialog events.
|
||||
*/
|
||||
private class PopupListener extends MouseAdapter {
|
||||
JPopupMenu popup;
|
||||
|
||||
PopupListener(JPopupMenu popupMenu) {
|
||||
popup = popupMenu;
|
||||
}
|
||||
|
||||
public void mousePressed(MouseEvent e) {
|
||||
maybeShowPopup(e);
|
||||
}
|
||||
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
maybeShowPopup(e);
|
||||
}
|
||||
|
||||
private void maybeShowPopup(MouseEvent e) {
|
||||
if (e.isPopupTrigger()) {
|
||||
popup.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
<body>Smack optional Debuggers.</body>
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
import org.jivesoftware.smackx.packet.MUCAdmin;
|
||||
import org.jivesoftware.smackx.packet.MUCOwner;
|
||||
|
||||
/**
|
||||
* Represents an affiliation of a user to a given room. The affiliate's information will always have
|
||||
* the bare jid of the real user and its affiliation. If the affiliate is an occupant of the room
|
||||
* then we will also have information about the role and nickname of the user in the room.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class Affiliate {
|
||||
// Fields that must have a value
|
||||
private String jid;
|
||||
private String affiliation;
|
||||
|
||||
// Fields that may have a value
|
||||
private String role;
|
||||
private String nick;
|
||||
|
||||
Affiliate(MUCOwner.Item item) {
|
||||
super();
|
||||
this.jid = item.getJid();
|
||||
this.affiliation = item.getAffiliation();
|
||||
this.role = item.getRole();
|
||||
this.nick = item.getNick();
|
||||
}
|
||||
|
||||
Affiliate(MUCAdmin.Item item) {
|
||||
super();
|
||||
this.jid = item.getJid();
|
||||
this.affiliation = item.getAffiliation();
|
||||
this.role = item.getRole();
|
||||
this.nick = item.getNick();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bare JID of the affiliated user. This information will always be available.
|
||||
*
|
||||
* @return the bare JID of the affiliated user.
|
||||
*/
|
||||
public String getJid() {
|
||||
return jid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the affiliation of the afffiliated user. Possible affiliations are: "owner", "admin",
|
||||
* "member", "outcast". This information will always be available.
|
||||
*
|
||||
* @return the affiliation of the afffiliated user.
|
||||
*/
|
||||
public String getAffiliation() {
|
||||
return affiliation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current role of the affiliated user if the user is currently in the room.
|
||||
* If the user is not present in the room then the answer will be null.
|
||||
*
|
||||
* @return the current role of the affiliated user in the room or null if the user is not in
|
||||
* the room.
|
||||
*/
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current nickname of the affiliated user if the user is currently in the room.
|
||||
* If the user is not present in the room then the answer will be null.
|
||||
*
|
||||
* @return the current nickname of the affiliated user in the room or null if the user is not in
|
||||
* the room.
|
||||
*/
|
||||
public String getNick() {
|
||||
return nick;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
/**
|
||||
* Default implementation of the ParticipantStatusListener interface.<p>
|
||||
*
|
||||
* This class does not provide any behavior by default. It just avoids having
|
||||
* to implement all the inteface methods if the user is only interested in implementing
|
||||
* some of the methods.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class DefaultParticipantStatusListener implements ParticipantStatusListener {
|
||||
|
||||
public void joined(String participant) {
|
||||
}
|
||||
|
||||
public void left(String participant) {
|
||||
}
|
||||
|
||||
public void kicked(String participant) {
|
||||
}
|
||||
|
||||
public void voiceGranted(String participant) {
|
||||
}
|
||||
|
||||
public void voiceRevoked(String participant) {
|
||||
}
|
||||
|
||||
public void banned(String participant) {
|
||||
}
|
||||
|
||||
public void membershipGranted(String participant) {
|
||||
}
|
||||
|
||||
public void membershipRevoked(String participant) {
|
||||
}
|
||||
|
||||
public void moderatorGranted(String participant) {
|
||||
}
|
||||
|
||||
public void moderatorRevoked(String participant) {
|
||||
}
|
||||
|
||||
public void ownershipGranted(String participant) {
|
||||
}
|
||||
|
||||
public void ownershipRevoked(String participant) {
|
||||
}
|
||||
|
||||
public void adminGranted(String participant) {
|
||||
}
|
||||
|
||||
public void adminRevoked(String participant) {
|
||||
}
|
||||
|
||||
public void nicknameChanged(String nickname) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
/**
|
||||
* Default implementation of the UserStatusListener interface.<p>
|
||||
*
|
||||
* This class does not provide any behavior by default. It just avoids having
|
||||
* to implement all the inteface methods if the user is only interested in implementing
|
||||
* some of the methods.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class DefaultUserStatusListener implements UserStatusListener {
|
||||
|
||||
public void kicked(String actor, String reason) {
|
||||
}
|
||||
|
||||
public void voiceGranted() {
|
||||
}
|
||||
|
||||
public void voiceRevoked() {
|
||||
}
|
||||
|
||||
public void banned(String actor, String reason) {
|
||||
}
|
||||
|
||||
public void membershipGranted() {
|
||||
}
|
||||
|
||||
public void membershipRevoked() {
|
||||
}
|
||||
|
||||
public void moderatorGranted() {
|
||||
}
|
||||
|
||||
public void moderatorRevoked() {
|
||||
}
|
||||
|
||||
public void ownershipGranted() {
|
||||
}
|
||||
|
||||
public void ownershipRevoked() {
|
||||
}
|
||||
|
||||
public void adminGranted() {
|
||||
}
|
||||
|
||||
public void adminRevoked() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.jivesoftware.smackx.packet.MUCInitialPresence;
|
||||
|
||||
/**
|
||||
* The DiscussionHistory class controls the number of characters or messages to receive
|
||||
* when entering a room. The room will decide the amount of history to return if you don't
|
||||
* specify a DiscussionHistory while joining a room.<p>
|
||||
*
|
||||
* You can use some or all of these variable to control the amount of history to receive:
|
||||
* <ul>
|
||||
* <li>maxchars -> total number of characters to receive in the history.
|
||||
* <li>maxstanzas -> total number of messages to receive in the history.
|
||||
* <li>seconds -> only the messages received in the last "X" seconds will be included in the
|
||||
* history.
|
||||
* <li>since -> only the messages received since the datetime specified will be included in
|
||||
* the history.
|
||||
* </ul>
|
||||
*
|
||||
* Note: Setting maxchars to 0 indicates that the user requests to receive no history.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class DiscussionHistory {
|
||||
|
||||
private int maxChars = -1;
|
||||
private int maxStanzas = -1;
|
||||
private int seconds = -1;
|
||||
private Date since;
|
||||
|
||||
/**
|
||||
* Returns the total number of characters to receive in the history.
|
||||
*
|
||||
* @return total number of characters to receive in the history.
|
||||
*/
|
||||
public int getMaxChars() {
|
||||
return maxChars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of messages to receive in the history.
|
||||
*
|
||||
* @return the total number of messages to receive in the history.
|
||||
*/
|
||||
public int getMaxStanzas() {
|
||||
return maxStanzas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of seconds to use to filter the messages received during that time.
|
||||
* In other words, only the messages received in the last "X" seconds will be included in
|
||||
* the history.
|
||||
*
|
||||
* @return the number of seconds to use to filter the messages received during that time.
|
||||
*/
|
||||
public int getSeconds() {
|
||||
return seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the since date to use to filter the messages received during that time.
|
||||
* In other words, only the messages received since the datetime specified will be
|
||||
* included in the history.
|
||||
*
|
||||
* @return the since date to use to filter the messages received during that time.
|
||||
*/
|
||||
public Date getSince() {
|
||||
return since;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the total number of characters to receive in the history.
|
||||
*
|
||||
* @param maxChars the total number of characters to receive in the history.
|
||||
*/
|
||||
public void setMaxChars(int maxChars) {
|
||||
this.maxChars = maxChars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the total number of messages to receive in the history.
|
||||
*
|
||||
* @param maxStanzas the total number of messages to receive in the history.
|
||||
*/
|
||||
public void setMaxStanzas(int maxStanzas) {
|
||||
this.maxStanzas = maxStanzas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of seconds to use to filter the messages received during that time.
|
||||
* In other words, only the messages received in the last "X" seconds will be included in
|
||||
* the history.
|
||||
*
|
||||
* @param seconds the number of seconds to use to filter the messages received during
|
||||
* that time.
|
||||
*/
|
||||
public void setSeconds(int seconds) {
|
||||
this.seconds = seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the since date to use to filter the messages received during that time.
|
||||
* In other words, only the messages received since the datetime specified will be
|
||||
* included in the history.
|
||||
*
|
||||
* @param since the since date to use to filter the messages received during that time.
|
||||
*/
|
||||
public void setSince(Date since) {
|
||||
this.since = since;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the history has been configured with some values.
|
||||
*
|
||||
* @return true if the history has been configured with some values.
|
||||
*/
|
||||
private boolean isConfigured() {
|
||||
return maxChars > -1 || maxStanzas > -1 || seconds > -1 || since != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the History that manages the amount of discussion history provided on entering a
|
||||
* room.
|
||||
*
|
||||
* @return the History that manages the amount of discussion history provided on entering a
|
||||
* room.
|
||||
*/
|
||||
MUCInitialPresence.History getMUCHistory() {
|
||||
// Return null if the history was not properly configured
|
||||
if (!isConfigured()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MUCInitialPresence.History mucHistory = new MUCInitialPresence.History();
|
||||
if (maxChars > -1) {
|
||||
mucHistory.setMaxChars(maxChars);
|
||||
}
|
||||
if (maxStanzas > -1) {
|
||||
mucHistory.setMaxStanzas(maxStanzas);
|
||||
}
|
||||
if (seconds > -1) {
|
||||
mucHistory.setSeconds(seconds);
|
||||
}
|
||||
if (since != null) {
|
||||
mucHistory.setSince(since);
|
||||
}
|
||||
return mucHistory;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
import org.jivesoftware.smackx.packet.DiscoverItems;
|
||||
|
||||
/**
|
||||
* Hosted rooms by a chat service may be discovered if they are configured to appear in the room
|
||||
* directory . The information that may be discovered is the XMPP address of the room and the room
|
||||
* name. The address of the room may be used for obtaining more detailed information
|
||||
* {@link org.jivesoftware.smackx.muc.MultiUserChat#getRoomInfo(org.jivesoftware.smack.XMPPConnection, String)}
|
||||
* or could be used for joining the room
|
||||
* {@link org.jivesoftware.smackx.muc.MultiUserChat#MultiUserChat(org.jivesoftware.smack.XMPPConnection, String)}
|
||||
* and {@link org.jivesoftware.smackx.muc.MultiUserChat#join(String)}.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class HostedRoom {
|
||||
|
||||
private String jid;
|
||||
|
||||
private String name;
|
||||
|
||||
public HostedRoom(DiscoverItems.Item item) {
|
||||
super();
|
||||
jid = item.getEntityID();
|
||||
name = item.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XMPP address of the hosted room by the chat service. This address may be used
|
||||
* when creating a <code>MultiUserChat</code> when joining a room.
|
||||
*
|
||||
* @return the XMPP address of the hosted room by the chat service.
|
||||
*/
|
||||
public String getJid() {
|
||||
return jid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the room.
|
||||
*
|
||||
* @return the name of the room.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
|
||||
/**
|
||||
* A listener that is fired anytime an invitation to join a MUC room is received.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public interface InvitationListener {
|
||||
|
||||
/**
|
||||
* Called when the an invitation to join a MUC room is received.<p>
|
||||
*
|
||||
* If the room is password-protected, the invitee will receive a password to use to join
|
||||
* the room. If the room is members-only, the the invitee may be added to the member list.
|
||||
*
|
||||
* @param conn the XMPPConnection that received the invitation.
|
||||
* @param room the room that invitation refers to.
|
||||
* @param inviter the inviter that sent the invitation. (e.g. crone1@shakespeare.lit).
|
||||
* @param reason the reason why the inviter sent the invitation.
|
||||
* @param password the password to use when joining the room.
|
||||
* @param message the message used by the inviter to send the invitation.
|
||||
*/
|
||||
public abstract void invitationReceived(XMPPConnection conn, String room, String inviter, String reason,
|
||||
String password, Message message);
|
||||
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
/**
|
||||
* A listener that is fired anytime an invitee declines or rejects an invitation.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public interface InvitationRejectionListener {
|
||||
|
||||
/**
|
||||
* Called when the invitee declines the invitation.
|
||||
*
|
||||
* @param invitee the invitee that declined the invitation. (e.g. hecate@shakespeare.lit).
|
||||
* @param reason the reason why the invitee declined the invitation.
|
||||
*/
|
||||
public abstract void invitationDeclined(String invitee, String reason);
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,104 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
import org.jivesoftware.smackx.packet.MUCAdmin;
|
||||
import org.jivesoftware.smackx.packet.MUCUser;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Represents the information about an occupant in a given room. The information will always have
|
||||
* the affiliation and role of the occupant in the room. The full JID and nickname are optional.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class Occupant {
|
||||
// Fields that must have a value
|
||||
private String affiliation;
|
||||
private String role;
|
||||
// Fields that may have a value
|
||||
private String jid;
|
||||
private String nick;
|
||||
|
||||
Occupant(MUCAdmin.Item item) {
|
||||
super();
|
||||
this.jid = item.getJid();
|
||||
this.affiliation = item.getAffiliation();
|
||||
this.role = item.getRole();
|
||||
this.nick = item.getNick();
|
||||
}
|
||||
|
||||
Occupant(Presence presence) {
|
||||
super();
|
||||
MUCUser mucUser = (MUCUser) presence.getExtension("x",
|
||||
"http://jabber.org/protocol/muc#user");
|
||||
MUCUser.Item item = mucUser.getItem();
|
||||
this.jid = item.getJid();
|
||||
this.affiliation = item.getAffiliation();
|
||||
this.role = item.getRole();
|
||||
// Get the nickname from the FROM attribute of the presence
|
||||
this.nick = StringUtils.parseResource(presence.getFrom());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full JID of the occupant. If this information was extracted from a presence and
|
||||
* the room is semi or full-anonymous then the answer will be null. On the other hand, if this
|
||||
* information was obtained while maintaining the voice list or the moderator list then we will
|
||||
* always have a full JID.
|
||||
*
|
||||
* @return the full JID of the occupant.
|
||||
*/
|
||||
public String getJid() {
|
||||
return jid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the affiliation of the occupant. Possible affiliations are: "owner", "admin",
|
||||
* "member", "outcast". This information will always be available.
|
||||
*
|
||||
* @return the affiliation of the occupant.
|
||||
*/
|
||||
public String getAffiliation() {
|
||||
return affiliation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current role of the occupant in the room. This information will always be
|
||||
* available.
|
||||
*
|
||||
* @return the current role of the occupant in the room.
|
||||
*/
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current nickname of the occupant in the room. If this information was extracted
|
||||
* from a presence then the answer will be null.
|
||||
*
|
||||
* @return the current nickname of the occupant in the room or null if this information was
|
||||
* obtained from a presence.
|
||||
*/
|
||||
public String getNick() {
|
||||
return nick;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
/**
|
||||
* A listener that is fired anytime a participant's status in a room is changed, such as the
|
||||
* user being kicked, banned, or granted admin permissions.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public interface ParticipantStatusListener {
|
||||
|
||||
/**
|
||||
* Called when a new room occupant has joined the room. Note: Take in consideration that when
|
||||
* you join a room you will receive the list of current occupants in the room. This message will
|
||||
* be sent for each occupant.
|
||||
*
|
||||
* @param participant the participant that has just joined the room
|
||||
* (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void joined(String participant);
|
||||
|
||||
/**
|
||||
* Called when a room occupant has left the room on its own. This means that the occupant was
|
||||
* neither kicked nor banned from the room.
|
||||
*
|
||||
* @param participant the participant that has left the room on its own.
|
||||
* (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void left(String participant);
|
||||
|
||||
/**
|
||||
* Called when a room participant has been kicked from the room. This means that the kicked
|
||||
* participant is no longer participating in the room.
|
||||
*
|
||||
* @param participant the participant that was kicked from the room
|
||||
* (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void kicked(String participant);
|
||||
|
||||
/**
|
||||
* Called when a moderator grants voice to a visitor. This means that the visitor
|
||||
* can now participate in the moderated room sending messages to all occupants.
|
||||
*
|
||||
* @param participant the participant that was granted voice in the room
|
||||
* (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void voiceGranted(String participant);
|
||||
|
||||
/**
|
||||
* Called when a moderator revokes voice from a participant. This means that the participant
|
||||
* in the room was able to speak and now is a visitor that can't send messages to the room
|
||||
* occupants.
|
||||
*
|
||||
* @param participant the participant that was revoked voice from the room
|
||||
* (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void voiceRevoked(String participant);
|
||||
|
||||
/**
|
||||
* Called when an administrator or owner banned a participant from the room. This means that
|
||||
* banned participant will no longer be able to join the room unless the ban has been removed.
|
||||
*
|
||||
* @param participant the participant that was banned from the room
|
||||
* (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void banned(String participant);
|
||||
|
||||
/**
|
||||
* Called when an administrator grants a user membership to the room. This means that the user
|
||||
* will be able to join the members-only room.
|
||||
*
|
||||
* @param participant the participant that was granted membership in the room
|
||||
* (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void membershipGranted(String participant);
|
||||
|
||||
/**
|
||||
* Called when an administrator revokes a user membership to the room. This means that the
|
||||
* user will not be able to join the members-only room.
|
||||
*
|
||||
* @param participant the participant that was revoked membership from the room
|
||||
* (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void membershipRevoked(String participant);
|
||||
|
||||
/**
|
||||
* Called when an administrator grants moderator privileges to a user. This means that the user
|
||||
* will be able to kick users, grant and revoke voice, invite other users, modify room's
|
||||
* subject plus all the partcipants privileges.
|
||||
*
|
||||
* @param participant the participant that was granted moderator privileges in the room
|
||||
* (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void moderatorGranted(String participant);
|
||||
|
||||
/**
|
||||
* Called when an administrator revokes moderator privileges from a user. This means that the
|
||||
* user will no longer be able to kick users, grant and revoke voice, invite other users,
|
||||
* modify room's subject plus all the partcipants privileges.
|
||||
*
|
||||
* @param participant the participant that was revoked moderator privileges in the room
|
||||
* (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void moderatorRevoked(String participant);
|
||||
|
||||
/**
|
||||
* Called when an owner grants a user ownership on the room. This means that the user
|
||||
* will be able to change defining room features as well as perform all administrative
|
||||
* functions.
|
||||
*
|
||||
* @param participant the participant that was granted ownership on the room
|
||||
* (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void ownershipGranted(String participant);
|
||||
|
||||
/**
|
||||
* Called when an owner revokes a user ownership on the room. This means that the user
|
||||
* will no longer be able to change defining room features as well as perform all
|
||||
* administrative functions.
|
||||
*
|
||||
* @param participant the participant that was revoked ownership on the room
|
||||
* (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void ownershipRevoked(String participant);
|
||||
|
||||
/**
|
||||
* Called when an owner grants administrator privileges to a user. This means that the user
|
||||
* will be able to perform administrative functions such as banning users and edit moderator
|
||||
* list.
|
||||
*
|
||||
* @param participant the participant that was granted administrator privileges
|
||||
* (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void adminGranted(String participant);
|
||||
|
||||
/**
|
||||
* Called when an owner revokes administrator privileges from a user. This means that the user
|
||||
* will no longer be able to perform administrative functions such as banning users and edit
|
||||
* moderator list.
|
||||
*
|
||||
* @param participant the participant that was revoked administrator privileges
|
||||
* (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void adminRevoked(String participant);
|
||||
|
||||
/**
|
||||
* Called when a participant changed his/her nickname in the room. The new participant's
|
||||
* nickname will be informed with the next available presence.
|
||||
*
|
||||
* @param nickname the old nickname that the participant decided to change.
|
||||
*/
|
||||
public abstract void nicknameChanged(String nickname);
|
||||
|
||||
}
|
||||
|
|
@ -1,184 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
import org.jivesoftware.smackx.packet.DiscoverInfo;
|
||||
import org.jivesoftware.smackx.Form;
|
||||
|
||||
/**
|
||||
* Represents the room information that was discovered using Service Discovery. It's possible to
|
||||
* obtain information about a room before joining the room but only for rooms that are public (i.e.
|
||||
* rooms that may be discovered).
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class RoomInfo {
|
||||
|
||||
/**
|
||||
* JID of the room. The node of the JID is commonly used as the ID of the room or name.
|
||||
*/
|
||||
private String room;
|
||||
/**
|
||||
* Description of the room.
|
||||
*/
|
||||
private String description = "";
|
||||
/**
|
||||
* Last known subject of the room.
|
||||
*/
|
||||
private String subject = "";
|
||||
/**
|
||||
* Current number of occupants in the room.
|
||||
*/
|
||||
private int occupantsCount = -1;
|
||||
/**
|
||||
* A room is considered members-only if an invitation is required in order to enter the room.
|
||||
* Any user that is not a member of the room won't be able to join the room unless the user
|
||||
* decides to register with the room (thus becoming a member).
|
||||
*/
|
||||
private boolean membersOnly;
|
||||
/**
|
||||
* Moderated rooms enable only participants to speak. Users that join the room and aren't
|
||||
* participants can't speak (they are just visitors).
|
||||
*/
|
||||
private boolean moderated;
|
||||
/**
|
||||
* Every presence packet can include the JID of every occupant unless the owner deactives this
|
||||
* configuration.
|
||||
*/
|
||||
private boolean nonanonymous;
|
||||
/**
|
||||
* Indicates if users must supply a password to join the room.
|
||||
*/
|
||||
private boolean passwordProtected;
|
||||
/**
|
||||
* Persistent rooms are saved to the database to make sure that rooms configurations can be
|
||||
* restored in case the server goes down.
|
||||
*/
|
||||
private boolean persistent;
|
||||
|
||||
RoomInfo(DiscoverInfo info) {
|
||||
super();
|
||||
this.room = info.getFrom();
|
||||
// Get the information based on the discovered features
|
||||
this.membersOnly = info.containsFeature("muc_membersonly");
|
||||
this.moderated = info.containsFeature("muc_moderated");
|
||||
this.nonanonymous = info.containsFeature("muc_nonanonymous");
|
||||
this.passwordProtected = info.containsFeature("muc_passwordprotected");
|
||||
this.persistent = info.containsFeature("muc_persistent");
|
||||
// Get the information based on the discovered extended information
|
||||
Form form = Form.getFormFrom(info);
|
||||
if (form != null) {
|
||||
this.description =
|
||||
(String) form.getField("muc#roominfo_description").getValues().next();
|
||||
this.subject = (String) form.getField("muc#roominfo_subject").getValues().next();
|
||||
this.occupantsCount =
|
||||
Integer.parseInt((String) form.getField("muc#roominfo_occupants").getValues()
|
||||
.next());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the JID of the room whose information was discovered.
|
||||
*
|
||||
* @return the JID of the room whose information was discovered.
|
||||
*/
|
||||
public String getRoom() {
|
||||
return room;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the discovered description of the room.
|
||||
*
|
||||
* @return the discovered description of the room.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the discovered subject of the room. The subject may be empty if the room does not
|
||||
* have a subject.
|
||||
*
|
||||
* @return the discovered subject of the room.
|
||||
*/
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the discovered number of occupants that are currently in the room. If this
|
||||
* information was not discovered (i.e. the server didn't send it) then a value of -1 will be
|
||||
* returned.
|
||||
*
|
||||
* @return the number of occupants that are currently in the room or -1 if that information was
|
||||
* not provided by the server.
|
||||
*/
|
||||
public int getOccupantsCount() {
|
||||
return occupantsCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the room has restricted the access so that only members may enter the room.
|
||||
*
|
||||
* @return true if the room has restricted the access so that only members may enter the room.
|
||||
*/
|
||||
public boolean isMembersOnly() {
|
||||
return membersOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the room enabled only participants to speak. Occupants with a role of
|
||||
* visitor won't be able to speak in the room.
|
||||
*
|
||||
* @return true if the room enabled only participants to speak.
|
||||
*/
|
||||
public boolean isModerated() {
|
||||
return moderated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if presence packets will include the JID of every occupant.
|
||||
*
|
||||
* @return true if presence packets will include the JID of every occupant.
|
||||
*/
|
||||
public boolean isNonanonymous() {
|
||||
return nonanonymous;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if users musy provide a valid password in order to join the room.
|
||||
*
|
||||
* @return true if users musy provide a valid password in order to join the room.
|
||||
*/
|
||||
public boolean isPasswordProtected() {
|
||||
return passwordProtected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the room will persist after the last occupant have left the room.
|
||||
*
|
||||
* @return true if the room will persist after the last occupant have left the room.
|
||||
*/
|
||||
public boolean isPersistent() {
|
||||
return persistent;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
/**
|
||||
* A listener that is fired anytime a MUC room changes its subject.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public interface SubjectUpdatedListener {
|
||||
|
||||
/**
|
||||
* Called when a MUC room has changed its subject.
|
||||
*
|
||||
* @param subject the new room's subject.
|
||||
* @param from the user that changed the room's subject (e.g. room@conference.jabber.org/nick).
|
||||
*/
|
||||
public abstract void subjectUpdated(String subject, String from);
|
||||
|
||||
}
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
/**
|
||||
* A listener that is fired anytime your participant's status in a room is changed, such as the
|
||||
* user being kicked, banned, or granted admin permissions.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public interface UserStatusListener {
|
||||
|
||||
/**
|
||||
* Called when a moderator kicked your user from the room. This means that you are no longer
|
||||
* participanting in the room.
|
||||
*
|
||||
* @param actor the moderator that kicked your user from the room (e.g. user@host.org).
|
||||
* @param reason the reason provided by the actor to kick you from the room.
|
||||
*/
|
||||
public abstract void kicked(String actor, String reason);
|
||||
|
||||
/**
|
||||
* Called when a moderator grants voice to your user. This means that you were a visitor in
|
||||
* the moderated room before and now you can participate in the room by sending messages to
|
||||
* all occupants.
|
||||
*
|
||||
*/
|
||||
public abstract void voiceGranted();
|
||||
|
||||
/**
|
||||
* Called when a moderator revokes voice from your user. This means that you were a
|
||||
* participant in the room able to speak and now you are a visitor that can't send
|
||||
* messages to the room occupants.
|
||||
*
|
||||
*/
|
||||
public abstract void voiceRevoked();
|
||||
|
||||
/**
|
||||
* Called when an administrator or owner banned your user from the room. This means that you
|
||||
* will no longer be able to join the room unless the ban has been removed.
|
||||
*
|
||||
* @param actor the administrator that banned your user (e.g. user@host.org).
|
||||
* @param reason the reason provided by the administrator to banned you.
|
||||
*/
|
||||
public abstract void banned(String actor, String reason);
|
||||
|
||||
/**
|
||||
* Called when an administrator grants your user membership to the room. This means that you
|
||||
* will be able to join the members-only room.
|
||||
*
|
||||
*/
|
||||
public abstract void membershipGranted();
|
||||
|
||||
/**
|
||||
* Called when an administrator revokes your user membership to the room. This means that you
|
||||
* will not be able to join the members-only room.
|
||||
*
|
||||
*/
|
||||
public abstract void membershipRevoked();
|
||||
|
||||
/**
|
||||
* Called when an administrator grants moderator privileges to your user. This means that you
|
||||
* will be able to kick users, grant and revoke voice, invite other users, modify room's
|
||||
* subject plus all the partcipants privileges.
|
||||
*
|
||||
*/
|
||||
public abstract void moderatorGranted();
|
||||
|
||||
/**
|
||||
* Called when an administrator revokes moderator privileges from your user. This means that
|
||||
* you will no longer be able to kick users, grant and revoke voice, invite other users,
|
||||
* modify room's subject plus all the partcipants privileges.
|
||||
*
|
||||
*/
|
||||
public abstract void moderatorRevoked();
|
||||
|
||||
/**
|
||||
* Called when an owner grants to your user ownership on the room. This means that you
|
||||
* will be able to change defining room features as well as perform all administrative
|
||||
* functions.
|
||||
*
|
||||
*/
|
||||
public abstract void ownershipGranted();
|
||||
|
||||
/**
|
||||
* Called when an owner revokes from your user ownership on the room. This means that you
|
||||
* will no longer be able to change defining room features as well as perform all
|
||||
* administrative functions.
|
||||
*
|
||||
*/
|
||||
public abstract void ownershipRevoked();
|
||||
|
||||
/**
|
||||
* Called when an owner grants administrator privileges to your user. This means that you
|
||||
* will be able to perform administrative functions such as banning users and edit moderator
|
||||
* list.
|
||||
*
|
||||
*/
|
||||
public abstract void adminGranted();
|
||||
|
||||
/**
|
||||
* Called when an owner revokes administrator privileges from your user. This means that you
|
||||
* will no longer be able to perform administrative functions such as banning users and edit
|
||||
* moderator list.
|
||||
*
|
||||
*/
|
||||
public abstract void adminRevoked();
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
<body>Classes and Interfaces that implement Multi-User Chat (MUC).</body>
|
||||
|
|
@ -1 +0,0 @@
|
|||
<body>Smack extensions API.</body>
|
||||
|
|
@ -1,296 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.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 {
|
||||
|
||||
private String type;
|
||||
private String title;
|
||||
private List instructions = new ArrayList();
|
||||
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 an Iterator for the list of instructions that explain how to fill out the form and
|
||||
* what the form is about. The dataform could include multiple instructions since each
|
||||
* instruction could not contain newlines characters. Join the instructions together in order
|
||||
* to show them to the user.
|
||||
*
|
||||
* @return an Iterator for the list of instructions that explain how to fill out the form.
|
||||
*/
|
||||
public Iterator getInstructions() {
|
||||
synchronized (instructions) {
|
||||
return Collections.unmodifiableList(new ArrayList(instructions)).iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 the list of instructions that explain how to fill out the form and what the form is
|
||||
* about. The dataform could include multiple instructions since each instruction could not
|
||||
* contain newlines characters.
|
||||
*
|
||||
* @param instructions list of instructions that explain how to fill out the form.
|
||||
*/
|
||||
public void setInstructions(List 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 instruction to the list of instructions that explain how to fill out the form
|
||||
* and what the form is about. The dataform could include multiple instructions since each
|
||||
* instruction could not contain newlines characters.
|
||||
*
|
||||
* @param instruction the new instruction that explain how to fill out the form.
|
||||
*/
|
||||
public void addInstruction(String instruction) {
|
||||
synchronized (instructions) {
|
||||
instructions.add(instruction);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new item returned from a search.
|
||||
*
|
||||
* @param item 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>");
|
||||
}
|
||||
for (Iterator it=getInstructions(); it.hasNext();) {
|
||||
buf.append("<instructions>").append(it.next()).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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Iterator;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Default implementation of the PrivateData interface. Unless a PrivateDataProvider
|
||||
* is registered with the PrivateDataManager class, instances of this class will be
|
||||
* returned when getting private data.<p>
|
||||
*
|
||||
* This class provides a very simple representation of an XML sub-document. Each element
|
||||
* is a key in a Map with its CDATA being the value. For example, given the following
|
||||
* XML sub-document:
|
||||
*
|
||||
* <pre>
|
||||
* <foo xmlns="http://bar.com">
|
||||
* <color>blue</color>
|
||||
* <food>pizza</food>
|
||||
* </foo></pre>
|
||||
*
|
||||
* In this case, getValue("color") would return "blue", and getValue("food") would
|
||||
* return "pizza". This parsing mechanism mechanism is very simplistic and will not work
|
||||
* as desired in all cases (for example, if some of the elements have attributes. In those
|
||||
* cases, a custom {@link org.jivesoftware.smackx.provider.PrivateDataProvider} should be used.
|
||||
*
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public class DefaultPrivateData implements PrivateData {
|
||||
|
||||
private String elementName;
|
||||
private String namespace;
|
||||
private Map map;
|
||||
|
||||
/**
|
||||
* Creates a new generic private data object.
|
||||
*
|
||||
* @param elementName the name of the element of the XML sub-document.
|
||||
* @param namespace the namespace of the element.
|
||||
*/
|
||||
public DefaultPrivateData(String elementName, String namespace) {
|
||||
this.elementName = elementName;
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML element name of the private data sub-packet root element.
|
||||
*
|
||||
* @return the XML element name of the packet extension.
|
||||
*/
|
||||
public String getElementName() {
|
||||
return elementName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML namespace of the private data sub-packet root element.
|
||||
*
|
||||
* @return the XML namespace of the packet extension.
|
||||
*/
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<").append(elementName).append(" xmlns=\"").append(namespace).append("\">");
|
||||
for (Iterator i=getNames(); i.hasNext(); ) {
|
||||
String name = (String)i.next();
|
||||
String value = getValue(name);
|
||||
buf.append("<").append(name).append(">");
|
||||
buf.append(value);
|
||||
buf.append("</").append(name).append(">");
|
||||
}
|
||||
buf.append("</").append(elementName).append(">");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for the names that can be used to get
|
||||
* values of the private data.
|
||||
*
|
||||
* @return an Iterator for the names.
|
||||
*/
|
||||
public synchronized Iterator getNames() {
|
||||
if (map == null) {
|
||||
return Collections.EMPTY_LIST.iterator();
|
||||
}
|
||||
return Collections.unmodifiableMap(new HashMap(map)).keySet().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value given a name.
|
||||
*
|
||||
* @param name the name.
|
||||
* @return the value.
|
||||
*/
|
||||
public synchronized String getValue(String name) {
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
return (String)map.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value given the name.
|
||||
*
|
||||
* @param name the name.
|
||||
* @param value the value.
|
||||
*/
|
||||
public synchronized void setValue(String name, String value) {
|
||||
if (map == null) {
|
||||
map = new HashMap();
|
||||
}
|
||||
map.put(name, value);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
|
||||
/**
|
||||
* Represents timestamp information about data stored for later delivery. A DelayInformation will
|
||||
* always includes the timestamp when the packet was originally sent and may include more
|
||||
* information such as the JID of the entity that originally sent the packet as well as the reason
|
||||
* for the dealy.<p>
|
||||
*
|
||||
* For more information see <a href="http://www.jabber.org/jeps/jep-0091.html">JEP-91</a>.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class DelayInformation implements PacketExtension {
|
||||
|
||||
public static SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
|
||||
/**
|
||||
* New date format based on JEP-82 that some clients may use when sending delayed dates.
|
||||
* JEP-91 is using a SHOULD other servers or clients may be using this format instead of the
|
||||
* old UTC format.
|
||||
*/
|
||||
public static SimpleDateFormat NEW_UTC_FORMAT =
|
||||
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
|
||||
|
||||
static {
|
||||
UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
|
||||
NEW_UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
}
|
||||
|
||||
private Date stamp;
|
||||
private String from;
|
||||
private String reason;
|
||||
|
||||
/**
|
||||
* Creates a new instance with the specified timestamp.
|
||||
*/
|
||||
public DelayInformation(Date stamp) {
|
||||
super();
|
||||
this.stamp = stamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the JID of the entity that originally sent the packet or that delayed the
|
||||
* delivery of the packet or <tt>null</tt> if this information is not available.
|
||||
*
|
||||
* @return the JID of the entity that originally sent the packet or that delayed the
|
||||
* delivery of the packet.
|
||||
*/
|
||||
public String getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the JID of the entity that originally sent the packet or that delayed the
|
||||
* delivery of the packet or <tt>null</tt> if this information is not available.
|
||||
*
|
||||
* @param from the JID of the entity that originally sent the packet.
|
||||
*/
|
||||
public void setFrom(String from) {
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the timstamp when the packet was originally sent. The returned Date is
|
||||
* be understood as UTC.
|
||||
*
|
||||
* @return the timstamp when the packet was originally sent.
|
||||
*/
|
||||
public Date getStamp() {
|
||||
return stamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a natural-language description of the reason for the delay or <tt>null</tt> if
|
||||
* this information is not available.
|
||||
*
|
||||
* @return a natural-language description of the reason for the delay or <tt>null</tt>.
|
||||
*/
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a natural-language description of the reason for the delay or <tt>null</tt> if
|
||||
* this information is not available.
|
||||
*
|
||||
* @param reason a natural-language description of the reason for the delay or <tt>null</tt>.
|
||||
*/
|
||||
public void setReason(String reason) {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public String getElementName() {
|
||||
return "x";
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return "jabber:x:delay";
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
|
||||
"\"");
|
||||
buf.append(" stamp=\"").append(UTC_FORMAT.format(stamp)).append("\"");
|
||||
if (from != null && from.length() > 0) {
|
||||
buf.append(" from=\"").append(from).append("\"");
|
||||
}
|
||||
buf.append(">");
|
||||
if (reason != null && reason.length() > 0) {
|
||||
buf.append(reason);
|
||||
}
|
||||
buf.append("</").append(getElementName()).append(">");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,268 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
||||
/**
|
||||
* A DiscoverInfo IQ packet, which is used by XMPP clients to request and receive information
|
||||
* to/from other XMPP entities.<p>
|
||||
*
|
||||
* The received information may contain one or more identities of the requested XMPP entity, and
|
||||
* a list of supported features by the requested XMPP entity.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class DiscoverInfo extends IQ {
|
||||
|
||||
private List features = new ArrayList();
|
||||
private List identities = new ArrayList();
|
||||
private String node;
|
||||
|
||||
/**
|
||||
* Adds a new feature to the discovered information.
|
||||
*
|
||||
* @param feature the discovered feature
|
||||
*/
|
||||
public void addFeature(String feature) {
|
||||
addFeature(new DiscoverInfo.Feature(feature));
|
||||
}
|
||||
|
||||
private void addFeature(Feature feature) {
|
||||
synchronized (features) {
|
||||
features.add(feature);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the discovered features of an XMPP entity.
|
||||
*
|
||||
* @return an Iterator on the discovered features of an XMPP entity
|
||||
*/
|
||||
Iterator getFeatures() {
|
||||
synchronized (features) {
|
||||
return Collections.unmodifiableList(new ArrayList(features)).iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new identity of the requested entity to the discovered information.
|
||||
*
|
||||
* @param identity the discovered entity's identity
|
||||
*/
|
||||
public void addIdentity(Identity identity) {
|
||||
synchronized (identities) {
|
||||
identities.add(identity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the discovered identities of an XMPP entity.
|
||||
*
|
||||
* @return an Iterator on the discoveted identities
|
||||
*/
|
||||
public Iterator getIdentities() {
|
||||
synchronized (identities) {
|
||||
return Collections.unmodifiableList(new ArrayList(identities)).iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node attribute that supplements the 'jid' attribute. A node is merely
|
||||
* something that is associated with a JID and for which the JID can provide information.<p>
|
||||
*
|
||||
* Node attributes SHOULD be used only when trying to provide or query information which
|
||||
* is not directly addressable.
|
||||
*
|
||||
* @return the node attribute that supplements the 'jid' attribute
|
||||
*/
|
||||
public String getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the node attribute that supplements the 'jid' attribute. A node is merely
|
||||
* something that is associated with a JID and for which the JID can provide information.<p>
|
||||
*
|
||||
* Node attributes SHOULD be used only when trying to provide or query information which
|
||||
* is not directly addressable.
|
||||
*
|
||||
* @param node the node attribute that supplements the 'jid' attribute
|
||||
*/
|
||||
public void setNode(String node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified feature is part of the discovered information.
|
||||
*
|
||||
* @param feature the feature to check
|
||||
* @return true if the requestes feature has been discovered
|
||||
*/
|
||||
public boolean containsFeature(String feature) {
|
||||
for (Iterator it = getFeatures(); it.hasNext();) {
|
||||
if (feature.equals(((DiscoverInfo.Feature) it.next()).getVar()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getChildElementXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<query xmlns=\"http://jabber.org/protocol/disco#info\"");
|
||||
if (getNode() != null) {
|
||||
buf.append(" node=\"");
|
||||
buf.append(getNode());
|
||||
buf.append("\"");
|
||||
}
|
||||
buf.append(">");
|
||||
synchronized (identities) {
|
||||
for (int i = 0; i < identities.size(); i++) {
|
||||
Identity identity = (Identity) identities.get(i);
|
||||
buf.append(identity.toXML());
|
||||
}
|
||||
}
|
||||
synchronized (features) {
|
||||
for (int i = 0; i < features.size(); i++) {
|
||||
Feature feature = (Feature) features.get(i);
|
||||
buf.append(feature.toXML());
|
||||
}
|
||||
}
|
||||
// Add packet extensions, if any are defined.
|
||||
buf.append(getExtensionsXML());
|
||||
buf.append("</query>");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the identity of a given XMPP entity. An entity may have many identities but all
|
||||
* the identities SHOULD have the same name.<p>
|
||||
*
|
||||
* Refer to <a href="http://www.jabber.org/registrar/disco-categories.html">Jabber::Registrar</a>
|
||||
* in order to get the official registry of values for the <i>category</i> and <i>type</i>
|
||||
* attributes.
|
||||
*
|
||||
*/
|
||||
public static class Identity {
|
||||
|
||||
private String category;
|
||||
private String name;
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* Creates a new identity for an XMPP entity.
|
||||
*
|
||||
* @param category the entity's category.
|
||||
* @param name the entity's name.
|
||||
*/
|
||||
public Identity(String category, String name) {
|
||||
this.category = category;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entity's category. To get the official registry of values for the
|
||||
* 'category' attribute refer to <a href="http://www.jabber.org/registrar/disco-categories.html">Jabber::Registrar</a>
|
||||
*
|
||||
* @return the entity's category.
|
||||
*/
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identity's name.
|
||||
*
|
||||
* @return the identity's name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entity's type. To get the official registry of values for the
|
||||
* 'type' attribute refer to <a href="http://www.jabber.org/registrar/disco-categories.html">Jabber::Registrar</a>
|
||||
*
|
||||
* @return the entity's type.
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entity's type. To get the official registry of values for the
|
||||
* 'type' attribute refer to <a href="http://www.jabber.org/registrar/disco-categories.html">Jabber::Registrar</a>
|
||||
*
|
||||
* @param type the identity's type.
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<identity category=\"").append(category).append("\"");
|
||||
buf.append(" name=\"").append(name).append("\"");
|
||||
if (type != null) {
|
||||
buf.append(" type=\"").append(type).append("\"");
|
||||
}
|
||||
buf.append("/>");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the features offered by the item. This information helps requestors determine
|
||||
* what actions are possible with regard to this item (registration, search, join, etc.)
|
||||
* as well as specific feature types of interest, if any (e.g., for the purpose of feature
|
||||
* negotiation).
|
||||
*/
|
||||
public static class Feature {
|
||||
|
||||
private String variable;
|
||||
|
||||
/**
|
||||
* Creates a new feature offered by an XMPP entity or item.
|
||||
*
|
||||
* @param variable the feature's variable.
|
||||
*/
|
||||
public Feature(String variable) {
|
||||
this.variable = variable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the feature's variable.
|
||||
*
|
||||
* @return the feature's variable.
|
||||
*/
|
||||
public String getVar() {
|
||||
return variable;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<feature var=\"").append(variable).append("\"/>");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,235 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
||||
/**
|
||||
* A DiscoverItems IQ packet, which is used by XMPP clients to request and receive items
|
||||
* associated with XMPP entities.<p>
|
||||
*
|
||||
* The items could also be queried in order to discover if they contain items inside. Some items
|
||||
* may be addressable by its JID and others may require to be addressed by a JID and a node name.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class DiscoverItems extends IQ {
|
||||
|
||||
private List items = new ArrayList();
|
||||
private String node;
|
||||
|
||||
/**
|
||||
* Adds a new item to the discovered information.
|
||||
*
|
||||
* @param item the discovered entity's item
|
||||
*/
|
||||
public void addItem(Item item) {
|
||||
synchronized (items) {
|
||||
items.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the discovered items of the queried XMPP entity.
|
||||
*
|
||||
* @return an Iterator on the discovered entity's items
|
||||
*/
|
||||
public Iterator getItems() {
|
||||
synchronized (items) {
|
||||
return Collections.unmodifiableList(new ArrayList(items)).iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node attribute that supplements the 'jid' attribute. A node is merely
|
||||
* something that is associated with a JID and for which the JID can provide information.<p>
|
||||
*
|
||||
* Node attributes SHOULD be used only when trying to provide or query information which
|
||||
* is not directly addressable.
|
||||
*
|
||||
* @return the node attribute that supplements the 'jid' attribute
|
||||
*/
|
||||
public String getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the node attribute that supplements the 'jid' attribute. A node is merely
|
||||
* something that is associated with a JID and for which the JID can provide information.<p>
|
||||
*
|
||||
* Node attributes SHOULD be used only when trying to provide or query information which
|
||||
* is not directly addressable.
|
||||
*
|
||||
* @param node the node attribute that supplements the 'jid' attribute
|
||||
*/
|
||||
public void setNode(String node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public String getChildElementXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<query xmlns=\"http://jabber.org/protocol/disco#items\"");
|
||||
if (getNode() != null) {
|
||||
buf.append(" node=\"");
|
||||
buf.append(getNode());
|
||||
buf.append("\"");
|
||||
}
|
||||
buf.append(">");
|
||||
synchronized (items) {
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
Item item = (Item) items.get(i);
|
||||
buf.append(item.toXML());
|
||||
}
|
||||
}
|
||||
buf.append("</query>");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* An item is associated with an XMPP Entity, usually thought of a children of the parent
|
||||
* entity and normally are addressable as a JID.<p>
|
||||
*
|
||||
* An item associated with an entity may not be addressable as a JID. In order to handle
|
||||
* such items, Service Discovery uses an optional 'node' attribute that supplements the
|
||||
* 'jid' attribute.
|
||||
*/
|
||||
public static class Item {
|
||||
|
||||
/**
|
||||
* Request to create or update the item.
|
||||
*/
|
||||
public static final String UPDATE_ACTION = "update";
|
||||
|
||||
/**
|
||||
* Request to remove the item.
|
||||
*/
|
||||
public static final String REMOVE_ACTION = "remove";
|
||||
|
||||
private String entityID;
|
||||
private String name;
|
||||
private String node;
|
||||
private String action;
|
||||
|
||||
/**
|
||||
* Create a new Item associated with a given entity.
|
||||
*
|
||||
* @param entityID the id of the entity that contains the item
|
||||
*/
|
||||
public Item(String entityID) {
|
||||
this.entityID = entityID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entity's ID.
|
||||
*
|
||||
* @return the entity's ID.
|
||||
*/
|
||||
public String getEntityID() {
|
||||
return entityID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entity's name.
|
||||
*
|
||||
* @return the entity's name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entity's name.
|
||||
*
|
||||
* @param name the entity's name.
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node attribute that supplements the 'jid' attribute. A node is merely
|
||||
* something that is associated with a JID and for which the JID can provide information.<p>
|
||||
*
|
||||
* Node attributes SHOULD be used only when trying to provide or query information which
|
||||
* is not directly addressable.
|
||||
*
|
||||
* @return the node attribute that supplements the 'jid' attribute
|
||||
*/
|
||||
public String getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the node attribute that supplements the 'jid' attribute. A node is merely
|
||||
* something that is associated with a JID and for which the JID can provide information.<p>
|
||||
*
|
||||
* Node attributes SHOULD be used only when trying to provide or query information which
|
||||
* is not directly addressable.
|
||||
*
|
||||
* @param node the node attribute that supplements the 'jid' attribute
|
||||
*/
|
||||
public void setNode(String node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the action that specifies the action being taken for this item. Possible action
|
||||
* values are: "update" and "remove". Update should either create a new entry if the node
|
||||
* and jid combination does not already exist, or simply update an existing entry. If
|
||||
* "remove" is used as the action, the item should be removed from persistent storage.
|
||||
*
|
||||
* @return the action being taken for this item
|
||||
*/
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the action that specifies the action being taken for this item. Possible action
|
||||
* values are: "update" and "remove". Update should either create a new entry if the node
|
||||
* and jid combination does not already exist, or simply update an existing entry. If
|
||||
* "remove" is used as the action, the item should be removed from persistent storage.
|
||||
*
|
||||
* @param action the action being taken for this item
|
||||
*/
|
||||
public void setAction(String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<item jid=\"").append(entityID).append("\"");
|
||||
if (name != null) {
|
||||
buf.append(" name=\"").append(name).append("\"");
|
||||
}
|
||||
if (node != null) {
|
||||
buf.append(" node=\"").append(node).append("\"");
|
||||
}
|
||||
if (action != null) {
|
||||
buf.append(" action=\"").append(action).append("\"");
|
||||
}
|
||||
buf.append("/>");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,234 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
import java.util.*;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
||||
/**
|
||||
* IQ packet that serves for kicking users, granting and revoking voice, banning users,
|
||||
* modifying the ban list, granting and revoking membership and granting and revoking
|
||||
* moderator privileges. All these operations are scoped by the
|
||||
* 'http://jabber.org/protocol/muc#admin' namespace.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class MUCAdmin extends IQ {
|
||||
|
||||
private List items = new ArrayList();
|
||||
|
||||
/**
|
||||
* Returns an Iterator for item childs that holds information about roles, affiliation,
|
||||
* jids and nicks.
|
||||
*
|
||||
* @return an Iterator for item childs that holds information about roles, affiliation,
|
||||
* jids and nicks.
|
||||
*/
|
||||
public Iterator getItems() {
|
||||
synchronized (items) {
|
||||
return Collections.unmodifiableList(new ArrayList(items)).iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item child that holds information about roles, affiliation, jids and nicks.
|
||||
*
|
||||
* @param item the item child that holds information about roles, affiliation, jids and nicks.
|
||||
*/
|
||||
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#admin\">");
|
||||
synchronized (items) {
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
Item item = (Item) items.get(i);
|
||||
buf.append(item.toXML());
|
||||
}
|
||||
}
|
||||
// Add packet extensions, if any are defined.
|
||||
buf.append(getExtensionsXML());
|
||||
buf.append("</query>");
|
||||
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();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -1,223 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
|
||||
/**
|
||||
* Represents extended presence information whose sole purpose is to signal the ability of
|
||||
* the occupant to speak the MUC protocol when joining a room. If the room requires a password
|
||||
* then the MUCInitialPresence should include one.<p>
|
||||
*
|
||||
* The amount of discussion history provided on entering a room (perhaps because the
|
||||
* user is on a low-bandwidth connection or is using a small-footprint client) could be managed by
|
||||
* setting a configured History instance to the MUCInitialPresence instance.
|
||||
* @see MUCInitialPresence#setHistory(MUCInitialPresence.History).
|
||||
*
|
||||
* @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("</password>");
|
||||
}
|
||||
if (getHistory() != null) {
|
||||
buf.append(getHistory().toXML());
|
||||
}
|
||||
buf.append("</").append(getElementName()).append(">");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the history that manages the amount of discussion history provided on
|
||||
* entering a room.
|
||||
*
|
||||
* @return the history that manages the amount of discussion history provided on
|
||||
* entering a room.
|
||||
*/
|
||||
public History getHistory() {
|
||||
return history;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password to use when the room requires a password.
|
||||
*
|
||||
* @return the password to use when the room requires a password.
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the History that manages the amount of discussion history provided on
|
||||
* entering a room.
|
||||
*
|
||||
* @param history that manages the amount of discussion history provided on
|
||||
* entering a room.
|
||||
*/
|
||||
public void setHistory(History history) {
|
||||
this.history = history;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the password to use when the room requires a password.
|
||||
*
|
||||
* @param password the password to use when the room requires a password.
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* The History class controls the number of characters or messages to receive
|
||||
* when entering a room.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public static class History {
|
||||
|
||||
private int maxChars = -1;
|
||||
private int maxStanzas = -1;
|
||||
private int seconds = -1;
|
||||
private Date since;
|
||||
|
||||
/**
|
||||
* Returns the total number of characters to receive in the history.
|
||||
*
|
||||
* @return total number of characters to receive in the history.
|
||||
*/
|
||||
public int getMaxChars() {
|
||||
return maxChars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of messages to receive in the history.
|
||||
*
|
||||
* @return the total number of messages to receive in the history.
|
||||
*/
|
||||
public int getMaxStanzas() {
|
||||
return maxStanzas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of seconds to use to filter the messages received during that time.
|
||||
* In other words, only the messages received in the last "X" seconds will be included in
|
||||
* the history.
|
||||
*
|
||||
* @return the number of seconds to use to filter the messages received during that time.
|
||||
*/
|
||||
public int getSeconds() {
|
||||
return seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the since date to use to filter the messages received during that time.
|
||||
* In other words, only the messages received since the datetime specified will be
|
||||
* included in the history.
|
||||
*
|
||||
* @return the since date to use to filter the messages received during that time.
|
||||
*/
|
||||
public Date getSince() {
|
||||
return since;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the total number of characters to receive in the history.
|
||||
*
|
||||
* @param maxChars the total number of characters to receive in the history.
|
||||
*/
|
||||
public void setMaxChars(int maxChars) {
|
||||
this.maxChars = maxChars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the total number of messages to receive in the history.
|
||||
*
|
||||
* @param maxStanzas the total number of messages to receive in the history.
|
||||
*/
|
||||
public void setMaxStanzas(int maxStanzas) {
|
||||
this.maxStanzas = maxStanzas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of seconds to use to filter the messages received during that time.
|
||||
* In other words, only the messages received in the last "X" seconds will be included in
|
||||
* the history.
|
||||
*
|
||||
* @param seconds the number of seconds to use to filter the messages received during
|
||||
* that time.
|
||||
*/
|
||||
public void setSeconds(int seconds) {
|
||||
this.seconds = seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the since date to use to filter the messages received during that time.
|
||||
* In other words, only the messages received since the datetime specified will be
|
||||
* included in the history.
|
||||
*
|
||||
* @param since the since date to use to filter the messages received during that time.
|
||||
*/
|
||||
public void setSince(Date since) {
|
||||
this.since = since;
|
||||
}
|
||||
|
||||
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("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
|
||||
utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
buf.append(" since=\"").append(utcFormat.format(getSince())).append("\"");
|
||||
}
|
||||
buf.append("/>");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,339 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
import java.util.*;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
||||
/**
|
||||
* IQ packet that serves for granting and revoking ownership privileges, granting
|
||||
* and revoking administrative privileges and destroying a room. All these operations
|
||||
* are scoped by the 'http://jabber.org/protocol/muc#owner' namespace.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class MUCOwner extends IQ {
|
||||
|
||||
private List items = new ArrayList();
|
||||
private Destroy destroy;
|
||||
|
||||
/**
|
||||
* Returns an Iterator for item childs that holds information about affiliation,
|
||||
* jids and nicks.
|
||||
*
|
||||
* @return an Iterator for item childs that holds information about affiliation,
|
||||
* jids and nicks.
|
||||
*/
|
||||
public Iterator getItems() {
|
||||
synchronized (items) {
|
||||
return Collections.unmodifiableList(new ArrayList(items)).iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a request to the server to destroy a room. The sender of the request
|
||||
* should be the room's owner. If the sender of the destroy request is not the room's owner
|
||||
* then the server will answer a "Forbidden" error.
|
||||
*
|
||||
* @return a request to the server to destroy a room.
|
||||
*/
|
||||
public Destroy getDestroy() {
|
||||
return destroy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a request to the server to destroy a room. The sender of the request
|
||||
* should be the room's owner. If the sender of the destroy request is not the room's owner
|
||||
* then the server will answer a "Forbidden" error.
|
||||
*
|
||||
* @param destroy the request to the server to destroy a room.
|
||||
*/
|
||||
public void setDestroy(Destroy destroy) {
|
||||
this.destroy = destroy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item child that holds information about affiliation, jids and nicks.
|
||||
*
|
||||
* @param item the item child that holds information about affiliation, jids and nicks.
|
||||
*/
|
||||
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 {
|
||||
|
||||
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
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets 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.
|
||||
*
|
||||
* @param role the new privilege level of an occupant within a room.
|
||||
*/
|
||||
public void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a request to the server to destroy a room. The sender of the request
|
||||
* should be the room's owner. If the sender of the destroy request is not the room's owner
|
||||
* then the server will answer a "Forbidden" error.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public static class Destroy {
|
||||
private String reason;
|
||||
private String jid;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the JID of an alternate location since the current room is being destroyed.
|
||||
*
|
||||
* @return the JID of an alternate location.
|
||||
*/
|
||||
public String getJid() {
|
||||
return jid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reason for the room destruction.
|
||||
*
|
||||
* @return the reason for the room destruction.
|
||||
*/
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the JID of an alternate location since the current room is being destroyed.
|
||||
*
|
||||
* @param jid the JID of an alternate location.
|
||||
*/
|
||||
public void setJid(String jid) {
|
||||
this.jid = jid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the reason for the room destruction.
|
||||
*
|
||||
* @param reason the reason for the room destruction.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,627 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.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 Invite invite;
|
||||
private Decline decline;
|
||||
private Item item;
|
||||
private String password;
|
||||
private Status status;
|
||||
private Destroy destroy;
|
||||
|
||||
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 (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());
|
||||
}
|
||||
if (getDestroy() != null) {
|
||||
buf.append(getDestroy().toXML());
|
||||
}
|
||||
buf.append("</").append(getElementName()).append(">");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 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.
|
||||
*
|
||||
* @return an invitation for another user to a room.
|
||||
*/
|
||||
public Invite getInvite() {
|
||||
return invite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 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.
|
||||
*
|
||||
* @return a rejection to an invitation from another user to a room.
|
||||
*/
|
||||
public Decline getDecline() {
|
||||
return decline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item child that holds information about roles, affiliation, jids and nicks.
|
||||
*
|
||||
* @return an item child that holds information about roles, affiliation, jids and nicks.
|
||||
*/
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password to use to enter Password-Protected Room. A Password-Protected Room is
|
||||
* a room that a user cannot enter without first providing the correct password.
|
||||
*
|
||||
* @return the password to use to enter Password-Protected Room.
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status which holds a code that assists in presenting notification messages.
|
||||
*
|
||||
* @return the status which holds a code that assists in presenting notification messages.
|
||||
*/
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the notification that the room has been destroyed. After a room has been destroyed,
|
||||
* the room occupants will receive a Presence packet of type 'unavailable' with the reason for
|
||||
* the room destruction if provided by the room owner.
|
||||
*
|
||||
* @return a notification that the room has been destroyed.
|
||||
*/
|
||||
public Destroy getDestroy() {
|
||||
return destroy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 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.
|
||||
*
|
||||
* @param invite the invitation for another user to a room.
|
||||
*/
|
||||
public void setInvite(Invite invite) {
|
||||
this.invite = invite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 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.
|
||||
*
|
||||
* @param decline the rejection to an invitation from another user to a room.
|
||||
*/
|
||||
public void setDecline(Decline decline) {
|
||||
this.decline = decline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the item child that holds information about roles, affiliation, jids and nicks.
|
||||
*
|
||||
* @param item the item child that holds information about roles, affiliation, jids and nicks.
|
||||
*/
|
||||
public void setItem(Item item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the password to use to enter Password-Protected Room. A Password-Protected Room is
|
||||
* a room that a user cannot enter without first providing the correct password.
|
||||
*
|
||||
* @param string the password to use to enter Password-Protected Room.
|
||||
*/
|
||||
public void setPassword(String string) {
|
||||
password = string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the status which holds a code that assists in presenting notification messages.
|
||||
*
|
||||
* @param status the status which holds a code that assists in presenting notification
|
||||
* messages.
|
||||
*/
|
||||
public void setStatus(Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the notification that the room has been destroyed. After a room has been destroyed,
|
||||
* the room occupants will receive a Presence packet of type 'unavailable' with the reason for
|
||||
* the room destruction if provided by the room owner.
|
||||
*
|
||||
* @param destroy the notification that the room has been destroyed.
|
||||
*/
|
||||
public void setDestroy(Destroy destroy) {
|
||||
this.destroy = destroy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Returns the bare JID of the inviter or, optionally, the room JID. (e.g.
|
||||
* 'crone1@shakespeare.lit/desktop').
|
||||
*
|
||||
* @return the room's occupant that sent the invitation.
|
||||
*/
|
||||
public String getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message explaining the invitation.
|
||||
*
|
||||
* @return the message explaining the invitation.
|
||||
*/
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bare JID of the invitee. (e.g. 'hecate@shakespeare.lit')
|
||||
*
|
||||
* @return the bare JID of the invitee.
|
||||
*/
|
||||
public String getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bare JID of the inviter or, optionally, the room JID. (e.g.
|
||||
* 'crone1@shakespeare.lit/desktop')
|
||||
*
|
||||
* @param from the bare JID of the inviter or, optionally, the room JID.
|
||||
*/
|
||||
public void setFrom(String from) {
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message explaining the invitation.
|
||||
*
|
||||
* @param reason the message explaining the invitation.
|
||||
*/
|
||||
public void setReason(String reason) {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bare JID of the invitee. (e.g. 'hecate@shakespeare.lit')
|
||||
*
|
||||
* @param to the bare JID of the invitee.
|
||||
*/
|
||||
public void setTo(String to) {
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Returns the bare JID of the invitee that rejected the invitation. (e.g.
|
||||
* 'crone1@shakespeare.lit/desktop').
|
||||
*
|
||||
* @return the bare JID of the invitee that rejected the invitation.
|
||||
*/
|
||||
public String getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message explaining why the invitation was rejected.
|
||||
*
|
||||
* @return the message explaining the reason for the rejection.
|
||||
*/
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bare JID of the inviter. (e.g. 'hecate@shakespeare.lit')
|
||||
*
|
||||
* @return the bare JID of the inviter.
|
||||
*/
|
||||
public String getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bare JID of the invitee that rejected the invitation. (e.g.
|
||||
* 'crone1@shakespeare.lit/desktop').
|
||||
*
|
||||
* @param from the bare JID of the invitee that rejected the invitation.
|
||||
*/
|
||||
public void setFrom(String from) {
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message explaining why the invitation was rejected.
|
||||
*
|
||||
* @param reason the message explaining the reason for the rejection.
|
||||
*/
|
||||
public void setReason(String reason) {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bare JID of the inviter. (e.g. 'hecate@shakespeare.lit')
|
||||
*
|
||||
* @param to the bare JID of the inviter.
|
||||
*/
|
||||
public void setTo(String to) {
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
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 == null ? "" : 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 == null ? "" : 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. The following link provides the
|
||||
* list of existing error codes (@link http://www.jabber.org/jeps/jep-0045.html#errorstatus).
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public static class Status {
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* Creates a new instance of Status with the specified code.
|
||||
*
|
||||
* @param code the code that uniquely identifies the reason of the error.
|
||||
*/
|
||||
public Status(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code that uniquely identifies the reason of the error. The code
|
||||
* assists in presenting notification messages.
|
||||
*
|
||||
* @return the code that uniquely identifies the reason of the error.
|
||||
*/
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<status code=\"").append(getCode()).append("\"/>");
|
||||
return buf.toString();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a notification that the room has been destroyed. After a room has been destroyed,
|
||||
* the room occupants will receive a Presence packet of type 'unavailable' with the reason for
|
||||
* the room destruction if provided by the room owner.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public static class Destroy {
|
||||
private String reason;
|
||||
private String jid;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the JID of an alternate location since the current room is being destroyed.
|
||||
*
|
||||
* @return the JID of an alternate location.
|
||||
*/
|
||||
public String getJid() {
|
||||
return jid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reason for the room destruction.
|
||||
*
|
||||
* @return the reason for the room destruction.
|
||||
*/
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the JID of an alternate location since the current room is being destroyed.
|
||||
*
|
||||
* @param jid the JID of an alternate location.
|
||||
*/
|
||||
public void setJid(String jid) {
|
||||
this.jid = jid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the reason for the room destruction.
|
||||
*
|
||||
* @param reason the reason for the room destruction.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,334 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
|
||||
/**
|
||||
* Represents message events relating to the delivery, display, composition and cancellation of
|
||||
* messages.<p>
|
||||
*
|
||||
* There are four message events currently defined in this namespace:
|
||||
* <ol>
|
||||
* <li>Offline<br>
|
||||
* Indicates that the message has been stored offline by the intended recipient's server. This
|
||||
* event is triggered only if the intended recipient's server supports offline storage, has that
|
||||
* support enabled, and the recipient is offline when the server receives the message for delivery.</li>
|
||||
*
|
||||
* <li>Delivered<br>
|
||||
* Indicates that the message has been delivered to the recipient. This signifies that the message
|
||||
* has reached the recipient's XMPP client, but does not necessarily mean that the message has
|
||||
* been displayed. This event is to be raised by the XMPP client.</li>
|
||||
*
|
||||
* <li>Displayed<br>
|
||||
* Once the message has been received by the recipient's XMPP client, it may be displayed to the
|
||||
* user. This event indicates that the message has been displayed, and is to be raised by the
|
||||
* XMPP client. Even if a message is displayed multiple times, this event should be raised only
|
||||
* once.</li>
|
||||
*
|
||||
* <li>Composing<br>
|
||||
* In threaded chat conversations, this indicates that the recipient is composing a reply to a
|
||||
* message. The event is to be raised by the recipient's XMPP client. A XMPP client is allowed
|
||||
* to raise this event multiple times in response to the same request, providing the original
|
||||
* event is cancelled first.</li>
|
||||
* </ol>
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class MessageEvent implements PacketExtension {
|
||||
|
||||
public static final String OFFLINE = "offline";
|
||||
public static final String COMPOSING = "composing";
|
||||
public static final String DISPLAYED = "displayed";
|
||||
public static final String DELIVERED = "delivered";
|
||||
public static final String CANCELLED = "cancelled";
|
||||
|
||||
private boolean offline = false;
|
||||
private boolean delivered = false;
|
||||
private boolean displayed = false;
|
||||
private boolean composing = false;
|
||||
private boolean cancelled = true;
|
||||
|
||||
private String packetID = null;
|
||||
|
||||
/**
|
||||
* Returns the XML element name of the extension sub-packet root element.
|
||||
* Always returns "x"
|
||||
*
|
||||
* @return the XML element name of the packet extension.
|
||||
*/
|
||||
public String getElementName() {
|
||||
return "x";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML namespace of the extension sub-packet root element.
|
||||
* According the specification the namespace is always "jabber:x:event"
|
||||
*
|
||||
* @return the XML namespace of the packet extension.
|
||||
*/
|
||||
public String getNamespace() {
|
||||
return "jabber:x:event";
|
||||
}
|
||||
|
||||
/**
|
||||
* When the message is a request returns if the sender of the message requests to be notified
|
||||
* when the receiver is composing a reply.
|
||||
* When the message is a notification returns if the receiver of the message is composing a
|
||||
* reply.
|
||||
*
|
||||
* @return true if the sender is requesting to be notified when composing or when notifying
|
||||
* that the receiver of the message is composing a reply
|
||||
*/
|
||||
public boolean isComposing() {
|
||||
return composing;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the message is a request returns if the sender of the message requests to be notified
|
||||
* when the message is delivered.
|
||||
* When the message is a notification returns if the message was delivered or not.
|
||||
*
|
||||
* @return true if the sender is requesting to be notified when delivered or when notifying
|
||||
* that the message was delivered
|
||||
*/
|
||||
public boolean isDelivered() {
|
||||
return delivered;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the message is a request returns if the sender of the message requests to be notified
|
||||
* when the message is displayed.
|
||||
* When the message is a notification returns if the message was displayed or not.
|
||||
*
|
||||
* @return true if the sender is requesting to be notified when displayed or when notifying
|
||||
* that the message was displayed
|
||||
*/
|
||||
public boolean isDisplayed() {
|
||||
return displayed;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the message is a request returns if the sender of the message requests to be notified
|
||||
* when the receiver of the message is offline.
|
||||
* When the message is a notification returns if the receiver of the message was offline.
|
||||
*
|
||||
* @return true if the sender is requesting to be notified when offline or when notifying
|
||||
* that the receiver of the message is offline
|
||||
*/
|
||||
public boolean isOffline() {
|
||||
return offline;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the message is a notification returns if the receiver of the message cancelled
|
||||
* composing a reply.
|
||||
*
|
||||
* @return true if the receiver of the message cancelled composing a reply
|
||||
*/
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique ID of the message that requested to be notified of the event.
|
||||
* The packet id is not used when the message is a request for notifications
|
||||
*
|
||||
* @return the message id that requested to be notified of the event.
|
||||
*/
|
||||
public String getPacketID() {
|
||||
return packetID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the types of events. The type of event could be:
|
||||
* "offline", "composing","delivered","displayed", "offline"
|
||||
*
|
||||
* @return an iterator over all the types of events of the MessageEvent.
|
||||
*/
|
||||
public Iterator getEventTypes() {
|
||||
ArrayList allEvents = new ArrayList();
|
||||
if (isDelivered()) {
|
||||
allEvents.add(MessageEvent.DELIVERED);
|
||||
}
|
||||
if (isCancelled()) {
|
||||
allEvents.add(MessageEvent.CANCELLED);
|
||||
}
|
||||
if (isComposing()) {
|
||||
allEvents.add(MessageEvent.COMPOSING);
|
||||
}
|
||||
if (isDisplayed()) {
|
||||
allEvents.add(MessageEvent.DISPLAYED);
|
||||
}
|
||||
if (isOffline()) {
|
||||
allEvents.add(MessageEvent.OFFLINE);
|
||||
}
|
||||
return allEvents.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* When the message is a request sets if the sender of the message requests to be notified
|
||||
* when the receiver is composing a reply.
|
||||
* When the message is a notification sets if the receiver of the message is composing a
|
||||
* reply.
|
||||
*
|
||||
* @param composing sets if the sender is requesting to be notified when composing or when
|
||||
* notifying that the receiver of the message is composing a reply
|
||||
*/
|
||||
public void setComposing(boolean composing) {
|
||||
this.composing = composing;
|
||||
setCancelled(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* When the message is a request sets if the sender of the message requests to be notified
|
||||
* when the message is delivered.
|
||||
* When the message is a notification sets if the message was delivered or not.
|
||||
*
|
||||
* @param delivered sets if the sender is requesting to be notified when delivered or when
|
||||
* notifying that the message was delivered
|
||||
*/
|
||||
public void setDelivered(boolean delivered) {
|
||||
this.delivered = delivered;
|
||||
setCancelled(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* When the message is a request sets if the sender of the message requests to be notified
|
||||
* when the message is displayed.
|
||||
* When the message is a notification sets if the message was displayed or not.
|
||||
*
|
||||
* @param displayed sets if the sender is requesting to be notified when displayed or when
|
||||
* notifying that the message was displayed
|
||||
*/
|
||||
public void setDisplayed(boolean displayed) {
|
||||
this.displayed = displayed;
|
||||
setCancelled(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* When the message is a request sets if the sender of the message requests to be notified
|
||||
* when the receiver of the message is offline.
|
||||
* When the message is a notification sets if the receiver of the message was offline.
|
||||
*
|
||||
* @param offline sets if the sender is requesting to be notified when offline or when
|
||||
* notifying that the receiver of the message is offline
|
||||
*/
|
||||
public void setOffline(boolean offline) {
|
||||
this.offline = offline;
|
||||
setCancelled(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* When the message is a notification sets if the receiver of the message cancelled
|
||||
* composing a reply.
|
||||
* The Cancelled event is never requested explicitly. It is requested implicitly when
|
||||
* requesting to be notified of the Composing event.
|
||||
*
|
||||
* @param cancelled sets if the receiver of the message cancelled composing a reply
|
||||
*/
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the unique ID of the message that requested to be notified of the event.
|
||||
* The packet id is not used when the message is a request for notifications
|
||||
*
|
||||
* @param packetID the message id that requested to be notified of the event.
|
||||
*/
|
||||
public void setPacketID(String packetID) {
|
||||
this.packetID = packetID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this MessageEvent is a request for notifications.
|
||||
* Returns false if this MessageEvent is a notification of an event.
|
||||
*
|
||||
* @return true if this message is a request for notifications.
|
||||
*/
|
||||
public boolean isMessageEventRequest() {
|
||||
return this.packetID == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML representation of a Message Event according the specification.
|
||||
*
|
||||
* Usually the XML representation will be inside of a Message XML representation like
|
||||
* in the following examples:<p>
|
||||
*
|
||||
* Request to be notified when displayed:
|
||||
* <pre>
|
||||
* <message
|
||||
* to='romeo@montague.net/orchard'
|
||||
* from='juliet@capulet.com/balcony'
|
||||
* id='message22'>
|
||||
* <x xmlns='jabber:x:event'>
|
||||
* <displayed/>
|
||||
* </x>
|
||||
* </message>
|
||||
* </pre>
|
||||
*
|
||||
* Notification of displayed:
|
||||
* <pre>
|
||||
* <message
|
||||
* from='romeo@montague.net/orchard'
|
||||
* to='juliet@capulet.com/balcony'>
|
||||
* <x xmlns='jabber:x:event'>
|
||||
* <displayed/>
|
||||
* <id>message22</id>
|
||||
* </x>
|
||||
* </message>
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public String toXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
|
||||
"\">");
|
||||
// Note: Cancellation events don't specify any tag. They just send the packetID
|
||||
|
||||
// Add the offline tag if the sender requests to be notified of offline events or if
|
||||
// the target is offline
|
||||
if (isOffline())
|
||||
buf.append("<").append(MessageEvent.OFFLINE).append("/>");
|
||||
// Add the delivered tag if the sender requests to be notified when the message is
|
||||
// delivered or if the target notifies that the message has been delivered
|
||||
if (isDelivered())
|
||||
buf.append("<").append(MessageEvent.DELIVERED).append("/>");
|
||||
// Add the displayed tag if the sender requests to be notified when the message is
|
||||
// displayed or if the target notifies that the message has been displayed
|
||||
if (isDisplayed())
|
||||
buf.append("<").append(MessageEvent.DISPLAYED).append("/>");
|
||||
// Add the composing tag if the sender requests to be notified when the target is
|
||||
// composing a reply or if the target notifies that he/she is composing a reply
|
||||
if (isComposing())
|
||||
buf.append("<").append(MessageEvent.COMPOSING).append("/>");
|
||||
// Add the id tag only if the MessageEvent is a notification message (not a request)
|
||||
if (getPacketID() != null)
|
||||
buf.append("<id>").append(getPacketID()).append("</id>");
|
||||
buf.append("</").append(getElementName()).append(">");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* OfflineMessageInfo is an extension included in the retrieved offline messages requested by
|
||||
* the {@link org.jivesoftware.smackx.OfflineMessageManager}. This extension includes a stamp
|
||||
* that uniquely identifies the offline message. This stamp may be used for deleting the offline
|
||||
* message. The stamp may be of the form UTC timestamps but it is not required to have that format.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class OfflineMessageInfo implements PacketExtension {
|
||||
|
||||
private String node = null;
|
||||
|
||||
/**
|
||||
* Returns the XML element name of the extension sub-packet root element.
|
||||
* Always returns "offline"
|
||||
*
|
||||
* @return the XML element name of the packet extension.
|
||||
*/
|
||||
public String getElementName() {
|
||||
return "offline";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML namespace of the extension sub-packet root element.
|
||||
* According the specification the namespace is always "http://jabber.org/protocol/offline"
|
||||
*
|
||||
* @return the XML namespace of the packet extension.
|
||||
*/
|
||||
public String getNamespace() {
|
||||
return "http://jabber.org/protocol/offline";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stamp that uniquely identifies the offline message. This stamp may
|
||||
* be used for deleting the offline message. The stamp may be of the form UTC timestamps
|
||||
* but it is not required to have that format.
|
||||
*
|
||||
* @return the stamp that uniquely identifies the offline message.
|
||||
*/
|
||||
public String getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stamp that uniquely identifies the offline message. This stamp may
|
||||
* be used for deleting the offline message. The stamp may be of the form UTC timestamps
|
||||
* but it is not required to have that format.
|
||||
*
|
||||
* @param node the stamp that uniquely identifies the offline message.
|
||||
*/
|
||||
public void setNode(String node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
|
||||
"\">");
|
||||
if (getNode() != null)
|
||||
buf.append("<item node=\"").append(getNode()).append("\"/>");
|
||||
buf.append("</").append(getElementName()).append(">");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static class Provider implements PacketExtensionProvider {
|
||||
|
||||
/**
|
||||
* Creates a new Provider.
|
||||
* ProviderManager requires that every PacketExtensionProvider has a public,
|
||||
* no-argument constructor
|
||||
*/
|
||||
public Provider() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a OfflineMessageInfo 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 {
|
||||
OfflineMessageInfo info = new OfflineMessageInfo();
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("item"))
|
||||
info.setNode(parser.getAttributeValue("", "node"));
|
||||
} else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("offline")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,237 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a request to get some or all the offline messages of a user. This class can also
|
||||
* be used for deleting some or all the offline messages of a user.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class OfflineMessageRequest extends IQ {
|
||||
|
||||
private List items = new ArrayList();
|
||||
private boolean purge = false;
|
||||
private boolean fetch = false;
|
||||
|
||||
/**
|
||||
* Returns an Iterator for item childs that holds information about offline messages to
|
||||
* view or delete.
|
||||
*
|
||||
* @return an Iterator for item childs that holds information about offline messages to
|
||||
* view or delete.
|
||||
*/
|
||||
public Iterator getItems() {
|
||||
synchronized (items) {
|
||||
return Collections.unmodifiableList(new ArrayList(items)).iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item child that holds information about offline messages to view or delete.
|
||||
*
|
||||
* @param item the item child that holds information about offline messages to view or delete.
|
||||
*/
|
||||
public void addItem(Item item) {
|
||||
synchronized (items) {
|
||||
items.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if all the offline messages of the user should be deleted.
|
||||
*
|
||||
* @return true if all the offline messages of the user should be deleted.
|
||||
*/
|
||||
public boolean isPurge() {
|
||||
return purge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if all the offline messages of the user should be deleted.
|
||||
*
|
||||
* @param purge true if all the offline messages of the user should be deleted.
|
||||
*/
|
||||
public void setPurge(boolean purge) {
|
||||
this.purge = purge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if all the offline messages of the user should be retrieved.
|
||||
*
|
||||
* @return true if all the offline messages of the user should be retrieved.
|
||||
*/
|
||||
public boolean isFetch() {
|
||||
return fetch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if all the offline messages of the user should be retrieved.
|
||||
*
|
||||
* @param fetch true if all the offline messages of the user should be retrieved.
|
||||
*/
|
||||
public void setFetch(boolean fetch) {
|
||||
this.fetch = fetch;
|
||||
}
|
||||
|
||||
public String getChildElementXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<offline xmlns=\"http://jabber.org/protocol/offline\">");
|
||||
synchronized (items) {
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
Item item = (Item) items.get(i);
|
||||
buf.append(item.toXML());
|
||||
}
|
||||
}
|
||||
if (purge) {
|
||||
buf.append("<purge/>");
|
||||
}
|
||||
if (fetch) {
|
||||
buf.append("<fetch/>");
|
||||
}
|
||||
// Add packet extensions, if any are defined.
|
||||
buf.append(getExtensionsXML());
|
||||
buf.append("</offline>");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Item child that holds information about offline messages to view or delete.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public static class Item {
|
||||
private String action;
|
||||
private String jid;
|
||||
private String node;
|
||||
|
||||
/**
|
||||
* Creates a new item child.
|
||||
*
|
||||
* @param node the actor's affiliation to the room
|
||||
*/
|
||||
public Item(String node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public String getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns "view" or "remove" that indicate if the server should return the specified
|
||||
* offline message or delete it.
|
||||
*
|
||||
* @return "view" or "remove" that indicate if the server should return the specified
|
||||
* offline message or delete it.
|
||||
*/
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the server should return the specified offline message or delete it. Possible
|
||||
* values are "view" or "remove".
|
||||
*
|
||||
* @param action if the server should return the specified offline message or delete it.
|
||||
*/
|
||||
public void setAction(String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public String getJid() {
|
||||
return jid;
|
||||
}
|
||||
|
||||
public void setJid(String jid) {
|
||||
this.jid = jid;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<item");
|
||||
if (getAction() != null) {
|
||||
buf.append(" action=\"").append(getAction()).append("\"");
|
||||
}
|
||||
if (getJid() != null) {
|
||||
buf.append(" jid=\"").append(getJid()).append("\"");
|
||||
}
|
||||
if (getNode() != null) {
|
||||
buf.append(" node=\"").append(getNode()).append("\"");
|
||||
}
|
||||
buf.append("/>");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Provider implements IQProvider {
|
||||
|
||||
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||
OfflineMessageRequest request = new OfflineMessageRequest();
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("item")) {
|
||||
request.addItem(parseItem(parser));
|
||||
}
|
||||
else if (parser.getName().equals("purge")) {
|
||||
request.setPurge(true);
|
||||
}
|
||||
else if (parser.getName().equals("fetch")) {
|
||||
request.setFetch(true);
|
||||
}
|
||||
} else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("offline")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
private Item parseItem(XmlPullParser parser) throws Exception {
|
||||
boolean done = false;
|
||||
Item item = new Item(parser.getAttributeValue("", "node"));
|
||||
item.setAction(parser.getAttributeValue("", "action"));
|
||||
item.setJid(parser.getAttributeValue("", "jid"));
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("item")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
|
||||
/**
|
||||
* Interface to represent private data. Each private data chunk is an XML sub-document
|
||||
* with a root element name and namespace.
|
||||
*
|
||||
* @see org.jivesoftware.smackx.PrivateDataManager
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public interface PrivateData {
|
||||
|
||||
/**
|
||||
* Returns the root element name.
|
||||
*
|
||||
* @return the element name.
|
||||
*/
|
||||
public String getElementName();
|
||||
|
||||
/**
|
||||
* Returns the root element XML namespace.
|
||||
*
|
||||
* @return the namespace.
|
||||
*/
|
||||
public String getNamespace();
|
||||
|
||||
/**
|
||||
* Returns the XML reppresentation of the PrivateData.
|
||||
*
|
||||
* @return the private data as XML.
|
||||
*/
|
||||
public String toXML();
|
||||
}
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jivesoftware.smack.*;
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.jivesoftware.smackx.*;
|
||||
|
||||
/**
|
||||
* Represents XMPP Roster Item Exchange packets.<p>
|
||||
*
|
||||
* The 'jabber:x:roster' namespace (which is not to be confused with the 'jabber:iq:roster'
|
||||
* namespace) is used to send roster items from one client to another. A roster item is sent by
|
||||
* adding to the <message/> element an <x/> child scoped by the 'jabber:x:roster' namespace. This
|
||||
* <x/> element may contain one or more <item/> children (one for each roster item to be sent).<p>
|
||||
*
|
||||
* Each <item/> element may possess the following attributes:<p>
|
||||
*
|
||||
* <jid/> -- The id of the contact being sent. This attribute is required.<br>
|
||||
* <name/> -- A natural-language nickname for the contact. This attribute is optional.<p>
|
||||
*
|
||||
* Each <item/> element may also contain one or more <group/> children specifying the
|
||||
* natural-language name of a user-specified group, for the purpose of categorizing this contact
|
||||
* into one or more roster groups.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class RosterExchange implements PacketExtension {
|
||||
|
||||
private List remoteRosterEntries = new ArrayList();
|
||||
|
||||
/**
|
||||
* Creates a new empty roster exchange package.
|
||||
*
|
||||
*/
|
||||
public RosterExchange() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new roster exchange package with the entries specified in roster.
|
||||
*
|
||||
* @param roster the roster to send to other XMPP entity.
|
||||
*/
|
||||
public RosterExchange(Roster roster) {
|
||||
// Add all the roster entries to the new RosterExchange
|
||||
for (Iterator rosterEntries = roster.getEntries(); rosterEntries.hasNext();) {
|
||||
this.addRosterEntry((RosterEntry) rosterEntries.next());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a roster entry to the packet.
|
||||
*
|
||||
* @param rosterEntry a roster entry to add.
|
||||
*/
|
||||
public void addRosterEntry(RosterEntry rosterEntry) {
|
||||
// Obtain a String[] from the roster entry groups name
|
||||
ArrayList groupNamesList = new ArrayList();
|
||||
String[] groupNames;
|
||||
for (Iterator groups = rosterEntry.getGroups(); groups.hasNext();) {
|
||||
groupNamesList.add(((RosterGroup) groups.next()).getName());
|
||||
}
|
||||
groupNames = (String[]) groupNamesList.toArray(new String[groupNamesList.size()]);
|
||||
|
||||
// Create a new Entry based on the rosterEntry and add it to the packet
|
||||
RemoteRosterEntry remoteRosterEntry = new RemoteRosterEntry(rosterEntry.getUser(), rosterEntry.getName(), groupNames);
|
||||
|
||||
addRosterEntry(remoteRosterEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a remote roster entry to the packet.
|
||||
*
|
||||
* @param remoteRosterEntry a remote roster entry to add.
|
||||
*/
|
||||
public void addRosterEntry(RemoteRosterEntry remoteRosterEntry) {
|
||||
synchronized (remoteRosterEntries) {
|
||||
remoteRosterEntries.add(remoteRosterEntry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML element name of the extension sub-packet root element.
|
||||
* Always returns "x"
|
||||
*
|
||||
* @return the XML element name of the packet extension.
|
||||
*/
|
||||
public String getElementName() {
|
||||
return "x";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML namespace of the extension sub-packet root element.
|
||||
* According the specification the namespace is always "jabber:x:roster"
|
||||
* (which is not to be confused with the 'jabber:iq:roster' namespace
|
||||
*
|
||||
* @return the XML namespace of the packet extension.
|
||||
*/
|
||||
public String getNamespace() {
|
||||
return "jabber:x:roster";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for the roster entries in the packet.
|
||||
*
|
||||
* @return an Iterator for the roster entries in the packet.
|
||||
*/
|
||||
public Iterator getRosterEntries() {
|
||||
synchronized (remoteRosterEntries) {
|
||||
List entries = Collections.unmodifiableList(new ArrayList(remoteRosterEntries));
|
||||
return entries.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a count of the entries in the roster exchange.
|
||||
*
|
||||
* @return the number of entries in the roster exchange.
|
||||
*/
|
||||
public int getEntryCount() {
|
||||
return remoteRosterEntries.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML representation of a Roster Item Exchange according the specification.
|
||||
*
|
||||
* Usually the XML representation will be inside of a Message XML representation like
|
||||
* in the following example:
|
||||
* <pre>
|
||||
* <message id="MlIpV-4" to="gato1@gato.home" from="gato3@gato.home/Smack">
|
||||
* <subject>Any subject you want</subject>
|
||||
* <body>This message contains roster items.</body>
|
||||
* <x xmlns="jabber:x:roster">
|
||||
* <item jid="gato1@gato.home"/>
|
||||
* <item jid="gato2@gato.home"/>
|
||||
* </x>
|
||||
* </message>
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public String toXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
|
||||
"\">");
|
||||
// Loop through all roster entries and append them to the string buffer
|
||||
for (Iterator i = getRosterEntries(); i.hasNext();) {
|
||||
RemoteRosterEntry remoteRosterEntry = (RemoteRosterEntry) i.next();
|
||||
buf.append(remoteRosterEntry.toXML());
|
||||
}
|
||||
buf.append("</").append(getElementName()).append(">");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,196 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
||||
import java.util.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.text.DateFormat;
|
||||
|
||||
/**
|
||||
* A Time IQ packet, which is used by XMPP clients to exchange their respective local
|
||||
* times. Clients that wish to fully support the entitity time protocol should register
|
||||
* a PacketListener for incoming time requests that then respond with the local time.
|
||||
* This class can be used to request the time from other clients, such as in the
|
||||
* following code snippet:
|
||||
*
|
||||
* <pre>
|
||||
* // Request the time from a remote user.
|
||||
* Time timeRequest = new Time();
|
||||
* timeRequest.setType(IQ.Type.GET);
|
||||
* timeRequest.setTo(someUser@example.com);
|
||||
*
|
||||
* // Create a packet collector to listen for a response.
|
||||
* PacketCollector collector = con.createPacketCollector(
|
||||
* new PacketIDFilter(timeRequest.getPacketID()));
|
||||
*
|
||||
* con.sendPacket(timeRequest);
|
||||
*
|
||||
* // Wait up to 5 seconds for a result.
|
||||
* IQ result = (IQ)collector.nextResult(5000);
|
||||
* if (result != null && result.getType() == IQ.Type.RESULT) {
|
||||
* Time timeResult = (Time)result;
|
||||
* // Do something with result...
|
||||
* }</pre><p>
|
||||
*
|
||||
* Warning: this is an non-standard protocol documented by
|
||||
* <a href="http://www.jabber.org/jeps/jep-0090.html">JEP-90</a>. Because this is a
|
||||
* non-standard protocol, it is subject to change.
|
||||
*
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public class Time extends IQ {
|
||||
|
||||
private static SimpleDateFormat utcFormat = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
|
||||
private static DateFormat displayFormat = DateFormat.getDateTimeInstance();
|
||||
|
||||
private String utc = null;
|
||||
private String tz = null;
|
||||
private String display = null;
|
||||
|
||||
/**
|
||||
* Creates a new Time instance with empty values for all fields.
|
||||
*/
|
||||
public Time() {
|
||||
this(Calendar.getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Time instance using the specified calendar instance as
|
||||
* the time value to send.
|
||||
*
|
||||
* @param cal the time value.
|
||||
*/
|
||||
public Time(Calendar cal) {
|
||||
TimeZone timeZone = cal.getTimeZone();
|
||||
tz = cal.getTimeZone().getID();
|
||||
display = displayFormat.format(cal.getTime());
|
||||
// Convert local time to the UTC time.
|
||||
utc = utcFormat.format(new Date(
|
||||
cal.getTimeInMillis() - timeZone.getOffset(cal.getTimeInMillis())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the local time or <tt>null</tt> if the time hasn't been set.
|
||||
*
|
||||
* @return the lcocal time.
|
||||
*/
|
||||
public Date getTime() {
|
||||
if (utc == null) {
|
||||
return null;
|
||||
}
|
||||
Date date = null;
|
||||
try {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
// Convert the UTC time to local time.
|
||||
cal.setTime(new Date(utcFormat.parse(utc).getTime() +
|
||||
cal.getTimeZone().getOffset(cal.getTimeInMillis())));
|
||||
date = cal.getTime();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time using the local time.
|
||||
*
|
||||
* @param time the current local time.
|
||||
*/
|
||||
public void setTime(Date time) {
|
||||
// Convert local time to UTC time.
|
||||
utc = utcFormat.format(new Date(
|
||||
time.getTime() - TimeZone.getDefault().getOffset(time.getTime())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time as a UTC formatted String using the format CCYYMMDDThh:mm:ss.
|
||||
*
|
||||
* @return the time as a UTC formatted String.
|
||||
*/
|
||||
public String getUtc() {
|
||||
return utc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time using UTC formatted String in the format CCYYMMDDThh:mm:ss.
|
||||
*
|
||||
* @param utc the time using a formatted String.
|
||||
*/
|
||||
public void setUtc(String utc) {
|
||||
this.utc = utc;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time zone.
|
||||
*
|
||||
* @return the time zone.
|
||||
*/
|
||||
public String getTz() {
|
||||
return tz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time zone.
|
||||
*
|
||||
* @param tz the time zone.
|
||||
*/
|
||||
public void setTz(String tz) {
|
||||
this.tz = tz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the local (non-utc) time in human-friendly format.
|
||||
*
|
||||
* @return the local time in human-friendly format.
|
||||
*/
|
||||
public String getDisplay() {
|
||||
return display;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the local time in human-friendly format.
|
||||
*
|
||||
* @param display the local time in human-friendly format.
|
||||
*/
|
||||
public void setDisplay(String display) {
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
public String getChildElementXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<query xmlns=\"jabber:iq:time\">");
|
||||
if (utc != null) {
|
||||
buf.append("<utc>").append(utc).append("</utc>");
|
||||
}
|
||||
if (tz != null) {
|
||||
buf.append("<tz>").append(tz).append("</tz>");
|
||||
}
|
||||
if (display != null) {
|
||||
buf.append("<display>").append(display).append("</display>");
|
||||
}
|
||||
buf.append("</query>");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,646 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
|
||||
import org.jivesoftware.smack.PacketCollector;
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.filter.PacketIDFilter;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.XMPPError;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A VCard class for use with the
|
||||
* <a href="http://www.jivesoftware.org/smack/" target="_blank">SMACK jabber library</a>.<p>
|
||||
*
|
||||
* You should refer to the
|
||||
* <a href="http://www.jabber.org/jeps/jep-0054.html" target="_blank">JEP-54 documentation</a>.<p>
|
||||
*
|
||||
* Please note that this class is incomplete but it does provide the most commonly found
|
||||
* information in vCards. Also remember that VCard transfer is not a standard, and the protocol
|
||||
* may change or be replaced.<p>
|
||||
*
|
||||
* <b>Usage:</b>
|
||||
* <pre>
|
||||
*
|
||||
* // To save VCard:
|
||||
*
|
||||
* VCard vCard = new VCard();
|
||||
* vCard.setFirstName("kir");
|
||||
* vCard.setLastName("max");
|
||||
* vCard.setEmailHome("foo@fee.bar");
|
||||
* vCard.setJabberId("jabber@id.org");
|
||||
* vCard.setOrganization("Jetbrains, s.r.o");
|
||||
* vCard.setNickName("KIR");
|
||||
*
|
||||
* vCard.setField("TITLE", "Mr");
|
||||
* vCard.setAddressFieldHome("STREET", "Some street");
|
||||
* vCard.setAddressFieldWork("CTRY", "US");
|
||||
* vCard.setPhoneWork("FAX", "3443233");
|
||||
*
|
||||
* vCard.save(connection);
|
||||
*
|
||||
* // To load VCard:
|
||||
*
|
||||
* VCard vCard = new VCard();
|
||||
* vCard.load(conn); // load own VCard
|
||||
* vCard.load(conn, "joe@foo.bar"); // load someone's VCard
|
||||
* </pre>
|
||||
*
|
||||
* @author Kirill Maximov (kir@maxkir.com)
|
||||
*/
|
||||
public class VCard extends IQ {
|
||||
|
||||
/**
|
||||
* Phone types:
|
||||
* VOICE?, FAX?, PAGER?, MSG?, CELL?, VIDEO?, BBS?, MODEM?, ISDN?, PCS?, PREF?
|
||||
*/
|
||||
private Map homePhones = new HashMap();
|
||||
private Map workPhones = new HashMap();
|
||||
|
||||
|
||||
/**
|
||||
* Address types:
|
||||
* POSTAL?, PARCEL?, (DOM | INTL)?, PREF?, POBOX?, EXTADR?, STREET?, LOCALITY?,
|
||||
* REGION?, PCODE?, CTRY?
|
||||
*/
|
||||
private Map homeAddr = new HashMap();
|
||||
private Map workAddr = new HashMap();
|
||||
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String middleName;
|
||||
|
||||
private String emailHome;
|
||||
private String emailWork;
|
||||
|
||||
private String organization;
|
||||
private String organizationUnit;
|
||||
|
||||
/**
|
||||
* Such as DESC ROLE GEO etc.. see JEP-0054
|
||||
*/
|
||||
private Map otherSimpleFields = new HashMap();
|
||||
|
||||
public VCard() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set generic VCard field.
|
||||
*
|
||||
* @param field value of field. Possible values: NICKNAME, PHOTO, BDAY, JABBERID, MAILER, TZ,
|
||||
* GEO, TITLE, ROLE, LOGO, NOTE, PRODID, REV, SORT-STRING, SOUND, UID, URL, DESC.
|
||||
*/
|
||||
public String getField(String field) {
|
||||
return (String) otherSimpleFields.get(field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set generic VCard field.
|
||||
*
|
||||
* @param value value of field
|
||||
* @param field field to set. See {@link #getField(String)}
|
||||
* @see #getField(String)
|
||||
*/
|
||||
public void setField(String field, String value) {
|
||||
otherSimpleFields.put(field, value);
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getMiddleName() {
|
||||
return middleName;
|
||||
}
|
||||
|
||||
public void setMiddleName(String middleName) {
|
||||
this.middleName = middleName;
|
||||
}
|
||||
|
||||
public String getNickName() {
|
||||
return (String) otherSimpleFields.get("NICKNAME");
|
||||
}
|
||||
|
||||
public void setNickName(String nickName) {
|
||||
otherSimpleFields.put("NICKNAME", nickName);
|
||||
}
|
||||
|
||||
public String getEmailHome() {
|
||||
return emailHome;
|
||||
}
|
||||
|
||||
public void setEmailHome(String email) {
|
||||
this.emailHome = email;
|
||||
}
|
||||
|
||||
public String getEmailWork() {
|
||||
return emailWork;
|
||||
}
|
||||
|
||||
public void setEmailWork(String emailWork) {
|
||||
this.emailWork = emailWork;
|
||||
}
|
||||
|
||||
public String getJabberId() {
|
||||
return (String) otherSimpleFields.get("JABBERID");
|
||||
}
|
||||
|
||||
public void setJabberId(String jabberId) {
|
||||
otherSimpleFields.put("JABBERID", jabberId);
|
||||
}
|
||||
|
||||
public String getOrganization() {
|
||||
return organization;
|
||||
}
|
||||
|
||||
public void setOrganization(String organization) {
|
||||
this.organization = organization;
|
||||
}
|
||||
|
||||
public String getOrganizationUnit() {
|
||||
return organizationUnit;
|
||||
}
|
||||
|
||||
public void setOrganizationUnit(String organizationUnit) {
|
||||
this.organizationUnit = organizationUnit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get home address field
|
||||
*
|
||||
* @param addrField one of POSTAL, PARCEL, (DOM | INTL), PREF, POBOX, EXTADR, STREET,
|
||||
* LOCALITY, REGION, PCODE, CTRY
|
||||
*/
|
||||
public String getAddressFieldHome(String addrField) {
|
||||
return (String) homeAddr.get(addrField);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set home address field
|
||||
*
|
||||
* @param addrField one of POSTAL, PARCEL, (DOM | INTL), PREF, POBOX, EXTADR, STREET,
|
||||
* LOCALITY, REGION, PCODE, CTRY
|
||||
*/
|
||||
public void setAddressFieldHome(String addrField, String value) {
|
||||
homeAddr.put(addrField, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get work address field
|
||||
*
|
||||
* @param addrField one of POSTAL, PARCEL, (DOM | INTL), PREF, POBOX, EXTADR, STREET,
|
||||
* LOCALITY, REGION, PCODE, CTRY
|
||||
*/
|
||||
public String getAddressFieldWork(String addrField) {
|
||||
return (String) workAddr.get(addrField);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set work address field
|
||||
*
|
||||
* @param addrField one of POSTAL, PARCEL, (DOM | INTL), PREF, POBOX, EXTADR, STREET,
|
||||
* LOCALITY, REGION, PCODE, CTRY
|
||||
*/
|
||||
public void setAddressFieldWork(String addrField, String value) {
|
||||
workAddr.put(addrField, value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set home phone number
|
||||
*
|
||||
* @param phoneType one of VOICE, FAX, PAGER, MSG, CELL, VIDEO, BBS, MODEM, ISDN, PCS, PREF
|
||||
* @param phoneNum phone number
|
||||
*/
|
||||
public void setPhoneHome(String phoneType, String phoneNum) {
|
||||
homePhones.put(phoneType, phoneNum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get home phone number
|
||||
*
|
||||
* @param phoneType one of VOICE, FAX, PAGER, MSG, CELL, VIDEO, BBS, MODEM, ISDN, PCS, PREF
|
||||
*/
|
||||
public String getPhoneHome(String phoneType) {
|
||||
return (String) homePhones.get(phoneType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set work phone number
|
||||
*
|
||||
* @param phoneType one of VOICE, FAX, PAGER, MSG, CELL, VIDEO, BBS, MODEM, ISDN, PCS, PREF
|
||||
* @param phoneNum phone number
|
||||
*/
|
||||
public void setPhoneWork(String phoneType, String phoneNum) {
|
||||
workPhones.put(phoneType, phoneNum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get work phone number
|
||||
*
|
||||
* @param phoneType one of VOICE, FAX, PAGER, MSG, CELL, VIDEO, BBS, MODEM, ISDN, PCS, PREF
|
||||
*/
|
||||
public String getPhoneWork(String phoneType) {
|
||||
return (String) workPhones.get(phoneType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save this vCard for the user connected by 'connection'. Connection should be authenticated
|
||||
* and not anonymous.<p>
|
||||
* <p/>
|
||||
* NOTE: the method is asynchronous and does not wait for the returned value.
|
||||
*/
|
||||
public void save(XMPPConnection connection) {
|
||||
checkAuthenticated(connection);
|
||||
|
||||
setType(IQ.Type.SET);
|
||||
setFrom(connection.getUser());
|
||||
connection.sendPacket(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load VCard information for a connected user. Connection should be authenticated
|
||||
* and not anonymous.
|
||||
*/
|
||||
public void load(XMPPConnection connection) throws XMPPException {
|
||||
checkAuthenticated(connection);
|
||||
|
||||
setFrom(connection.getUser());
|
||||
doLoad(connection, connection.getUser());
|
||||
}
|
||||
|
||||
/**
|
||||
* Load VCard information for a given user. Connection should be authenticated and not anonymous.
|
||||
*/
|
||||
public void load(XMPPConnection connection, String user) throws XMPPException {
|
||||
checkAuthenticated(connection);
|
||||
|
||||
setTo(user);
|
||||
doLoad(connection, user);
|
||||
}
|
||||
|
||||
private void doLoad(XMPPConnection connection, String user) throws XMPPException {
|
||||
setType(Type.GET);
|
||||
PacketCollector collector = connection.createPacketCollector(
|
||||
new PacketIDFilter(getPacketID()));
|
||||
connection.sendPacket(this);
|
||||
|
||||
VCard result = null;
|
||||
try {
|
||||
result = (VCard) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||
|
||||
if (result == null) {
|
||||
throw new XMPPException(new XMPPError(408, "Timeout getting VCard information"));
|
||||
}
|
||||
if (result.getError() != null) {
|
||||
throw new XMPPException(result.getError());
|
||||
}
|
||||
} catch (ClassCastException e) {
|
||||
System.out.println("No VCard for " + user);
|
||||
}
|
||||
|
||||
copyFieldsFrom(result);
|
||||
}
|
||||
|
||||
public String getChildElementXML() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
new VCardWriter(sb).write();
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void copyFieldsFrom(VCard result) {
|
||||
if (result == null) result = new VCard();
|
||||
|
||||
Field[] fields = VCard.class.getDeclaredFields();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
if (field.getDeclaringClass() == VCard.class &&
|
||||
!Modifier.isFinal(field.getModifiers())) {
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
field.set(this, field.get(result));
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("This cannot happen:" + field, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAuthenticated(XMPPConnection connection) {
|
||||
if (connection == null) {
|
||||
new IllegalArgumentException("No connection was provided");
|
||||
}
|
||||
if (!connection.isAuthenticated()) {
|
||||
new IllegalArgumentException("Connection is not authenticated");
|
||||
}
|
||||
if (connection.isAnonymous()) {
|
||||
new IllegalArgumentException("Connection cannot be anonymous");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasContent() {
|
||||
//noinspection OverlyComplexBooleanExpression
|
||||
return hasNameField()
|
||||
|| hasOrganizationFields()
|
||||
|| emailHome != null
|
||||
|| emailWork != null
|
||||
|| otherSimpleFields.size() > 0
|
||||
|| homeAddr.size() > 0
|
||||
|| homePhones.size() > 0
|
||||
|| workAddr.size() > 0
|
||||
|| workPhones.size() > 0
|
||||
;
|
||||
}
|
||||
|
||||
private boolean hasNameField() {
|
||||
return firstName != null || lastName != null || middleName != null;
|
||||
}
|
||||
|
||||
private boolean hasOrganizationFields() {
|
||||
return organization != null || organizationUnit != null;
|
||||
}
|
||||
|
||||
// Used in tests:
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final VCard vCard = (VCard) o;
|
||||
|
||||
if (emailHome != null ? !emailHome.equals(vCard.emailHome) : vCard.emailHome != null) {
|
||||
return false;
|
||||
}
|
||||
if (emailWork != null ? !emailWork.equals(vCard.emailWork) : vCard.emailWork != null) {
|
||||
return false;
|
||||
}
|
||||
if (firstName != null ? !firstName.equals(vCard.firstName) : vCard.firstName != null) {
|
||||
return false;
|
||||
}
|
||||
if (!homeAddr.equals(vCard.homeAddr)) {
|
||||
return false;
|
||||
}
|
||||
if (!homePhones.equals(vCard.homePhones)) {
|
||||
return false;
|
||||
}
|
||||
if (lastName != null ? !lastName.equals(vCard.lastName) : vCard.lastName != null) {
|
||||
return false;
|
||||
}
|
||||
if (middleName != null ? !middleName.equals(vCard.middleName) : vCard.middleName != null) {
|
||||
return false;
|
||||
}
|
||||
if (organization != null ?
|
||||
!organization.equals(vCard.organization) : vCard.organization != null) {
|
||||
return false;
|
||||
}
|
||||
if (organizationUnit != null ?
|
||||
!organizationUnit.equals(vCard.organizationUnit) : vCard.organizationUnit != null) {
|
||||
return false;
|
||||
}
|
||||
if (!otherSimpleFields.equals(vCard.otherSimpleFields)) {
|
||||
return false;
|
||||
}
|
||||
if (!workAddr.equals(vCard.workAddr)) {
|
||||
return false;
|
||||
}
|
||||
if (!workPhones.equals(vCard.workPhones)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result;
|
||||
result = homePhones.hashCode();
|
||||
result = 29 * result + workPhones.hashCode();
|
||||
result = 29 * result + homeAddr.hashCode();
|
||||
result = 29 * result + workAddr.hashCode();
|
||||
result = 29 * result + (firstName != null ? firstName.hashCode() : 0);
|
||||
result = 29 * result + (lastName != null ? lastName.hashCode() : 0);
|
||||
result = 29 * result + (middleName != null ? middleName.hashCode() : 0);
|
||||
result = 29 * result + (emailHome != null ? emailHome.hashCode() : 0);
|
||||
result = 29 * result + (emailWork != null ? emailWork.hashCode() : 0);
|
||||
result = 29 * result + (organization != null ? organization.hashCode() : 0);
|
||||
result = 29 * result + (organizationUnit != null ? organizationUnit.hashCode() : 0);
|
||||
result = 29 * result + otherSimpleFields.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getChildElementXML();
|
||||
}
|
||||
|
||||
//==============================================================
|
||||
|
||||
private class VCardWriter {
|
||||
private final StringBuffer sb;
|
||||
|
||||
VCardWriter(StringBuffer sb) {
|
||||
this.sb = sb;
|
||||
}
|
||||
|
||||
public void write() {
|
||||
appendTag("vCard", "xmlns", "vcard-temp", hasContent(), new ContentBuilder() {
|
||||
public void addTagContent() {
|
||||
buildActualContent();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void buildActualContent() {
|
||||
if (hasNameField()) {
|
||||
appendFN();
|
||||
appendN();
|
||||
}
|
||||
|
||||
appendOrganization();
|
||||
appendGenericFields();
|
||||
|
||||
appendEmail(emailWork, "WORK");
|
||||
appendEmail(emailHome, "HOME");
|
||||
|
||||
appendPhones(workPhones, "WORK");
|
||||
appendPhones(homePhones, "HOME");
|
||||
|
||||
appendAddress(workAddr, "WORK");
|
||||
appendAddress(homeAddr, "HOME");
|
||||
}
|
||||
|
||||
private void appendEmail(final String email, final String type) {
|
||||
if (email != null) {
|
||||
appendTag("EMAIL", true, new ContentBuilder() {
|
||||
public void addTagContent() {
|
||||
appendEmptyTag(type);
|
||||
appendEmptyTag("INTERNET");
|
||||
appendEmptyTag("PREF");
|
||||
appendTag("USERID", email);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void appendPhones(Map phones, final String code) {
|
||||
Iterator it = phones.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
final Map.Entry entry = (Map.Entry) it.next();
|
||||
appendTag("TEL", true, new ContentBuilder() {
|
||||
public void addTagContent() {
|
||||
appendEmptyTag(entry.getKey());
|
||||
appendEmptyTag(code);
|
||||
appendTag("NUMBER", (String) entry.getValue());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void appendAddress(final Map addr, final String code) {
|
||||
if (addr.size() > 0) {
|
||||
appendTag("ADR", true, new ContentBuilder() {
|
||||
public void addTagContent() {
|
||||
appendEmptyTag(code);
|
||||
|
||||
Iterator it = addr.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
final Map.Entry entry = (Map.Entry) it.next();
|
||||
appendTag((String) entry.getKey(), (String) entry.getValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void appendEmptyTag(Object tag) {
|
||||
sb.append('<').append(tag).append("/>");
|
||||
}
|
||||
|
||||
private void appendGenericFields() {
|
||||
Iterator it = otherSimpleFields.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry entry = (Map.Entry) it.next();
|
||||
appendTag(entry.getKey().toString(), (String) entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void appendOrganization() {
|
||||
if (hasOrganizationFields()) {
|
||||
appendTag("ORG", true, new ContentBuilder() {
|
||||
public void addTagContent() {
|
||||
appendTag("ORGNAME", organization);
|
||||
appendTag("ORGUNIT", organizationUnit);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void appendField(String tag) {
|
||||
String value = (String) otherSimpleFields.get(tag);
|
||||
appendTag(tag, value);
|
||||
}
|
||||
|
||||
private void appendFN() {
|
||||
final ContentBuilder contentBuilder = new ContentBuilder() {
|
||||
public void addTagContent() {
|
||||
if (firstName != null) {
|
||||
sb.append(firstName + ' ');
|
||||
}
|
||||
if (middleName != null) {
|
||||
sb.append(middleName + ' ');
|
||||
}
|
||||
if (lastName != null) {
|
||||
sb.append(lastName);
|
||||
}
|
||||
}
|
||||
};
|
||||
appendTag("FN", true, contentBuilder);
|
||||
}
|
||||
|
||||
private void appendN() {
|
||||
appendTag("N", true, new ContentBuilder() {
|
||||
public void addTagContent() {
|
||||
appendTag("FAMILY", lastName);
|
||||
appendTag("GIVEN", firstName);
|
||||
appendTag("MIDDLE", middleName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void appendTag(String tag, String attr, String attrValue, boolean hasContent,
|
||||
ContentBuilder builder) {
|
||||
sb.append('<').append(tag);
|
||||
if (attr != null) {
|
||||
sb.append(' ').append(attr).append('=').append('\'').append(attrValue).append('\'');
|
||||
}
|
||||
|
||||
if (hasContent) {
|
||||
sb.append('>');
|
||||
builder.addTagContent();
|
||||
sb.append("</").append(tag).append(">\n");
|
||||
} else {
|
||||
sb.append("/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
private void appendTag(String tag, boolean hasContent, ContentBuilder builder) {
|
||||
appendTag(tag, null, null, hasContent, builder);
|
||||
}
|
||||
|
||||
private void appendTag(String tag, final String tagText) {
|
||||
if (tagText == null) return;
|
||||
final ContentBuilder contentBuilder = new ContentBuilder() {
|
||||
public void addTagContent() {
|
||||
sb.append(tagText.trim());
|
||||
}
|
||||
};
|
||||
appendTag(tag, true, contentBuilder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//==============================================================
|
||||
|
||||
private interface ContentBuilder {
|
||||
void addTagContent();
|
||||
}
|
||||
|
||||
//==============================================================
|
||||
}
|
||||
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
||||
/**
|
||||
* A Version IQ packet, which is used by XMPP clients to discover version information
|
||||
* about the software running at another entity's JID.<p>
|
||||
*
|
||||
* An example to discover the version of the server:
|
||||
* <pre>
|
||||
* // Request the version from the server.
|
||||
* Version versionRequest = new Version();
|
||||
* timeRequest.setType(IQ.Type.GET);
|
||||
* timeRequest.setTo("example.com");
|
||||
*
|
||||
* // Create a packet collector to listen for a response.
|
||||
* PacketCollector collector = con.createPacketCollector(
|
||||
* new PacketIDFilter(versionRequest.getPacketID()));
|
||||
*
|
||||
* con.sendPacket(versionRequest);
|
||||
*
|
||||
* // Wait up to 5 seconds for a result.
|
||||
* IQ result = (IQ)collector.nextResult(5000);
|
||||
* if (result != null && result.getType() == IQ.Type.RESULT) {
|
||||
* Version versionResult = (Version)result;
|
||||
* // Do something with result...
|
||||
* }</pre><p>
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class Version extends IQ {
|
||||
|
||||
private String name;
|
||||
private String version;
|
||||
private String os;
|
||||
|
||||
/**
|
||||
* Returns the natural-language name of the software. This property will always be
|
||||
* present in a result.
|
||||
*
|
||||
* @return the natural-language name of the software.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the natural-language name of the software. This message should only be
|
||||
* invoked when parsing the XML and setting the property to a Version instance.
|
||||
*
|
||||
* @param name the natural-language name of the software.
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specific version of the software. This property will always be
|
||||
* present in a result.
|
||||
*
|
||||
* @return the specific version of the software.
|
||||
*/
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specific version of the software. This message should only be
|
||||
* invoked when parsing the XML and setting the property to a Version instance.
|
||||
*
|
||||
* @param version the specific version of the software.
|
||||
*/
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the operating system of the queried entity. This property will always be
|
||||
* present in a result.
|
||||
*
|
||||
* @return the operating system of the queried entity.
|
||||
*/
|
||||
public String getOs() {
|
||||
return os;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the operating system of the queried entity. This message should only be
|
||||
* invoked when parsing the XML and setting the property to a Version instance.
|
||||
*
|
||||
* @param os operating system of the queried entity.
|
||||
*/
|
||||
public void setOs(String os) {
|
||||
this.os = os;
|
||||
}
|
||||
|
||||
public String getChildElementXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<query xmlns=\"jabber:iq:version\">");
|
||||
if (name != null) {
|
||||
buf.append("<name>").append(name).append("</name>");
|
||||
}
|
||||
if (version != null) {
|
||||
buf.append("<version>").append(version).append("</version>");
|
||||
}
|
||||
if (os != null) {
|
||||
buf.append("<os>").append(os).append("</os>");
|
||||
}
|
||||
buf.append("</query>");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.packet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
|
||||
/**
|
||||
* An XHTML sub-packet, which is used by XMPP clients to exchange formatted text. The XHTML
|
||||
* extension is only a subset of XHTML 1.0.<p>
|
||||
*
|
||||
* The following link summarizes the requirements of XHTML IM:
|
||||
* <a href="http://www.jabber.org/jeps/jep-0071.html#sect-id2598018">Valid tags</a>.<p>
|
||||
*
|
||||
* Warning: this is an non-standard protocol documented by
|
||||
* <a href="http://www.jabber.org/jeps/jep-0071.html">JEP-71</a>. Because this is a
|
||||
* non-standard protocol, it is subject to change.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class XHTMLExtension implements PacketExtension {
|
||||
|
||||
private List bodies = new ArrayList();
|
||||
|
||||
/**
|
||||
* Returns the XML element name of the extension sub-packet root element.
|
||||
* Always returns "html"
|
||||
*
|
||||
* @return the XML element name of the packet extension.
|
||||
*/
|
||||
public String getElementName() {
|
||||
return "html";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML namespace of the extension sub-packet root element.
|
||||
* According the specification the namespace is always "http://jabber.org/protocol/xhtml-im"
|
||||
*
|
||||
* @return the XML namespace of the packet extension.
|
||||
*/
|
||||
public String getNamespace() {
|
||||
return "http://jabber.org/protocol/xhtml-im";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML representation of a XHTML extension according the specification.
|
||||
*
|
||||
* Usually the XML representation will be inside of a Message XML representation like
|
||||
* in the following example:
|
||||
* <pre>
|
||||
* <message id="MlIpV-4" to="gato1@gato.home" from="gato3@gato.home/Smack">
|
||||
* <subject>Any subject you want</subject>
|
||||
* <body>This message contains something interesting.</body>
|
||||
* <html xmlns="http://jabber.org/protocol/xhtml-im">
|
||||
* <body><p style='font-size:large'>This message contains something <em>interesting</em>.</p></body>
|
||||
* </html>
|
||||
* </message>
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public String toXML() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
|
||||
"\">");
|
||||
// Loop through all the bodies and append them to the string buffer
|
||||
for (Iterator i = getBodies(); i.hasNext();) {
|
||||
buf.append((String) i.next());
|
||||
}
|
||||
buf.append("</").append(getElementName()).append(">");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for the bodies in the packet.
|
||||
*
|
||||
* @return an Iterator for the bodies in the packet.
|
||||
*/
|
||||
public Iterator getBodies() {
|
||||
synchronized (bodies) {
|
||||
return Collections.unmodifiableList(new ArrayList(bodies)).iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a body to the packet.
|
||||
*
|
||||
* @param body the body to add.
|
||||
*/
|
||||
public void addBody(String body) {
|
||||
synchronized (bodies) {
|
||||
bodies.add(body);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a count of the bodies in the XHTML packet.
|
||||
*
|
||||
* @return the number of bodies in the XHTML packet.
|
||||
*/
|
||||
public int getBodiesCount() {
|
||||
return bodies.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
<body>XML packets that are part of the XMPP extension protocols.</body>
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.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.addInstruction(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(parser.getAttributeValue("", "var"));
|
||||
formField.setLabel(parser.getAttributeValue("", "label"));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.provider;
|
||||
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||
import org.jivesoftware.smackx.packet.DelayInformation;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* The DelayInformationProvider parses DelayInformation packets.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class DelayInformationProvider implements PacketExtensionProvider {
|
||||
|
||||
/**
|
||||
* Creates a new DeliveryInformationProvider.
|
||||
* ProviderManager requires that every PacketExtensionProvider has a public, no-argument
|
||||
* constructor
|
||||
*/
|
||||
public DelayInformationProvider() {
|
||||
}
|
||||
|
||||
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
|
||||
Date stamp = null;
|
||||
try {
|
||||
stamp = DelayInformation.UTC_FORMAT.parse(parser.getAttributeValue("", "stamp"));
|
||||
} catch (ParseException e) {
|
||||
// Try again but assuming that the date follows JEP-82 format
|
||||
// (Jabber Date and Time Profiles)
|
||||
try {
|
||||
stamp = DelayInformation.NEW_UTC_FORMAT
|
||||
.parse(parser.getAttributeValue("", "stamp"));
|
||||
} catch (ParseException e1) {
|
||||
// Last attempt. Try parsing the date assuming that it does not include milliseconds
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
|
||||
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
stamp = formatter.parse(parser.getAttributeValue("", "stamp"));
|
||||
}
|
||||
}
|
||||
DelayInformation delayInformation = new DelayInformation(stamp);
|
||||
delayInformation.setFrom(parser.getAttributeValue("", "from"));
|
||||
delayInformation.setReason(parser.nextText());
|
||||
return delayInformation;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.provider;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smackx.packet.DiscoverInfo;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* The DiscoverInfoProvider parses Service Discovery information packets.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class DiscoverInfoProvider implements IQProvider {
|
||||
|
||||
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||
DiscoverInfo discoverInfo = new DiscoverInfo();
|
||||
boolean done = false;
|
||||
DiscoverInfo.Feature feature = null;
|
||||
DiscoverInfo.Identity identity = null;
|
||||
String category = "";
|
||||
String name = "";
|
||||
String type = "";
|
||||
String variable = "";
|
||||
discoverInfo.setNode(parser.getAttributeValue("", "node"));
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("identity")) {
|
||||
// Initialize the variables from the parsed XML
|
||||
category = parser.getAttributeValue("", "category");
|
||||
name = parser.getAttributeValue("", "name");
|
||||
type = parser.getAttributeValue("", "type");
|
||||
}
|
||||
else if (parser.getName().equals("feature")) {
|
||||
// Initialize the variables from the parsed XML
|
||||
variable = parser.getAttributeValue("", "var");
|
||||
}
|
||||
// Otherwise, it must be a packet extension.
|
||||
else {
|
||||
discoverInfo.addExtension(PacketParserUtils.parsePacketExtension(parser
|
||||
.getName(), parser.getNamespace(), parser));
|
||||
}
|
||||
} else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("identity")) {
|
||||
// Create a new identity and add it to the discovered info.
|
||||
identity = new DiscoverInfo.Identity(category, name);
|
||||
identity.setType(type);
|
||||
discoverInfo.addIdentity(identity);
|
||||
}
|
||||
if (parser.getName().equals("feature")) {
|
||||
// Create a new feature and add it to the discovered info.
|
||||
discoverInfo.addFeature(variable);
|
||||
}
|
||||
if (parser.getName().equals("query")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return discoverInfo;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.provider;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.jivesoftware.smackx.packet.*;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* The DiscoverInfoProvider parses Service Discovery items packets.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class DiscoverItemsProvider implements IQProvider {
|
||||
|
||||
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||
DiscoverItems discoverItems = new DiscoverItems();
|
||||
boolean done = false;
|
||||
DiscoverItems.Item item = null;
|
||||
String jid = "";
|
||||
String name = "";
|
||||
String action = "";
|
||||
String node = "";
|
||||
discoverItems.setNode(parser.getAttributeValue("", "node"));
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("item")) {
|
||||
// Initialize the variables from the parsed XML
|
||||
jid = parser.getAttributeValue("", "jid");
|
||||
name = parser.getAttributeValue("", "name");
|
||||
node = parser.getAttributeValue("", "node");
|
||||
action = parser.getAttributeValue("", "action");
|
||||
}
|
||||
} else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("item")) {
|
||||
// Create a new Item and add it to DiscoverItems.
|
||||
item = new DiscoverItems.Item(jid);
|
||||
item.setName(name);
|
||||
item.setNode(node);
|
||||
item.setAction(action);
|
||||
discoverItems.addItem(item);
|
||||
}
|
||||
if (parser.getName().equals("query")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return discoverItems;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.provider;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.jivesoftware.smackx.packet.MUCAdmin;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* The MUCAdminProvider parses MUCAdmin packets. (@see MUCAdmin)
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class MUCAdminProvider implements IQProvider {
|
||||
|
||||
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||
MUCAdmin mucAdmin = new MUCAdmin();
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("item")) {
|
||||
mucAdmin.addItem(parseItem(parser));
|
||||
}
|
||||
}
|
||||
else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("query")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mucAdmin;
|
||||
}
|
||||
|
||||
private MUCAdmin.Item parseItem(XmlPullParser parser) throws Exception {
|
||||
boolean done = false;
|
||||
MUCAdmin.Item item =
|
||||
new MUCAdmin.Item(
|
||||
parser.getAttributeValue("", "affiliation"),
|
||||
parser.getAttributeValue("", "role"));
|
||||
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.nextText());
|
||||
}
|
||||
}
|
||||
else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("item")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.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;
|
||||
|
||||
/**
|
||||
* The MUCOwnerProvider parses MUCOwner packets. (@see MUCOwner)
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class MUCOwnerProvider implements IQProvider {
|
||||
|
||||
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||
MUCOwner mucOwner = new MUCOwner();
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("item")) {
|
||||
mucOwner.addItem(parseItem(parser));
|
||||
}
|
||||
else 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.setRole(parser.getAttributeValue("", "role"));
|
||||
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.nextText());
|
||||
}
|
||||
}
|
||||
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.nextText());
|
||||
}
|
||||
}
|
||||
else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("destroy")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return destroy;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,174 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.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;
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("invite")) {
|
||||
mucUser.setInvite(parseInvite(parser));
|
||||
}
|
||||
if (parser.getName().equals("item")) {
|
||||
mucUser.setItem(parseItem(parser));
|
||||
}
|
||||
if (parser.getName().equals("password")) {
|
||||
mucUser.setPassword(parser.nextText());
|
||||
}
|
||||
if (parser.getName().equals("status")) {
|
||||
mucUser.setStatus(new MUCUser.Status(parser.getAttributeValue("", "code")));
|
||||
}
|
||||
if (parser.getName().equals("decline")) {
|
||||
mucUser.setDecline(parseDecline(parser));
|
||||
}
|
||||
if (parser.getName().equals("destroy")) {
|
||||
mucUser.setDestroy(parseDestroy(parser));
|
||||
}
|
||||
}
|
||||
else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("x")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mucUser;
|
||||
}
|
||||
|
||||
private MUCUser.Item parseItem(XmlPullParser parser) throws Exception {
|
||||
boolean done = false;
|
||||
MUCUser.Item item =
|
||||
new MUCUser.Item(
|
||||
parser.getAttributeValue("", "affiliation"),
|
||||
parser.getAttributeValue("", "role"));
|
||||
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.nextText());
|
||||
}
|
||||
}
|
||||
else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("item")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
private MUCUser.Invite parseInvite(XmlPullParser parser) throws Exception {
|
||||
boolean done = false;
|
||||
MUCUser.Invite invite = new MUCUser.Invite();
|
||||
invite.setFrom(parser.getAttributeValue("", "from"));
|
||||
invite.setTo(parser.getAttributeValue("", "to"));
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("reason")) {
|
||||
invite.setReason(parser.nextText());
|
||||
}
|
||||
}
|
||||
else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("invite")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return invite;
|
||||
}
|
||||
|
||||
private MUCUser.Decline parseDecline(XmlPullParser parser) throws Exception {
|
||||
boolean done = false;
|
||||
MUCUser.Decline decline = new MUCUser.Decline();
|
||||
decline.setFrom(parser.getAttributeValue("", "from"));
|
||||
decline.setTo(parser.getAttributeValue("", "to"));
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("reason")) {
|
||||
decline.setReason(parser.nextText());
|
||||
}
|
||||
}
|
||||
else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("decline")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return decline;
|
||||
}
|
||||
|
||||
private MUCUser.Destroy parseDestroy(XmlPullParser parser) throws Exception {
|
||||
boolean done = false;
|
||||
MUCUser.Destroy destroy = new MUCUser.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.nextText());
|
||||
}
|
||||
}
|
||||
else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("destroy")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return destroy;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.provider;
|
||||
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||
import org.jivesoftware.smackx.packet.MessageEvent;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
*
|
||||
* The MessageEventProvider parses Message Event packets.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class MessageEventProvider implements PacketExtensionProvider {
|
||||
|
||||
/**
|
||||
* Creates a new MessageEventProvider.
|
||||
* ProviderManager requires that every PacketExtensionProvider has a public, no-argument constructor
|
||||
*/
|
||||
public MessageEventProvider() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a MessageEvent 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 {
|
||||
MessageEvent messageEvent = new MessageEvent();
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("id"))
|
||||
messageEvent.setPacketID(parser.nextText());
|
||||
if (parser.getName().equals(MessageEvent.COMPOSING))
|
||||
messageEvent.setComposing(true);
|
||||
if (parser.getName().equals(MessageEvent.DELIVERED))
|
||||
messageEvent.setDelivered(true);
|
||||
if (parser.getName().equals(MessageEvent.DISPLAYED))
|
||||
messageEvent.setDisplayed(true);
|
||||
if (parser.getName().equals(MessageEvent.OFFLINE))
|
||||
messageEvent.setOffline(true);
|
||||
} else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("x")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return messageEvent;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.provider;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.jivesoftware.smackx.packet.PrivateData;
|
||||
|
||||
/**
|
||||
* An interface for parsing custom private data. Each PrivateDataProvider must
|
||||
* be registered with the PrivateDataManager class for it to be used. Every implementation
|
||||
* of this interface <b>must</b> have a public, no-argument constructor.
|
||||
*
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public interface PrivateDataProvider {
|
||||
|
||||
/**
|
||||
* Parse the private data sub-document and create a PrivateData instance. At the
|
||||
* beginning of the method call, the xml parser will be positioned at the opening
|
||||
* tag of the private data child element. At the end of the method call, the parser
|
||||
* <b>must</b> be positioned on the closing tag of the child element.
|
||||
*
|
||||
* @param parser an XML parser.
|
||||
* @return a new PrivateData instance.
|
||||
* @throws Exception if an error occurs parsing the XML.
|
||||
*/
|
||||
public PrivateData parsePrivateData(XmlPullParser parser) throws Exception;
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.provider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||
import org.jivesoftware.smackx.*;
|
||||
import org.jivesoftware.smackx.packet.*;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
*
|
||||
* The RosterExchangeProvider parses RosterExchange packets.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class RosterExchangeProvider implements PacketExtensionProvider {
|
||||
|
||||
/**
|
||||
* Creates a new RosterExchangeProvider.
|
||||
* ProviderManager requires that every PacketExtensionProvider has a public, no-argument constructor
|
||||
*/
|
||||
public RosterExchangeProvider() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a RosterExchange 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 {
|
||||
|
||||
RosterExchange rosterExchange = new RosterExchange();
|
||||
boolean done = false;
|
||||
RemoteRosterEntry remoteRosterEntry = null;
|
||||
String jid = "";
|
||||
String name = "";
|
||||
ArrayList groupsName = new ArrayList();
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("item")) {
|
||||
// Reset this variable since they are optional for each item
|
||||
groupsName = new ArrayList();
|
||||
// Initialize the variables from the parsed XML
|
||||
jid = parser.getAttributeValue("", "jid");
|
||||
name = parser.getAttributeValue("", "name");
|
||||
}
|
||||
if (parser.getName().equals("group")) {
|
||||
groupsName.add(parser.nextText());
|
||||
}
|
||||
} else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("item")) {
|
||||
// Create packet.
|
||||
remoteRosterEntry = new RemoteRosterEntry(jid, name, (String[]) groupsName.toArray(new String[groupsName.size()]));
|
||||
rosterExchange.addRosterEntry(remoteRosterEntry);
|
||||
}
|
||||
if (parser.getName().equals("x")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rosterExchange;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,209 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.provider;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.jivesoftware.smackx.packet.VCard;
|
||||
import org.w3c.dom.*;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Gaston
|
||||
* Date: Jun 18, 2005
|
||||
* Time: 1:00:57 AM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class VCardProvider implements IQProvider {
|
||||
|
||||
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
try {
|
||||
int event = parser.getEventType();
|
||||
// get the content
|
||||
while (true) {
|
||||
switch (event) {
|
||||
case XmlPullParser.TEXT:
|
||||
sb.append(parser.getText());
|
||||
break;
|
||||
case XmlPullParser.START_TAG:
|
||||
sb.append('<' + parser.getName() + '>');
|
||||
break;
|
||||
case XmlPullParser.END_TAG:
|
||||
sb.append("</" + parser.getName() + '>');
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
if (event == XmlPullParser.END_TAG && "vCard".equals(parser.getName())) break;
|
||||
|
||||
event = parser.next();
|
||||
}
|
||||
} catch (XmlPullParserException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
String xmlText = sb.toString();
|
||||
VCard vCard = new VCard();
|
||||
try {
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
Document document = documentBuilder.parse(new ByteArrayInputStream(xmlText.getBytes()));
|
||||
|
||||
new VCardReader(vCard, document).initializeFields();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
return vCard;
|
||||
}
|
||||
|
||||
private class VCardReader {
|
||||
private final VCard vCard;
|
||||
private final Document document;
|
||||
|
||||
VCardReader(VCard vCard, Document document) {
|
||||
this.vCard = vCard;
|
||||
this.document = document;
|
||||
}
|
||||
|
||||
public void initializeFields() {
|
||||
vCard.setFirstName(getTagContents("GIVEN"));
|
||||
vCard.setLastName(getTagContents("FAMILY"));
|
||||
vCard.setMiddleName(getTagContents("MIDDLE"));
|
||||
|
||||
setupEmails();
|
||||
|
||||
vCard.setOrganization(getTagContents("ORGNAME"));
|
||||
vCard.setOrganizationUnit(getTagContents("ORGUNIT"));
|
||||
|
||||
setupSimpleFields();
|
||||
setupPhones("WORK", true);
|
||||
setupPhones("HOME", false);
|
||||
|
||||
setupAddress("WORK", true);
|
||||
setupAddress("HOME", false);
|
||||
}
|
||||
|
||||
private void setupEmails() {
|
||||
NodeList nodes = document.getElementsByTagName("USERID");
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Element element = (Element) nodes.item(i);
|
||||
if ("WORK".equals(element.getParentNode().getFirstChild().getNodeName())) {
|
||||
vCard.setEmailWork(getTextContent(element));
|
||||
} else {
|
||||
vCard.setEmailHome(getTextContent(element));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setupPhones(String type, boolean work) {
|
||||
NodeList allPhones = document.getElementsByTagName("TEL");
|
||||
for (int i = 0; i < allPhones.getLength(); i++) {
|
||||
Element node = (Element) allPhones.item(i);
|
||||
if (type.equals(node.getChildNodes().item(1).getNodeName())) {
|
||||
String code = node.getFirstChild().getNodeName();
|
||||
String value = getTextContent(node.getChildNodes().item(2));
|
||||
if (work) {
|
||||
vCard.setPhoneWork(code, value);
|
||||
}
|
||||
else {
|
||||
vCard.setPhoneHome(code, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setupAddress(String type, boolean work) {
|
||||
NodeList allAddresses = document.getElementsByTagName("ADR");
|
||||
for (int i = 0; i < allAddresses.getLength(); i++) {
|
||||
Element node = (Element) allAddresses.item(i);
|
||||
NodeList childNodes = node.getChildNodes();
|
||||
if (type.equals(childNodes.item(0).getNodeName())) {
|
||||
for (int j = 1; j < childNodes.getLength(); j++) {
|
||||
Node item = childNodes.item(j);
|
||||
if (item instanceof Element) {
|
||||
if (work) {
|
||||
vCard.setAddressFieldWork(item.getNodeName(), getTextContent(item));
|
||||
}
|
||||
else {
|
||||
vCard.setAddressFieldHome(item.getNodeName(), getTextContent(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getTagContents(String tag) {
|
||||
NodeList nodes = document.getElementsByTagName(tag);
|
||||
if (nodes.getLength() == 1) {
|
||||
return getTextContent(nodes.item(0));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setupSimpleFields() {
|
||||
NodeList childNodes = document.getDocumentElement().getChildNodes();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (node instanceof Element) {
|
||||
Element element = (Element) node;
|
||||
if ("FN".equals(element.getNodeName())) continue;
|
||||
|
||||
if (element.getChildNodes().getLength() == 0) {
|
||||
vCard.setField(element.getNodeName(), "");
|
||||
} else if (element.getChildNodes().getLength() == 1 &&
|
||||
element.getChildNodes().item(0) instanceof Text) {
|
||||
vCard.setField(element.getNodeName(), getTextContent(element));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getTextContent(Node node) {
|
||||
StringBuffer result = new StringBuffer();
|
||||
appendText(result, node);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private void appendText(StringBuffer result, Node node) {
|
||||
NodeList childNodes = node.getChildNodes();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node nd = childNodes.item(i);
|
||||
String nodeValue = nd.getNodeValue();
|
||||
if (nodeValue != null) {
|
||||
result.append(nodeValue);
|
||||
}
|
||||
appendText(result, nd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.provider;
|
||||
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||
import org.jivesoftware.smackx.packet.XHTMLExtension;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* The XHTMLExtensionProvider parses XHTML packets.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class XHTMLExtensionProvider implements PacketExtensionProvider {
|
||||
|
||||
/**
|
||||
* Creates a new XHTMLExtensionProvider.
|
||||
* ProviderManager requires that every PacketExtensionProvider has a public, no-argument constructor
|
||||
*/
|
||||
public XHTMLExtensionProvider() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a XHTMLExtension 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 {
|
||||
XHTMLExtension xhtmlExtension = new XHTMLExtension();
|
||||
boolean done = false;
|
||||
StringBuffer buffer = new StringBuffer();;
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("body"))
|
||||
buffer = new StringBuffer();
|
||||
buffer.append(parser.getText());
|
||||
} else if (eventType == XmlPullParser.TEXT) {
|
||||
if (buffer != null) buffer.append(parser.getText());
|
||||
} else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("body")) {
|
||||
buffer.append(parser.getText());
|
||||
xhtmlExtension.addBody(buffer.toString());
|
||||
}
|
||||
else if (parser.getName().equals(xhtmlExtension.getElementName())) {
|
||||
done = true;
|
||||
}
|
||||
else
|
||||
buffer.append(parser.getText());
|
||||
}
|
||||
}
|
||||
|
||||
return xhtmlExtension;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
<body>Provides pluggable parsing logic for Smack extensions.</body>
|
||||
Loading…
Add table
Add a link
Reference in a new issue