Package com.ajjpj.amapper.javabean.mappingdef

Source Code of com.ajjpj.amapper.javabean.mappingdef.CollectionToArrayMappingDef

package com.ajjpj.amapper.javabean.mappingdef;

import com.ajjpj.abase.collection.immutable.AMap;
import com.ajjpj.abase.collection.immutable.AOption;
import com.ajjpj.amapper.collection.ACollectionHelper;
import com.ajjpj.amapper.core.AIdentifierExtractor;
import com.ajjpj.amapper.core.AMapperDiffWorker;
import com.ajjpj.amapper.core.AMapperWorker;
import com.ajjpj.amapper.core.AObjectMappingDef;
import com.ajjpj.amapper.core.diff.ADiffBuilder;
import com.ajjpj.amapper.core.path.APath;
import com.ajjpj.amapper.core.tpe.AQualifiedSourceAndTargetType;
import com.ajjpj.amapper.core.tpe.AQualifiedType;
import com.ajjpj.amapper.core.tpe.AType;
import com.ajjpj.amapper.javabean.JavaBeanType;
import com.ajjpj.amapper.javabean.JavaBeanTypes;
import com.ajjpj.amapper.javabean.SingleParamBeanType;
import com.ajjpj.amapper.util.AArraySupport;

import java.lang.reflect.Array;
import java.util.*;


/**
* @author arno
*/
class CollectionToArrayMappingDef implements AObjectMappingDef<Object, Object, ACollectionHelper> {
    @Override public boolean canHandle (AQualifiedSourceAndTargetType types) throws Exception {
        return
                BuiltinCollectionMappingDefs.isBeanCollectionType (types.sourceType()) &&
                types.targetType() instanceof JavaBeanType &&
                ((JavaBeanType) types.targetType()).cls.isArray ();
    }

    @Override public boolean isCacheable () {
        return true;
    }

    @SuppressWarnings ("unchecked")
    @Override public Object map (Object source, Object target, AQualifiedSourceAndTargetType types, AMapperWorker<? extends ACollectionHelper> worker, AMap<String, Object> context, APath path) throws Exception {
        if (source == null) {
            return null;
        }

        final AQualifiedType sourceElementType = worker.getHelpers ().elementType (types.source ());
        final AQualifiedType targetElementType = worker.getHelpers ().elementType (types.target ());

        final AQualifiedSourceAndTargetType elTypes = AQualifiedSourceAndTargetType.create (sourceElementType, targetElementType);

        final Map<Object, Object> targetValuesByIdentifier = byIdentifier (worker.getHelpers ().asJuCollection (target, types.target ()),
                worker.getIdentifierExtractor (),
                targetElementType, // this is intentional: extract identifiers for target elements in terms of the target element type
                targetElementType);


        int index = 0;
        final List<Object> mappedTargetList = new ArrayList<> ();
        for (Object sourceEl: worker.getHelpers ().asJuCollection (source, types.source ())) {
            final Object sourceIdent = worker.getIdentifierExtractor ().uniqueIdentifier (sourceEl, sourceElementType, targetElementType);

            final APath elPath = path.withElementChild (index++, sourceIdent);
            final AOption<Object> mappedOpt = worker.map (elPath, sourceEl, targetValuesByIdentifier.get (sourceIdent), elTypes, context);
            if (mappedOpt.isDefined ()) {
                mappedTargetList.add (mappedOpt.get ());
            }
        }

        final Class<?> targetElementClass = ((SingleParamBeanType<?,?>) types.targetType()).paramCls;
        if (target == null || Array.getLength (target) != mappedTargetList.size ()) {
            target = Array.newInstance (targetElementClass, mappedTargetList.size ());
        }

        AArraySupport.setValues (target, mappedTargetList);

        return target;
    }

    private Map<Object, Object> byIdentifier (Collection<?> coll, AIdentifierExtractor identifierExtractor, AQualifiedType type, AQualifiedType targetType) {
        final Map<Object, Object> result = new HashMap<> ();

        if (coll == null) {
            return result;
        }

        for (Object o: coll) {
            result.put (identifierExtractor.uniqueIdentifier (o, type, targetType), o);
        }

        return result;
    }

    //TODO test this
    @Override public void diff (ADiffBuilder diff, Object sourceOld, Object sourceNew, AQualifiedSourceAndTargetType types, AMapperDiffWorker<? extends ACollectionHelper> worker, AMap<String, Object> contextOld, AMap<String, Object> contextNew, APath path, boolean isDerived) throws Exception {
        final AType targetElementType = worker.getHelpers ().elementType (types.target ()).tpe;
        final AType targetTypeAsList = JavaBeanTypes.create (List.class, ((JavaBeanType) targetElementType).cls);
        final AQualifiedSourceAndTargetType typesWithListTarget = AQualifiedSourceAndTargetType.create (types.source (), new AQualifiedType (targetTypeAsList, types.targetQualifier ()));

        worker.diff (path, sourceOld, sourceNew, typesWithListTarget, contextOld, contextNew, isDerived);
    }
}
TOP

Related Classes of com.ajjpj.amapper.javabean.mappingdef.CollectionToArrayMappingDef

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.