Open Source Repository

Home /sojo/sojo-1.0.0 | Repository Home


net/sf/sojo/core/conversion/Iterateable2IterateableConversion.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.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import net.sf.sojo.core.ConversionException;
import net.sf.sojo.core.IConverter;
import net.sf.sojo.core.IConverterExtension;
import net.sf.sojo.core.IterateableConversion;
import net.sf.sojo.core.reflect.ReflectionHelper;
import net.sf.sojo.util.ArrayIterator;


/**
 * Convert iterateable object (list, set, array or map) into iterateable object.
 
 @author linke
 *
 */
public class Iterateable2IterateableConversion extends IterateableConversion {

  public static final Class DEFAULT_COLLECTION_TYPE = ArrayList.class;

  
  public Iterateable2IterateableConversion() {
    this(null);
  }
  
  
  public Iterateable2IterateableConversion(Class pvNewIteratableType) {
    newIteratableType = pvNewIteratableType;
    if (newIteratableType == null) {
      newIteratableType = DEFAULT_COLLECTION_TYPE;
    }
    validateTargetIteratableType(newIteratableType);
  }
  
  private void validateTargetIteratableType(Class pvIteratableType) {
    if (Collection.class.isAssignableFrom(pvIteratableType== false) {
      throw new IllegalArgumentException("The class: " + pvIteratableType + " must be implements the java.util.Collection interface.");
    }
    if (pvIteratableType.isInterface() == true) {
      throw new IllegalArgumentException("The class: " + pvIteratableType + " must be a implementation and not an interface.");
    }    
  }

  public final boolean isAssignableFrom(Object pvObject) {
    return ReflectionHelper.isIterateableType(pvObject);
  }
  
  public boolean isAssignableTo(final Class pvToType) {
    return ReflectionHelper.isIterateableType(pvToType);
  }

  
  public Object convert(final Object pvObject, final Class pvToType, final IConverterExtension pvConverter) {
    Iterator it = null
    int size = 0;

    if (pvObject.getClass().isArray()) {
      it = new ArrayIterator(pvObject);
      size = ((ArrayIteratorit).getLength();
    else {
      Collection lvOldList = (CollectionpvObject;
      size = lvOldList.size();
      it = lvOldList.iterator();
    }
    
    // entweder Array, Set oder List
    Object lvNewTargetType = null;
    // Array
    if (pvToType != null && pvToType.isArray()) {
      int lvSize = 0;
      if (pvObject instanceof Collection) {
        Collection lvOldList = (CollectionpvObject;
        lvSize = lvOldList.size();
      else {
        Object lvObjectArray[] (Object[]) pvObject;
        lvSize = lvObjectArray.length;
      }
      lvNewTargetType = Array.newInstance(pvToType.getComponentType(), lvSize);
    else {
      Class lvToType = ( ( pvToType == null || pvToType.isInterface() ) ? newIteratableType : pvToType);
      // Set
      if (pvToType != null && pvToType.isAssignableFrom(Set.class)  && ! lvToType.isAssignableFrom(Set.class) ) && pvObject instanceof Collection) {        
        lvNewTargetType = ReflectionHelper.createNewIteratableInstance(HashSet.class, size);
      
      // List
      else {
        lvNewTargetType = ReflectionHelper.createNewIteratableInstance(lvToType, size);
      }
    }
    return super.iterate(pvObject, lvNewTargetType, it, pvConverter);
  }

  

  protected Object[] doTransformIteratorObject2KeyValuePair(Object pvIteratorObject) {
    return new Object [] { null, pvIteratorObject};
  }

  protected Object[] doConvert(Object pvSourceObject, final Object pvNewTargetObject, Object pvKey, Object pvValue, IConverter pvConverter) {
    Object lvValueAfterConvert = pvConverter.convert(pvValue);
    return new Object [] { null, lvValueAfterConvert };
  }

  protected void doAddObject(Object pvSourceObject, Object pvNewTargetObject, Object pvKey, Object pvValue, int pvIteratorPosition) {
    if (pvNewTargetObject.getClass().isArray() == false) {
      Collection lvCollection = (CollectionpvNewTargetObject;
      lvCollection.add(pvValue);
    else {
      
      // transform value, is this a good idea?
      // pvValue.getClass != clazz
      try {
        Class clazz = pvNewTargetObject.getClass().getComponentType();
        if (pvValue != null && pvValue.getClass().equals(clazz== false) {
          pvValue = ReflectionHelper.createNewSimpleObject(clazz, pvValue);
        }
      catch (InstantiationException e) {
        throw new ConversionException(e.getMessage(), e);
      }
      
      Array.set(pvNewTargetObject, pvIteratorPosition, pvValue);
    }
  }
  
}