package com.sdicons.json.mapper.helper.impl;

/*
    JSONTools - Java JSON Tools
    Copyright (C) 2006 S.D.I.-Consulting BVBA
    http://www.sdi-consulting.com
    mailto://nospam@sdi-consulting.com

    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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

import com.sdicons.json.mapper.JSONMapper;
import com.sdicons.json.mapper.MapperException;
import com.sdicons.json.mapper.helper.ComplexMapperHelper;
import com.sdicons.json.model.JSONArray;
import com.sdicons.json.model.JSONValue;

import java.util.Collection;
import java.util.LinkedList;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class CollectionMapper
implements ComplexMapperHelper
{
    public Class getHelpedClass()
    {
        return Collection.class;
    }

    public Object toJava(JSONValue aValue, Class aRequestedClass)
    throws MapperException
    {
        return this.toJava(aValue, aRequestedClass, new Type[0]);
    }

    public Object toJava(JSONValue aValue, Class aRawClass, Type[] aTypes)
    throws MapperException
    {
        if (!aValue.isArray()) throw new MapperException("CollectionMapper cannot map: " + aValue.getClass().getName());
        if (!Collection.class.isAssignableFrom(aRawClass))
            throw new MapperException("CollectionMapper cannot map: " + aValue.getClass().getName());
        JSONArray aObject = (JSONArray) aValue;

        Collection lCollObj;

        try
        {
            // First we try to instantiate the correct
            // collection class.
            lCollObj = (Collection) aRawClass.newInstance();
        }
        catch (Exception e)
        {
            // If the requested class cannot create an instance because
            // it is abstract, or an interface, we use a default fallback class.
            // This solution is far from perfect, but we try to make the mapper
            // as convenient as possible.
            lCollObj = new LinkedList();
        }

        if(aTypes.length == 0)
        {
            // Simple, raw collection.
            for (JSONValue lVal : aObject.getValue())
            {
                lCollObj.add(JSONMapper.toJava(lVal));
            }
        }
        else if(aTypes.length == 1)
        {
            // Generic collection, we can make use of the type of the elements.            
            for (JSONValue lVal : aObject.getValue())
            {
                
                if(aTypes[0] instanceof Class)
                	lCollObj.add(JSONMapper.toJava(lVal, (Class) aTypes[0]));
                else
                	lCollObj.add(JSONMapper.toJava(lVal, (ParameterizedType) aTypes[0]));                	               
            }
        }
        else
        {
            // Not possible, a collection cannot have more than two types for
            // its contents.
            throw new MapperException("CollectionMapper cannot map: " + aValue.getClass().getName());
        }

        return lCollObj;
    }

    public JSONValue toJSON(Object aPojo)
    throws MapperException
    {
        JSONArray lArray = new JSONArray();
        if(! Collection.class.isAssignableFrom(aPojo.getClass())) throw new MapperException("CollectionMapper cannot map: " + aPojo.getClass().getName());

        Collection lColl = (Collection) aPojo;
        for(Object lEl : lColl)
        {
            lArray.getValue().add(JSONMapper.toJSON(lEl));
        }
        return lArray;
    }
}

@@ -1251,25 +1251,131 @@
 va.util.
-LinkedLis
+HashSet;%0D%0Aimport java.util.LinkedList;%0D%0Aimport java.util.Set;%0D%0Aimport java.util.SortedSet;%0D%0Aimport java.util.TreeSe
 t;%0D%0Aimpo
@@ -2375,32 +2375,417 @@
 s.%0D%0A            
+if(aRawClass.isInterface())%7B%0D%0A            %09//we still can't deal with some unusual interfaces. %0D%0A            %09if(aRawClass==Set.class)%7B%0D%0A            %09%09lCollObj = new HashSet();%0D%0A            %09%7Delse if(aRawClass==SortedSet.class)%7B%0D%0A            %09%09lCollObj = new TreeSet();%0D%0A            %09%7Delse%7B%0D%0A            %09%09lCollObj = new LinkedList();%0D%0A            %09%7D%0D%0A            %7Delse%7B%0D%0A            %09
 lCollObj = (Coll
@@ -2816,16 +2816,32 @@
 tance();
+%09%0D%0A            %7D
 %0D%0A      

support Set and SortedSet interfaces