All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.avaje.ebeaninternal.server.deploy.BeanListHelp Maven / Gradle / Ivy

package com.avaje.ebeaninternal.server.deploy;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.InvalidValue;
import com.avaje.ebean.Query;
import com.avaje.ebean.Transaction;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollectionAdd;
import com.avaje.ebean.bean.BeanCollectionLoader;
import com.avaje.ebean.common.BeanList;
import com.avaje.ebeaninternal.server.text.json.WriteJsonContext;

/**
 * Helper object for dealing with Lists.
 */
public final class BeanListHelp implements BeanCollectionHelp {
	
	private final BeanPropertyAssocMany many;
	private final BeanDescriptor targetDescriptor;
	private BeanCollectionLoader loader;
	
	public BeanListHelp(BeanPropertyAssocMany many){
		this.many = many;
		this.targetDescriptor = many.getTargetDescriptor();
	}
	
	public BeanListHelp(){
		this.many = null;
		this.targetDescriptor = null;
	}
	
	public void setLoader(BeanCollectionLoader loader){
		this.loader = loader;
	}
	
	public void add(BeanCollection collection, Object bean) {
		collection.internalAdd(bean);
	}

	
	public BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) {
		
	    if (bc instanceof BeanList){
	    
    		BeanList bl = (BeanList)bc;
    		if (bl.getActualList() == null){
    			bl.setActualList(new ArrayList());
    		}
    		return bl;
	    } else if (bc instanceof List){
	        return new VanillaAdd((List)bc);
	        
	    } else {
	        throw new RuntimeException("Unhandled type "+bc);
	    }
	}

    @SuppressWarnings("unchecked")
    static class VanillaAdd implements BeanCollectionAdd {

		@SuppressWarnings("rawtypes")
		private final List list;

        private VanillaAdd(List list) {
            this.list = list;
        }

        public void addBean(Object bean) {
            list.add(bean);
        }
    }
    
	public Iterator getIterator(Object collection) {
        return ((List)collection).iterator();
    }
	
	@SuppressWarnings("unchecked")
    public Object copyCollection(Object source, CopyContext ctx, int maxDepth, Object parentBean) {
	    if (source instanceof List == false){
	        return null;
	    }

        List l = ctx.isVanillaMode()? new ArrayList() : new BeanList();

	    if (source instanceof BeanList == false){
	        l.addAll((List)source);
	        return l;
	        
	    } 
        BeanList bl = (BeanList)source;
        if (!bl.isPopulated()) {
            if (ctx.isVanillaMode() || parentBean == null){
                return null;
            } else {
                return createReference(parentBean, many.getName());
            }
        }
        List actualList = bl.getActualList();
        for (int i = 0; i < actualList.size(); i++) {
            Object sourceDetail = actualList.get(i);
            Object destDetail = targetDescriptor.createCopy(sourceDetail, ctx, maxDepth-1);
            l.add((T)destDetail);
        }
        return l;
    }
	
    public Object createEmpty(boolean vanilla) {
		return vanilla ? new ArrayList() : new BeanList();
	}

	public BeanCollection createReference(Object parentBean, String propertyName) {
		
		return new BeanList(loader, parentBean, propertyName);
	}
	
	public ArrayList validate(Object manyValue) {
		
		ArrayList errs = null;
		
		List l = (List)manyValue;
		for (int i = 0; i < l.size(); i++) {
			Object detailBean = l.get(i);
			InvalidValue invalid = targetDescriptor.validate(true, detailBean);
			if (invalid != null){
				if (errs == null){
					errs = new ArrayList();
				}
				errs.add(invalid);
			}
		}
		return errs;
	}
	
	public void refresh(EbeanServer server, Query query, Transaction t, Object parentBean) {

		BeanList newBeanList = (BeanList)server.findList(query, t);
		refresh(newBeanList, parentBean);
	}
	
	public void refresh(BeanCollection bc, Object parentBean) {

		BeanList newBeanList = (BeanList)bc;
		
		List currentList = (List)many.getValueUnderlying(parentBean);
		
		newBeanList.setModifyListening(many.getModifyListenMode());

		if (currentList == null){
			// the currentList is null?  Not really expecting this...
			many.setValue(parentBean,newBeanList);
			
		} else if (currentList instanceof BeanList) {
			// normally this case, replace just the underlying list
			BeanList currentBeanList = (BeanList)currentList;
			currentBeanList.setActualList(newBeanList.getActualList());
			currentBeanList.setModifyListening(many.getModifyListenMode());

		} else {
			// replace the entire list with the BeanList
			many.setValue(parentBean, newBeanList);
		}
	}
	
    public void jsonWrite(WriteJsonContext ctx, String name, Object collection, boolean explicitInclude) {
        
        List list;
        if (collection instanceof BeanCollection){
            BeanList beanList = (BeanList)collection;
            if (!beanList.isPopulated()){
                if (explicitInclude){
                    // invoke lazy loading as collection 
                    // is explicitly included in the output
                    beanList.size();
                } else {
                    return;
                }
            } 
            list = beanList.getActualList();
        } else {
            list = (List)collection;
        }
        
        ctx.beginAssocMany(name);
        for (int j = 0; j < list.size(); j++) {
            if (j > 0){
                ctx.appendComma();
            }
            Object detailBean = list.get(j);
            targetDescriptor.jsonWrite(ctx, detailBean);
        }
        ctx.endAssocMany();     
    }
    
}