src/org/ohmage/domain/campaign/prompt/MultiChoiceCustomPrompt.java
@Override
	public Object validateValue(
			final Object value) 
			throws DomainException {
		
		Collection<String> collectionValue = null;
		
		// If it's already a NoResponse value, then make sure that if it
		// was skipped that it is skippable.
		if(value instanceof NoResponse) {
			if(NoResponse.SKIPPED.equals(value) && (! skippable())) {
				throw new DomainException(
						"The prompt, '" +
							getId() +
							"', was skipped, but it is not skippable.");
			}
			
			//throw new NoResponseException((NoResponse) value);
			return value;
		}
		// If it's already a collection, first ensure that all of the elements
		// are strings.
		else if(value instanceof Collection<?>) {
			Collection<?> values = (Collection<?>) value;
			collectionValue = new HashSet<String>(values.size());
			
			for(Object currResponse : values) {
				if(currResponse instanceof String) {
					collectionValue.add((String) currResponse);
				}
				else {
					throw new DomainException(
						"An object in the list was not a valid label value for prompt '" +
							getId() +
							"'.");
				}
			}
		}
		// If it's a JSONArray, parse it and get the items.
		else if(value instanceof JSONArray) {
			JSONArray responses = (JSONArray) value;
			int numResponses = responses.length();
			collectionValue = new HashSet<String>(numResponses);
			
			for(int i = 0; i < numResponses; i++) {
				try {
					collectionValue.add(responses.getString(i));
				}
				catch(JSONException notKey) {
					throw new DomainException(
						"The value was a JSONArray, but not all of the elements were strings for prompt '" +
							getId() +
							"'.", 
						notKey);
				}
			}
		}
		// If it's a sting, parse it to check if it's a NoResponse value and,
		// if not, parse it and generate a list of values.
		else if(value instanceof String) {
			String valueString = (String) value;
			
			try {
				return NoResponse.valueOf(valueString);
			}
			catch(IllegalArgumentException notNoResponse) {
				try {
					JSONArray responses = new JSONArray(valueString);
					collectionValue = new HashSet<String>(responses.length());

					int numResponses = responses.length();
					for(int i = 0; i < numResponses; i++) {
						try {
							collectionValue.add(responses.getString(i));
						}
						catch(JSONException notString) {
							throw new DomainException(
								"One of the items in the list was not decodable as a string value for prompt '" +
									getId() +
									"'.");
						}
					}
				}
				catch(JSONException notJsonArray) {
					String[] responses = valueString.split(",");
					collectionValue = new HashSet<String>(responses.length);
					
					for(int i = 0; i < responses.length; i++) {
						String currResponse = responses[i];
						
						if(! StringUtils.isEmptyOrWhitespaceOnly(currResponse)) {
							collectionValue.add(currResponse);
						}
					}
				}
			}
		}
		else {
			throw new DomainException(
					"The value is not decodable as a reponse value for prompt '" +
						getId() +
						"'.");
		}
		
		Map<Integer, LabelValuePair> choices = getAllChoices();
		
		// If there are no default choices, set the next key to zero.
		int nextKey;
		if(choices.isEmpty()) {
			nextKey = 0;
		}
		// Otherwise, set the next key to the current maximum key plus one.
		else {
			List<Integer> keys = new ArrayList<Integer>(choices.keySet());
			Collections.sort(keys);
			nextKey = keys.get(keys.size() - 1) + 1;
		}
		
		// Now, get the known choices from the list.
		Collection<LabelValuePair> values = 
				new ArrayList<LabelValuePair>(choices.values());
		
		// Cycle through the decoded labels and, if one of those labels isn't 
		// found, add it to the collection.
		for(String labelValue : collectionValue) {
			boolean exists = false;
			for(LabelValuePair lvp : values) {
				if(lvp.getLabel().equals(labelValue)) {
					exists = true;
					break;
				}
			}
			
			if(! exists) {
				addChoice(nextKey++, labelValue, null);
				values.add(new LabelValuePair(labelValue, null));
			}
		}
		
		return collectionValue;
	}
