Package org.fjank.jcache

Source Code of org.fjank.jcache.CacheGroup

/*   Open Source Java Caching Service
*    Copyright (C) 2002 Frank Karlstr�m
*    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
*    The author can be contacted by email: fjankk@users.sourceforge.net
*/
package org.fjank.jcache;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.fjank.jcache.collection.CollectionProxy;
import org.fjank.jcache.collection.SetProxy;
import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;

/**
* Class for representin grouops in the cache. Groups can contain CacheObjects
* and other groups.
*
* @author Frank Karlstr�m
*/
public class CacheGroup implements Serializable {
    /** the name of this group. */
    protected String name;
    /** the attributes for this group */
    private AttributesImpl attributes = new AttributesImpl();
    /** the current number of objects in this group. */
    private int currentSize;
    /** The number of objects in this group*/
    private int objectCount;
    /** the WeakReference objects in this group. */
    protected transient Map weakReferenceObjects = new ConcurrentHashMap();
    private transient final Map groups = new HashMap();
    /** the actual objects in this group. These objects are here until they expire
     * when they have expired, this map is cleared,
     * then the weakReference is also cleared, if and only if no other
     * code references the objects. */
    final transient Map objects = new ConcurrentHashMap();

    Map getGroups() {
        return groups;
    }

    /**
     * Creates a new CacheGroup object.
     *
     * @param name the name of the CacheGroup to create
     */
    public CacheGroup(final String name) {
        this(name, null);
    }

    /**
     * Creates a new CacheGroup object.
     *
     * @param name the name of the CacheGroup to create
     * @param attributes the attributes of the group to create
     */
    public CacheGroup(final String name, final AttributesImpl attributes) {
        setName(name);
        setAttributes(attributes);
    }

    /**
     * sets the attribute for this group
     *
     * @param attributes the attributes to set.
     */
    private void setAttributes(final AttributesImpl attributes) {
        if (attributes == null) {
            return;
        }
        this.attributes = attributes;
    }

    /**
     * sets the name of this group.
     *
     * @param name the name to set.
     */
    private void setName(final String name) {
        this.name = name;
    }

    /**
     * gets an object from this group.
     *
     * @param name the name of the object to retrieve.
     *
     * @return the named object, or null if it is not found.
     *
     */
    public Object get(final Object aName) {
        //      2004/09-FB
        if ((aName != null) && aName.equals(name)) {
            return this;
        }
        Object obj = weakReferenceObjects.get(aName);
        if (obj == null) {
            //      2004/09-FB
            for (Iterator iter = groups.keySet().iterator(); iter.hasNext();) {
                Object groupName = iter.next();
                CacheGroup group = (CacheGroup) groups.get(groupName);
                obj = group.get(aName);
                if (obj != null) {
                    return obj;
                }
            }
        }
        return obj;
    }

    /**
     * puts the named object into this group.
     *
     * @param name the name of the object
     * @param object the object to insert.
     *
     */
    public void put(final Object name, final CacheObject object, final Object realObject) {
        currentSize += object.getAttributes().getSize();
        increaseObjectCount();
        weakReferenceObjects.put(name, object);
        objects.put(name, realObject);
    }

    /**
     * puts the group into this group
     *
     * @param object the group to put.
     *
     */
    public void put(final CacheGroup group) {
        currentSize += group.getAttributes().getSize();
        groups.put(group.getName(), group);
    }

    /**
     * returns the attributes for this group.
     *
     * @return the attributes for this group.
     */
    AttributesImpl getAttributes() {
        return this.attributes;
    }

    /**
     * Will create a new version of the object indentified by the name,
     * replacing the current version with the object specified. If the object
     * doesn't exist in the cache, replace is equivalent to a put. The
     * attributes will be inherited from the existing object or if no object
     * exists, from the group or region the object associated with. Names are
     * in the scope of a region so they must be unique within the region they
     * are placed. This method is not valid on a disk, StreamAccess or Group
     * Object.
     *
     * @param name the name of the object to replace.
     * @param object The new object to be put in the cache.
     *
     * @return a reference to the newly replaced object.
     */
    public CacheObject replace(final Object name, final CacheObject object) {
        CacheObject oldObj = (CacheObject) weakReferenceObjects.get(name);
        if (oldObj != null) {
            if (oldObj.getAttributes() != null) {
                object.setAttributes(oldObj.getAttributes());
            }
            weakReferenceObjects.remove(name);
            objects.remove(name);
        } else {
            increaseObjectCount();
        }
        weakReferenceObjects.put(name, object);
        objects.put(name, object.get());
        return object;
    }

