Package com.ajjpj.amapper.javabean2.propbased

Source Code of com.ajjpj.amapper.javabean2.propbased.ASourceAndTargetProp

package com.ajjpj.amapper.javabean2.propbased;

import com.ajjpj.amapper.core2.AMapperDiffWorker;
import com.ajjpj.amapper.core2.AMapperWorker;
import com.ajjpj.amapper.core2.diff.ADiffBuilder;
import com.ajjpj.amapper.core2.path.APath;
import com.ajjpj.amapper.core2.path.APathSegment;
import com.ajjpj.amapper.core2.tpe.AQualifiedSourceAndTargetType;
import com.ajjpj.amapper.javabean2.JavaBeanMappingHelper;
import com.ajjpj.amapper.javabean2.propbased.accessors.APropertyAccessor;
import com.ajjpj.amapper.util.coll.AMap;
import com.ajjpj.amapper.util.coll.AOption;
import com.ajjpj.amapper.util.func.AFunction0;
import com.ajjpj.amapper.util.func.AVoidFunction1;

/**
* @author arno
*/
public class ASourceAndTargetProp<S,T> implements APartialBeanMapping<S,T,JavaBeanMappingHelper> {
    private final APropertyAccessor sourceProp;
    private final APropertyAccessor targetProp;

    private final AQualifiedSourceAndTargetType types;

    public ASourceAndTargetProp(APropertyAccessor sourceProp, APropertyAccessor targetProp) {
        if(! targetProp.isWritable()) {
            throw new IllegalArgumentException("target property is not writable: " + targetProp); //TODO weaken this condition - or what to handle this?!
        }

        this.sourceProp = sourceProp;
        this.targetProp = targetProp;

        this.types = new AQualifiedSourceAndTargetType (sourceProp.getType(), sourceProp.getSourceQualifier(), targetProp.getType(), targetProp.getTargetQualifier());
    }

    public ASourceAndTargetProp<T,S> reverse() {
        return new ASourceAndTargetProp<T, S>(targetProp, sourceProp);
    }

    @Override public String getSourceName() {
        return sourceProp.getName();
    }

    @Override public String getTargetName() {
        return targetProp.getName();
    }

    private APath childPath(APath path, boolean isSourceSide) {
        return path.withChild(APathSegment.simple(isSourceSide ? getSourceName() : getTargetName()));
    }

    @Override
    public String toString() {
        return "SourceAndTarget{" + sourceProp + " / " + targetProp + "}";
    }

    @Override public void doMap(S source, final T target, AMapperWorker<? extends JavaBeanMappingHelper> worker, AMap<String, Object> context, APath path) throws Exception {
        if(sourceProp.isDeferred()) {
            final AFunction0<Object,Exception> tp = new AFunction0<Object,Exception>() {
                @Override public Object apply() throws Exception {
                    return targetProp.get(target);
                }
            };

            worker.mapDeferred (childPath(path, true), sourceProp.get(source), tp, types, new AVoidFunction1<Object,Exception>() {
                @Override public void apply(Object o) throws Exception {
                    targetProp.set(target, o);
                }
            });
        }
        else {
            final Object oldTargetValue = targetProp.get(target);
            final AOption<Object> opt = worker.map(childPath(path, true), sourceProp.get(source), oldTargetValue, types, context);
            if(opt.isDefined() && opt.get() != oldTargetValue) {
                targetProp.set(target, opt.get());
            }
        }
    }

    @Override
    public void doDiff(ADiffBuilder diff, S sourceOld, S sourceNew, AMapperDiffWorker<? extends JavaBeanMappingHelper> worker, AMap<String, Object> contextOld, AMap<String, Object> contextNew, APath path, boolean isDerived) throws Exception {
        //TODO use 'default values' (e.g. based on an 'empty' target object) instead of this 'null' default --> add 'getDefaultValue()' to property accessor?
        final Object oldProp = sourceOld != null ? sourceProp.get(sourceOld) : null;
        final Object newProp = sourceNew != null ? sourceProp.get(sourceNew) : null; //TODO does sourceOld/New==null force 'isDerived'?

        if(sourceProp.isDeferred()) {
            worker.diffDeferred(childPath(path, false), oldProp, newProp, types, contextOld, contextNew, isDerived);
        }
        else {
            worker.diff (childPath (path, false), oldProp, newProp, types, contextOld, contextNew, isDerived);
        }
    }
}
TOP

Related Classes of com.ajjpj.amapper.javabean2.propbased.ASourceAndTargetProp

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.