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

com.avaje.ebean.common.BeanMap Maven / Gradle / Ivy

There is a newer version: 2.8.1
Show newest version
/**
 * Copyright (C) 2006  Robin Bygrave
 * 
 * This file is part of Ebean.
 * 
 * Ebean 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.
 *  
 * Ebean 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 Ebean; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA  
 */
package com.avaje.ebean.common;

import java.io.ObjectStreamException;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import com.avaje.ebean.bean.BeanCollectionLoader;
import com.avaje.ebean.bean.SerializeControl;

/**
 * Map capable of lazy loading.
 */
public final class BeanMap extends AbstractBeanCollection implements Map {

	/**
	 * The underlying map implementation.
	 */
	private Map map;

	/**
	 * Create with a given Map.
	 */
	public BeanMap(Map map) {
		this.map = map;
	}

	/**
	 * Create using a underlying LinkedHashMap.
	 */
	public BeanMap() {
		this(new LinkedHashMap());
	}

	public BeanMap(BeanCollectionLoader ebeanServer, Object ownerBean, String propertyName) {
		super(ebeanServer, ownerBean, propertyName);
	}

	Object readResolve() throws ObjectStreamException {
		if (SerializeControl.isVanillaCollections()) {
			return map;
		}
		return this;
	}

	Object writeReplace() throws ObjectStreamException {
		if (SerializeControl.isVanillaCollections()) {
			return map;
		}
		return this;
	}

	public void internalAdd(Object bean) {
		throw new RuntimeException("Not allowed for map");
	}
	
	/**
	 * Return true if the underlying map has been populated. Returns false if it
	 * has a deferred fetch pending.
	 */
	public boolean isPopulated() {
		return map != null;
	}
	
    /**
     * Return true if this is a reference (lazy loading) bean collection.
     * This is the same as !isPopulated();
     */	
    public boolean isReference() {
        return map == null;
    }
	
    public boolean checkEmptyLazyLoad() {
        if (map == null) {
            map = new LinkedHashMap();
            return true;
        } else {
            return false;
        }
    }

	private void initClear() {
		synchronized (this) {
			if (map == null) {
				if (modifyListening){
					lazyLoadCollection(true);						
				} else {
					map = new LinkedHashMap();
				}
			}
			touched();
		}
	}
	
	private void init() {
		synchronized (this) {
			if (map == null) {
				lazyLoadCollection(false);
			}
			touched();
		}
	}

	/**
	 * Set the actual underlying map. Used for performing lazy fetch.
	 */
	@SuppressWarnings("unchecked")
	public void setActualMap(Map map) {
		this.map = (Map) map;
	}

	/**
	 * Return the actual underlying map.
	 */
	public Map getActualMap() {
		return map;
	}

	/**
	 * Returns the map entrySet iterator.
	 * 

* This is because the key values may need to be set against the details (so * they don't need to be set twice). *

*/ public Collection getActualDetails() { return map.values(); } /** * Returns the underlying map. */ public Object getActualCollection() { return map; } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("BeanMap "); if (isSharedInstance()){ sb.append("sharedInstance "); } else if (isReadOnly()){ sb.append("readOnly "); } if (map == null) { sb.append("deferred "); } else { sb.append("size[").append(map.size()).append("]"); sb.append(" hasMoreRows[").append(hasMoreRows).append("]"); sb.append(" map").append(map); } return sb.toString(); } /** * Equal if obj is a Map and equal in a Map sense. */ public boolean equals(Object obj) { init(); return map.equals(obj); } public int hashCode() { init(); return map.hashCode(); } public void clear() { checkReadOnly(); initClear(); if (modifyRemoveListening) { for (K key : map.keySet()) { E o = map.remove(key); modifyRemoval(o); } } map.clear(); } public boolean containsKey(Object key) { init(); return map.containsKey(key); } public boolean containsValue(Object value) { init(); return map.containsValue(value); } @SuppressWarnings({ "unchecked", "rawtypes" }) public Set> entrySet() { init(); if (isReadOnly()){ return Collections.unmodifiableSet(map.entrySet()); } if (modifyListening) { Set> s = map.entrySet(); return new ModifySet(this, s); } return map.entrySet(); } public E get(Object key) { init(); return map.get(key); } public boolean isEmpty() { init(); return map.isEmpty(); } public Set keySet() { init(); if (isReadOnly()){ return Collections.unmodifiableSet(map.keySet()); } // we don't really care about modifications to the ketSet? return map.keySet(); } public E put(K key, E value) { checkReadOnly(); init(); if (modifyListening) { Object o = map.put(key, value); modifyAddition(value); modifyRemoval(o); } return map.put(key, value); } @SuppressWarnings({ "unchecked", "rawtypes" }) public void putAll(Map t) { checkReadOnly(); init(); if (modifyListening) { Iterator it = t.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); Object o = map.put((K) entry.getKey(), (E) entry.getValue()); modifyAddition((E) entry.getValue()); modifyRemoval(o); } } map.putAll(t); } public E remove(Object key) { checkReadOnly(); init(); if (modifyRemoveListening) { E o = map.remove(key); modifyRemoval(o); return o; } return map.remove(key); } public int size() { init(); return map.size(); } public Collection values() { init(); if (isReadOnly()){ return Collections.unmodifiableCollection(map.values()); } if (modifyListening) { Collection c = map.values(); return new ModifyCollection(this, c); } return map.values(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy