/*******************************************************************************
$Source: /cvs/repositories/openii3/project/java/source/org/openeai/layouts/EnterpriseLayoutManagerImpl.java,v $
$Revision: 1.24 $
*******************************************************************************/
/**********************************************************************
This file is part of the OpenEAI Application Foundation or
OpenEAI Message Object API created by Tod Jackson
(tod@openeai.org) and Steve Wheat (steve@openeai.org) at
the University of Illinois Urbana-Champaign.
Copyright (C) 2002 The OpenEAI Software Foundation
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; 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 build commercial integration software or to implement
integrations for your enterprise, visit http://www.OpenEai.org/licensing.
***********************************************************************/
package org.openeai.layouts;
import java.util.*;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Attribute;
import java.lang.reflect.*;
import org.openeai.*;
import org.openeai.xml.*;
import org.openeai.config.EnterpriseFieldException;
import org.openeai.moa.*;
/**
* The parent class of all EnterpriseLayoutManagers created by the OpenEAI software foundation. Provides convenience
* methods to the decendant objects.
* <P>
* @author Tod Jackson (tod@openeai.org)
* @author Steve Wheat (steve@openeai.org)
* @version 3.0 - 28 January 2003
*/
public abstract class EnterpriseLayoutManagerImpl extends OpenEaiObject {
private Element m_layout = null;
private Element m_layoutRoot = null;
private boolean m_validate = false;
private String m_layoutManagerName = "";
private String m_targetAppName = "";
private String m_enterpriseObjectsUri = "";
protected final static String LIST = "java.util.List";
/**
* Constructor
*/
public EnterpriseLayoutManagerImpl() {
}
/**
* Sets the name of the target application for which an output is being built.
* Since outputs can be built in two ways (using enterprise values and or
* using application specific values) this method sets the name of that target
* application if the method of serializing the object to an output is for a
* specific application.
*<P>
* This application name will be used to "reverse-translate" data from enterprise
* values to application values if translations/mappings exist.
*<P>
* @param appName String the name of the application.
* @see org.openeai.config.EnterpriseTranslator
* @see org.openeai.config.EnterpriseMapping
*/
protected void setTargetAppName(String appName) {
m_targetAppName = appName;
}
/**
* Returns the target application name associated to this layout manager. This
* will be use to reverse-translate enterprise values to application specific values
* if translations/mappings exist.
*<P>
* @return String the target application name
* @see org.openeai.config.EnterpriseTranslator
* @see org.openeai.config.EnterpriseMapping
*/
protected String getTargetAppName() {
if (m_targetAppName == null || m_targetAppName.length() == 0) {
return null;
}
else {
return m_targetAppName;
}
}
/**
* This method sets the layout manager's root element. This is the starting point
* for all other activity that is performed using the layout document. Generally,
* this is the EnterpriseObjects documents associated to an object.
*<P>
* @param layout Element the root element of the XML document
*/
protected final void setLayoutRoot(Element layout) {
m_layoutRoot = layout;
}
/**
* Returns the layout manager's root element.
*<P>
* @return Element
*/
public final Element getLayoutRoot() {
return m_layoutRoot;
}
/**
* Sets the EnterpriseObjects document uri associated to this EnterpriseFields object.
* This document contains the rules that will be use to build the EnterpriseFields object.
*
* @param uri String URI to the EnterpriseObjects document. Can be file system or web uri.
*/
public final void setEnterpriseObjectsUri(String uri) {
m_enterpriseObjectsUri = uri;
}
/**
* Returns the EnterpriseObjects document uri associated to this EnterpriseFields object.
* This document contains the rules that will be use to build the EnterpriseFields object.
*
* @return String URI to the EnterpriseObjects document. Can be file system or web uri.
*/
public final String getEnterpriseObjectsUri() {
return m_enterpriseObjectsUri;
}
/**
* This method sets the actual layout element associated with this layout manager.
* Generally, this is found in the EnterpriseObjects documents but it is up to
* the layout manager implementation to determine exactly where this is. It doesn't
* have to be in the EnterpriseObjects documents.
*<P>
* This is the element that provides the details regarding what the layout being used
* really is. It's the layout's definition.
*<P>
* @param layout Element the layout element.
*/
protected final void setLayout(Element layout) {
m_layout = layout;
}
/**
* This method returns the actual layout element associated with this layout manager.
* Generally, this is found in the EnterpriseObjects documents but it is up to
* the layout manager implementation to determine exactly where this is. It doesn't
* have to be in the EnterpriseObjects documents.
*<P>
* This is the element that provides the details regarding what the layout being used
* really is. It's the layout's definition.
*<P>
* @return Element the layout element.
*/
protected final Element getLayout() {
return m_layout;
}
/**
* Returns the Layout Element associated to a particular field as specified in an
* application's deployment document. Note, this method assumes the layout is part
* of the Deployment document and is specified by the OpenEAI Deployment.dtd definition.
* It is not required that a layout be specified through this file but this method
* assumes that it is. It's is completely acceptable for layout manager implementations
* use some other layout document altogether to specify the exact details of a particular
* layout. The EnterpriseObject documents are still used though to provied the Object and Field Defintions.
* <P>
* @return Element the layout element associate to the field passed in.
* @param eField Element the Field XML Element contained within the EnterpriseObjects documents
* @param name String the layout name contained within the Layout Element in the EnterpriseObjects document
*/
protected final Element getFieldLayout(Element eField, String name) {
Element eLayouts = eField.getChild("Layouts");
if (eLayouts != null) {
java.util.List lLayouts = eLayouts.getChildren("Layout");
for (int i=0; i<lLayouts.size(); i++) {
Element eLayout = (Element)lLayouts.get(i);
Attribute aName = eLayout.getAttribute("name");
if (aName != null) {
String layoutName = aName.getValue();
logger.debug("Layout [" + i + "] name is: " + layoutName);
if (layoutName.equalsIgnoreCase(name)) {
return eLayout;
}
}
}
}
return null;
}
/**
* This method sets the name associated to the layout manager.
*<P>
* @param name String the layout manager name.
*/
public final void setLayoutManagerName(String name) {
m_layoutManagerName = name;
}
/**
* This method returns the name of the layout manager.
*<P>
* @return String the name of the layout manager.
*/
public final String getLayoutManagerName() {
return m_layoutManagerName;
}
private java.util.List getChildDefinitions(Element root) throws EnterpriseLayoutException {
ArrayList objDefs = new ArrayList();
java.util.List eChildren = root.getChildren("ObjectDefinition");
for (int j=0; j<eChildren.size(); j++) {
Element eChild = (Element)eChildren.get(j);
objDefs.add(eChild);
}
Element eIncludeList = root.getChild("IncludeList");
if (eIncludeList != null) {
java.util.List eDocUriList = eIncludeList.getChildren();
XmlDocumentReader xmlReader = new XmlDocumentReader();
for (int i=0; i<eDocUriList.size(); i++) {
Element eDocUri = (Element)eDocUriList.get(i);
String docUri = eDocUri.getText();
try {
Document includedDoc = xmlReader.initializeDocument(docUri,false);
java.util.List includedObjDefs = getChildDefinitions(includedDoc.getRootElement());
for (int h=0; h<includedObjDefs.size(); h++) {
objDefs.add((Element)includedObjDefs.get(h));
}
}
catch (XmlDocumentReaderException e) {
logger.fatal(e.getMessage(), e);
String msg = "Exception occurred parsing the enterprise objects document " + docUri + ". Exception: " + e.getMessage();
logger.fatal(msg);
throw new EnterpriseLayoutException(msg, e);
}
}
}
return objDefs;
}
private void buildLayoutDocument(Document inDoc) throws EnterpriseLayoutException {
// recursively parse and build all 'included' enterprise object document references.
Element inDocRoot = inDoc.getRootElement();
java.util.List objDefs = getChildDefinitions(inDocRoot);
for (int j=0; j<objDefs.size(); j++) {
Element eChild = (Element)objDefs.get(j);
String childName = eChild.getAttribute("name").getValue();
if (childExists(childName, inDocRoot) == false) {
inDocRoot.addContent((Element)eChild.clone());
}
}
}
private boolean childExists(String childName, Element rootElement) {
java.util.List eChildren = rootElement.getChildren("ObjectDefinition");
for (int j=0; j<eChildren.size(); j++) {
Element eChild = (Element)eChildren.get(j);
String existingChildName = eChild.getAttribute("name").getValue();
if (childName.equals(existingChildName)) {
return true;
}
}
return false;
}
/**
* This is the default initialization method that can be used by child layout managers.
* It basically goes through the EnterpriseObjects document and pulls all object definitions.
* Additionally, it recursively includes any external references to other EO documents
* that are included in the "IncludeList" element for the document passed to this method.
*<P>
* @param layoutManagerName String the layout manager's name
* @param layoutDoc Document the layout document. Typically, this is the EnterpriseObjects document
* associated to the object that this layout manager is being configured for.
*/
public void init(String layoutManagerName, Document layoutDoc)
throws EnterpriseLayoutException {
// This is only the base behavior
// This is all that is necessary for the XmlLayout.
// All other layouts will have to do something else in addition
// to this by using the layoutManagerName
buildLayoutDocument(layoutDoc);
setLayoutManagerName(layoutManagerName);
Element rootElement = layoutDoc.getRootElement();
logger.debug("RootElement is: " + rootElement.getName());
Element layoutElement = rootElement;
setLayoutRoot(layoutElement);
}
/**
* This method searches for and returns the field definition which is part of the layout for an
* object that matches the name passed in.
*<P>
* @param startingElement Element the element that is the starting point for the search. Typically, this is the root element of the EO document
* @param name String the name of the layout manager we're looking for. Typically, this will be the name of the object.
* @return Element the Element that corresponds to the object definition in the EO document.
*/
protected Element getLayout(Element startingElement, String name) throws EnterpriseLayoutException {
logger.debug("getting layout named " + name + " in XmlLayout...");
XmlElementLocator xmlLoc = new XmlElementLocator();
/* DEBUG CODE...
logger.info("EnterpriseLayoutManagerImpl: startingElement is " + startingElement.getName());
java.util.List children = startingElement.getChildren();
for (int i=0; i<children.size(); i++) {
Element e = (Element)children.get(i);
Attribute aName = e.getAttribute("name");
if (aName != null) {
String sname = aName.getValue();
logger.info(" " + e.getName() + " Name: " + sname);
}
}
*/
Element layoutElement = xmlLoc.getElementByAttributeNameValue(startingElement,"name",name);
if (layoutElement != null) {
logger.debug("Found layout manager " + name + " Element name: " + layoutElement.getName());
}
else {
// Need to throw an exception here!
throw new EnterpriseLayoutException("Could not find layout manager named " + name);
}
return layoutElement;
}
/**
* Uses the field definition passed in to determine if a field is required. This
* information is part of the Format element associated to a field in the EnterpriseObjects documents.
*<P>
* @return boolean true if the field is required, false if not.
* @throws EnterpriseLayoutException if the Field's Format element can't be found.
*/
protected boolean isRequired(Element eField) throws EnterpriseLayoutException {
boolean isRequired = false; // default
// if (eField != null && eField.isRootElement() == false && eField.getParent().isRootElement() == false) {
if (eField != null && eField.isRootElement() == false) {
String fieldName = eField.getAttribute("name").getValue();
Element eFormat = eField.getChild("Format");
if (eFormat == null) {
throw new EnterpriseLayoutException("The EnterpriseObjects document is invalid." +
" A Format element is required. " + fieldName + " doesn't have one!");
}
else {
isRequired = new Boolean(eFormat.getAttribute("required").getValue()).booleanValue();
}
}
return isRequired;
}
/**
* Convenience method that tells the layout manager implementation if the field specified
* is a repeating field on the object passed in.
*<P>
* If a child object is a repeating object within a parent object, the "getter"
* method for that child object will return a java.util.List. This method inspects the
* return type of that getter method and checks to see if it's a java.util.List.
* <P>
* For example, the Address child object in the BasicPerson object is repeating. Therefore,
* the BasicPerson object has a "getAddress" method that returns a java.util.List of Address
* objects that exist in that BasicPerson. This method invokes that method and
* checks the class type (instanceof) the returned object. If it's a java.util.List
* it knows the Address is a repeating child on the BasicPerson. This will work for any
* XmlEnterpriseObject.
* <P>
* @return boolean true if the field is a repeating field, false if not.
* @param xeo Object the object that's being queried
* @param fieldName String the name of the field being tested.
* @throws EnterpriseLayoutException if an error occurs executing the child object's getter method.
*/
protected boolean isRepeating(Object xeo, String fieldName) throws EnterpriseLayoutException {
boolean isRepeating = false;
String className = xeo.getClass().getName();
String objectName = className.substring(className.lastIndexOf('.') + 1); // Our based element in the XML passed in
try {
Method getter = null;
logger.debug("Seeing if " + fieldName + " is a repeating object on " + objectName + " passed in.");
getter = xeo.getClass().getMethod("get" + fieldName, new Class[] {});
String returnType = getter.getReturnType().getName();
logger.debug("get" + fieldName + " return type: " + returnType);
if (returnType.equals(LIST)) {
logger.debug(fieldName + " is a repeating object in " + objectName + " passed in.");
isRepeating = true;
}
else {
logger.debug(fieldName + " is NOT a repeating object in " + objectName + " passed in.");
}
}
catch (Exception e) {
logger.fatal(e.getMessage(), e);
throw new EnterpriseLayoutException("Unexpected Error attempting to invoke the 'get" +
fieldName + "' method on the '" + objectName + "' object. Exception: " + e.getMessage(), e);
}
return isRepeating;
}
/**
* Convenience method that tells the layout manager implementation how many instances
* of a given repeatable field exist on the parent object. This is useful in determining
* how many child objects need to be serialized when building an output from an object.
*<P>
* If a child object is a repeating object within a parent object, the "getter"
* method for that child object will return a java.util.List. This method invokes
* the getter method for the child object and returns the size of that List. If the
* List returned is null, zero will be returned.
* <P>
* For example, the Address child object in the BasicPerson object is repeating. Therefore,
* the BasicPerson object has a "getAddress" method that returns a java.util.List of Address
* objects that exist in that BasicPerson. This method invokes that method and
* returns the size of the returned object.
* <P>
* @return int the number of child objects
* @param xeo XmlEnterpriseObject the parent object being queried
* @param fieldName String the name of the child object being tested
* @throws EnterpriseLayoutException if an error occurs executing the getter method for the particular
* field on the parent object passed in. An exception will also be thrown if the
* object being checked is not a repeating field (the object returned by the getter method
* is not a java.util.List.
*/
protected int getLength(XmlEnterpriseObject xeo, String fieldName) throws EnterpriseLayoutException {
int numObjects = 0;
String className = xeo.getClass().getName();
String objectName = className.substring(className.lastIndexOf('.') + 1); // Our based element in the XML passed in
try {
Method getter = null;
logger.debug("Seeing if " + fieldName + " is a repeating object on " + objectName + " passed in.");
getter = xeo.getClass().getMethod("get" + fieldName, new Class[] {});
String returnType = getter.getReturnType().getName();
logger.debug("get" + fieldName + " return type: " + returnType);
if (returnType.equals(LIST)) {
Object obj = getter.invoke(xeo, new Object[] {});
if (obj != null) {
java.util.List aList = (java.util.List)obj;
numObjects = aList.size();
}
else {
numObjects = 0;
}
}
else {
throw new EnterpriseLayoutException("The field '" + fieldName +
"' is NOT a repeating child field in the '" + objectName + "' object.");
}
}
catch (Exception e) {
throw new EnterpriseLayoutException("Unexpected Error attempting to invoke the 'get" +
fieldName + "' method on the '" + objectName + "' object. Exception: " + e.getMessage(), e);
}
return numObjects;
}
/**
* Convenience method used by layout manager implementations to instantiate child objects
* that need to be built from the input passed to them and added to the parent object being built.
*<P>
* String class name of the object to instantiate.
*/
protected Object instantiate(String className) {
Object xeo = null;
if (className.indexOf("(") != -1) {
// there are parms to pass (i.e. - Date)
logger.debug("Special case...");
String tempClass = className.substring(0,className.indexOf("("));
String sparms = className.substring(className.indexOf("(") + 1, className.indexOf(")"));
className = tempClass;
logger.debug("ClassName is now: " + className);
logger.debug("Parms: " + sparms);
Class[] parms = {String.class};
try {
java.lang.Class obj = java.lang.Class.forName(className);
Constructor c = obj.getConstructor(parms);
Object[] o = {sparms};
xeo = c.newInstance(o);
logger.debug("Instantiated a " + xeo.getClass().getName());
}
catch (Exception e) {
logger.fatal("Error instantiating a " + className);
logger.fatal(e.getMessage(), e);
}
}
else {
try {
java.lang.Class obj = java.lang.Class.forName(className);
xeo = obj.newInstance();
logger.debug("Instantiated a " + xeo.getClass().getName());
}
catch (Exception e) {
logger.fatal("Error instantiating a " + className);
logger.fatal(e.getMessage(), e);
}
}
return xeo;
}
/**
* Convenience method used by layout manager implementations to retrieve data from
* a parent object for a particular application. It uses the field namd passed
* in to build a "getter" method call on the Parent object passed in. If the
* field has translations/mappings associated to it, the value currently contained
* in the parent object will be converted to the application specific value associated
* to the application name passed in.
*<P>
* @return Object the value returned from the "getter" method call.
* @param xeo XmlEnterpriseObject the parent object being queried.
* @param appName String the name of the application used for the "reverse-translation" from
* enterprise value to application specific value.
* @throws EnterpriseLayoutException if errors occur reverse-translating the enterprise
* value to an application specific value.
*/
protected Object getValueFromObject(XmlEnterpriseObject xeo, String appName,
String fieldName) throws EnterpriseLayoutException {
String className = xeo.getClass().getName();
String objectName = className.substring(className.lastIndexOf('.') + 1); // Our based element in the XML passed in
String enterpriseValue = (String)getValueFromObject(xeo, fieldName);
try {
String appValue =
xeo.getEnterpriseFields().getApplicationValue(objectName, appName, fieldName, enterpriseValue);
return appValue;
}
catch (Exception e) {
String errMessage = "Error getting Application Value for " +
objectName + "/" + fieldName + ". Exception: " + e.getMessage();
throw new EnterpriseLayoutException(errMessage, e);
}
}
/**
* Returns the value currently held in the parent object for the field passed in.
*<P>
* @return Object the value currently contained in the field
* @param xeo XmlEnterpriseObject the parent object
* @param fieldName String the name of the field that the getter method should be called for
* @throws EnterpriseLayoutException if errors occur invoking the getter method on the field
*/
protected Object getValueFromObject(XmlEnterpriseObject xeo, String fieldName)
throws EnterpriseLayoutException {
String className = xeo.getClass().getName();
String objectName = className.substring(className.lastIndexOf('.') + 1); // Our based element in the XML passed in
try {
Method getter = null;
logger.debug("Calling getter method for " + fieldName);
getter = xeo.getClass().getMethod("get" + fieldName, new Class[] {});
Class c = getter.getReturnType();
Object obj = getter.invoke(xeo, new Object[] {});
return obj;
}
catch (Exception e) {
// logger.info("EO doc for " + fieldName + " is " + xeo.getEnterpriseFields().getEnterpriseObjectsUri());
String errMessage = "Error calling getter method for " +
objectName + "/" + fieldName + ". Exception: " + e.getMessage();
throw new EnterpriseLayoutException(errMessage, e);
}
}
/**
* Convenience method used by layout manager implementations to retrieve data from
* a repeating field (of type Element or Attribute) on a parent object for a particular application.
* It uses the field namd passed in to build a "getter" method call on the Parent object passed in.
* It uses the "parms" passed in to determine which index to use when retrieving the data from the repeatable field.
* If the field has translations/mappings associated to it, the value currently contained
* in the repeatable field at the specified index in parent object will be converted to the application specific value associated
* to the application name passed in.
*<P>
* @return Object the value returned from the "getter" method call.
* @param xeo XmlEnterpriseObject the parent object being queried.
* @param appName String the name of the application used for the "reverse-translation" from
* enterprise value to application specific value.
* @param fieldName String the name of the repeatable field (of type Attribute or Element) from which to get the data
* @param parms Object[] the index from which to pull the repeatable child field
* @param parmTypes Class[] the data type of the index (Integer.TYPE)
* @throws EnterpriseLayoutException if errors occur reverse-translating the enterprise
* value to an application specific value.
*/
protected Object getValueFromObject(XmlEnterpriseObject xeo, String appName, String fieldName, Object[] parms, Class[] parmTypes)
throws EnterpriseLayoutException {
String className = xeo.getClass().getName();
String objectName = className.substring(className.lastIndexOf('.') + 1); // Our based element in the XML passed in
String enterpriseValue = (String)getValueFromObject(xeo, fieldName, parms, parmTypes);
try {
String appValue =
xeo.getEnterpriseFields().getApplicationValue(objectName, appName, fieldName, enterpriseValue);
return appValue;
}
catch (Exception e) {
String errMessage = "Error getting Application Value for " +
objectName + "/" + fieldName + ". Exception: " + e.getMessage();
throw new EnterpriseLayoutException(errMessage, e);
}
}
/**
* Convenience method used by layout manager implementations to retrieve data from
* a repeating field (of any type) on a parent object.
* It uses the field namd passed in to build a "getter" method call on the Parent object passed in.
* It uses the "parms" passed in to determine which index to use when retrieving the data from the repeatable field.
* If the field has translations/mappings associated to it, the value currently contained
* in the repeatable field at the specified index in parent object will be converted to the application specific value associated
* to the application name passed in.
*<P>
* @return Object the value returned from the "getter" method call.
* This could be a String or an XmlEnterpriseObject depending on the type of child object.
* @param xeo XmlEnterpriseObject the parent object being queried.
* @param fieldName String the name of the repeatable field (of any type) from which to get the data
* @param parms Object[] the index from which to pull the repeatable child field
* @param parmTypes Class[] the data type of the index (Integer.TYPE)
* @throws EnterpriseLayoutException if errors occur reverse-translating the enterprise
* value to an application specific value.
*/
protected Object getValueFromObject(XmlEnterpriseObject xeo, String fieldName, Object[] parms, Class[] parmTypes)
throws EnterpriseLayoutException {
String className = xeo.getClass().getName();
String objectName = className.substring(className.lastIndexOf('.') + 1); // Our based element in the XML passed in
try {
Method getter = null;
logger.debug("Calling getter method for " + fieldName);
getter = xeo.getClass().getMethod("get" + fieldName, parmTypes);
Class c = getter.getReturnType();
Object obj = getter.invoke(xeo, parms);
return obj;
}
catch (Exception e) {
String errMessage = "Error calling getter method for " +
objectName + "/" + fieldName + " Exception: " + e.getMessage();
throw new EnterpriseLayoutException(errMessage, e);
}
}
/**
* Convenience method that sets a field on an object passed in to the value passed in by
* finding the appropriate setter method (by field name) on the object and invoking that method.
* <P>
* By invoking the setter method on the object passed in, all the rules that are specified
* in the EnterpriseFields object are invoked when that setter method is called.
*<P>
* @param mObj Object the object on which the setter method is being invoked.
* @param variableName String the name of the field for which the setter method should be called
* @param value Object the value to pass to the setter method.
* @param classType Class the class type of variable being set
* @throws EnterpriseFieldException
* @see org.openeai.config.EnterpriseFields
* @see org.openeai.config.EnterpriseFormatter
*/
protected void setVariableValue(Object mObj, String variableName, Object value, Class classType)
throws EnterpriseFieldException {
String className = mObj.getClass().getName();
String methodPrefix = "";
try {
if (isRepeating(mObj, variableName)) {
methodPrefix = "add";
}
else {
methodPrefix = "set";
}
}
catch (EnterpriseLayoutException e) {
String objectName = className.substring(className.lastIndexOf('.') + 1);
String errMessage = "Error setting " + objectName + "/" + variableName +
" to " + value + " Exception: " + e.getMessage();
throw new EnterpriseFieldException(errMessage, e);
}
if (variableName.indexOf("(") != -1) {
// there are parms to pass (i.e. - Date)
String fieldName = variableName.substring(variableName.indexOf("(") + 1, variableName.indexOf(")"));
logger.debug("setVariableValue: field: " + fieldName);
variableName = fieldName;
}
logger.debug("setVariableValue: " + methodPrefix + "ing " + variableName + " to " + value + " on " + mObj.getClass().getName());
try {
// get setter method
Method setter = null;
try {
setter = mObj.getClass().getMethod(methodPrefix + variableName, new Class[] {classType});
}
catch (Exception exc) {
String errMessage = "ERROR - locating method " + methodPrefix +
variableName + " on " + mObj.getClass().getName() +
". Exception: " + exc.getMessage();
throw new EnterpriseFieldException(errMessage, exc);
}
logger.debug("Setting '" + className + ":" + variableName + "' => '" + value + "'");
setter.invoke(mObj, new Object[] {value});
}
catch (Exception e1) {
String objectName = className.substring(className.lastIndexOf('.') + 1);
String errMessage = "ERROR - " + methodPrefix + "ing " + objectName + "/" +
variableName + " to '" + value + "' Exception: " + e1.getMessage();
throw new EnterpriseFieldException(errMessage, e1);
}
}
// 4/4/2002 fix
// this method is specifically for setting repeating field variables at a particular index.
// this is so we don't keep adding items to an existing list.
/**
* This method replaces the repeatable child object at a particular index with the value passed in.
* <P>
* @param mObj Object the object on which to call the setter method (the parent object).
* @param variableName String the name of the child object that's being set.
* @param value Object value the object being passed to the setter method.
* @param classType Class the type of class being passed to the setter (String or XmlEnterpriseObject)
* @param index int the index at which to replace the data
* @throws EnterpriseFieldException if errors occur calling the setter method.
*/
protected void setVariableValue(Object mObj, String variableName, Object value, Class classType, int index)
throws EnterpriseFieldException {
String className = mObj.getClass().getName();
String methodPrefix = "set";
if (variableName.indexOf("(") != -1) {
// there are parms to pass (i.e. - Date)
String fieldName = variableName.substring(variableName.indexOf("(") + 1, variableName.indexOf(")"));
logger.debug("setVariableValue: field: " + fieldName);
variableName = fieldName;
}
logger.debug("setVariableValue: " + methodPrefix + "ing " + variableName + " to " + value + " on " + mObj.getClass().getName());
try {
// get setter method
Method setter = null;
try {
setter = mObj.getClass().getMethod(methodPrefix + variableName, new Class[] {Integer.TYPE, classType});
}
catch (Exception exc) {
String errMessage = "ERROR - locating method " + methodPrefix +
variableName + "(int, String) on " + mObj.getClass().getName() +
". Exception: " + exc.getMessage();
throw new EnterpriseFieldException(errMessage, exc);
}
logger.debug("Setting '" + className + ":" + variableName + "' => '" + index + ", " + value + "'");
setter.invoke(mObj, new Object[] {new Integer(index), value});
}
catch (Exception e1) {
String objectName = className.substring(className.lastIndexOf('.') + 1);
String errMessage = "ERROR - " + methodPrefix + "ing " + objectName + "/" +
variableName + " to '" + value + "' Exception: " + e1.getMessage();
throw new EnterpriseFieldException(errMessage, e1);
}
}
/**
* Determines if the class name passed in is one of the OpenEAI Date objects (Date or Datetime).
*
* @return boolean
*
*/
protected boolean isDate(String className) {
String objectName = className.substring(className.lastIndexOf('.') + 1);
if (objectName.equals("Date") || objectName.equals("Datetime")) {
return true;
}
return false;
}
}