/*******************************************************************************
$Source: /cvs/repositories/openii3/project/java/examples/org/any_openeai_enterprise/services/egs/commands/GreetingRequestCommand.java,v $
$Revision: 1.3 $
*******************************************************************************/
/**********************************************************************
This file is part of the OpenEAI sample, reference implementation,
and deployment management suite created by Tod Jackson
(tod@openeai.org) and Steve Wheat (steve@openeai.org).
Copyright (C) 2003 The OpenEAI Software Foundation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For specific licensing details and examples of how this software
can be used to implement integrations for your enterprise, visit
http://www.OpenEai.org/licensing.
*/
package org.any_openeai_enterprise.services.egs.commands;
// Core Java
import java.util.ArrayList;
import javax.jms.*;
// JDOM
import org.jdom.*;
import org.jdom.output.XMLOutputter;
// General OpenEAI foundation
import org.openeai.config.*;
import org.openeai.xml.*;
import org.openeai.jms.consumer.commands.*;
import org.openeai.jms.producer.*;
import org.openeai.layouts.EnterpriseLayoutException;
import org.openeai.moa.EnterpriseObjectSyncException;
// Objects and message objects from OpenEAI implementations
import org.any_openeai_enterprise.moa.objects.resources.v1_0.Greetee;
import org.any_openeai_enterprise.moa.jmsobjects.coreapplication.v1_0.Greeting;
/**
* This class implements the message support of the EnterpriseGreetingService.
* <P>
* Specifically, this command handles
* org.any-openeai-enterprise.CoreApplication.Greeting.Generate-Request messages
* and replies with an
* org.any-openeai-enterprise.CoreApplication.Greeting.Response-Reply.
* <P>
* <B>1. org.any-openeai-enterprise.CoreApplication.Greeting.Generate-Request</B>
* <P>
* Gets the value of the Greetee/FullName and concatenates, 'Hello', the
* value of the FullName, and '!' to generate the Greeting.
* <P>
* <B>Configuration Parameters:</B>
* <P>
* This command expects exactly one properties object in the command
* configuration named 'GreetingRequestCommandProperties' with the following
* properties. The properties object may have any name, because it is retrieved
* by type.
* <P>
* <TABLE BORDER=2 CELLPADDING=5 CELLSPACING=2>
* <TR>
* <TH>Name</TH>
* <TH>Required</TH>
* <TH>Description</TH>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD>responseDocumentUri</TD>
* <TD>yes</TD>
* <TD>URI for retrieving the primed
* org.any-openeai-enterprise.CoreMessaging.Greeting.Response-Reply document</TD>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD>defaultGreetingText</TD>
* <TD>yes</TD>
* <TD>Default text to use for a greeting, of no other input is provided.</TD>
* </TR>
* </TABLE>
* <P>
* <B>Error Messages:</B>
* <P>
* <TABLE BORDER=2 CELLPADDING=5 CELLSPACING=2>
* <TR>
* <TH>Code</TH>
* <TH>Type</TH>
* <TH>Description</TH>
* <TH>Explanation</TH>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD><NOBR>OpenEAI-1001</NOBR></TD>
* <TD>application</TD>
* <TD>Unsupported message object: [unsupported message object name]. This
* 'Greeting')</TD>
* <TD>Somehow the wrong message object name is getting placed into the
* message by the sending application or it is sending the wrong message
* entirely.</TD>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD><NOBR>OpenEAI-1002</NOBR></TD>
* <TD>application</TD>
* <TD>Unsupported message action: [unsupported message action name]. This
* command only supports '[supported message action name(s)]'. (in this case
* 'generate')</TD>
* <TD>Somehow the wrong message action name is getting placed into the
* message by the sending application or it is sending the wrong message
* entirely. This command only supports Generate-Request messages.</TD>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD><NOBR>OpenEAI-1015</NOBR></TD>
* <TD>application</TD>
* <TD>Invalid generate element found in the Generate-Request message. This
* command expects a Greetee.</TD>
* <TD>Somehow the wrong generate object is getting placed into the
* message by the sending application. A Greetee object is expected.</TD>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD><NOBR>EnterpriseGreetingService-1001</NOBR></TD>
* <TD>application</TD>
* <TD>An error occurred building the Greetee object from the Greetee element
* in the Generate-Request. The exception is: [EnterpriseLayoutException
* message].</TD>
* <TD>There was an error building the Greetee XmlEnterpriseObject from the
* Greetee element in the message. Verify that the Greetee object sent in
* has allowable values.</TD>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD><NOBR>EnterpriseGreetingService-1002</NOBR></TD>
* <TD>application</TD>
* <TD>An error occurred setting the value of the greeting text. The exception
* is: [EnterpriseFieldException message].</TD>
* <TD>There was an error setting the value of the greeting text. Verify that
* the command is generating a value allowed by the enterprise objects document
* used for greeting.</TD>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD><NOBR>EnterpriseGreetingService-1003</NOBR></TD>
* <TD>application</TD>
* <TD>An error occurred retrieving a pub/sub producer to use to publish the
* Greeting.Create-Sync message. The exception is: [JMSException message].</TD>
* <TD>Verify that the ProducerPool is correctly configured and that the
* JMS Provider is operating and the producers are able to connect to it.</TD>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD><NOBR>EnterpriseGreetingService-1004</NOBR></TD>
* <TD>application</TD>
* <TD>An error occurred building the greeting element from the greeting object.
* The exception is: [EnterpriseLayoutException message].</TD>
* <TD>Verify that the command is generating a value allowed by the enterprise
* objects document used for greeting.</TD>
* </TR>
* <TR HALIGN="left" VALIGN="top">
* <TD><NOBR>EnterpriseGreetingService-1005</NOBR></TD>
* <TD>application</TD>
* <TD>An error occurred publishing the Greeting.Create-Sync message to
* communicate this create action to the rest of the enterprise. The
* Generate-Request cannot be processed. The exception is:
* [EnterpriseLayoutException message].</TD>
* <TD>Verify that the command is generating a value allowed by the enterprise
* objects document used for greeting.</TD>
* </TR>
* </TABLE>
* <P>
* @author Steve Wheat (steve@openeai.org)
* @version 1.0 - 24 September 2003
*/
public class GreetingRequestCommand
extends RequestCommandImpl implements RequestCommand {
private Document m_responseDoc = null; // the primed XML response document
private ProducerPool m_pubSubProducerPool = null; // for publishing syncs
private String m_defaultGreetingText = null; // default greeting text
/**
* @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 'GreetingRequestCommandProperties'. 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 GreetingRequestCommand(CommandConfig cConfig) throws
InstantiationException {
super(cConfig);
// Get and set the general properties for this command.
PropertyConfig pConfig = new PropertyConfig();
try {
pConfig = (PropertyConfig)getAppConfig()
.getObject("GreetingRequestCommandProperties");
}
catch (EnterpriseConfigurationObjectException eoce) {
String errMsg = "Error retrieving a PropertyConfig object from " +
"AppConfig: The exception is: " + eoce.getMessage();
logger.fatal("[GreetingRequestCommand] " + errMsg);
throw new InstantiationException(errMsg);
}
setProperties(pConfig.getProperties());
// Initialize response document.
XmlDocumentReader xmlReader = new XmlDocumentReader();
try {
logger.debug("[GreetingRequestCommand] " +
"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("[GreetingRequestCommand] " + errMsg);
throw new InstantiationException(errMsg);
}
}
catch (XmlDocumentReaderException e) {
logger.fatal("[GreetingRequestCommand] Error initializing" +
" the primed documents.");
e.printStackTrace();
throw new InstantiationException(e.getMessage());
}
// Initialize a pub/sub producer pool.
try {
m_pubSubProducerPool = (ProducerPool)getAppConfig().
getObject("EgsPubSubProducerPool");
}
catch (EnterpriseConfigurationObjectException eoce) {
String errMsg = "Error retrieving a ProducerPool object " +
"from AppConfig. The exception is: " + eoce.getMessage();
logger.fatal("[GreetingRequestCommand] " + errMsg);
throw new InstantiationException(errMsg);
}
// Get the defaultGreetingText property.
String defaultGreetingText = getProperties()
.getProperty("defaultGreetingText");
if (defaultGreetingText == null || defaultGreetingText.equals("")) {
throw new InstantiationException("Missing 'defaultGreetingText' " +
"property in the deployment descriptor. Can't continue.");
}
setDefaultGreetingText(defaultGreetingText);
logger.info("[GreetingRequestCommand] defaultGreetingText is '" +
getDefaultGreetingText() + "'.");
logger.info("[GreetingRequestCommand] instantiated successfully.");
}
/**
* @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
* Greeting. If the message object is not a Greeting, the command replies with
* an error to the client. If the message object is a Greeting, it processes
* the message. The comments above contain a detailed description of the
* processing logic for supported message actions for a Greeting. 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 Greeting; if not,
// reply with an error.
if (msgObject.equalsIgnoreCase("Greeting") == false) {
String errType = "application";
String errCode = "OpenEAI-1001";
String errDesc = "Unsupported message object: " + msgObject +
". This command expects 'Greeting'.";
logger.fatal("[GreetingRequestCommand] " + errDesc);
logger.fatal("[GreetingRequestCommand] 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);
}
// Get a configured Greeting and Greetee from AppConfig.
Greeting greeting = new Greeting();
try {
greeting = (Greeting)getAppConfig().getObjectByType(greeting.getClass()
.getName());
}
catch (EnterpriseConfigurationObjectException eoce) {
logger.fatal("[GreetingRequestCommand] Error retrieving a Greeting " +
"object from AppConfig: The exception is: " + eoce.getMessage());
}
Greetee greetee = new Greetee();
try {
greetee = (Greetee)getAppConfig().getObjectByType(greetee.getClass()
.getName());
}
catch (EnterpriseConfigurationObjectException eoce) {
logger.fatal("[GreetingRequestCommand] Error retrieving a Greeting " +
"object from AppConfig: The exception is: " + eoce.getMessage());
}
// Handle a Generate-Request.
if (msgAction.equalsIgnoreCase("Generate")) {
logger.info("[GreetingRequestCommand] Handling an " +
"org.any-openeai-enterprise.CoreApplication.Greeting.Generate-Request" +
" message.");
Element eGreetee = inDoc.getRootElement().getChild("DataArea")
.getChild("Greetee");
// Verify that Greetee element is not null; if it is, reply with an error.
if (eGreetee == null) {
String errType = "application";
String errCode = "OpenEAI-1015";
String errDesc = "Invalid generate element found in the Generate-" +
"Request message. This command expects a Greetee.";
logger.fatal("[GreetingRequestCommand] " + 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);
}
// Now build a Greetee object from the Greetee element in the message.
try {
greetee.buildObjectFromInput(eGreetee);
}
catch (EnterpriseLayoutException ele) {
// There was an error building the Greetee object from a Greetee
// element.
String errType = "application";
String errCode = "EnterpriseGreetingService-1001";
String errDesc = "An error occurred building Greetee object from the " +
"Greetee element in the Generate-Request message. The exception " +
"is: " + ele.getMessage();
logger.fatal("[GreeteeRequestCommand] " + 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);
}
// Generate the greeting.
try {
if (greetee.getFullName() != null && greetee.getFullName() != "") {
// There is a greetee with a name to greet. Prepare the greeting text.
greeting.setText("Hello, " + greetee.getFullName() + "!");
}
else {
// There is no greetee with a name to greet. Use the default greeting
// text.
greeting.setText(getDefaultGreetingText());
}
}
catch (EnterpriseFieldException efe) {
// An error occurred setting the value of the greeting text. Log it and
// reply with an error.
String errType = "application";
String errCode = "EnterpriseGreetingService-1002";
String errDesc = "An error occurred setting the value of the " +
"greeting text. The exception is: " + efe.getMessage();
logger.fatal("[GreetingRequestCommand " + errDesc);
ArrayList errors = new ArrayList();
errors.add(buildError(errType, errCode, errDesc));
String replyContents =
buildReplyDocumentWithErrors(eControlArea, localResponseDoc, errors);
return getMessage(msg, replyContents);
}
// Set the TestId.
greeting.setTestId(greetee.getTestId());
// Get pub/sub producer to use in this transaction.
PubSubProducer pub = null;
try {
pub = (PubSubProducer)m_pubSubProducerPool.getProducer();
}
catch (JMSException jmse) {
// An error occurred retrieving a pub/sub producer to use to publish
// the Greeting.Create-Sync. Log it and reply with an error.
String errType = "application";
String errCode = "EnterpriseGreetingService-1003";
String errDesc = "An error occurred retrieving a pub/sub producer to " +
"use to publish the Greeting.Create-Sync. The exception is: " +
jmse.getMessage();
logger.fatal("[GreetingRequestCommand " + errDesc);
ArrayList errors = new ArrayList();
errors.add(buildError(errType, errCode, errDesc));
String replyContents =
buildReplyDocumentWithErrors(eControlArea, localResponseDoc, errors);
return getMessage(msg, replyContents);
}
// Serialize the greeting and place it into the reply.
String replyContents = null;
try {
localResponseDoc.getRootElement().getChild("DataArea").removeContent();
localResponseDoc.getRootElement().getChild("DataArea").
addContent((Element)greeting.buildOutputFromObject());
replyContents = buildReplyDocument(eControlArea, localResponseDoc);
}
catch (EnterpriseLayoutException ele) {
// There was an error building the Greeting element from the Greeting
// object.
String errType = "application";
String errCode = "EnterpriseGreetingService-1004";
String errDesc = "Error building Greeting element from the Greeting " +
"object. The exception is: " + ele.getMessage();
logger.fatal("[GreetingRequestCommand " + errDesc);
ArrayList errors = new ArrayList();
errors.add(buildError(errType, errCode, errDesc));
replyContents = buildReplyDocumentWithErrors(eControlArea,
localResponseDoc, errors);
return getMessage(msg, replyContents);
}
// Publish the create sync message.
try { greeting.createSync(pub); }
catch (EnterpriseObjectSyncException eose) {
// An error occurred publishing the Greeting.Create-Sync message.
// Log it and reply with an error.
String errType = "application";
String errCode = "EnterpriseGreetingService-1005";
String errDesc = "An error occurred publishing the Greeting.Create-" +
"Sync message to communicate the create action to the rest of the " +
"enterprise. The Generate-Request cannot be processed. " +
"The exception is: " + eose.getMessage();
logger.fatal("[GreetingRequestCommand " + 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 'generate'.";
logger.fatal("[GreetingRequestCommand] " + 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);
}
}
/**
* @param String, the default greeting text.
* <P>
* Sets the default greeting text.
*/
private void setDefaultGreetingText(String defaultGreetingText) {
m_defaultGreetingText = defaultGreetingText;
}
/**
* @return String, the default greeting text.
* <P>
* Returns the default greeting text.
*/
private String getDefaultGreetingText() {
return m_defaultGreetingText;
}
}