Package org.openeai.layouts

Source Code of org.openeai.layouts.EnterpriseLayoutManagerImpl

/*******************************************************************************
$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;
  }

}
TOP

Related Classes of org.openeai.layouts.EnterpriseLayoutManagerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.