/* vim: set ts=2 et sw=2 cindent fo=qroca: */
package com.globant.katari.hibernate.coreuser;
import org.apache.commons.lang.Validate;
import java.util.List;
import java.util.LinkedList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** A message to notify that a user is being deleted, and its response.
*/
public class DeleteMessage {
/** The class logger.
*/
private static Logger log = LoggerFactory.getLogger(DeleteMessage.class);
/** The id of the user to delete.
*/
private long userId;
/** The list of aggregated causes that stops the entity from being deleted.
*
* This is never null.
*/
private List<String> causes = new LinkedList<String>();
/** Marks this delete message as a delete request.
*/
private boolean request = true;
/** Creates a message to notify listeners that a user is being deleted.
*
* @param theUserId the id of the user to delete.
*/
public DeleteMessage(final long theUserId) {
userId = theUserId;
}
/** Constructor for a 'goAhead' delete message response.
*
* @param theUserId the id of the user to delete.
*
* @param response ignored. This is a 'mark' parameter to distinguish this
* constructor from the delete user request constructor.
*/
private DeleteMessage(final long theUserId, final boolean response) {
request = false;
userId = theUserId;
}
/** Constructor for a 'reject' delete message response.
*
* @param theUserId the id of the user to delete.
*
* @param theCause The motive of the rejection. It cannot be null.
*/
private DeleteMessage(final long theUserId, final String theCause) {
Validate.notNull(theCause, "The cause cannot be null.");
request = false;
userId = theUserId;
causes.add(theCause);
}
/** Constructor for an aggregated 'reject' delete message response.
*
* @param theUserId the id of the user to delete.
*
* @param theCauses The motives of the rejection. It cannot be null.
*/
private DeleteMessage(final long theUserId, final List<String> theCauses) {
Validate.notNull(theCauses, "The causes cannot be null.");
request = false;
userId = theUserId;
causes.addAll(theCauses);
}
/** Obtains the id of the user to delete.
*
* @return the user id.
*/
public long getUserId() {
return userId;
}
/** Generates a go ahead message response to this request.
*
* @return a delete message response to allow the delete operation.
*/
public DeleteMessage goAhead() {
Validate.isTrue(request, "This only makes sense for a request.");
return new DeleteMessage(userId, true);
}
/** Generates a reject message response to this request.
*
* @param theCause The reason that this delete request is rejected. It cannot
* be null.
*
* @return a delete message response to reject the delete operation.
*/
public DeleteMessage reject(final String theCause) {
Validate.isTrue(request, "This only makes sense for a request.");
return new DeleteMessage(userId, theCause);
}
/** True if the user can be safely deleted.
*
* This operation also returns true if this message corresponds to a request
* event. This is helpful if you want to use the default null event listener,
* that just copies the input to its output.
*
* @return true if the user can be deleted.
*/
public boolean canDelete() {
return causes.isEmpty();
}
/** A message to show to the admin if the user could not be deleted.
*
* Can only be callod if canDelete returns false.
*
* @param prefix the prefix to prepend to each of the reject causes. It
* cannot be null.
*
* @param suffix the suffix to append to each of the reject causes. It cannot
* be null.
*
* @return a string with the message to show.
*/
public String getMessage(final String prefix, final String suffix) {
Validate.notNull(prefix, "The prefix cannot be null.");
Validate.notNull(suffix, "The suffix cannot be null.");
StringBuilder builder = new StringBuilder();
for (String cause : causes) {
builder.append(prefix).append(cause).append(suffix);
}
return builder.toString();
}
/** Creates a new message that results in merging this message with the
* provided one.
*
* The resulting message can only be a go ahead message if this message and
* the provided one are both go ahead messages. Otherwise, the returned
* message in a rejection.
*
* The new message contains all the causes of both messages.
*
* @param message The message to merge with this. It cannot be null.
*
* @return a new aggregated message, never null.
*/
public DeleteMessage aggregate(final DeleteMessage message) {
log.trace("Entering aggregate({})", message);
Validate.notNull(message, "The message cannot be null.");
Validate.isTrue(!request, "This only makes sense for a response.");
DeleteMessage result = this;
if (!message.canDelete()) {
List<String> allCauses = new LinkedList<String>();
if (canDelete()) {
allCauses.addAll(message.causes);
result = new DeleteMessage(userId, allCauses);
} else {
allCauses.addAll(causes);
allCauses.addAll(message.causes);
result = new DeleteMessage(userId, allCauses);
}
}
log.trace("Leaving aggregate");
return result;
}
/** Returns a human readable representation of this message.
*
* @return a string, never null.
*/
public String toString() {
if (request) {
return "Request to delete user " + userId;
} else if (causes.isEmpty()) {
return "Request to delete user " + userId + " allowed.";
} else {
return "Request to delete user " + userId + " rejected:"
+ getMessage("", "\n");
}
}
}