/**
	 * Validates that a given value is valid and, if so, converts it into an
	 * appropriate object.
	 * 
	 * @param value The value to be validated. This must be one of the  
	 * 				following:<br />
	 * 				<ul>
	 * 				<li>{@link NoResponse}</li>
	 * 				<li>{@link Integer}. This will be converted into a list of
	 * 				  one items that contains this integer. The {@link Integer}
	 * 				  should be the key of the item that the user chose.</li>
	 * 				<li>A {@link Collection} of {@link String}s where each
	 * 				  {@link String} is the label for a unique item the user 
	 * 				  chose.</li>
	 * 				<li>A {@link JSONArray} of {@link String}s where each
	 * 				  {@link String} is the label for a unique item the user 
	 * 				  chose.</li>
	 * 				<li>{@link String} that represents:</li>
	 * 				  <ul>
	 * 				    <li>{@link NoResponse}</li>
	 * 				    <li>A {@link JSONArray} of {@link String}s where each
	 * 				      {@link String} is the label for a unique item the  
	 * 				      user chose.</li>
	 * 				    <li>A comma-separated list of {@link String}s where 
	 * 				      each {@link String} is the label for a unique item  
	 * 				      the user chose.</li>
	 * 				  <ul>
	 * 				</ul>
	 * 
	 * @return A {@link Collection} of {@link String}s or a {@link NoResponse}
	 * 		   object.
	 * 
	 * @throws DomainException The value is invalid.
	 */
Validates that a given value is valid and, if so, converts it into an
appropriate object.

@param value The value to be validated. This must be one of the
following:

 NoResponse
 Integer. This will be converted into a list of
one items that contains this integer. The  Integer
should be the key of the item that the user chose.
A  Collection of  Strings where each
String is the label for a unique item the user
chose.
A  JSONArray of  Strings where each
String is the label for a unique item the user
chose.
 String that represents:

 NoResponse
A  JSONArray of  Strings where each
String is the label for a unique item the
user chose.
A comma-separated list of  Strings where
each  String is the label for a unique item
the user chose.



@return A  Collection of  Strings or a  NoResponse
object.

@throws DomainException The value is invalid.
Validates that a given value is valid and if so converts it into an appropriate object . @param value The value to be validated . This must be one of the following : NoResponse Integer . This will be converted into a list of one items that contains this integer . The Integer should be the key of the item that the user chose . A Collection of Strings where each String is the label for a unique item the user chose . A JSONArray of Strings where each String is the label for a unique item the user chose . String that represents : NoResponse A JSONArray of Strings where each String is the label for a unique item the user chose . A comma - separated list of Strings where each String is the label for a unique item the user chose . @return A Collection of Strings or a NoResponse object . @throws DomainException The value is invalid .
@Override
	public Object validateValue(
			final Object value) 
			throws DomainException {
		Collection<String> collectionValue = null;
		if(value instanceof NoResponse) {
			if(NoResponse.SKIPPED.equals(value) && (! skippable())) {
				throw new DomainException(
						"The prompt, '" +
							getId() +
							"', was skipped, but it is not skippable.");
			}
			return value;
		}
		else if(value instanceof Collection<?>) {
			Collection<?> values = (Collection<?>) value;
			collectionValue = new HashSet<String>(values.size());
			for(Object currResponse : values) {
				if(currResponse instanceof String) {
					collectionValue.add((String) currResponse);
				}
				else {
					throw new DomainException(
						"An object in the list was not a valid label value for prompt '" +
							getId() +
							"'.");
				}
			}
		}
		else if(value instanceof JSONArray) {
			JSONArray responses = (JSONArray) value;
			int numResponses = responses.length();
			collectionValue = new HashSet<String>(numResponses);
			for(int i = 0; i < numResponses; i++) {
				try {
					collectionValue.add(responses.getString(i));
				}
				catch(JSONException notKey) {
					throw new DomainException(
						"The value was a JSONArray, but not all of the elements were strings for prompt '" +
							getId() +
							"'.", 
						notKey);
				}
			}
		}
		else if(value instanceof String) {
			String valueString = (String) value;
			try {
				return NoResponse.valueOf(valueString);
			}
			catch(IllegalArgumentException notNoResponse) {
				try {
					JSONArray responses = new JSONArray(valueString);
					collectionValue = new HashSet<String>(responses.length());
					int numResponses = responses.length();
					for(int i = 0; i < numResponses; i++) {
						try {
							collectionValue.add(responses.getString(i));
						}
						catch(JSONException notString) {
							throw new DomainException(
								"One of the items in the list was not decodable as a string value for prompt '" +
									getId() +
									"'.");
						}
					}
				}
				catch(JSONException notJsonArray) {
					String[] responses = valueString.split(",");
					collectionValue = new HashSet<String>(responses.length);
					for(int i = 0; i < responses.length; i++) {
						String currResponse = responses[i];
						if(! StringUtils.isEmptyOrWhitespaceOnly(currResponse)) {
							collectionValue.add(currResponse);
						}
					}
				}
			}
		}
		else {
			throw new DomainException(
					"The value is not decodable as a reponse value for prompt '" +
						getId() +
						"'.");
		}
		Map<Integer, LabelValuePair> choices = getAllChoices();
		int nextKey;
		if(choices.isEmpty()) {
			nextKey = 0;
		}
		else {
			List<Integer> keys = new ArrayList<Integer>(choices.keySet());
			Collections.sort(keys);
			nextKey = keys.get(keys.size() - 1) + 1;
		}
		Collection<LabelValuePair> values = 
				new ArrayList<LabelValuePair>(choices.values());
		for(String labelValue : collectionValue) {
			boolean exists = false;
			for(LabelValuePair lvp : values) {
				if(lvp.getLabel().equals(labelValue)) {
					exists = true;
					break;
				}
			}
			if(! exists) {
				addChoice(nextKey++, labelValue, null);
				values.add(new LabelValuePair(labelValue, null));
			}
		}
		return collectionValue;
	}
@ Override public Object validateValue ( final Object value ) throws DomainException { Collection < String > collectionValue = null ; if ( value instanceof NoResponse ) { if ( NoResponse . SKIPPED . equals ( value ) && ( ! skippable ( ) ) ) { throw new DomainException ( "The prompt, '" + getId ( ) + "', was skipped, but it is not skippable." ) ; } return value ; } else if ( value instanceof Collection < ? > ) { Collection < ? > values = ( Collection < ? > ) value ; collectionValue = new HashSet < String > ( values . size ( ) ) ; for ( Object currResponse : values ) { if ( currResponse instanceof String ) { collectionValue . add ( ( String ) currResponse ) ; } else { throw new DomainException ( "An object in the list was not a valid label value for prompt '" + getId ( ) + "'." ) ; } } } else if ( value instanceof JSONArray ) { JSONArray responses = ( JSONArray ) value ; int numResponses = responses . length ( ) ; collectionValue = new HashSet < String > ( numResponses ) ; for ( int i = 0 ; i < numResponses ; i ++ ) { try { collectionValue . add ( responses . getString ( i ) ) ; } catch ( JSONException notKey ) { throw new DomainException ( "The value was a JSONArray, but not all of the elements were strings for prompt '" + getId ( ) + "'." , notKey ) ; } } } else if ( value instanceof String ) { String valueString = ( String ) value ; try { return NoResponse . valueOf ( valueString ) ; } catch ( IllegalArgumentException notNoResponse ) { try { JSONArray responses = new JSONArray ( valueString ) ; collectionValue = new HashSet < String > ( responses . length ( ) ) ; int numResponses = responses . length ( ) ; for ( int i = 0 ; i < numResponses ; i ++ ) { try { collectionValue . add ( responses . getString ( i ) ) ; } catch ( JSONException notString ) { throw new DomainException ( "One of the items in the list was not decodable as a string value for prompt '" + getId ( ) + "'." ) ; } } } catch ( JSONException notJsonArray ) { String [ ] responses = valueString . split ( "," ) ; collectionValue = new HashSet < String > ( responses . length ) ; for ( int i = 0 ; i < responses . length ; i ++ ) { String currResponse = responses [ i ] ; if ( ! StringUtils . isEmptyOrWhitespaceOnly ( currResponse ) ) { collectionValue . add ( currResponse ) ; } } } } } else { throw new DomainException ( "The value is not decodable as a reponse value for prompt '" + getId ( ) + "'." ) ; } Map < Integer , LabelValuePair > choices = getAllChoices ( ) ; int nextKey ; if ( choices . isEmpty ( ) ) { nextKey = 0 ; } else { List < Integer > keys = new ArrayList < Integer > ( choices . keySet ( ) ) ; Collections . sort ( keys ) ; nextKey = keys . get ( keys . size ( ) - 1 ) + 1 ; } Collection < LabelValuePair > values = new ArrayList < LabelValuePair > ( choices . values ( ) ) ; for ( String labelValue : collectionValue ) { boolean exists = false ; for ( LabelValuePair lvp : values ) { if ( lvp . getLabel ( ) . equals ( labelValue ) ) { exists = true ; break ; } } if ( ! exists ) { addChoice ( nextKey ++ , labelValue , null ) ; values . add ( new LabelValuePair ( labelValue , null ) ) ; } } return collectionValue ; }
Validates that a given value is valid and, if so, converts it into an
 appropriate object.
Validates that a given value is valid and if so converts it into an appropriate object .
// If it's already a NoResponse value, then make sure that if it // was skipped that it is skippable. //throw new NoResponseException((NoResponse) value); // If it's already a collection, first ensure that all of the elements // are strings. // If it's a JSONArray, parse it and get the items. // If it's a sting, parse it to check if it's a NoResponse value and, // if not, parse it and generate a list of values. // If there are no default choices, set the next key to zero. // Otherwise, set the next key to the current maximum key plus one. // Now, get the known choices from the list. // Cycle through the decoded labels and, if one of those labels isn't  // found, add it to the collection.