summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/isode')
-rw-r--r--src/com/isode/stroke/adhoc/OutgoingAdHocCommandSession.java20
-rw-r--r--src/com/isode/stroke/elements/Command.java157
-rw-r--r--src/com/isode/stroke/elements/Form.java81
-rw-r--r--src/com/isode/stroke/elements/FormField.java311
-rw-r--r--src/com/isode/stroke/eventloop/DummyEventLoop.java9
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/CommandParser.java29
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/FormParser.java39
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/FormParserFactory.java13
-rw-r--r--src/com/isode/stroke/queries/IQRouter.java10
-rw-r--r--src/com/isode/stroke/serializer/payloadserializers/CommandSerializer.java8
-rw-r--r--src/com/isode/stroke/serializer/payloadserializers/FormSerializer.java15
-rw-r--r--src/com/isode/stroke/serializer/xml/XMLTextNode.java4
12 files changed, 438 insertions, 258 deletions
diff --git a/src/com/isode/stroke/adhoc/OutgoingAdHocCommandSession.java b/src/com/isode/stroke/adhoc/OutgoingAdHocCommandSession.java
index a9db0b6..6b1d04c 100644
--- a/src/com/isode/stroke/adhoc/OutgoingAdHocCommandSession.java
+++ b/src/com/isode/stroke/adhoc/OutgoingAdHocCommandSession.java
@@ -53,15 +53,15 @@ public class OutgoingAdHocCommandSession {
};
/**
- * Emitted when the form for the next stage is available. The client should
- * add a listener to this signal which will be called when the server sends
+ * Emitted when the form for the next stage is available. The caller should
+ * add a listener to this signal which will be invoked when the target sends
* a form.
*/
public final Signal1<Command> onNextStageReceived = new Signal1<Command>();
/**
- * Emitted on error. The client should add a listener to this signal which
- * will be called when the server sends an error.
+ * Emitted on error. The caller should add a listener to this signal which
+ * will be invoked when the target sends an error.
*/
public final Signal1<ErrorPayload> onError = new Signal1<ErrorPayload>();
@@ -75,13 +75,13 @@ public class OutgoingAdHocCommandSession {
/**
* Create an Ad-Hoc command session. The initial command will be sent to the
* server on calling {@link #start()}.
- *
- * @param to JID of the user for which the Ad-Hoc command is executed, must
- * not be null
+ *
+ * @param to JID of the entity that the Ad-Hoc command is executed on (user
+ * JID, server JID, etc.), must not be null
* @param commandNode Node part of the Ad-Hoc command as published by the
- * server (e.g. "http://isode.com/xmpp/commands#test"), must not
+ * target (e.g. "http://isode.com/xmpp/commands#test"), must not
* be null
- * @param iqRouter TODO: not sure how to explain this, must not be null
+ * @param iqRouter IQ router to be used for the session, must not be null
*/
public OutgoingAdHocCommandSession(JID to, String commandNode,
IQRouter iqRouter) {
@@ -156,7 +156,7 @@ public class OutgoingAdHocCommandSession {
public void start() {
Action action = null;
GenericRequest<Command> commandRequest = new GenericRequest<Command>(
- IQ.Type.Set, to_, new Command(commandNode_, null, action),
+ IQ.Type.Set, to_, new Command(commandNode_, "", action),
iqRouter_);
commandRequest.onResponse.connect(new Slot2<Command, ErrorPayload>() {
public void call(Command payload, ErrorPayload error) {
diff --git a/src/com/isode/stroke/elements/Command.java b/src/com/isode/stroke/elements/Command.java
index 75f3bf2..d82808f 100644
--- a/src/com/isode/stroke/elements/Command.java
+++ b/src/com/isode/stroke/elements/Command.java
@@ -85,9 +85,9 @@ public class Command extends Payload {
/**
* Get status from its string form.
- *
+ *
* @param stringForm String form of status, can be null
- *
+ *
* @return Corresponding status if match found, otherwise
* {@link #NO_STATUS}. Will never be null.
*/
@@ -148,9 +148,9 @@ public class Command extends Payload {
/**
* Get action from its string form.
- *
+ *
* @param stringForm String form of action, can be null
- *
+ *
* @return Corresponding action if match found, otherwise
* {@link Action#NO_ACTION}. Will never be null.
*/
@@ -176,7 +176,7 @@ public class Command extends Payload {
/**
* This class contains information about the current status of the command.
- * TODO: I am not sure why this is not an immutable class.
+ * This is an immutable class.
*/
public static class Note {
/**
@@ -207,9 +207,9 @@ public class Command extends Payload {
/**
* Get type from its string form.
- *
+ *
* @param stringForm String form of type, can be null
- *
+ *
* @return Corresponding type if match found, otherwise
* {@link Type#INFO}. Will never be null.
*/
@@ -235,15 +235,19 @@ public class Command extends Payload {
/**
* Create a note element for the Ad-Hoc command.
- *
- * @param note user-readable text, can be null which will be stored as
- * an empty string
- * @param type Severity of the note, can be null which will be stored as
- * {@link Type#INFO}
+ *
+ * @param note user-readable text, must not be null
+ * @param type Severity of the note, must not be null
*/
public Note(String note, Type type) {
- this.note = (note != null) ? note : "";
- this.type = (type != null) ? type : Type.INFO;
+ if (note == null) {
+ throw new NullPointerException("'note' must not be null");
+ }
+ if (type == null) {
+ throw new NullPointerException("'type' must not be null");
+ }
+ this.note = note;
+ this.type = type;
}
/**
@@ -272,21 +276,20 @@ public class Command extends Payload {
setSessionID(sessionID);
setAction(action);
setStatus(status);
- setExecuteAction(null);
+ setExecuteAction(Action.NO_ACTION);
}
/**
* Create an Ad-Hoc command with the given node, session ID, status and
* {@link Action#NO_ACTION} action.
- *
- * @param node Command identification, can be null which will be stored as
- * an empty string
+ *
+ * @param node Node, must not be null. Each command is identified by its
+ * 'node' attribute. This matches its 'node' attribute from the
+ * service discovery.
* @param sessionID The ID of the session within which the command exists,
- * can be null (which will be stored as an empty string) or empty
- * if this is the first stage of the command and the client does
- * not know it yet
- * @param status Status of the command, can be null which will be stored as
- * {@link Status#NO_STATUS}
+ * must not be null but can be empty if this is the first stage
+ * of the command and the client does not know it yet
+ * @param status Status of the command, must not be null
*/
public Command(String node, String sessionID, Status status) {
assignData(node, sessionID, Action.NO_ACTION, status);
@@ -295,18 +298,17 @@ public class Command extends Payload {
/**
* Create an Ad-Hoc command with the given node, session ID, action and
* {@link Status#NO_STATUS} status.
- *
- * @param node Command identification, can be null which will be stored as
- * an empty string
+ *
+ * @param node Node, must not be null. Each command is identified by its
+ * 'node' attribute. This matches its 'node' attribute from the
+ * service discovery.
* @param sessionID The ID of the session within which the command exists,
- * can be null (which will be stored as an empty string) or empty
- * if this is the first stage of the command and the client does
- * not know it yet
- * @param action action of the command, can be null which will be stored as
- * {@link Action#EXECUTE}
+ * must not be null but can be empty if this is the first stage
+ * of the command and the client does not know it yet
+ * @param action action of the command, must not be null
*/
public Command(String node, String sessionID, Action action) {
- assignData(node, sessionID, action, null);
+ assignData(node, sessionID, action, Status.NO_STATUS);
}
/**
@@ -314,24 +316,27 @@ public class Command extends Payload {
* {@link Action#EXECUTE} action and {@link Status#NO_STATUS} status.
*/
public Command() {
- this(null, null, (Action) null);
+ this("", "", Action.EXECUTE);
}
/**
- * @return The command ID, will never be null
+ * @return Node, will never be null
*/
public String getNode() {
return node_;
}
/**
- * Set command ID.
- *
- * @param node Command identification, can be null which will be stored as
- * an empty string
+ * Set command node.
+ *
+ * @param node Node, must not be null
*/
public void setNode(String node) {
- node_ = (node != null) ? node : "";
+ if (node == null) {
+ throw new NullPointerException("'node' must not be null");
+ }
+
+ node_ = node;
}
/**
@@ -345,14 +350,17 @@ public class Command extends Payload {
/**
* Set session ID.
- *
+ *
* @param sessionID The ID of the session within which the command exists,
- * can be null (which will be stored as an empty string) or empty
- * if this is the first stage of the command and the client does
- * not know it yet
+ * must not be null but can be empty if this is the first stage
+ * of the command and the client does not know it yet
*/
public void setSessionID(String sessionID) {
- sessionID_ = (sessionID != null) ? sessionID : "";
+ if (sessionID == null) {
+ throw new NullPointerException("'sessionID' must not be null");
+ }
+
+ sessionID_ = sessionID;
}
/**
@@ -364,12 +372,15 @@ public class Command extends Payload {
/**
* Set action of the command.
- *
- * @param action action of the command, can be null which will be stored as
- * {@link Action#EXECUTE}
+ *
+ * @param action action of the command, must not be null
*/
public void setAction(Action action) {
- action_ = (action != null) ? action : Action.EXECUTE;
+ if (action == null) {
+ throw new NullPointerException("'action' must not be null");
+ }
+
+ action_ = action;
}
/**
@@ -381,12 +392,15 @@ public class Command extends Payload {
/**
* Set execute action of the command.
- *
- * @param action execute action of the command, can be null which will be
- * stored as {@link Action#NO_ACTION}
+ *
+ * @param action execute action of the command, must not be null
*/
public void setExecuteAction(Action action) {
- executeAction_ = (action != null) ? action : Action.NO_ACTION;
+ if (action == null) {
+ throw new NullPointerException("'action' must not be null");
+ }
+
+ executeAction_ = action;
}
/**
@@ -398,17 +412,21 @@ public class Command extends Payload {
/**
* Set status of the command.
- *
- * @param status Status of the command, can be null which will be stored as
- * {@link Status#NO_STATUS}
+ *
+ * @param status Status of the command, must not be null
*/
public void setStatus(Status status) {
- status_ = (status != null) ? status : Status.NO_STATUS;
+ if (status == null) {
+ throw new NullPointerException("'status' must not be null");
+ }
+
+ status_ = status;
}
/**
* @return List of allowed actions for this stage of execution, will never
- * be null
+ * be null. The instance of the list stored in the object is not
+ * returned, a copy is made.
*/
public List<Action> getAvailableActions() {
return new ArrayList<Action>(availableActions_);
@@ -416,18 +434,21 @@ public class Command extends Payload {
/**
* Add to the list of allowed actions for this stage of execution.
- *
- * @param action Action to add, can be null in which case it will be ignored
+ *
+ * @param action Action to add, must not be null
*/
public void addAvailableAction(Action action) {
- if (action != null) {
- availableActions_.add(action);
+ if (action == null) {
+ throw new NullPointerException("'action' must not be null");
}
+
+ availableActions_.add(action);
}
/**
* @return List of information elements for the current status of the
- * command, will never be null
+ * command, will never be null. The instance of the list stored in
+ * the object is not returned, a copy is made.
*/
public List<Note> getNotes() {
return new ArrayList<Note>(notes_);
@@ -436,13 +457,15 @@ public class Command extends Payload {
/**
* Add to the list of information elements for the current status of the
* command.
- *
- * @param note Note to add, can be null in which case it will be ignored
+ *
+ * @param note Note to add, must not be null
*/
public void addNote(Note note) {
- if (note != null) {
- notes_.add(note);
+ if (note == null) {
+ throw new NullPointerException("'note' must not be null");
}
+
+ notes_.add(note);
}
/**
@@ -455,7 +478,7 @@ public class Command extends Payload {
/**
* Set form for the command.
- *
+ *
* @param payload Form for the command, can be null. The instance of the
* form is stored in the object, a copy is not made.
*/
diff --git a/src/com/isode/stroke/elements/Form.java b/src/com/isode/stroke/elements/Form.java
index 1c2e830..362408a 100644
--- a/src/com/isode/stroke/elements/Form.java
+++ b/src/com/isode/stroke/elements/Form.java
@@ -73,9 +73,9 @@ public class Form extends Payload {
/**
* Get type from its string form.
- *
+ *
* @param stringForm String form of type, can be null
- *
+ *
* @return Corresponding type if match found, otherwise
* {@link Type#FORM_TYPE}. Will never be null.
*/
@@ -106,8 +106,8 @@ public class Form extends Payload {
/**
* Create a form of the given type.
- *
- * @param type Form type, if null then {@link Type#FORM_TYPE} is assumed
+ *
+ * @param type Form type, must not be null
*/
public Form(Type type) {
setType(type);
@@ -117,26 +117,28 @@ public class Form extends Payload {
* Create a form of {@link Type#FORM_TYPE}.
*/
public Form() {
- this(null);
+ this(Type.FORM_TYPE);
}
/**
* Add to the list of fields for the form.
- *
- * @param field Field to add, can be null in which case it will be ignored.
- * The instance of the form field is stored in the object, a copy
- * is not made.
+ *
+ * @param field Field to add, must not be null. The instance of the form
+ * field is stored in the object, a copy is not made.
*/
public void addField(FormField field) {
- if (field != null) {
- fields_.add(field);
+ if (field == null) {
+ throw new NullPointerException("'field' must not be null");
}
+
+ fields_.add(field);
}
/**
- * @return List of fields for the form, will never be null. The instances of
- * the form fields stored in the object is returned, a copy is not
- * made.
+ * @return List of fields for the form, will never be null. The instance of
+ * the list stored in the object is not returned, a copy is made.
+ * But the instances of the form fields stored in the list is the
+ * same as the list in the object, a copy is not made.
*/
public List<FormField> getFields() {
return new ArrayList<FormField>(fields_);
@@ -144,12 +146,15 @@ public class Form extends Payload {
/**
* Set title of the form.
- *
- * @param title title of the form, can be null in which case an empty string
- * will be stored
+ *
+ * @param title title of the form, must not be null
*/
public void setTitle(String title) {
- title_ = (title != null) ? title : "";
+ if (title == null) {
+ throw new NullPointerException("'title' must not be null");
+ }
+
+ title_ = title;
}
/**
@@ -161,12 +166,15 @@ public class Form extends Payload {
/**
* Set natural-language instructions for the form.
- *
- * @param instructions instructions for the form, can be null in which case
- * an empty string will be stored
+ *
+ * @param instructions instructions for the form, must not be null
*/
public void setInstructions(String instructions) {
- instructions_ = (instructions != null) ? instructions : "";
+ if (instructions == null) {
+ throw new NullPointerException("'instructions' must not be null");
+ }
+
+ instructions_ = instructions;
}
/**
@@ -178,11 +186,15 @@ public class Form extends Payload {
/**
* Set type of the form.
- *
- * @param type Form type, if null then {@link Type#FORM_TYPE} is assumed
+ *
+ * @param type Form type, must not be null
*/
public void setType(Type type) {
- type_ = (type != null) ? type : Type.FORM_TYPE;
+ if (type == null) {
+ throw new NullPointerException("'type' must not be null");
+ }
+
+ type_ = type;
}
/**
@@ -214,20 +226,21 @@ public class Form extends Payload {
/**
* Get form field for the given name.
- *
- * @param name Name of form field to retrieve, can be null in which case
- * null will be returned
- *
+ *
+ * @param name Name of form field to retrieve, must not be null
+ *
* @return Form field with the given name if it is present in the form, null
* otherwise. The instance of the form field stored in the object is
* returned, a copy is not made.
*/
public FormField getField(String name) {
- if (name != null) {
- for (FormField field : fields_) {
- if (field.getName().equals(name)) {
- return field;
- }
+ if (name == null) {
+ throw new NullPointerException("'name' must not be null");
+ }
+
+ for (FormField field : fields_) {
+ if (field.getName().equals(name)) {
+ return field;
}
}
diff --git a/src/com/isode/stroke/elements/FormField.java b/src/com/isode/stroke/elements/FormField.java
index 06b2ce6..aedc8fe 100644
--- a/src/com/isode/stroke/elements/FormField.java
+++ b/src/com/isode/stroke/elements/FormField.java
@@ -17,14 +17,15 @@ import com.isode.stroke.jid.JID;
/**
* This class implements the field element of a form.
- *
+ *
* <p>
- * Data validation is the responsibility of the form-processing entity (commonly
- * a server, service, or bot) rather than the form-submitting entity (commonly a
- * client controlled by a human user). This helps to meet the requirement for
- * keeping client implementations simple. If the form-processing entity
- * determines that the data provided is not valid, it SHOULD return a
- * "Not Acceptable" error, optionally providing a textual explanation.
+ * From http://xmpp.org/extensions/xep-0050.html: Data validation is the
+ * responsibility of the form-processing entity (commonly a server, service, or
+ * bot) rather than the form-submitting entity (commonly a client controlled by
+ * a human user). This helps to meet the requirement for keeping client
+ * implementations simple. If the form-processing entity determines that the
+ * data provided is not valid, it SHOULD return a "Not Acceptable" error,
+ * optionally providing a textual explanation.
*/
public class FormField {
/**
@@ -124,33 +125,35 @@ public class FormField {
/**
* This class defines the option element that can be used in
- * {@link ListSingleFormField} and {@link ListMultiFormField}. TODO: This
- * class should be immutable.
+ * {@link ListSingleFormField} and {@link ListMultiFormField}. This class is
+ * immutable.
*/
public static class Option {
/**
- * Human-readable name for the option, must not be null
+ * Human-readable name for the option, will not be null
*/
- public String label;
+ public final String label;
/**
- * Option value, must not be null
+ * Option value, will not be null
*/
- public String value;
+ public final String value;
/**
* Create an option element.
- *
- * @param label Human-readable name for the option, can be null in which
- * case an empty string will be stored
+ *
+ * @param label Human-readable name for the option, must not be null
* @param value Option value, must not be null
*/
public Option(String label, String value) {
+ if (label == null) {
+ throw new NullPointerException("'label' must not be null");
+ }
if (value == null) {
throw new NullPointerException("'value' must not be null");
}
- this.label = (label != null) ? label : "";
+ this.label = label;
this.value = value;
}
}
@@ -168,12 +171,15 @@ public class FormField {
/**
* Set the unique identifier for the field in the form.
- *
- * @param name unique identifier for the field in the form, can be null in
- * which case an empty string will be stored
+ *
+ * @param name unique identifier for the field in the form, must not be null
*/
public void setName(String name) {
- this.name = (name != null) ? name : "";
+ if (name == null) {
+ throw new NullPointerException("'name' must not be null");
+ }
+
+ this.name = name;
}
/**
@@ -185,12 +191,15 @@ public class FormField {
/**
* Set the human-readable name for the field.
- *
- * @param label human-readable name for the field, can be null in which case
- * an empty string will be stored
+ *
+ * @param label human-readable name for the field, must not be null
*/
public void setLabel(String label) {
- this.label = (label != null) ? label : "";
+ if (label == null) {
+ throw new NullPointerException("'label' must not be null");
+ }
+
+ this.label = label;
}
/**
@@ -202,12 +211,16 @@ public class FormField {
/**
* Set the natural-language description for the field.
- *
- * @param description natural-language description for the field, can be
- * null in which case an empty string will be stored
+ *
+ * @param description natural-language description for the field, must not
+ * be null
*/
public void setDescription(String description) {
- this.description = (description != null) ? description : "";
+ if (description == null) {
+ throw new NullPointerException("'description' must not be null");
+ }
+
+ this.description = description;
}
/**
@@ -219,7 +232,7 @@ public class FormField {
/**
* Set if the field is required for the form to be considered valid.
- *
+ *
* @param required true if the field is required for the form to be
* considered valid
*/
@@ -236,17 +249,20 @@ public class FormField {
/**
* Add to the list of options for this form field.
- *
- * @param option Option to add, can be null in which case it will be ignored
+ *
+ * @param option Option to add, must not be null
*/
public void addOption(Option option) {
- if (option != null) {
- options.add(option);
+ if (option == null) {
+ throw new NullPointerException("'option' must not be null");
}
+
+ options.add(option);
}
/**
- * @return List of options for this form, will never be null
+ * @return List of options for this form, will never be null. The instance
+ * of the list stored in the object is not returned, a copy is made.
*/
public List<Option> getOptions() {
return new ArrayList<Option>(options);
@@ -257,15 +273,20 @@ public class FormField {
* a form of {@link Type#FORM_TYPE} or results provided in a form of
* {@link Type#RESULT_TYPE} or values submitted in a form of
* {@link Type#SUBMIT_TYPE}.
- *
- * @param value Value to add, can be null
+ *
+ * @param value Value to add, must not be null
*/
public void addRawValue(String value) {
+ if (value == null) {
+ throw new NullPointerException("'value' must not be null");
+ }
+
rawValues.add(value);
}
/**
- * @return List of values for this field, will never be null
+ * @return List of values for this field, will never be null. The instance
+ * of the list stored in the object is not returned, a copy is made.
*/
public List<String> getRawValues() {
return new ArrayList<String>(rawValues);
@@ -273,7 +294,7 @@ public class FormField {
/**
* Template for creating a form field.
- *
+ *
* @param <T> Type of form field.
*/
public static class GenericFormField<T> extends FormField {
@@ -283,10 +304,10 @@ public class FormField {
* @return Values for this field. The values can be the defaults
* suggested in a form of {@link Type#FORM_TYPE} or results
* provided in a form of {@link Type#RESULT_TYPE} or values
- * submitted in a form of {@link Type#SUBMIT_TYPE}. Will never be
- * null.
+ * submitted in a form of {@link Type#SUBMIT_TYPE}. Will never
+ * be null.
*/
- public T getValue() {
+ public final T getValue() {
return value;
}
@@ -295,10 +316,10 @@ public class FormField {
* in a form of {@link Type#FORM_TYPE} or results provided in a form of
* {@link Type#RESULT_TYPE} or values submitted in a form of
* {@link Type#SUBMIT_TYPE}.
- *
+ *
* @param value Value to set, must not be null
*/
- public void setValue(T value) {
+ public void setValue(final T value) {
if (value == null) {
throw new NullPointerException("'value' must not be null");
}
@@ -306,7 +327,7 @@ public class FormField {
this.value = value;
}
- protected GenericFormField(T value) {
+ protected GenericFormField(final T value) {
setValue(value);
}
}
@@ -317,28 +338,31 @@ public class FormField {
*/
public static class BooleanFormField extends GenericFormField<Boolean> {
private BooleanFormField(Boolean value) {
- super((value == null) ? Boolean.FALSE : value);
+ super(value);
}
/**
* Create an object with given value.
- *
- * @param value Value for this field, can be null which will be assumed
- * as FALSE.
- *
+ *
+ * @param value Value for this field, must not be null
+ *
* @return new object, will never be null
*/
- public static BooleanFormField create(Boolean value) {
+ public static BooleanFormField create(final Boolean value) {
+ if (value == null) {
+ throw new NullPointerException("'value' must not be null");
+ }
+
return new BooleanFormField(value);
}
/**
* Create an object with value FALSE.
- *
+ *
* @return new object, will never be null
*/
public static BooleanFormField create() {
- return create(null);
+ return new BooleanFormField(Boolean.FALSE);
}
}
@@ -348,28 +372,31 @@ public class FormField {
*/
public static class FixedFormField extends GenericFormField<String> {
private FixedFormField(String value) {
- super((value != null) ? value : "");
+ super(value);
}
/**
* Create an object with given value.
- *
- * @param value Value for this field, can be null which will be stored
- * as empty string.
- *
+ *
+ * @param value Value for this field, must not be null
+ *
* @return new object, will never be null
*/
- public static FixedFormField create(String value) {
+ public static FixedFormField create(final String value) {
+ if (value == null) {
+ throw new NullPointerException("'value' must not be null");
+ }
+
return new FixedFormField(value);
}
/**
* Create an object with value as an empty string.
- *
+ *
* @return new object, will never be null
*/
public static FixedFormField create() {
- return create(null);
+ return new FixedFormField("");
}
}
@@ -379,28 +406,31 @@ public class FormField {
*/
public static class HiddenFormField extends GenericFormField<String> {
private HiddenFormField(String value) {
- super((value != null) ? value : "");
+ super(value);
}
/**
* Create an object with given value.
- *
- * @param value Value for this field, can be null which will be stored
- * as empty string.
- *
+ *
+ * @param value Value for this field, must not be null
+ *
* @return new object, will never be null
*/
- public static HiddenFormField create(String value) {
+ public static HiddenFormField create(final String value) {
+ if (value == null) {
+ throw new NullPointerException("'value' must not be null");
+ }
+
return new HiddenFormField(value);
}
/**
* Create an object with value as an empty string.
- *
+ *
* @return new object, will never be null
*/
public static HiddenFormField create() {
- return create(null);
+ return new HiddenFormField("");
}
}
@@ -410,28 +440,31 @@ public class FormField {
*/
public static class ListSingleFormField extends GenericFormField<String> {
private ListSingleFormField(String value) {
- super((value != null) ? value : "");
+ super(value);
}
/**
* Create an object with given value.
- *
- * @param value Value for this field, can be null which will be stored
- * as empty string.
- *
+ *
+ * @param value Value for this field, must not be null
+ *
* @return new object, will never be null
*/
- public static ListSingleFormField create(String value) {
+ public static ListSingleFormField create(final String value) {
+ if (value == null) {
+ throw new NullPointerException("'value' must not be null");
+ }
+
return new ListSingleFormField(value);
}
/**
* Create an object with value as an empty string.
- *
+ *
* @return new object, will never be null
*/
public static ListSingleFormField create() {
- return create(null);
+ return new ListSingleFormField("");
}
}
@@ -441,28 +474,31 @@ public class FormField {
*/
public static class TextMultiFormField extends GenericFormField<String> {
private TextMultiFormField(String value) {
- super((value != null) ? value : "");
+ super(value);
}
/**
* Create an object with given value.
- *
- * @param value Value for this field, can be null which will be stored
- * as empty string.
- *
+ *
+ * @param value Value for this field, must not be null
+ *
* @return new object, will never be null
*/
- public static TextMultiFormField create(String value) {
+ public static TextMultiFormField create(final String value) {
+ if (value == null) {
+ throw new NullPointerException("'value' must not be null");
+ }
+
return new TextMultiFormField(value);
}
/**
* Create an object with value as an empty string.
- *
+ *
* @return new object, will never be null
*/
public static TextMultiFormField create() {
- return create(null);
+ return new TextMultiFormField("");
}
}
@@ -473,28 +509,31 @@ public class FormField {
*/
public static class TextPrivateFormField extends GenericFormField<String> {
private TextPrivateFormField(String value) {
- super((value != null) ? value : "");
+ super(value);
}
/**
* Create an object with given value.
- *
- * @param value Value for this field, can be null which will be stored
- * as empty string.
- *
+ *
+ * @param value Value for this field, must not be null
+ *
* @return new object, will never be null
*/
- public static TextPrivateFormField create(String value) {
+ public static TextPrivateFormField create(final String value) {
+ if (value == null) {
+ throw new NullPointerException("'value' must not be null");
+ }
+
return new TextPrivateFormField(value);
}
/**
* Create an object with value as an empty string.
- *
+ *
* @return new object, will never be null
*/
public static TextPrivateFormField create() {
- return create(null);
+ return new TextPrivateFormField("");
}
}
@@ -504,28 +543,31 @@ public class FormField {
*/
public static class TextSingleFormField extends GenericFormField<String> {
private TextSingleFormField(String value) {
- super((value != null) ? value : "");
+ super(value);
}
/**
* Create an object with given value.
- *
- * @param value Value for this field, can be null which will be stored
- * as empty string.
- *
+ *
+ * @param value Value for this field, must not be null
+ *
* @return new object, will never be null
*/
- public static TextSingleFormField create(String value) {
+ public static TextSingleFormField create(final String value) {
+ if (value == null) {
+ throw new NullPointerException("'value' must not be null");
+ }
+
return new TextSingleFormField(value);
}
/**
* Create an object with value as an empty string.
- *
+ *
* @return new object, will never be null
*/
public static TextSingleFormField create() {
- return create(null);
+ return new TextSingleFormField("");
}
}
@@ -534,28 +576,31 @@ public class FormField {
*/
public static class JIDSingleFormField extends GenericFormField<JID> {
private JIDSingleFormField(JID value) {
- super((value != null) ? value : new JID());
+ super(value);
}
/**
* Create an object with given value.
- *
- * @param value Value for this field, can be null which will be stored
- * as an invalid JID.
- *
+ *
+ * @param value Value for this field, must not be null
+ *
* @return new object, will never be null
*/
- public static JIDSingleFormField create(JID value) {
+ public static JIDSingleFormField create(final JID value) {
+ if (value == null) {
+ throw new NullPointerException("'value' must not be null");
+ }
+
return new JIDSingleFormField(value);
}
/**
* Create an object with value as an invalid JID.
- *
+ *
* @return new object, will never be null
*/
public static JIDSingleFormField create() {
- return create(null);
+ return new JIDSingleFormField(new JID());
}
}
@@ -564,30 +609,32 @@ public class FormField {
*/
public static class JIDMultiFormField extends GenericFormField<List<JID>> {
private JIDMultiFormField(List<JID> value) {
- super((value == null) ? new ArrayList<JID>() : new ArrayList<JID>(
- value));
+ super(value);
}
/**
* Create an object with given value.
- *
- * @param value Value for this field, can be null which will be assumed
- * to be an empty list. A copy of the given list will be kept
- * by this object.
- *
+ *
+ * @param value Value for this field, must not be null. A copy of the
+ * given list will be kept by this object.
+ *
* @return new object, will never be null
*/
- public static JIDMultiFormField create(List<JID> value) {
- return new JIDMultiFormField(value);
+ public static JIDMultiFormField create(final List<JID> value) {
+ if (value == null) {
+ throw new NullPointerException("'value' must not be null");
+ }
+
+ return new JIDMultiFormField(new ArrayList<JID>(value));
}
/**
* Create an object with an empty list.
- *
+ *
* @return new object, will never be null
*/
public static JIDMultiFormField create() {
- return create(null);
+ return new JIDMultiFormField(new ArrayList<JID>());
}
}
@@ -598,30 +645,32 @@ public class FormField {
public static class ListMultiFormField extends
GenericFormField<List<String>> {
private ListMultiFormField(List<String> value) {
- super((value == null) ? new ArrayList<String>()
- : new ArrayList<String>(value));
+ super(value);
}
/**
* Create an object with given value.
- *
- * @param value Value for this field, can be null which will be assumed
- * to be an empty list. A copy of the given list will be kept
- * by this object.
- *
+ *
+ * @param value Value for this field, must not be null. A copy of the
+ * given list will be kept by this object.
+ *
* @return new object, will never be null
*/
- public static ListMultiFormField create(List<String> value) {
- return new ListMultiFormField(value);
+ public static ListMultiFormField create(final List<String> value) {
+ if (value == null) {
+ throw new NullPointerException("'value' must not be null");
+ }
+
+ return new ListMultiFormField(new ArrayList<String>(value));
}
/**
* Create an object with an empty list.
- *
+ *
* @return new object, will never be null
*/
public static ListMultiFormField create() {
- return create(null);
+ return new ListMultiFormField(new ArrayList<String>());
}
}
diff --git a/src/com/isode/stroke/eventloop/DummyEventLoop.java b/src/com/isode/stroke/eventloop/DummyEventLoop.java
index 47f8928..dd2911a 100644
--- a/src/com/isode/stroke/eventloop/DummyEventLoop.java
+++ b/src/com/isode/stroke/eventloop/DummyEventLoop.java
@@ -12,9 +12,8 @@ package com.isode.stroke.eventloop;
import java.util.Vector;
/**
- * Dummy event loop that can be used for tests, etc.
- *
- * @since 15.2
+ * Dummy event loop that can be used for tests, etc. This class is thread-safe
+ * as it uses {@link Vector} which is thread-safe.
*/
public class DummyEventLoop extends EventLoop {
private Vector<Event> events_ = new Vector<Event>();
@@ -26,7 +25,9 @@ public class DummyEventLoop extends EventLoop {
}
/**
- * Process pending events.
+ * Process pending events. This method is thread-safe as it is intended to
+ * be always called from the same thread for an instance of
+ * {@link DummyEventLoop}
*/
public void processEvents() {
while (!events_.isEmpty()) {
diff --git a/src/com/isode/stroke/parser/payloadparsers/CommandParser.java b/src/com/isode/stroke/parser/payloadparsers/CommandParser.java
index b94acfb..bb7fe27 100644
--- a/src/com/isode/stroke/parser/payloadparsers/CommandParser.java
+++ b/src/com/isode/stroke/parser/payloadparsers/CommandParser.java
@@ -33,7 +33,7 @@ public class CommandParser extends GenericPayloadParser<Command> {
private Type noteType_;
private FormParserFactory formParserFactory_;
private FormParser formParser_;
- private String currentText_;
+ private String currentText_ = "";
/**
* Constructor
@@ -51,7 +51,17 @@ public class CommandParser extends GenericPayloadParser<Command> {
}
public void handleStartElement(String element, String ns,
- AttributeMap attributes) {
+ final AttributeMap attributes) {
+ if (element == null) {
+ throw new NullPointerException("'element' must not be null");
+ }
+ if (ns == null) {
+ throw new NullPointerException("'ns' must not be null");
+ }
+ if (attributes == null) {
+ throw new NullPointerException("'attributes' must not be null");
+ }
+
++level_;
Command command = getPayloadInternal();
@@ -95,6 +105,13 @@ public class CommandParser extends GenericPayloadParser<Command> {
}
public void handleEndElement(String element, String ns) {
+ if (element == null) {
+ throw new NullPointerException("'element' must not be null");
+ }
+ if (ns == null) {
+ throw new NullPointerException("'ns' must not be null");
+ }
+
if (formParser_ != null) {
formParser_.handleEndElement(element, ns);
}
@@ -122,6 +139,10 @@ public class CommandParser extends GenericPayloadParser<Command> {
}
public void handleCharacterData(String data) {
+ if (data == null) {
+ throw new NullPointerException("'data' must not be null");
+ }
+
if (formParser_ != null) {
formParser_.handleCharacterData(data);
} else {
@@ -130,6 +151,10 @@ public class CommandParser extends GenericPayloadParser<Command> {
}
private static Action parseAction(String action) {
+ if (action == null) {
+ throw new NullPointerException("'action' must not be null");
+ }
+
return Action.getAction(action);
}
diff --git a/src/com/isode/stroke/parser/payloadparsers/FormParser.java b/src/com/isode/stroke/parser/payloadparsers/FormParser.java
index 2ca50c1..0b72e6b 100644
--- a/src/com/isode/stroke/parser/payloadparsers/FormParser.java
+++ b/src/com/isode/stroke/parser/payloadparsers/FormParser.java
@@ -38,6 +38,10 @@ public class FormParser extends GenericPayloadParser<Form> {
protected GenericFormField<T> field;
public void addValue(String s) {
+ if (s == null) {
+ throw new NullPointerException("'s' must not be null");
+ }
+
field.addRawValue(s);
}
@@ -48,47 +52,47 @@ public class FormParser extends GenericPayloadParser<Form> {
private static class BoolFieldParseHelper extends FieldParseHelper<Boolean> {
public void addValue(String s) {
- field.setValue(((s.equals("1")) || (s.equals("true"))));
super.addValue(s);
+ field.setValue(((s.equals("1")) || (s.equals("true"))));
}
}
private static class StringFieldParseHelper extends
FieldParseHelper<String> {
public void addValue(String s) {
+ super.addValue(s);
if (field.getValue().isEmpty()) {
field.setValue(s);
} else {
field.setValue(field.getValue() + "\n" + s);
}
- super.addValue(s);
}
};
private static class JIDFieldParseHelper extends FieldParseHelper<JID> {
public void addValue(String s) {
- field.setValue(new JID(s));
super.addValue(s);
+ field.setValue(new JID(s));
}
};
private static class StringListFieldParseHelper extends
FieldParseHelper<List<String>> {
public void addValue(String s) {
+ super.addValue(s);
List<String> l = field.getValue();
l.add(s);
field.setValue(l);
- super.addValue(s);
}
};
private static class JIDListFieldParseHelper extends
FieldParseHelper<List<JID>> {
public void addValue(String s) {
+ super.addValue(s);
List<JID> l = field.getValue();
l.add(new JID(s));
field.setValue(l);
- super.addValue(s);
}
};
@@ -208,7 +212,7 @@ public class FormParser extends GenericPayloadParser<Form> {
private int level_;
private String currentText_ = "";
- private String currentOptionLabel_;
+ private String currentOptionLabel_ = "";
private FieldParseHelper<?> currentFieldParseHelper_ = null;
/**
@@ -221,7 +225,17 @@ public class FormParser extends GenericPayloadParser<Form> {
}
public void handleStartElement(String element, String ns,
- AttributeMap attributes) {
+ final AttributeMap attributes) {
+ if (element == null) {
+ throw new NullPointerException("'element' must not be null");
+ }
+ if (ns == null) {
+ throw new NullPointerException("'ns' must not be null");
+ }
+ if (attributes == null) {
+ throw new NullPointerException("'attributes' must not be null");
+ }
+
Form form = getPayloadInternal();
if (level_ == TopLevel) {
@@ -296,6 +310,13 @@ public class FormParser extends GenericPayloadParser<Form> {
}
public void handleEndElement(String element, String ns) {
+ if (element == null) {
+ throw new NullPointerException("'element' must not be null");
+ }
+ if (ns == null) {
+ throw new NullPointerException("'ns' must not be null");
+ }
+
--level_;
Form form = getPayloadInternal();
@@ -337,6 +358,10 @@ public class FormParser extends GenericPayloadParser<Form> {
}
public void handleCharacterData(String text) {
+ if (text == null) {
+ throw new NullPointerException("'text' must not be null");
+ }
+
currentText_ += text;
}
diff --git a/src/com/isode/stroke/parser/payloadparsers/FormParserFactory.java b/src/com/isode/stroke/parser/payloadparsers/FormParserFactory.java
index 228c093..0287cca 100644
--- a/src/com/isode/stroke/parser/payloadparsers/FormParserFactory.java
+++ b/src/com/isode/stroke/parser/payloadparsers/FormParserFactory.java
@@ -24,7 +24,18 @@ public class FormParserFactory implements PayloadParserFactory {
public FormParserFactory() {
}
- public boolean canParse(String element, String ns, AttributeMap attributes) {
+ public boolean canParse(String element, String ns,
+ final AttributeMap attributes) {
+ if (element == null) {
+ throw new NullPointerException("'element' must not be null");
+ }
+ if (ns == null) {
+ throw new NullPointerException("'ns' must not be null");
+ }
+ if (attributes == null) {
+ throw new NullPointerException("'attributes' must not be null");
+ }
+
return ns.equals("jabber:x:data");
}
diff --git a/src/com/isode/stroke/queries/IQRouter.java b/src/com/isode/stroke/queries/IQRouter.java
index 2f300d7..61c2221 100644
--- a/src/com/isode/stroke/queries/IQRouter.java
+++ b/src/com/isode/stroke/queries/IQRouter.java
@@ -8,13 +8,19 @@
*/
package com.isode.stroke.queries;
+import java.util.Vector;
+
import com.isode.stroke.elements.ErrorPayload;
import com.isode.stroke.elements.IQ;
import com.isode.stroke.signals.Slot1;
-import java.util.Vector;
/**
- * Route IQs to handlers
+ * This class is responsible for routing all IQ stanzas to the handlers. It's
+ * needed because, unlike Message and Presence, there are strict rules about
+ * replying to IQ stanzas, replies need to be tracked, handled by the
+ * responsible bit of code, replied to, etc. and when it's an outgoing IQ, it
+ * needs to be tracked such that when the reply comes in, the callback is
+ * called.
*/
public class IQRouter {
diff --git a/src/com/isode/stroke/serializer/payloadserializers/CommandSerializer.java b/src/com/isode/stroke/serializer/payloadserializers/CommandSerializer.java
index 411e711..d4ec836 100644
--- a/src/com/isode/stroke/serializer/payloadserializers/CommandSerializer.java
+++ b/src/com/isode/stroke/serializer/payloadserializers/CommandSerializer.java
@@ -30,6 +30,10 @@ public class CommandSerializer extends GenericPayloadSerializer<Command> {
}
public String serializePayload(Command command) {
+ if (command == null) {
+ throw new NullPointerException("'command' must not be null");
+ }
+
XMLElement commandElement = new XMLElement("command",
"http://jabber.org/protocol/commands");
commandElement.setAttribute(Command.COMMAND_ATTRIBUTE_NODE, command
@@ -86,6 +90,10 @@ public class CommandSerializer extends GenericPayloadSerializer<Command> {
}
private String actionToString(Action action) {
+ if (action == null) {
+ throw new NullPointerException("'action' must not be null");
+ }
+
return action.getStringForm();
}
diff --git a/src/com/isode/stroke/serializer/payloadserializers/FormSerializer.java b/src/com/isode/stroke/serializer/payloadserializers/FormSerializer.java
index 6a3760b..c2a2189 100644
--- a/src/com/isode/stroke/serializer/payloadserializers/FormSerializer.java
+++ b/src/com/isode/stroke/serializer/payloadserializers/FormSerializer.java
@@ -42,6 +42,10 @@ public class FormSerializer extends GenericPayloadSerializer<Form> {
}
public String serializePayload(Form form) {
+ if (form == null) {
+ throw new NullPointerException("'form' must not be null");
+ }
+
XMLElement formElement = new XMLElement("x", "jabber:x:data");
String type = form.getType().getStringForm();
formElement.setAttribute(Form.FORM_ATTRIBUTE_TYPE, type);
@@ -59,6 +63,10 @@ public class FormSerializer extends GenericPayloadSerializer<Form> {
}
private XMLElement fieldToXML(FormField field) {
+ if (field == null) {
+ throw new NullPointerException("'field' must not be null");
+ }
+
XMLElement fieldElement = new XMLElement(Form.FORM_ELEMENT_FIELD);
if (!field.getName().isEmpty()) {
fieldElement.setAttribute(FormField.FORM_FIELD_ATTRIBUTE_VAR, field
@@ -164,6 +172,13 @@ public class FormSerializer extends GenericPayloadSerializer<Form> {
private void multiLineify(String text, String elementName,
XMLElement element) {
+ if (text == null) {
+ throw new NullPointerException("'text' must not be null");
+ }
+ if (elementName == null) {
+ throw new NullPointerException("'elementName' must not be null");
+ }
+
String unRdText = text.replaceAll("\r", "");
String[] lines = unRdText.split("\n");
for (String line : lines) {
diff --git a/src/com/isode/stroke/serializer/xml/XMLTextNode.java b/src/com/isode/stroke/serializer/xml/XMLTextNode.java
index 22a6785..b6940c4 100644
--- a/src/com/isode/stroke/serializer/xml/XMLTextNode.java
+++ b/src/com/isode/stroke/serializer/xml/XMLTextNode.java
@@ -31,6 +31,10 @@ public class XMLTextNode implements XMLNode {
* @return new object, will never be null
*/
public static XMLTextNode create(String text) {
+ if (text == null) {
+ throw new NullPointerException("'text' must not be null");
+ }
+
return new XMLTextNode(text);
}
}