    /**
     * Setter for property valid.
     */
    public void invalidate() {
        Iterator iter = weakReferenceObjects.keySet().iterator();
        while (iter.hasNext()) {
            Object key = iter.next();
            CacheObject obj = (CacheObject) weakReferenceObjects.get(key);
            obj.invalidate();
        }
        objects.clear();
        iter = groups.keySet().iterator();
        while (iter.hasNext()) {
            Object key = iter.next();
            CacheGroup obj = (CacheGroup) groups.get(key);
            obj.invalidate();
        }
        this.objectCount = 0;
    }

    /**
     * Destroys this group and all its children.
     *
     */
    public void destroy() {
        this.attributes = null;
        this.currentSize = 0;
        this.name = null;
        for (Iterator iter = weakReferenceObjects.keySet().iterator(); iter.hasNext();) {
            ((CacheObject) weakReferenceObjects.get(iter.next())).destroy();
        }
        for (Iterator iter = groups.keySet().iterator(); iter.hasNext();) {
            ((CacheGroup) groups.get(iter.next())).destroy();
        }
        weakReferenceObjects.clear();
        objects.clear();
        groups.clear();
        weakReferenceObjects = null;
    }

    /**
     * Checks wether this group contains the specified objects
     * @param aName the name of the object to check
     *
     * @return a boolean indicating wether the object was present or not in
     *         this group.
     */
    public boolean contains(final Object aName) {
        if ((aName != null) && aName.equals(name)) {
            return true;
        }
        //check the real objects instead.
        if (objects.containsKey(aName))
            return true;
        //        for(Iterator iter = weakReferenceObjects.keySet().iterator();iter.hasNext();) {
        //      CacheObject obj = (CacheObject)weakReferenceObjects.get(iter.next());
        //            if ((obj.getKey() != null)
        //                && obj.getKey().equals(aName)) {
        //                return true;
        //            }
        //        }
        for (Iterator iter = groups.keySet().iterator(); iter.hasNext();) {
            Object groupName = iter.next();
            CacheGroup group = (CacheGroup) groups.get(groupName);
            if (group.contains(aName)) {
                return true;
            }
        }
        return false;
    }

    /**
     * removes the object from this group.
     *
     * @param object the object to remove.
     */
    public void removeMe(final CacheObject object) {
        Iterator iter = weakReferenceObjects.keySet().iterator();
        while (iter.hasNext()) {
            if (((CacheObject) weakReferenceObjects.get(iter.next())) == object) {
                iter.remove();
                objects.remove(object.getKey());
                decreaseObjectCount();
                currentSize -= object.getAttributes().getSize();
                break;
            }
        }
    }

    private void decreaseObjectCount() {
        this.objectCount = objectCount - 1;
    }

    private void increaseObjectCount() {
        this.objectCount = objectCount + 1;
    }

    /**
     * gets the current size (in bytes) of th3e objects in this group.
     *
     * @return the current size (in bytes) of th3e objects in this group.
     */
    int getCurrentSize() {
        return currentSize;
    }

    /**
     * gets the named group from this group.
     * If no group with the specified name is found, <code>null</code> is returned.
     * @param group the group to get.
     *
     * @return the named group.
     *
     */
    public CacheGroup getGroup(final String group) {
        return (CacheGroup) groups.get(group);
    }

    /**
     * gets the name of this group.
     *
     * @return the name of this group.
     */
    public String getName() {
        return name;
    }

    /** Return the current number of objects in this group.
     * @return the current number of objects in this group.
     */
    public int getObjectCount() {
        if (groups.isEmpty()) {
            return objectCount;
        }
        int count = objectCount;
        for (Iterator iter = groups.keySet().iterator(); iter.hasNext();) {
            Object key = iter.next();
            CacheGroup gr = (CacheGroup) groups.get(key);
            count += gr.getObjectCount();
        }
        return count;
    }

    /**returns a boolean indicating wether this value is present
     * in the cache root.
     * @param value the value to check
     * @return <code>true</code> if the value is present, <code>false</code> otherwise.
     */
    public boolean containsValue(Object value) {
        return objects.containsValue(value);
    }

    public Set keySet() {
        return new SetProxy(weakReferenceObjects.keySet(), this);
    }

    public Collection values() {
        return new CollectionProxy(weakReferenceObjects.values(), this);
    }

    public Set entrySet() {
        return new SetProxy(weakReferenceObjects.entrySet(), this);
    }

    void removeObjectReference(Object key) {
        //if(objects.containsKey(key)) {
        objects.remove(key);
        //decreaseObjectCount();
        //}
    }

    Map getObjectReferences() {
        return objects;
    }
}
TOP

Related Classes of org.fjank.jcache.CacheGroup

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.