SchemaHelper.java :  » Web-Framework » roma-webwizard » org » romaframework » core » schema » Java Open Source

Java Open Source » Web Framework » roma webwizard 
roma webwizard » org » romaframework » core » schema » SchemaHelper.java
/*
 * Copyright 2006 Luca Garulli (luca.garulli@assetdata.it)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.romaframework.core.schema;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.romaframework.aspect.view.ViewAspect;
import org.romaframework.aspect.view.feature.ViewClassFeatures;
import org.romaframework.aspect.view.feature.ViewFieldFeatures;
import org.romaframework.aspect.view.form.ContentComponent;
import org.romaframework.core.Utility;
import org.romaframework.core.binding.BindingException;
import org.romaframework.core.entity.ComposedEntity;
import org.romaframework.core.entity.EntityHelper;
import org.romaframework.core.exception.ConfigurationException;
import org.romaframework.core.exception.UserException;
import org.romaframework.core.flow.Controller;
import org.romaframework.core.flow.ObjectContext;
import org.romaframework.core.flow.UserObjectEventListener;
import org.romaframework.xml.config.XmlConfigAreaType;

public class SchemaHelper {

  final static public Object[]  NO_PARAMETERS  = new Object[] {};

  private static Log            log            = LogFactory.getLog(SchemaHelper.class);

  public static Type getEmbeddedType(SchemaField iField) throws ConfigurationException {
    Type embeddedType = iField.getEmbeddedType();

    if (embeddedType.equals(Object.class)) {
      String selectionFieldName = (String) iField.getFeature(ViewAspect.ASPECT_NAME, ViewFieldFeatures.SELECTION_FIELD);
      // NO EMBEDDED TYPE SETTED: TRY TO DETERMINE IT BY SELECTION FIELD
      if (selectionFieldName != null) {
        SchemaField selectionField = SchemaHelper.getFieldName(iField.getEntity(), selectionFieldName);

        if (selectionField == null)
          throw new ConfigurationException("Cannot find the selection field called " + selectionFieldName
              + " defined in the correlated field " + iField.getEntity().getSchemaClass().getName() + "." + iField.getName());

        embeddedType = selectionField.getTypeClass();
      }

      if (embeddedType == null)
        throw new ConfigurationException("Cannot find embedded type definition for the field "
            + iField.getEntity().getSchemaClass().getName() + "." + iField.getName());
    }

    return embeddedType;
  }

  /**
   * Get the field name by a field path.
   * 
   * @param iClassDef
   * @param iFieldName
   * @return SchemaField instance if found
   * @throws BindingException
   */
  public static SchemaField getFieldName(SchemaClassDefinition iClassDef, String iFieldName) throws BindingException {
    int sepPos = iFieldName.indexOf(Utility.PACKAGE_SEPARATOR);

    if (sepPos == -1)
      return iClassDef.getField(iFieldName);

    String fieldName = iFieldName.substring(0, sepPos);

    SchemaField field = iClassDef.getField(fieldName);

    return getFieldName(field.getComplexClass(), iFieldName.substring(sepPos + 1));
  }

  /**
   * Get the field value reading a field path.
   * 
   * @param iClassDef
   * @param iFieldName
   * @param iInstance
   * @param iValue
   * @throws BindingException
   */
  public static Object getFieldValue(SchemaClassDefinition iClassDef, String iFieldName, Object iInstance) throws BindingException {
    int sepPos = iFieldName.indexOf(Utility.PACKAGE_SEPARATOR);

    if (sepPos == -1) {
      SchemaField field = iClassDef.getField(iFieldName);

      if (field == null)
        throw new UserException(iInstance, "Cannot find field or getter method '" + iFieldName + "' in object of class "
            + iInstance.getClass().getName());

      return getFieldValue(field, iInstance);
    }

    String fieldName = iFieldName.substring(0, sepPos);

    SchemaField field = iClassDef.getField(fieldName);

    Object embeddedObject = getFieldValue(field, iInstance);

    if (embeddedObject == null)
      return null;

    return getFieldValue(field.getComplexClass(), iFieldName.substring(sepPos + 1), embeddedObject);
  }

  public static Object getFieldValue(SchemaField iField, Object iInstance) throws BindingException {
    Object value = null;
    try {
      // TRY TO INVOKE GETTER IF ANY
      Method method = iField.getGetterMethod();
      if (method != null) {
        try {
          value = method.invoke(iInstance, (Object[]) null);
        } catch (IllegalArgumentException e) {
          // PROBABLY AN ISSUE OF CLASS VERSION
          throw new BindingException(iInstance, iField.getName(),
              "Error on using different classes together. Maybe it's an issue due to class reloading. Assure to use objects of the same class.");
        } catch (InvocationTargetException e) {
          Throwable nested = e.getCause();
          if (nested == null)
            nested = e.getTargetException();

          // BYPASS REFLECTION EXCEPTION: THROW REAL NESTED EXCEPTION
          throw new BindingException(iInstance, iField.getName(), nested);
        }
      } else {
        // READ FROM FIELD
        Field field = iField.getField();
        if (!field.isAccessible())
          field.setAccessible(true);

        value = field.get(iInstance);
      }

      // CALL ALL LISTENERS BEFORE TO RETURN THE VALUE
      List<UserObjectEventListener> listeners = Controller.getInstance().getListeners(UserObjectEventListener.class);
      synchronized (listeners) {
        for (UserObjectEventListener listener : listeners) {
          value = listener.onBeforeFieldRead(iInstance, iField, value);
        }
      }

    } catch (Exception e) {
      if (iField != null)
        throw new BindingException(iInstance, iField.getName(), e);
      else
        throw new BindingException(iInstance, "field unknown", e);
    }
    return value;
  }

  /**
   * Set the field value reading a field path.
   * 
   * @param iClassDef
   * @param iFieldName
   * @param iInstance
   * @param iValue
   * @throws BindingException
   */
  public static void setFieldValue(SchemaClassDefinition iClassDef, String iFieldName, Object iInstance, Object iValue)
      throws BindingException {
    int sepPos = iFieldName.indexOf(Utility.PACKAGE_SEPARATOR);

    if (sepPos == -1) {
      setFieldValue(iClassDef.getField(iFieldName), iInstance, iValue);
      return;
    }

    String fieldName = iFieldName.substring(0, sepPos);

    SchemaField field = iClassDef.getField(fieldName);

    Object embeddedObject = getFieldValue(field, iInstance);

    setFieldValue(field.getComplexClass(), iFieldName.substring(sepPos + 1), embeddedObject, iValue);
  }

  public static void setFieldValue(SchemaField iField, Object iInstance, Object iValue) throws BindingException {
    try {
      Object value = null;
      Class<?> type = iField.getTypeClass();

      if (iValue instanceof String) {
        String v = (String) iValue;

        if (v.length() == 0)
          value = null;
        else {
          if (type.equals(Integer.class) || type.equals(Integer.TYPE))
            value = Integer.parseInt(v);
          else if (type.equals(Long.class) || type.equals(Long.TYPE))
            value = Long.parseLong(v);
          else if (type.equals(Short.class) || type.equals(Short.TYPE))
            value = Short.parseShort(v);
          else if (type.equals(Boolean.class) || type.equals(Boolean.TYPE))
            value = Boolean.parseBoolean(iValue.toString());
          else if (type.equals(Float.class) || type.equals(Float.TYPE)) {
            value = Float.parseFloat(v);
          } else if (type.equals(Double.class) || type.equals(Double.TYPE)) {
            value = Double.parseDouble(v);
          } else if (type.equals(Byte.class) || type.equals(Byte.TYPE))
            value = Byte.parseByte(v);
          else if (type.equals(Character.class) || type.equals(Character.TYPE))
            value = v.charAt(0);
          else
            value = iValue;
        }
      } else {
        if (iValue != null) {

          String textValue = iValue.toString();

          // TRY A SOFT CONVERSION
          if (type.equals(Integer.class) || type.equals(Integer.TYPE))
            value = Integer.parseInt(textValue);
          else if (type.equals(Long.class) || type.equals(Long.TYPE))
            value = Long.parseLong(textValue);
          else if (type.equals(Short.class) || type.equals(Short.TYPE))
            value = Short.parseShort(textValue);
          else if (type.equals(Byte.class) || type.equals(Byte.TYPE))
            value = Byte.parseByte(textValue);
          else if (type.equals(Character.class) || type.equals(Character.TYPE)) {
            if (textValue.length() > 0)
              value = new Character(textValue.charAt(0));
          } else if (type.equals(Float.class) || type.equals(Float.TYPE))
            value = Float.parseFloat(textValue);
          else if (type.equals(Double.class) || type.equals(Double.TYPE))
            value = Double.parseDouble(textValue);
          else if (iValue != null && !type.isArray() && iValue.getClass().isArray())
            // DESTINATION VALUE IS NOT AN ARRAY: ASSIGN THE FIRST ONE ELEMENT
            value = ((Object[]) iValue)[0];
          else
            value = iValue;
        }
      }

      if (value != null && !type.isAssignableFrom(value.getClass())) {
        if (value instanceof ComposedEntity)
          value = ((ComposedEntity<?>) value).getEntity();
      }

      if (value == null && type.isPrimitive()) {
        log.warn("Cannot set the field value to null for primitive types! Field: " + iField.getEntity() + "." + iField.getName()
            + " of class " + type.getName() + ". Setting value to 0.");
        // SET THE VALUE TO 0
        value = assignDefaultValueToLiteral(type);
      }

      List<UserObjectEventListener> listeners = Controller.getInstance().getListeners(UserObjectEventListener.class);
      try {
        // CALL ALL LISTENERS BEFORE FIELD WRITE CALLBACKS
        synchronized (listeners) {
          for (UserObjectEventListener listener : listeners) {
            value = listener.onBeforeFieldWrite(iInstance, iField, value);
          }
        }

        // TRY TO INVOKE SETTER IF ANY
        Method method = iField.getSetterMethod();
        if (method != null) {
          method.invoke(iInstance, new Object[] { value });
        } else {
          // WRITE THE FIELD
          Field field = iField.getField();
          if (field == null) {
            log.debug("[SchemaHelper.setFieldValue] Cannot set the value '" + iValue + "' for field '" + iField.getName()
                + "' on object " + iInstance + " since it has neither setter neir field declared");
            return;
          }

          if (!field.isAccessible())
            field.setAccessible(true);

          field.set(iInstance, value);
        }
      } finally {
        // ASSURE TO CALL THE AFTER FIELD WRITE CALLBACKS
        synchronized (listeners) {
          for (UserObjectEventListener listener : listeners) {
            value = listener.onAfterFieldWrite(iInstance, iField, value);
          }
        }
      }
    } catch (Exception e) {
      log.error("[SchemaHelper.setFieldValue] Error on setting value '" + iValue + "' for field '" + iField.getName()
          + "' on object " + iInstance, e);
      throw new BindingException(iInstance, iField.getName(), e);
    }
  }

  private static Object assignDefaultValueToLiteral(Class<?> type) {
    Object value;
    if (type.equals(Integer.TYPE))
      value = Integer.valueOf(0);
    else if (type.equals(Long.TYPE))
      value = Long.valueOf(0);
    else if (type.equals(Short.TYPE))
      value = Short.valueOf((short) 0);
    else if (type.equals(Byte.TYPE))
      value = Byte.valueOf((byte) 0);
    else if (type.equals(Float.TYPE))
      value = Float.valueOf(0);
    else if (type.equals(Double.TYPE))
      value = Double.valueOf(0);
    else
      value = null;
    return value;
  }

  public static Field getField(Class<?> iClass, String iFieldName) {
    Field field = null;
    try {
      field = iClass.getDeclaredField(iFieldName);
    } catch (Exception e) {
      // NOT FOUND: TRY TO SEARCH RECURSIVELY IN TO INHERITANCE TREE
      Class<?> superClass = iClass.getSuperclass();
      if (superClass != null)
        field = getField(superClass, iFieldName);
    }
    return field;
  }

  /**
   * Get all fields of a class. This method differs from Class.getFields() since it returns also non public fields.
   * 
   * @param iClass
   *          Class<?> to introspect
   * @return Fields array
   */
  public static Field[] getFields(Class<?> iClass) {
    HashMap<String, Field> fieldSum = new HashMap<String, Field>();
    Class<?> currentClass = iClass;
    Field[] fields;

    // BROWSE CURRENT CLASS AND GO UP
    while (currentClass != null && currentClass != Object.class) {
      fields = currentClass.getDeclaredFields();
      for (int i = 0; i < fields.length; ++i)
        if (!fieldSum.containsKey(fields[i].getName()))
          // IF NOT PRESENT INSERT IT
          fieldSum.put(fields[i].getName(), fields[i]);
      currentClass = currentClass.getSuperclass();
    }

    Field[] result = new Field[fieldSum.size()];
    fieldSum.values().toArray(result);
    return result;
  }

  /**
   * Get all methods of a class. This method differs from Class.getMethods() since it reads the class and go up. if a method is
   * declared also in a base class will not be inserted, since the presumption is that the lower-defined method is more relevant
   * than higher one.
   * 
   * @param iClass
   *          Class<?> to introspect
   * @return Methods array
   */
  public static Method[] getMethods(Class<?> iClass) {
    HashMap<String, Method> methodSum = new HashMap<String, Method>();
    Class<?> currentClass = iClass;
    Method[] methods;

    // BROWSE CURRENT CLASS AND GO UP
    while (currentClass != null && currentClass != Object.class) {
      methods = currentClass.getDeclaredMethods();
      for (int i = 0; i < methods.length; ++i)
        if (!methodSum.containsKey(methods[i].getName()))
          // IF NOT PRESENT INSERT IT
          methodSum.put(methods[i].getName(), methods[i]);
      currentClass = currentClass.getSuperclass();
    }

    Method[] result = new Method[methodSum.size()];
    methodSum.values().toArray(result);
    return result;
  }

  public static boolean invokeEvent(ContentComponent iComponent, String iFieldName) throws IllegalArgumentException,
      IllegalAccessException, InvocationTargetException {

    // BROWSE UP UNTIL ROOT CONTENT COMPONENT SEARCHING THE EVENT
    SchemaObject currentSchemaInstance = iComponent.getSchemaInstance();
    ContentComponent currentComponent = iComponent;
    SchemaEvent event = null;
    Object currentContent;

    Object lastGoodContent = null;
    SchemaEvent lastGoodEvent = null;

    while (currentComponent != null) {
      event = currentSchemaInstance.getEvent(iFieldName);

      currentContent = currentComponent.getContent();

      if (event != null) {
        lastGoodEvent = event;
        lastGoodContent = currentContent;
      }

      if (currentComponent.getContainerComponent() != null) {
        currentComponent = currentComponent.getContainerComponent();
        if (!(currentComponent.getContent() instanceof ComposedEntity))
          break;
      } else
        break;

      currentSchemaInstance = currentComponent.getSchemaInstance();
    }

    // INVOKE THE FIELD EVENT IF ANY
    if (lastGoodEvent != null) {
      executeEventMethod(lastGoodContent, lastGoodEvent);
      return true;
    }
    return false;
  }

  public static boolean invokeEvent(Object iObject, String iFieldName) throws IllegalArgumentException, IllegalAccessException,
      InvocationTargetException {

    // BROWSE UP UNTIL ROOT CONTENT COMPONENT SEARCHING THE EVENT
    SchemaEvent event = null;
    Object currentContent = iObject;

    Object lastGoodContent = null;
    SchemaEvent lastGoodEvent = null;

    SchemaClass cls;

    while (currentContent != null) {
      cls = ObjectContext.getInstance().getComponent(SchemaManager.class).getClassInfo(currentContent.getClass().getSimpleName());

      event = cls.getEvent(iFieldName);
      if (event != null) {
        lastGoodEvent = event;
        lastGoodContent = currentContent;
        // FOUND: BREAK SEARCH
        break;
      }

      if (!(currentContent instanceof ComposedEntity))
        break;

      currentContent = ((ComposedEntity<?>) currentContent).getEntity();
    }

    // INVOKE THE FIELD EVENT IF ANY
    if (lastGoodEvent != null) {
      executeEventMethod(lastGoodContent, lastGoodEvent);
      return true;
    }
    return false;
  }

  private static void executeEventMethod(Object lastGoodContent, SchemaEvent lastGoodEvent) throws IllegalAccessException,
      InvocationTargetException {
    if (!Controller.getInstance().invokeBeforeActionCallbacks(lastGoodContent, lastGoodEvent)) {
      // JUMP EXECUTION
      log.info("[SchemaHelper.executeEventMethod] Execution broken by a registered callback");
      return;
    }

    try {
      lastGoodEvent.getMethod().invoke(lastGoodContent, NO_PARAMETERS);
    } finally {
      Controller.getInstance().invokeAfterActionCallbacks(lastGoodContent, lastGoodEvent);
    }
  }

  /**
   * Extract the selectedField feature and bind that field with the selection content.
   * 
   * @param iField
   * @param iContent
   * @param iSelection
   */
  public static void bindSelectionForField(SchemaField iField, Object iContent, Object[] iSelection) {
    String selectionFieldName = (String) iField.getFeature(ViewAspect.ASPECT_NAME, ViewFieldFeatures.SELECTION_FIELD);
    if (selectionFieldName != null) {
      // UPDATE SELECTION
      SchemaField selectionField = iField.getEntity().getField(selectionFieldName);
      Object selectedObject = SchemaHelper.getFieldObject(iContent, selectionFieldName);

      insertElements(selectionField, selectedObject, iSelection);
    }
  }

  

  public static void insertElements(SchemaField iField, Object iContent, Object[] iSelection) {
    if (iField == null) {
      log.warn("[SchemaHelper.insertElements] Field is null");
      return;
    }

    if (iContent == null) {
      log.warn("[SchemaHelper.insertElements] target object is null. Cannot to value field " + iField);
      return;
    }

    // TODO: REVIEW BIND MODE WITH NESTED FIELDS EXPRESSION
    Object currentValue = SchemaHelper.getFieldValue(iField, iContent);

    if (currentValue instanceof Collection) {
      // INSERT EACH ELEMENT OF SELECTION IN THE COLLECTION
      if (iSelection != null)
        for (Object o : iSelection) {
          ((Collection<Object>) currentValue).add(EntityHelper.getInstanceValue(o));
        }
    } else if (currentValue instanceof Map) {
      // INSERT EACH ELEMENT OF SELECTION IN THE MAP (KEY = SELECTION
      // OBJ.toString()
      if (iSelection != null)
        for (Object o : iSelection)
          ((Map<String, Object>) currentValue).put(EntityHelper.getInstanceValue(o).toString(), EntityHelper.getInstanceValue(o));
    } else if (iField.getTypeClass().isArray()) {
      Object array = null;
      if (iField.getTypeClass().equals(Object[].class))
        // OBJECT[]: NO CONVERSION REQUIRED
        array = iSelection;
      else if (iSelection != null) {
        // COPY THE ARRAY TO USE REAL CLASS ARRAY, IF ANY
        array = Array.newInstance(iField.getTypeClass().getComponentType(), iSelection.length);
        for (int i = 0; i < iSelection.length; ++i)
          Array.set(array, i, iSelection[i]);
      }
      SchemaHelper.setFieldValue(iField, iContent, array);
    } else {
      Object firstSelection = iSelection != null && iSelection.length > 0 ? iSelection[0] : null;
      SchemaHelper.setFieldValue(iField, iContent, firstSelection);
    }

    // REFRESH THE FIELD
    ObjectContext.getInstance().refresh(iContent, iField.getName());
  }

  public static Object removeElements(Object iContent, Object[] iSelection) {
    if (iContent == null)
      return null;

    Object result = null;

    if (iContent instanceof Collection) {
      Collection<?> coll = ((Collection<?>) iContent);
      for (int i = 0; i < iSelection.length; ++i) {
        coll.remove(iSelection[i]);
      }
    } else if (iContent instanceof Map) {
      Map<?, ?> map = ((Map<?, ?>) iContent);
      for (int i = 0; i < iSelection.length; ++i) {
        map.values().remove(iSelection[i]);
      }
    } else if (iContent instanceof Set) {
      Set<?> set = ((Set<?>) iContent);
      for (int i = 0; i < iSelection.length; ++i) {
        set.remove(iSelection[i]);
      }
    } else if (iContent.getClass().isArray()) {
      Object[] array = ((Object[]) iContent);
      List<Object> tempResult = new ArrayList<Object>(array.length);

      boolean found;
      for (int i = 0; i < array.length; ++i) {
        found = false;
        for (int sel = 0; sel < iSelection.length; ++sel) {
          if (array[i].equals(iSelection[sel])) {
            found = true;
            break;
          }
        }

        if (!found)
          // OK, NOT TO BE REMOVED
          tempResult.add(array[i]);
      }

      result = tempResult.toArray();
    }
    return result;
  }

  /**
   * Move an object up or down in a List or array objects.
   * 
   * @param iContent
   *          List or array object
   * @param iSelection
   *          The object to move.
   * @param iDirection
   *          use positive integer to move the item forward or negative for backward
   * @return new element position
   */
  public static int moveElement(Object iContent, Object iSelection, int iDirection) {
    if (iContent == null)
      return -1;

    int newPos = 1;
    if (iContent instanceof List) {
      List list = ((List) iContent);
      // SEARCH CURRENT POSITION
      int currPos = list.indexOf(iSelection);

      if (currPos > -1) {
        newPos = currPos + iDirection;
        if (newPos >= 0 && newPos < list.size()) {
          // OK, VALID RANGE: SWAP IT
          Object tmp = list.get(newPos);
          list.set(newPos, iSelection);
          list.set(currPos, tmp);
        }
      }
    } else if (iContent.getClass().isArray()) {
      Object[] array = ((Object[]) iContent);

      // SEARCH CURRENT POSITION
      int currPos = -1;
      for (int i = 0; i < array.length; ++i) {
        if (array[i].equals(iSelection)) {
          currPos = i;
          break;
        }
      }

      newPos = currPos + iDirection;
      if (newPos >= 0 && newPos < array.length) {
        // OK, VALID RANGE: SWAP IT
        Object tmp = array[newPos];
        array[newPos] = iSelection;
        array[currPos] = tmp;
      }
    }
    return newPos;
  }

  /**
   * Return the generic type if iType uses Java5+ Generics.
   * 
   * @param iType
   *          Type with generics
   * @return Generic Class<?> if any
   */
  public static Class<?> getGenericClass(Type iType) {
    // CHECK IF IT'S A PARAMETIZERED TYPE
    if (!(iType instanceof ParameterizedType))
      return null;

    Class<?> returnClass = null;

    // list the raw type information
    ParameterizedType ptype = (ParameterizedType) iType;
    Type rtype = ptype.getRawType();

    if (!(rtype instanceof Class))
      // NO CLASS: RETURN NULL
      return null;

    Type[] targs = ptype.getActualTypeArguments();

    if (targs == null || targs.length == 0)
      return null;

    Class<?> classType = (Class<?>) rtype;

    try {
      if (classType.isArray()) {
        returnClass = (Class<?>) targs[0];
      } else if (java.util.Collection.class.isAssignableFrom((Class<?>) rtype)) {
        Object arg = targs[0];
        if (arg instanceof Class)
          returnClass = (Class<?>) arg;
        else if (arg instanceof ParameterizedType) {
          ParameterizedType embType = (ParameterizedType) arg;
          Type embRType = embType.getRawType();
          returnClass = (Class<?>) embRType;
        } else if (arg instanceof GenericArrayType) {
          // GenericArrayType embType = (GenericArrayType) arg;
          // returnClass = (Class) embType.getGenericComponentType();
          returnClass = Array.class;
        } else if (arg instanceof TypeVariable) {
          TypeVariable<?> embType = (TypeVariable<?>) arg;
          returnClass = (Class<?>) embType.getGenericDeclaration();
        } else
          returnClass = Object.class;
      } else if (java.util.Map.class.isAssignableFrom((Class<?>) rtype)) {
        returnClass = (Class<?>) targs[1];
      }
    } catch (ClassCastException e) {
      throw new ConfigurationException("Cannot determine embedded type for " + iType + ". Embedded class not found", e);
    }

    return returnClass;
  }

  /**
   * Returns the object of field in expression.
   * 
   * @param iStartingObject
   *          Starting object to navigate
   * @param iExpression
   *          Path of field
   * @return
   */
  public static Object getFieldObject(Object iStartingObject, String iExpression) {
    int lastSep = iExpression.lastIndexOf('.');
    if (lastSep == -1)
      return iStartingObject;

    String exp = iExpression.substring(0, lastSep);
    exp = exp.replace('.', '/');

    JXPathContext context = JXPathContext.newContext(iStartingObject);
    return context.getValue(exp);
  }

  public static XmlConfigAreaType getDesktopConfiguration(Class<?> currentClass) {
    SchemaClass schema = null;
    SchemaManager schemaManager = ObjectContext.getInstance().getComponent(SchemaManager.class);
    while (currentClass != null) {
      schema = schemaManager.getClassInfo(currentClass.getSimpleName());
      if (schema != null) {
        XmlConfigAreaType rootArea = (XmlConfigAreaType) schema.getFeature(ViewAspect.ASPECT_NAME, ViewClassFeatures.FORM);
        if (rootArea != null) {
          return rootArea;
        }
      }
      currentClass = currentClass.getSuperclass();
    }
    return null;
  }

  public static boolean isMultiValueObject(Type embType) {
    if (embType instanceof GenericArrayType)
      return true;

    if (embType instanceof Class) {
      Class<? extends Object> embClass = (Class<? extends Object>) embType;
      if (Array.class.isAssignableFrom(embClass))
        return true;
      if (java.util.Collection.class.isAssignableFrom(embClass))
        return true;
      if (java.util.Map.class.isAssignableFrom(embClass))
        return true;
    }
    return false;
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.