/*
* Created on Oct 3, 2006
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package com.any_service_provider.gateways.pvs.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
import javax.jms.Message;
import javax.jms.TextMessage;
import org.jdom.Document;
import org.jdom.Element;
import org.openeai.config.CommandConfig;
import org.openeai.config.EnterpriseConfigurationObjectException;
import org.openeai.config.PropertyConfig;
import org.openeai.jms.consumer.commands.CommandException;
import org.openeai.jms.consumer.commands.RequestCommand;
import org.openeai.jms.consumer.commands.RequestCommandImpl;
import org.openeai.xml.XmlDocumentReader;
import org.openeai.xml.XmlDocumentReaderException;
import org.openeai.layouts.EnterpriseLayoutException;
import org.openeai.moa.XmlEnterpriseObjectException;
import org.openeai.config.EnterpriseFieldException;
import com.any_service_provider.gateways.pvs.PasswordValidationException;
import com.any_service_provider.gateways.pvs.PasswordValidationRule;
import com.openii.moa.jmsobjects.services.v1_0.PasswordValidation;
import com.openii.moa.objects.resources.v1_0.*;
/**
* @author tcerven
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class PasswordValidationRequestCommand extends RequestCommandImpl implements RequestCommand {
private Document m_responseDoc = null; // the primed XML response document
private Vector validationRules = null; // list of rules
private ValidationStatus noViolation; // the "ok" validation status pre-build for speed
/**
* @param CommandConfig
* @throws InstantiationException
* <P>
* This constructor initializes the command using a CommandConfig object. It
* invokes the constructor of the ancestor, RequestCommandImpl, and then
* retrieves one PropertyConfig object from AppConfig by name and gets and
* sets the command properties using that PropertyConfig object. This means
* that this command must have one PropertyConfig object in its configuration
* named 'PasswordValidationRequestCommandProperties'. This constructor also initializes
* the response document and provide document used in replies. It also gets a
* pool of PubSubProducers from AppConfig for the command to use in publishing
* sync messages. The command excpects a producer pool named
* 'EgsSubSubProducerPool'. Then the constuctor gets the value of the
* defaultGreetingText property and sets the value of the defaultGreetingText
* to use if no Greetee information is received in a request.
*/
public PasswordValidationRequestCommand(CommandConfig cConfig) throws InstantiationException {
super(cConfig);
// Get and set the general properties for this command.
PropertyConfig pConfig = new PropertyConfig();
try {
pConfig = (PropertyConfig)getAppConfig()
.getObject("PasswordValidationRequestCommandProperties");
}
catch (EnterpriseConfigurationObjectException eoce) {
String errMsg = "Error retrieving a PropertyConfig object from " +
"AppConfig: The exception is: " + eoce.getMessage();
logger.fatal("[PasswordValidationRequestCommand] " + errMsg);
throw new InstantiationException(errMsg);
}
setProperties(pConfig.getProperties());
try {
// check from AppConfig resources needed during processing
PasswordValidationQuerySpecification vpasswordQuery = (PasswordValidationQuerySpecification)getAppConfig().getObject("ValidPasswordQuerySpecification.v1_0");
} catch (EnterpriseConfigurationObjectException e1) {
String errMsg = "Error retrieving a ValidPasswordQuerySpecification object from " +
"AppConfig: The exception is: " + e1.getMessage();
logger.fatal("[PasswordValidationRequestCommand] " + errMsg);
throw new InstantiationException(errMsg);
}
// Initialize response document.
XmlDocumentReader xmlReader = new XmlDocumentReader();
try {
logger.debug("[PasswordValidationRequestCommand] " +
"responseDocumentUri: " + getProperties()
.getProperty("responseDocumentUri"));
m_responseDoc = xmlReader.initializeDocument(getProperties()
.getProperty("responseDocumentUri"), getOutboundXmlValidation());
if (m_responseDoc == null) {
String errMsg = "Missing 'responseDocumentUri' " +
"property in the deployment descriptor. Can't continue.";
logger.fatal("[PasswordValidationRequestCommand] " + errMsg);
throw new InstantiationException(errMsg);
}
}
catch (XmlDocumentReaderException e) {
logger.fatal("[PasswordValidationRequestCommand] Error initializing" +
" the primed documents.");
e.printStackTrace();
throw new InstantiationException(e.getMessage());
}
// Initialize "good" validation status
noViolation = new ValidationStatus();
try {
noViolation.setStatusCode(getProperties().getProperty("validationStatusCode"));
noViolation.setDescription(getProperties().getProperty("description"));
noViolation.setExplanation(getProperties().getProperty("explanation"));
logger.info("[PasswordValidationRequestCommand] no violation validation status is: "
+noViolation.toXmlString());
} catch (EnterpriseFieldException e3) {
String errMsg = "Error retrieving an creating ValidationStatus for no violations. "
+ "The exception is: " + e3.getMessage();
logger.fatal("[PasswordValidationRequestCommand] " + errMsg);
throw new InstantiationException(errMsg);
} catch (XmlEnterpriseObjectException e4) {
String errMsg = "Error retrieving an creating ValidationStatus for no violations. "
+ "The exception is: " + e4.getMessage();
logger.fatal("[PasswordValidationRequestCommand] " + errMsg);
throw new InstantiationException(errMsg);
}
try {
List rules = getAppConfig().getObjectsLike("RuleProperties");
if (rules.size()>0) {
validationRules = new Vector();
logger.info("[PasswordValidationRequestCommand] "+rules.size()+" validation rules to load.");
for (int i=0;i<rules.size();i++) {
Properties ruleProps = ((PropertyConfig)rules.get(i)).getProperties();
String ruleClass = ruleProps.getProperty("ruleClass");
if (ruleClass!=null) {
logger.info("[PasswordValidationRequestCommand] Loading validation rule: "+ruleClass);
PasswordValidationRule rule = (PasswordValidationRule)this.getClass().getClassLoader()
.loadClass(ruleClass).newInstance();
rule.setProperites(ruleProps);
validationRules.add(rule);
logger.info("[PasswordValidationRequestCommand] "+ruleClass+" loaded.");
}
}
}
}
catch (EnterpriseConfigurationObjectException eoce) {
String errMsg = "Error retrieving a PropertyConfig object from " +
"AppConfig: The exception is: " + eoce.getMessage();
logger.fatal("[PasswordValidationRequestCommand] " + errMsg);
throw new InstantiationException(errMsg);
} catch (InstantiationException e) {
String errMsg = "InstantiationException loading validation rule: " + e.getMessage();
logger.fatal("[PasswordValidationRequestCommand] " + errMsg);
throw new InstantiationException(errMsg);
} catch (IllegalAccessException e) {
String errMsg = "IllegalAccessException loading validation rule: " + e.getMessage();
logger.fatal("[PasswordValidationRequestCommand] " + errMsg);
throw new InstantiationException(errMsg);
} catch (ClassNotFoundException e) {
String errMsg = "ClassNotFoundException loading validation rule: " + e.getMessage();
logger.fatal("[PasswordValidationRequestCommand] " + errMsg);
throw new InstantiationException(errMsg);
}
}
/**
* @param int, the number of the message processed by the consumer.
* @param Message, the message for the command to process.
* @throws CommandException, with details of the error processing the message.
* <P>
* This method makes a local copy of the response and provide documents to
* use in the reply to the request. Then it converts the JMS message to an XML
* document, retrieves the text portion of the message, clears the message
* body in preparation for the reply, gets the ControlArea from the XML
* document, and verifies that message object of the message is a
* ValidPassword. If the message object is not a ValidPassword, the command replies with
* an error to the client. If the message object is a ValidPassword, it processes
* the message. The comments above contain a detailed description of the
* processing logic for supported message actions for a ValidPassword. That logic
* is implemented in this method.
*/
public final Message execute(int messageNumber, Message aMessage)
throws CommandException {
// Make a local copy of the response document to use in the replies.
Document localResponseDoc = (Document)m_responseDoc.clone();
// Convert the JMS Message to an XML Document
Document inDoc = null;
try {
inDoc = initializeInput(messageNumber, aMessage);
}
catch (Exception e) {
String errMsg = "Exception occurred processing input message in " +
"org.openeai.jms.consumer.commands.Command. Exception: " +
e.getMessage();
throw new CommandException(errMsg);
}
// Retrieve text portion of message.
TextMessage msg = (TextMessage)aMessage;
try {
// Clear the message body for the reply, so we do not
// have to do it later.
msg.clearBody();
}
catch (Exception e) {
String errMsg = "Error clearing the message body.";
throw new CommandException(errMsg + ". The exception is: " +
e.getMessage());
}
// Get the ControlArea from XML document.
Element eControlArea = getControlArea(inDoc.getRootElement());
// Get messageAction and messageObject attributes from the
// ControlArea element.
String msgAction = eControlArea.getAttribute("messageAction").getValue();
String msgObject = eControlArea.getAttribute("messageObject").getValue();
// Verify that the message object we are dealing with is a ValidAddress; if not,
// reply with an error.
if (msgObject.equalsIgnoreCase("PasswordValidation") == false) {
String errType = "application";
String errCode = "OpenEAI-1001";
String errDesc = "Unsupported message object: " + msgObject +
". This command expects 'ValidPassword'.";
logger.fatal("[PasswordValidationRequestCommand] " + errDesc);
logger.fatal("[PasswordValidationRequestCommand] Message sent in is: \n" +
getMessageBody(inDoc));
ArrayList errors = new ArrayList();
errors.add(buildError(errType, errCode, errDesc));
String replyContents =
buildReplyDocumentWithErrors(eControlArea, localResponseDoc, errors);
return getMessage(msg, replyContents);
}
// Handle a Query-Request.
if (msgAction.equalsIgnoreCase("Query")) {
logger.info("[PasswordValidationRequestCommand] Handling an " +
"com.openii.Services.PasswordValidation.Query-Request" +
" message.");
Element eQuerySpec = inDoc.getRootElement().getChild("DataArea").getChild("PasswordValidationQuerySpecification");
// Verify that ValidPasswordQuerySpecification element is not null; if it is, reply with an error.
if (eQuerySpec == null) {
String errType = "application";
String errCode = "OpenEAI-1015";
String errDesc = "Invalid PasswordValidationQuerySpecification element found in the Query-Request message. This command expects a ValidPasswordQuerySpecification.";
logger.fatal("[PasswordValidationRequestCommand] " + errDesc);
logger.fatal("Message sent in is: \n" + getMessageBody(inDoc));
ArrayList errors = new ArrayList();
errors.add(buildError(errType, errCode, errDesc));
String replyContents =
buildReplyDocumentWithErrors(eControlArea, localResponseDoc, errors);
return getMessage(msg, replyContents);
}
// Initialize the ValidPasswordQuerySpecification object and a list of statuses, and a ValidPassword for the response
//ValidPasswordQuerySpecification querySpec = new ValidPasswordQuerySpecification();
PasswordValidationQuerySpecification querySpec;
Vector validationStatuses = new Vector();
PasswordValidation validPassword = new PasswordValidation();
try {
querySpec = (PasswordValidationQuerySpecification)getAppConfig().getObject("ValidPasswordQuerySpecification.v1_0");
querySpec.buildObjectFromInput(eQuerySpec);
String candidate = querySpec.getCandidatePassword();
logger.info("[PasswordValidationRequestCommand] Password to validate is: "+candidate);
validPassword.setCandidatePassword(candidate);
validPassword.setIdentifier(querySpec.getIdentifier());
// Here's where the validation occurs
for (int i=0;i<validationRules.size();i++) {
logger.info("[PasswordValidationRequestCommand] Running rule "+i+"...");
PasswordValidationRule rule=(PasswordValidationRule)validationRules.get(i);
ValidationStatus status=rule.validate(querySpec);
if (status!=null) {
logger.info("[PasswordValidationRequestCommand] Candidate password "+candidate
+" violates rule "+i+", "+rule.getClass().getName());
validationStatuses.add(status);
}
}
// check for rule violation. If none, return validation status 0
if (validationStatuses.size()==0) {
validationStatuses.add(noViolation);
}
// add ValidationStatuses to ValidPassword
validPassword.setValidationStatus(validationStatuses);
} catch (EnterpriseLayoutException ele) {
logger.fatal("[PasswordValidationRequestCommand] Error building PasswordValidationQuerySpecification " +
"object from Query object: The exception is: " + ele.getMessage());
String errType = "application";
String errCode = "OpenEAI-1015";
String errDesc = "EnterpriseLayoutException thrown during PasswordValidationQuerySpecification build.";
logger.fatal("[PasswordValidationRequestCommand] " + errDesc);
logger.fatal("Message sent in is: \n" + getMessageBody(inDoc));
ArrayList errors = new ArrayList();
errors.add(buildError(errType, errCode, errDesc));
String replyContents =
buildReplyDocumentWithErrors(eControlArea, localResponseDoc, errors);
return getMessage(msg, replyContents);
} catch (EnterpriseFieldException efe) {
logger.fatal("[PasswordValidationRequestCommand] Password validation processing error. The exception is: "
+ efe.getMessage());
String errType = "application";
String errCode = "OpenEAI-1016";
String errDesc = "EnterpriseFieldException thrown during address build.";
logger.fatal("[PasswordValidationRequestCommand] " + errDesc);
logger.fatal("Message sent in is: \n" + getMessageBody(inDoc));
ArrayList errors = new ArrayList();
errors.add(buildError(errType, errCode, errDesc));
String replyContents =
buildReplyDocumentWithErrors(eControlArea, localResponseDoc, errors);
return getMessage(msg, replyContents);
} catch (PasswordValidationException e) {
logger.fatal("[PasswordValidationRequestCommand] Password validation processing error. The exception is: "
+ e.getMessage());
String errType = "application";
String errCode = "OpenEAI-1017";
String errDesc = "PasswordValidationException thrown during address build.";
logger.fatal("[PasswordValidationRequestCommand] " + errDesc);
logger.fatal("Message sent in is: \n" + getMessageBody(inDoc));
ArrayList errors = new ArrayList();
errors.add(buildError(errType, errCode, errDesc));
String replyContents =
buildReplyDocumentWithErrors(eControlArea, localResponseDoc, errors);
return getMessage(msg, replyContents);
} catch (EnterpriseConfigurationObjectException e) {
logger.fatal("[PasswordValidationRequestCommand] Password validation processing error. The exception is: "
+ e.getMessage());
String errType = "application";
String errCode = "OpenEAI-1018";
String errDesc = "PasswordValidationException thrown during password query spec build.";
logger.fatal("[PasswordValidationRequestCommand] " + errDesc);
logger.fatal("Message sent in is: \n" + getMessageBody(inDoc));
ArrayList errors = new ArrayList();
errors.add(buildError(errType, errCode, errDesc));
String replyContents =
buildReplyDocumentWithErrors(eControlArea, localResponseDoc, errors);
return getMessage(msg, replyContents);
}
// Serialize the ValidPassord and place it into the reply.
String replyContents = null;
try {
localResponseDoc.getRootElement().getChild("DataArea").removeContent();
localResponseDoc.getRootElement().getChild("DataArea")
.addContent((Element)validPassword.buildOutputFromObject());
replyContents = buildReplyDocument(eControlArea, localResponseDoc);
}
catch (EnterpriseLayoutException ele) {
// There was an error building the ValidPassword element from the quuery request
// object.
String errType = "application";
String errCode = "PasswordValidationService-1004";
String errDesc = "Error building ValidPassord element from the ValidPassword " +
"object. The exception is: " + ele.getMessage();
logger.fatal("[PasswordValidationRequestCommand " + errDesc);
ArrayList errors = new ArrayList();
errors.add(buildError(errType, errCode, errDesc));
replyContents = buildReplyDocumentWithErrors(eControlArea,
localResponseDoc, errors);
return getMessage(msg, replyContents);
}
// Return the response with status success.
return getMessage(msg, replyContents);
} else {
// The messageAction is invalid; it is not a query.
String errType = "application";
String errCode = "OpenEAI-1002";
String errDesc = "Unsupported message action: " + msgAction + ". " +
"This command only supports 'query'.";
logger.fatal("[PasswordValidationRequestCommand] " + errDesc);
logger.fatal("Message sent in is: \n" + getMessageBody(inDoc));
ArrayList errors = new ArrayList();
errors.add(buildError(errType, errCode, errDesc));
String replyContents =
buildReplyDocumentWithErrors(eControlArea, localResponseDoc, errors);
return getMessage(msg, replyContents);
}
}
}