Open Source Repository

Home /sojo/sojo-1.0.0 | Repository Home


net/sf/sojo/core/conversion/IterateableMap2BeanConversion.java
/*
 * Copyright 2002-2005 the original author or authors.
 *
 * 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 net.sf.sojo.core.conversion;

import java.lang.reflect.AccessibleObject;
import java.util.Iterator;
import java.util.Map;

import net.sf.sojo.core.ConversionException;
import net.sf.sojo.core.IConverter;
import net.sf.sojo.core.IConverterExtension;
import net.sf.sojo.core.UniqueIdGenerator;
import net.sf.sojo.core.reflect.Property;
import net.sf.sojo.core.reflect.ReflectionHelper;
import net.sf.sojo.core.reflect.ReflectionPropertyHelper;

/**
 * Convert map into bean (JavaBean) object.
 
 @author linke
 *
 */
public class IterateableMap2BeanConversion extends IterateableMap2MapConversion {

  private Class toType = null;
  
  public IterateableMap2BeanConversion() { }

  public boolean isAssignableFrom(Object pvObject) {
    boolean lvReturn = false;
    if (pvObject != null && toType != null) {
      lvReturn = ReflectionHelper.isComplexType(toType);
    }
    if (lvReturn == false) {
      lvReturn = ReflectionHelper.isComplexMapType(pvObject);
    }
    // remove toType (reset)
    toType = null;
    return lvReturn;
  }
  
  public boolean isAssignableTo(final Class pvToType) {
    toType = pvToType;
    return ReflectionHelper.isComplexMapType(pvToType);
  }

  
  
  public Object convert(final Object pvObject, final Class pvToType, IConverterExtension pvConverter) {
    final Map lvOldMap = (MappvObject;
    Object beanObject = null;
    try {
      beanObject = ReflectionHelper.createBeanFromMap(lvOldMap, pvToType);
    catch (Exception e) {
      throw new ConversionException(e.getMessage(), e);
    }
    String lvUniqueId = (StringlvOldMap.get(UniqueIdGenerator.UNIQUE_ID_PROPERTY);
    if (lvUniqueId != null) {
      pvConverter.addObject(lvUniqueId, beanObject);
    }
    
    String lvFilter[] (String[]) lvOldMap.keySet().toArray(new String[0]);
    
    
    Map lvSetterMap = ReflectionPropertyHelper.getAllSetterProperties(beanObject.getClass(), lvFilter);
    Iterator iter = lvSetterMap.entrySet().iterator();
    Object lvReturn = super.iterate(pvObject, beanObject, iter, pvConverter);
    return lvReturn;
  }


  protected Object[] doConvert(Object pvSourceObject, Object pvNewTargetObject, Object pvKey, Object pvValue, IConverter pvConverter) {
    
    Object lvReturnValue = null;

    AccessibleObject lvAccessibleObject = (AccessibleObjectpvValue;
    Property lvProperty = new Property(lvAccessibleObject);
    Class lvParamType = lvProperty.getParameterType();

    Map lvMap = (MappvSourceObject;
    Object lvValue = lvMap.get(pvKey);
    if (lvValue != null && lvValue.toString().startsWith(UniqueIdGenerator.UNIQUE_ID_PROPERTY)) {
      String lvKey = lvValue.toString().substring(UniqueIdGenerator.UNIQUE_ID_PROPERTY.length());
      lvReturnValue = ((IConverterExtensionpvConverter).getObjectByUniqueId(lvKey);
    else {
      lvReturnValue = pvConverter.convert(lvValue, lvParamType);
    }

    try {
      if (lvReturnValue != null)  {
        Class lvClass = ReflectionHelper.mapFromSimpeToWrapper(lvReturnValue.getClass());
        Class lvParamClass = ReflectionHelper.mapFromSimpeToWrapper(lvParamType);
        
        // method-param-type and param-value are incompatible, try to recover the situation
        if ! lvParamClass.isAssignableFrom(lvClass) ) {
          // convert value to the desired method-param-type
          lvReturnValue = ReflectionHelper.createNewSimpleObject(lvParamClass, lvReturnValue);
          // second try
          if ! lvParamClass.isAssignableFrom(lvReturnValue.getClass()) ) {
            throw new ConversionException("Can't execute property: " + lvAccessibleObject + ". Parameter are not assignable: " + lvParamClass + " <--> " + lvClass +
                " and value: " + lvReturnValue);
          }
         }
      }
      lvProperty.executeSetValue(pvNewTargetObject, lvReturnValue);
    catch (Exception e) {
      if (instanceof ConversionException) {
        throw (ConversionExceptione;
      else {
        throw new ConversionException("Can't invoke set property: " + lvAccessibleObject + " with arg: " + lvReturnValue, e);
      }
    
    
    return new Object[] { pvKey, lvReturnValue };
  }

  protected void doAddObject (Object pvSourceObject, Object pvNewTargetObject, Object pvKey, Object pvValue, int pvIteratorPosition) {
    // do nothing, overwrite the super method
  }
}